0g-chain/x/incentive/keeper/hooks.go
Derrick Lee 26a4b93588
Add base earn incentives (#1292)
* Add incentive types

* Add earn state methods

* Update earn incentives

* Update unit test NewKeeper to include earn keeper

* Fix sharesOwned typo

* Shares not used for AfterVaultDepositCreated

* Add earn to init genesis

* Pass earn keeper to incentive keeper

* Add sdk.Msg impl, disable legacy migrations

* Disable migrations

* Update incentive earn sync test

* Add earn to client and querier

* Add accum and init tests

* Add additional earn tests

* Fill in fakeEarnKeeper methods to fix tests

* Add earn reward periods to params, begin blocker earn reward

* Add earn to query

* Update genesis_test with missing DefaultMultiRewardPeriods parameter

* Remove disable of migration package

* Fix proto type comments

* Remove unused migration state

* Add legacytx.LegacyMsg compile time interface check

* add earn state validation to genesis validation

Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com>
2022-09-22 11:26:08 -07:00

204 lines
8.5 KiB
Go

package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
savingstypes "github.com/kava-labs/kava/x/savings/types"
swaptypes "github.com/kava-labs/kava/x/swap/types"
)
// Hooks wrapper struct for hooks
type Hooks struct {
k Keeper
}
var (
_ cdptypes.CDPHooks = Hooks{}
_ hardtypes.HARDHooks = Hooks{}
_ stakingtypes.StakingHooks = Hooks{}
_ swaptypes.SwapHooks = Hooks{}
_ savingstypes.SavingsHooks = Hooks{}
_ earntypes.EarnHooks = Hooks{}
)
// Hooks create new incentive hooks
func (k Keeper) Hooks() Hooks { return Hooks{k} }
// ------------------- Cdp Module Hooks -------------------
// AfterCDPCreated function that runs after a cdp is created
func (h Hooks) AfterCDPCreated(ctx sdk.Context, cdp cdptypes.CDP) {
h.k.InitializeUSDXMintingClaim(ctx, cdp)
}
// BeforeCDPModified function that runs before a cdp is modified
// note that this is called immediately after interest is synchronized, and so could potentially
// be called AfterCDPInterestUpdated or something like that, if we we're to expand the scope of cdp hooks
func (h Hooks) BeforeCDPModified(ctx sdk.Context, cdp cdptypes.CDP) {
h.k.SynchronizeUSDXMintingReward(ctx, cdp)
}
// ------------------- Hard Module Hooks -------------------
// AfterDepositCreated function that runs after a deposit is created
func (h Hooks) AfterDepositCreated(ctx sdk.Context, deposit hardtypes.Deposit) {
h.k.InitializeHardSupplyReward(ctx, deposit)
}
// BeforeDepositModified function that runs before a deposit is modified
func (h Hooks) BeforeDepositModified(ctx sdk.Context, deposit hardtypes.Deposit) {
h.k.SynchronizeHardSupplyReward(ctx, deposit)
}
// AfterDepositModified function that runs after a deposit is modified
func (h Hooks) AfterDepositModified(ctx sdk.Context, deposit hardtypes.Deposit) {
h.k.UpdateHardSupplyIndexDenoms(ctx, deposit)
}
// AfterBorrowCreated function that runs after a borrow is created
func (h Hooks) AfterBorrowCreated(ctx sdk.Context, borrow hardtypes.Borrow) {
h.k.InitializeHardBorrowReward(ctx, borrow)
}
// BeforeBorrowModified function that runs before a borrow is modified
func (h Hooks) BeforeBorrowModified(ctx sdk.Context, borrow hardtypes.Borrow) {
h.k.SynchronizeHardBorrowReward(ctx, borrow)
}
// AfterBorrowModified function that runs after a borrow is modified
func (h Hooks) AfterBorrowModified(ctx sdk.Context, borrow hardtypes.Borrow) {
h.k.UpdateHardBorrowIndexDenoms(ctx, borrow)
}
/* ------------------- Staking Module Hooks -------------------
Rewards are calculated based on total delegated tokens to bonded validators (not shares).
We need to sync the claim before the user's delegated tokens are changed.
When delegated tokens (to bonded validators) are changed:
- user creates new delegation
- total bonded delegation increases
- user delegates or beginUnbonding or beginRedelegate an existing delegation
- total bonded delegation increases or decreases
- validator is slashed and Jailed/Tombstoned (tokens reduce, and validator is unbonded)
- slash: total bonded delegation decreases (less tokens)
- jail: total bonded delegation decreases (tokens no longer bonded (after end blocker runs))
- validator becomes unbonded (ie when they drop out of the top 100)
- total bonded delegation decreases (tokens no longer bonded)
- validator becomes bonded (ie when they're promoted into the top 100)
- total bonded delegation increases (tokens become bonded)
*/
// BeforeDelegationCreated runs before a delegation is created
func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
// Add a claim if one doesn't exist, otherwise sync the existing.
h.k.InitializeDelegatorReward(ctx, delAddr)
}
// BeforeDelegationSharesModified runs before an existing delegation is modified
func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
// Sync rewards based on total delegated to bonded validators.
h.k.SynchronizeDelegatorRewards(ctx, delAddr, nil, false)
}
// BeforeValidatorSlashed is called before a validator is slashed
// Validator status is not updated when Slash or Jail is called
func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {
// Sync all claims for users delegated to this validator.
// For each claim, sync based on the total delegated to bonded validators.
for _, delegation := range h.k.stakingKeeper.GetValidatorDelegations(ctx, valAddr) {
h.k.SynchronizeDelegatorRewards(ctx, delegation.GetDelegatorAddr(), nil, false)
}
}
// AfterValidatorBeginUnbonding is called after a validator begins unbonding
// Validator status is set to Unbonding prior to hook running
func (h Hooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
// Sync all claims for users delegated to this validator.
// For each claim, sync based on the total delegated to bonded validators, and also delegations to valAddr.
// valAddr's status has just been set to Unbonding, but we want to include delegations to it in the sync.
for _, delegation := range h.k.stakingKeeper.GetValidatorDelegations(ctx, valAddr) {
h.k.SynchronizeDelegatorRewards(ctx, delegation.GetDelegatorAddr(), valAddr, true)
}
}
// AfterValidatorBonded is called after a validator is bonded
// Validator status is set to Bonded prior to hook running
func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
// Sync all claims for users delegated to this validator.
// For each claim, sync based on the total delegated to bonded validators, except for delegations to valAddr.
// valAddr's status has just been set to Bonded, but we don't want to include delegations to it in the sync
for _, delegation := range h.k.stakingKeeper.GetValidatorDelegations(ctx, valAddr) {
h.k.SynchronizeDelegatorRewards(ctx, delegation.GetDelegatorAddr(), valAddr, false)
}
}
// NOTE: following hooks are just implemented to ensure StakingHooks interface compliance
// AfterDelegationModified runs after a delegation is modified
func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
}
// BeforeDelegationRemoved runs directly before a delegation is deleted. BeforeDelegationSharesModified is run prior to this.
func (h Hooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
}
// AfterValidatorCreated runs after a validator is created
func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {}
// BeforeValidatorModified runs before a validator is modified
func (h Hooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {}
// AfterValidatorRemoved runs after a validator is removed
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
}
// ------------------- Swap Module Hooks -------------------
func (h Hooks) AfterPoolDepositCreated(ctx sdk.Context, poolID string, depositor sdk.AccAddress, _ sdk.Int) {
h.k.InitializeSwapReward(ctx, poolID, depositor)
}
func (h Hooks) BeforePoolDepositModified(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharesOwned sdk.Int) {
h.k.SynchronizeSwapReward(ctx, poolID, depositor, sharesOwned)
}
// ------------------- Savings Module Hooks -------------------
// AfterSavingsDepositCreated function that runs after a deposit is created
func (h Hooks) AfterSavingsDepositCreated(ctx sdk.Context, deposit savingstypes.Deposit) {
h.k.InitializeSavingsReward(ctx, deposit)
}
// BeforeSavingsDepositModified function that runs before a deposit is modified
func (h Hooks) BeforeSavingsDepositModified(ctx sdk.Context, deposit savingstypes.Deposit, incomingDenoms []string) {
h.k.SynchronizeSavingsReward(ctx, deposit, incomingDenoms)
}
// ------------------- Earn Module Hooks -------------------
// AfterVaultDepositCreated function that runs after a vault deposit is created
func (h Hooks) AfterVaultDepositCreated(
ctx sdk.Context,
vaultDenom string,
depositor sdk.AccAddress,
_ sdk.Dec,
) {
h.k.InitializeEarnReward(ctx, vaultDenom, depositor)
}
// BeforeVaultDepositModified function that runs before a vault deposit is modified
func (h Hooks) BeforeVaultDepositModified(
ctx sdk.Context,
vaultDenom string,
depositor sdk.AccAddress,
sharesOwned sdk.Dec,
) {
h.k.SynchronizeEarnReward(ctx, vaultDenom, depositor, sharesOwned)
}