mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
Update delegator rewards to multi-reward index (#945)
* update claim attribute type to MultiRewardIndexes * update param attribute type to MultiRewardPeriods * keeper: update params to match types * keeper: update delegator core keeper methods * keeper: update InitializeHardDelegatorReward * keeper: update SynchronizeHardDelegatorRewards * remove reward factor in favor of reward indexes * update querier * fix test: delegator init test * fix test: delegator sync test * implement delegator reward accumulation * fix test: delegator general tests * add legact types, update v0_11 -> v0_14 migration * remove duplicate import form v0_15 migration * implement v0_15incentive migration * test data and migration test * add multiple reward denoms to init/sync tests * update delegator test with multiple reward coins * clean up simulation sync
This commit is contained in:
parent
baf17b4ec8
commit
bc33b94822
@ -23,8 +23,8 @@ import (
|
|||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
v0_14hard "github.com/kava-labs/kava/x/hard"
|
v0_14hard "github.com/kava-labs/kava/x/hard"
|
||||||
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
|
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
|
||||||
v0_14incentive "github.com/kava-labs/kava/x/incentive"
|
|
||||||
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
|
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
|
||||||
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
"github.com/kava-labs/kava/x/kavadist"
|
"github.com/kava-labs/kava/x/kavadist"
|
||||||
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
||||||
v0_14pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
v0_14pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
v0_14hard "github.com/kava-labs/kava/x/hard"
|
v0_14hard "github.com/kava-labs/kava/x/hard"
|
||||||
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
|
v0_11hard "github.com/kava-labs/kava/x/hard/legacy/v0_11"
|
||||||
v0_14incentive "github.com/kava-labs/kava/x/incentive"
|
|
||||||
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
|
v0_11incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_11"
|
||||||
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
||||||
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
|
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||||
|
|
||||||
|
@ -12,13 +12,16 @@ import (
|
|||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
"github.com/kava-labs/kava/x/committee/types"
|
|
||||||
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
||||||
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// TODO: update GenesisTime for kava-8 launch
|
// TODO: update GenesisTime for kava-8 launch
|
||||||
GenesisTime = time.Date(2021, 4, 8, 15, 0, 0, 0, time.UTC)
|
GenesisTime = time.Date(2021, 4, 8, 15, 0, 0, 0, time.UTC)
|
||||||
|
// TODO: update SWP reward per second amount before production
|
||||||
|
SwpRewardsPerSecond = sdk.NewCoin("swp", sdk.OneInt())
|
||||||
)
|
)
|
||||||
|
|
||||||
// Migrate translates a genesis file from kava v0.14 format to kava v0.15 format
|
// Migrate translates a genesis file from kava v0.14 format to kava v0.15 format
|
||||||
@ -47,6 +50,15 @@ func Migrate(genDoc tmtypes.GenesisDoc) tmtypes.GenesisDoc {
|
|||||||
// MigrateAppState migrates application state from v0.14 format to a kava v0.15 format
|
// MigrateAppState migrates application state from v0.14 format to a kava v0.15 format
|
||||||
func MigrateAppState(v0_14AppState genutil.AppMap) genutil.AppMap {
|
func MigrateAppState(v0_14AppState genutil.AppMap) genutil.AppMap {
|
||||||
v0_15AppState := v0_14AppState
|
v0_15AppState := v0_14AppState
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
|
||||||
|
// Migrate incentive app state
|
||||||
|
if v0_14AppState[v0_14incentive.ModuleName] != nil {
|
||||||
|
var incentiveGenState v0_14incentive.GenesisState
|
||||||
|
cdc.MustUnmarshalJSON(v0_14AppState[v0_15incentive.ModuleName], &incentiveGenState)
|
||||||
|
delete(v0_14AppState, v0_14incentive.ModuleName)
|
||||||
|
v0_15AppState[v0_15incentive.ModuleName] = cdc.MustMarshalJSON(Incentive(incentiveGenState))
|
||||||
|
}
|
||||||
|
|
||||||
// Migrate commmittee app state
|
// Migrate commmittee app state
|
||||||
if v0_14AppState[v0_14committee.ModuleName] != nil {
|
if v0_14AppState[v0_14committee.ModuleName] != nil {
|
||||||
@ -75,7 +87,7 @@ func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisS
|
|||||||
for _, com := range genesisState.Committees {
|
for _, com := range genesisState.Committees {
|
||||||
if com.ID == 1 {
|
if com.ID == 1 {
|
||||||
// Initialize member committee without permissions
|
// Initialize member committee without permissions
|
||||||
stabilityCom := types.NewMemberCommittee(com.ID, com.Description, com.Members,
|
stabilityCom := v0_15committee.NewMemberCommittee(com.ID, com.Description, com.Members,
|
||||||
[]v0_15committee.Permission{}, com.VoteThreshold, com.ProposalDuration,
|
[]v0_15committee.Permission{}, com.VoteThreshold, com.ProposalDuration,
|
||||||
v0_15committee.FirstPastThePost)
|
v0_15committee.FirstPastThePost)
|
||||||
|
|
||||||
@ -171,7 +183,7 @@ func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisS
|
|||||||
newStabilityCom := v0_15committee.MemberCommittee{BaseCommittee: baseStabilityCom}
|
newStabilityCom := v0_15committee.MemberCommittee{BaseCommittee: baseStabilityCom}
|
||||||
committees = append(committees, newStabilityCom)
|
committees = append(committees, newStabilityCom)
|
||||||
} else {
|
} else {
|
||||||
safetyCom := types.NewMemberCommittee(com.ID, com.Description, com.Members,
|
safetyCom := v0_15committee.NewMemberCommittee(com.ID, com.Description, com.Members,
|
||||||
[]v0_15committee.Permission{v0_15committee.SoftwareUpgradePermission{}},
|
[]v0_15committee.Permission{v0_15committee.SoftwareUpgradePermission{}},
|
||||||
com.VoteThreshold, com.ProposalDuration, v0_15committee.FirstPastThePost)
|
com.VoteThreshold, com.ProposalDuration, v0_15committee.FirstPastThePost)
|
||||||
committees = append(committees, safetyCom)
|
committees = append(committees, safetyCom)
|
||||||
@ -179,7 +191,7 @@ func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisS
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range genesisState.Votes {
|
for _, v := range genesisState.Votes {
|
||||||
newVote := v0_15committee.NewVote(v.ProposalID, v.Voter, types.Yes)
|
newVote := v0_15committee.NewVote(v.ProposalID, v.Voter, v0_15committee.Yes)
|
||||||
votes = append(votes, v0_15committee.Vote(newVote))
|
votes = append(votes, v0_15committee.Vote(newVote))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,3 +203,141 @@ func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisS
|
|||||||
return v0_15committee.NewGenesisState(
|
return v0_15committee.NewGenesisState(
|
||||||
genesisState.NextProposalID, committees, proposals, votes)
|
genesisState.NextProposalID, committees, proposals, votes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Incentive migrates from a v0.14 incentive genesis state to a v0.15 incentive genesis state
|
||||||
|
func Incentive(incentiveGS v0_14incentive.GenesisState) v0_15incentive.GenesisState {
|
||||||
|
// Migrate params
|
||||||
|
var claimMultipliers v0_15incentive.Multipliers
|
||||||
|
for _, m := range incentiveGS.Params.ClaimMultipliers {
|
||||||
|
newMultiplier := v0_15incentive.NewMultiplier(v0_15incentive.MultiplierName(m.Name), m.MonthsLockup, m.Factor)
|
||||||
|
claimMultipliers = append(claimMultipliers, newMultiplier)
|
||||||
|
}
|
||||||
|
|
||||||
|
var usdxMintingRewardPeriods v0_15incentive.RewardPeriods
|
||||||
|
for _, rp := range incentiveGS.Params.USDXMintingRewardPeriods {
|
||||||
|
usdxMintingRewardPeriod := v0_15incentive.NewRewardPeriod(rp.Active,
|
||||||
|
rp.CollateralType, rp.Start, rp.End, rp.RewardsPerSecond)
|
||||||
|
usdxMintingRewardPeriods = append(usdxMintingRewardPeriods, usdxMintingRewardPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardSupplyRewardPeriods v0_15incentive.MultiRewardPeriods
|
||||||
|
for _, rp := range incentiveGS.Params.HardSupplyRewardPeriods {
|
||||||
|
hardSupplyRewardPeriod := v0_15incentive.NewMultiRewardPeriod(rp.Active,
|
||||||
|
rp.CollateralType, rp.Start, rp.End, rp.RewardsPerSecond)
|
||||||
|
hardSupplyRewardPeriods = append(hardSupplyRewardPeriods, hardSupplyRewardPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardBorrowRewardPeriods v0_15incentive.MultiRewardPeriods
|
||||||
|
for _, rp := range incentiveGS.Params.HardBorrowRewardPeriods {
|
||||||
|
hardBorrowRewardPeriod := v0_15incentive.NewMultiRewardPeriod(rp.Active,
|
||||||
|
rp.CollateralType, rp.Start, rp.End, rp.RewardsPerSecond)
|
||||||
|
hardBorrowRewardPeriods = append(hardBorrowRewardPeriods, hardBorrowRewardPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardDelegatorRewardPeriods v0_15incentive.MultiRewardPeriods
|
||||||
|
for _, rp := range incentiveGS.Params.HardDelegatorRewardPeriods {
|
||||||
|
rewardsPerSecond := sdk.NewCoins(rp.RewardsPerSecond, SwpRewardsPerSecond)
|
||||||
|
hardDelegatorRewardPeriod := v0_15incentive.NewMultiRewardPeriod(rp.Active,
|
||||||
|
rp.CollateralType, rp.Start, rp.End, rewardsPerSecond)
|
||||||
|
hardDelegatorRewardPeriods = append(hardDelegatorRewardPeriods, hardDelegatorRewardPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build new params from migrated values
|
||||||
|
params := v0_15incentive.NewParams(
|
||||||
|
usdxMintingRewardPeriods,
|
||||||
|
hardSupplyRewardPeriods,
|
||||||
|
hardBorrowRewardPeriods,
|
||||||
|
hardDelegatorRewardPeriods,
|
||||||
|
claimMultipliers,
|
||||||
|
incentiveGS.Params.ClaimEnd,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Migrate accumulation times
|
||||||
|
var usdxAccumulationTimes v0_15incentive.GenesisAccumulationTimes
|
||||||
|
for _, t := range incentiveGS.USDXAccumulationTimes {
|
||||||
|
newAccumulationTime := v0_15incentive.NewGenesisAccumulationTime(t.CollateralType, t.PreviousAccumulationTime)
|
||||||
|
usdxAccumulationTimes = append(usdxAccumulationTimes, newAccumulationTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardSupplyAccumulationTimes v0_15incentive.GenesisAccumulationTimes
|
||||||
|
for _, t := range incentiveGS.HardSupplyAccumulationTimes {
|
||||||
|
newAccumulationTime := v0_15incentive.NewGenesisAccumulationTime(t.CollateralType, t.PreviousAccumulationTime)
|
||||||
|
hardSupplyAccumulationTimes = append(hardSupplyAccumulationTimes, newAccumulationTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardBorrowAccumulationTimes v0_15incentive.GenesisAccumulationTimes
|
||||||
|
for _, t := range incentiveGS.HardBorrowAccumulationTimes {
|
||||||
|
newAccumulationTime := v0_15incentive.NewGenesisAccumulationTime(t.CollateralType, t.PreviousAccumulationTime)
|
||||||
|
hardBorrowAccumulationTimes = append(hardBorrowAccumulationTimes, newAccumulationTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardDelegatorAccumulationTimes v0_15incentive.GenesisAccumulationTimes
|
||||||
|
for _, t := range incentiveGS.HardDelegatorAccumulationTimes {
|
||||||
|
newAccumulationTime := v0_15incentive.NewGenesisAccumulationTime(t.CollateralType, t.PreviousAccumulationTime)
|
||||||
|
hardDelegatorAccumulationTimes = append(hardDelegatorAccumulationTimes, newAccumulationTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate USDX minting claims
|
||||||
|
var usdxMintingClaims v0_15incentive.USDXMintingClaims
|
||||||
|
for _, claim := range incentiveGS.USDXMintingClaims {
|
||||||
|
var rewardIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, ri := range claim.RewardIndexes {
|
||||||
|
rewardIndex := v0_15incentive.NewRewardIndex(ri.CollateralType, ri.RewardFactor)
|
||||||
|
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
usdxMintingClaim := v0_15incentive.NewUSDXMintingClaim(claim.Owner, claim.Reward, rewardIndexes)
|
||||||
|
usdxMintingClaims = append(usdxMintingClaims, usdxMintingClaim)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate Hard protocol claims (including delegation rewards)
|
||||||
|
var hardClaims v0_15incentive.HardLiquidityProviderClaims
|
||||||
|
for _, claim := range incentiveGS.HardLiquidityProviderClaims {
|
||||||
|
// Migrate supply multi reward indexes
|
||||||
|
var supplyMultiRewardIndexes v0_15incentive.MultiRewardIndexes
|
||||||
|
for _, sri := range claim.SupplyRewardIndexes {
|
||||||
|
var rewardIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, ri := range sri.RewardIndexes {
|
||||||
|
rewardIndex := v0_15incentive.NewRewardIndex(ri.CollateralType, ri.RewardFactor)
|
||||||
|
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
supplyMultiRewardIndex := v0_15incentive.NewMultiRewardIndex(sri.CollateralType, rewardIndexes)
|
||||||
|
supplyMultiRewardIndexes = append(supplyMultiRewardIndexes, supplyMultiRewardIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate borrow multi reward indexes
|
||||||
|
var borrowMultiRewardIndexes v0_15incentive.MultiRewardIndexes
|
||||||
|
for _, bri := range claim.BorrowRewardIndexes {
|
||||||
|
var rewardIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, ri := range bri.RewardIndexes {
|
||||||
|
rewardIndex := v0_15incentive.NewRewardIndex(ri.CollateralType, ri.RewardFactor)
|
||||||
|
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
borrowMultiRewardIndex := v0_15incentive.NewMultiRewardIndex(bri.CollateralType, rewardIndexes)
|
||||||
|
borrowMultiRewardIndexes = append(borrowMultiRewardIndexes, borrowMultiRewardIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate delegator reward indexes to multi reward indexes under BondDenom
|
||||||
|
var delegatorMultiRewardIndexes v0_15incentive.MultiRewardIndexes
|
||||||
|
var delegatorRewardIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, ri := range claim.DelegatorRewardIndexes {
|
||||||
|
delegatorRewardIndex := v0_15incentive.NewRewardIndex(ri.CollateralType, ri.RewardFactor)
|
||||||
|
delegatorRewardIndexes = append(delegatorRewardIndexes, delegatorRewardIndex)
|
||||||
|
}
|
||||||
|
delegatorMultiRewardIndex := v0_15incentive.NewMultiRewardIndex(v0_15incentive.BondDenom, delegatorRewardIndexes)
|
||||||
|
delegatorMultiRewardIndexes = append(delegatorMultiRewardIndexes, delegatorMultiRewardIndex)
|
||||||
|
|
||||||
|
hardClaim := v0_15incentive.NewHardLiquidityProviderClaim(claim.Owner, claim.Reward,
|
||||||
|
supplyMultiRewardIndexes, borrowMultiRewardIndexes, delegatorMultiRewardIndexes)
|
||||||
|
hardClaims = append(hardClaims, hardClaim)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v0_15incentive.NewGenesisState(
|
||||||
|
params,
|
||||||
|
usdxAccumulationTimes,
|
||||||
|
hardSupplyAccumulationTimes,
|
||||||
|
hardBorrowAccumulationTimes,
|
||||||
|
hardDelegatorAccumulationTimes,
|
||||||
|
usdxMintingClaims,
|
||||||
|
hardClaims,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
||||||
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,3 +55,23 @@ func TestCommittee(t *testing.T) {
|
|||||||
require.Equal(t, len(oldSPCP.AllowedMarkets), len(newSPCP.AllowedMarkets))
|
require.Equal(t, len(oldSPCP.AllowedMarkets), len(newSPCP.AllowedMarkets))
|
||||||
require.Equal(t, len(oldSPCP.AllowedMoneyMarkets), len(newSPCP.AllowedMoneyMarkets))
|
require.Equal(t, len(oldSPCP.AllowedMoneyMarkets), len(newSPCP.AllowedMoneyMarkets))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncentive(t *testing.T) {
|
||||||
|
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-incentive-state.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
var oldIncentiveGenState v0_14incentive.GenesisState
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
cdc.MustUnmarshalJSON(bz, &oldIncentiveGenState)
|
||||||
|
})
|
||||||
|
|
||||||
|
newGenState := v0_15incentive.GenesisState{}
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
newGenState = Incentive(oldIncentiveGenState)
|
||||||
|
})
|
||||||
|
err = newGenState.Validate()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, len(oldIncentiveGenState.USDXMintingClaims), len(newGenState.USDXMintingClaims))
|
||||||
|
require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.HardLiquidityProviderClaims))
|
||||||
|
}
|
||||||
|
1
migrate/v0_15/testdata/kava-7-incentive-state.json
vendored
Normal file
1
migrate/v0_15/testdata/kava-7-incentive-state.json
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -104,7 +104,7 @@ var (
|
|||||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||||
HardDelegatorRewardFactorKeyPrefix = types.HardDelegatorRewardFactorKeyPrefix
|
HardDelegatorRewardIndexesKeyPrefix = types.HardDelegatorRewardIndexesKeyPrefix
|
||||||
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
||||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||||
|
@ -48,8 +48,13 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, supplyKeeper types.SupplyKeep
|
|||||||
k.SetHardBorrowRewardIndexes(ctx, mrp.CollateralType, newRewardIndexes)
|
k.SetHardBorrowRewardIndexes(ctx, mrp.CollateralType, newRewardIndexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rp := range gs.Params.HardDelegatorRewardPeriods {
|
for _, drp := range gs.Params.HardDelegatorRewardPeriods {
|
||||||
k.SetHardDelegatorRewardFactor(ctx, rp.CollateralType, sdk.ZeroDec())
|
newRewardIndexes := types.RewardIndexes{}
|
||||||
|
for _, rc := range drp.RewardsPerSecond {
|
||||||
|
ri := types.NewRewardIndex(rc.Denom, sdk.ZeroDec())
|
||||||
|
newRewardIndexes = append(newRewardIndexes, ri)
|
||||||
|
}
|
||||||
|
k.SetHardDelegatorRewardIndexes(ctx, drp.CollateralType, newRewardIndexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.SetParams(ctx, gs.Params)
|
k.SetParams(ctx, gs.Params)
|
||||||
@ -94,9 +99,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, supplyKeeper types.SupplyKeep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j, ri := range claim.DelegatorRewardIndexes {
|
for j, dri := range claim.DelegatorRewardIndexes {
|
||||||
if ri.RewardFactor != sdk.ZeroDec() {
|
for k, ri := range dri.RewardIndexes {
|
||||||
gs.HardLiquidityProviderClaims[i].DelegatorRewardIndexes[j].RewardFactor = sdk.ZeroDec()
|
if ri.RewardFactor != sdk.ZeroDec() {
|
||||||
|
gs.HardLiquidityProviderClaims[i].DelegatorRewardIndexes[j].RewardIndexes[k].RewardFactor = sdk.ZeroDec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
k.SetHardLiquidityProviderClaim(ctx, claim)
|
k.SetHardLiquidityProviderClaim(ctx, claim)
|
||||||
@ -140,8 +147,10 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
|
|||||||
claim.SupplyRewardIndexes[i].RewardIndexes[j].RewardFactor = sdk.ZeroDec()
|
claim.SupplyRewardIndexes[i].RewardIndexes[j].RewardFactor = sdk.ZeroDec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range claim.DelegatorRewardIndexes {
|
for i, dri := range claim.DelegatorRewardIndexes {
|
||||||
claim.DelegatorRewardIndexes[i].RewardFactor = sdk.ZeroDec()
|
for j := range dri.RewardIndexes {
|
||||||
|
claim.DelegatorRewardIndexes[i].RewardIndexes[j].RewardFactor = sdk.ZeroDec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
synchronizedHardClaims = append(synchronizedHardClaims, claim)
|
synchronizedHardClaims = append(synchronizedHardClaims, claim)
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,7 @@ func (suite *GenesisTestSuite) SetupTest() {
|
|||||||
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "bnb-a", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), c("ukava", 122354))},
|
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "bnb-a", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), c("ukava", 122354))},
|
||||||
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
|
||||||
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
|
||||||
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), c("hard", 122354))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))}, incentive.Multipliers{incentive.NewMultiplier(incentive.Small, 1, d("0.25")), incentive.NewMultiplier(incentive.Large, 12, d("1.0"))},
|
||||||
incentive.Multipliers{incentive.NewMultiplier(incentive.Small, 1, d("0.25")), incentive.NewMultiplier(incentive.Large, 12, d("1.0"))},
|
|
||||||
suite.genesisTime.Add(5*oneYear),
|
suite.genesisTime.Add(5*oneYear),
|
||||||
),
|
),
|
||||||
incentive.DefaultGenesisAccumulationTimes,
|
incentive.DefaultGenesisAccumulationTimes,
|
||||||
|
@ -47,7 +47,7 @@ func (suite *HandlerTestSuite) SetupTest() {
|
|||||||
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), c("ukava", 122354))},
|
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), c("ukava", 122354))},
|
||||||
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), cs(c("ukava", 122354)))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), cs(c("ukava", 122354)))},
|
||||||
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), cs(c("ukava", 122354)))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), cs(c("ukava", 122354)))},
|
||||||
incentive.RewardPeriods{incentive.NewRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), c("ukava", 122354))},
|
incentive.MultiRewardPeriods{incentive.NewMultiRewardPeriod(true, "bnb-a", time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC), time.Date(2024, 12, 15, 14, 0, 0, 0, time.UTC), cs(c("ukava", 122354)))},
|
||||||
incentive.Multipliers{incentive.NewMultiplier(incentive.MultiplierName("small"), 1, d("0.25")), incentive.NewMultiplier(incentive.MultiplierName("large"), 12, d("1.0"))},
|
incentive.Multipliers{incentive.NewMultiplier(incentive.MultiplierName("small"), 1, d("0.25")), incentive.NewMultiplier(incentive.MultiplierName("large"), 12, d("1.0"))},
|
||||||
time.Date(2025, 12, 15, 14, 0, 0, 0, time.UTC),
|
time.Date(2025, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
),
|
),
|
||||||
@ -88,10 +88,9 @@ func (suite *HandlerTestSuite) addHardLiquidityProviderClaim() {
|
|||||||
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
rewardPeriod := types.RewardIndexes{types.NewRewardIndex("bnb-s", sdk.ZeroDec())}
|
rewardPeriod := types.RewardIndexes{types.NewRewardIndex("bnb-s", sdk.ZeroDec())}
|
||||||
|
|
||||||
multiRewardIndex := types.NewMultiRewardIndex("bnb-s", rewardPeriod)
|
multiRewardIndex := types.NewMultiRewardIndex("bnb-s", rewardPeriod)
|
||||||
multiRewardIndexes := types.MultiRewardIndexes{multiRewardIndex}
|
multiRewardIndexes := types.MultiRewardIndexes{multiRewardIndex}
|
||||||
c1 := incentive.NewHardLiquidityProviderClaim(suite.addrs[0], cs(c("ukava", 1000000)), multiRewardIndexes, multiRewardIndexes, rewardPeriod)
|
c1 := incentive.NewHardLiquidityProviderClaim(suite.addrs[0], cs(c("ukava", 1000000)), multiRewardIndexes, multiRewardIndexes, multiRewardIndexes)
|
||||||
suite.NotPanics(func() {
|
suite.NotPanics(func() {
|
||||||
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, c1)
|
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, c1)
|
||||||
})
|
})
|
||||||
|
@ -157,7 +157,7 @@ func NewIncentiveGenState(previousAccumTime, endTime time.Time, rewardPeriods ..
|
|||||||
rewardPeriods,
|
rewardPeriods,
|
||||||
types.MultiRewardPeriods{},
|
types.MultiRewardPeriods{},
|
||||||
types.MultiRewardPeriods{},
|
types.MultiRewardPeriods{},
|
||||||
types.RewardPeriods{},
|
types.MultiRewardPeriods{},
|
||||||
incentive.Multipliers{
|
incentive.Multipliers{
|
||||||
incentive.NewMultiplier(incentive.Small, 1, d("0.25")),
|
incentive.NewMultiplier(incentive.Small, 1, d("0.25")),
|
||||||
incentive.NewMultiplier(incentive.Large, 12, d("1.0")),
|
incentive.NewMultiplier(incentive.Large, 12, d("1.0")),
|
||||||
|
@ -278,7 +278,7 @@ func (builder IncentiveGenesisBuilder) WithSimpleSupplyRewardPeriod(ctype string
|
|||||||
rewardsPerSecond,
|
rewardsPerSecond,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
func (builder IncentiveGenesisBuilder) WithInitializedDelegatorRewardPeriod(period types.RewardPeriod) IncentiveGenesisBuilder {
|
func (builder IncentiveGenesisBuilder) WithInitializedDelegatorRewardPeriod(period types.MultiRewardPeriod) IncentiveGenesisBuilder {
|
||||||
builder.Params.HardDelegatorRewardPeriods = append(builder.Params.HardDelegatorRewardPeriods, period)
|
builder.Params.HardDelegatorRewardPeriods = append(builder.Params.HardDelegatorRewardPeriods, period)
|
||||||
|
|
||||||
accumulationTimeForPeriod := types.NewGenesisAccumulationTime(period.CollateralType, builder.genesisTime)
|
accumulationTimeForPeriod := types.NewGenesisAccumulationTime(period.CollateralType, builder.genesisTime)
|
||||||
@ -286,8 +286,8 @@ func (builder IncentiveGenesisBuilder) WithInitializedDelegatorRewardPeriod(peri
|
|||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (builder IncentiveGenesisBuilder) WithSimpleDelegatorRewardPeriod(ctype string, rewardsPerSecond sdk.Coin) IncentiveGenesisBuilder {
|
func (builder IncentiveGenesisBuilder) WithSimpleDelegatorRewardPeriod(ctype string, rewardsPerSecond sdk.Coins) IncentiveGenesisBuilder {
|
||||||
return builder.WithInitializedDelegatorRewardPeriod(types.NewRewardPeriod(
|
return builder.WithInitializedDelegatorRewardPeriod(types.NewMultiRewardPeriod(
|
||||||
true,
|
true,
|
||||||
ctype,
|
ctype,
|
||||||
builder.genesisTime,
|
builder.genesisTime,
|
||||||
|
@ -273,32 +273,34 @@ func (k Keeper) IterateHardBorrowRewardIndexes(ctx sdk.Context, cb func(denom st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHardDelegatorRewardFactor returns the current reward factor for an individual collateral type
|
// GetHardDelegatorRewardIndexes gets the current reward indexes for an individual denom
|
||||||
func (k Keeper) GetHardDelegatorRewardFactor(ctx sdk.Context, ctype string) (factor sdk.Dec, found bool) {
|
func (k Keeper) GetHardDelegatorRewardIndexes(ctx sdk.Context, denom string) (types.RewardIndexes, bool) {
|
||||||
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix)
|
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardIndexesKeyPrefix)
|
||||||
bz := store.Get([]byte(ctype))
|
bz := store.Get([]byte(denom))
|
||||||
if bz == nil {
|
if bz == nil {
|
||||||
return sdk.ZeroDec(), false
|
return types.RewardIndexes{}, false
|
||||||
}
|
}
|
||||||
k.cdc.MustUnmarshalBinaryBare(bz, &factor)
|
var rewardIndexes types.RewardIndexes
|
||||||
return factor, true
|
k.cdc.MustUnmarshalBinaryBare(bz, &rewardIndexes)
|
||||||
|
return rewardIndexes, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHardDelegatorRewardFactor sets the current reward factor for an individual collateral type
|
// SetHardDelegatorRewardIndexes sets the current reward indexes for an individual denom
|
||||||
func (k Keeper) SetHardDelegatorRewardFactor(ctx sdk.Context, ctype string, factor sdk.Dec) {
|
func (k Keeper) SetHardDelegatorRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
|
||||||
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix)
|
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardIndexesKeyPrefix)
|
||||||
store.Set([]byte(ctype), k.cdc.MustMarshalBinaryBare(factor))
|
bz := k.cdc.MustMarshalBinaryBare(indexes)
|
||||||
|
store.Set([]byte(denom), bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IterateHardDelegatorRewardFactors iterates over all Hard delegator reward factor objects in the store and preforms a callback function
|
// IterateHardDelegatorRewardIndexes iterates over all Delegator reward index objects in the store and preforms a callback function
|
||||||
func (k Keeper) IterateHardDelegatorRewardFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) {
|
func (k Keeper) IterateHardDelegatorRewardIndexes(ctx sdk.Context, cb func(denom string, indexes types.RewardIndexes) (stop bool)) {
|
||||||
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix)
|
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardIndexesKeyPrefix)
|
||||||
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
||||||
defer iterator.Close()
|
defer iterator.Close()
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
var factor sdk.Dec
|
var indexes types.RewardIndexes
|
||||||
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &factor)
|
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &indexes)
|
||||||
if cb(string(iterator.Key()), factor) {
|
if cb(string(iterator.Key()), indexes) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,14 @@ func (k Keeper) GetHardBorrowRewardPeriods(ctx sdk.Context, denom string) (types
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetHardDelegatorRewardPeriod returns the reward period with the specified collateral type if it's found in the params
|
// GetHardDelegatorRewardPeriod returns the reward period with the specified collateral type if it's found in the params
|
||||||
func (k Keeper) GetHardDelegatorRewardPeriod(ctx sdk.Context, denom string) (types.RewardPeriod, bool) {
|
func (k Keeper) GetHardDelegatorRewardPeriods(ctx sdk.Context, denom string) (types.MultiRewardPeriod, bool) {
|
||||||
params := k.GetParams(ctx)
|
params := k.GetParams(ctx)
|
||||||
for _, rp := range params.HardDelegatorRewardPeriods {
|
for _, rp := range params.HardDelegatorRewardPeriods {
|
||||||
if rp.CollateralType == denom {
|
if rp.CollateralType == denom {
|
||||||
return rp, true
|
return rp, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return types.RewardPeriod{}, false
|
return types.MultiRewardPeriod{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMultiplier returns the multiplier with the specified name if it's found in the params
|
// GetMultiplier returns the multiplier with the specified name if it's found in the params
|
||||||
|
@ -223,9 +223,9 @@ func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]
|
|||||||
if found {
|
if found {
|
||||||
rewardFactor.HardBorrowRewardFactors = hardBorrowRewardIndexes
|
rewardFactor.HardBorrowRewardFactors = hardBorrowRewardIndexes
|
||||||
}
|
}
|
||||||
hardDelegatorRewardFactor, found := k.GetHardDelegatorRewardFactor(ctx, params.Denom)
|
hardDelegatorRewardIndexes, found := k.GetHardDelegatorRewardIndexes(ctx, params.Denom)
|
||||||
if found {
|
if found {
|
||||||
rewardFactor.HardDelegatorRewardFactor = hardDelegatorRewardFactor
|
rewardFactor.HardDelegatorRewardFactors = hardDelegatorRewardIndexes
|
||||||
}
|
}
|
||||||
rewardFactors = append(rewardFactors, rewardFactor)
|
rewardFactors = append(rewardFactors, rewardFactor)
|
||||||
} else {
|
} else {
|
||||||
@ -263,12 +263,12 @@ func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Populate mapping with Hard delegator reward factors
|
// Populate mapping with Hard delegator reward factors
|
||||||
k.IterateHardDelegatorRewardFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
|
k.IterateHardDelegatorRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||||
rewardFactor, ok := rewardFactorMap[denom]
|
rewardFactor, ok := rewardFactorMap[denom]
|
||||||
if !ok {
|
if !ok {
|
||||||
rewardFactor = types.RewardFactor{Denom: denom, HardDelegatorRewardFactor: factor}
|
rewardFactor = types.RewardFactor{Denom: denom, HardDelegatorRewardFactors: indexes}
|
||||||
} else {
|
} else {
|
||||||
rewardFactor.HardDelegatorRewardFactor = factor
|
rewardFactor.HardDelegatorRewardFactors = indexes
|
||||||
}
|
}
|
||||||
rewardFactorMap[denom] = rewardFactor
|
rewardFactorMap[denom] = rewardFactor
|
||||||
return false
|
return false
|
||||||
|
@ -9,37 +9,57 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// AccumulateHardDelegatorRewards updates the rewards accumulated for the input reward period
|
// AccumulateHardDelegatorRewards updates the rewards accumulated for the input reward period
|
||||||
func (k Keeper) AccumulateHardDelegatorRewards(ctx sdk.Context, rewardPeriod types.RewardPeriod) error {
|
func (k Keeper) AccumulateHardDelegatorRewards(ctx sdk.Context, rewardPeriods types.MultiRewardPeriod) error {
|
||||||
previousAccrualTime, found := k.GetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType)
|
previousAccrualTime, found := k.GetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriods.CollateralType)
|
||||||
if !found {
|
if !found {
|
||||||
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
|
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriods.CollateralType, ctx.BlockTime())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
timeElapsed := CalculateTimeElapsed(rewardPeriod.Start, rewardPeriod.End, ctx.BlockTime(), previousAccrualTime)
|
timeElapsed := CalculateTimeElapsed(rewardPeriods.Start, rewardPeriods.End, ctx.BlockTime(), previousAccrualTime)
|
||||||
if timeElapsed.IsZero() {
|
if timeElapsed.IsZero() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if rewardPeriod.RewardsPerSecond.Amount.IsZero() {
|
if rewardPeriods.RewardsPerSecond.IsZero() {
|
||||||
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
|
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriods.CollateralType, ctx.BlockTime())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
totalBonded := k.stakingKeeper.TotalBondedTokens(ctx).ToDec()
|
totalBonded := k.stakingKeeper.TotalBondedTokens(ctx).ToDec()
|
||||||
if totalBonded.IsZero() {
|
if totalBonded.IsZero() {
|
||||||
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
|
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriods.CollateralType, ctx.BlockTime())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newRewards := timeElapsed.Mul(rewardPeriod.RewardsPerSecond.Amount)
|
previousRewardIndexes, found := k.GetHardDelegatorRewardIndexes(ctx, rewardPeriods.CollateralType)
|
||||||
rewardFactor := newRewards.ToDec().Quo(totalBonded)
|
|
||||||
|
|
||||||
previousRewardFactor, found := k.GetHardDelegatorRewardFactor(ctx, rewardPeriod.CollateralType)
|
|
||||||
if !found {
|
if !found {
|
||||||
previousRewardFactor = sdk.ZeroDec()
|
for _, rewardCoin := range rewardPeriods.RewardsPerSecond {
|
||||||
|
rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||||
|
previousRewardIndexes = append(previousRewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
k.SetHardDelegatorRewardIndexes(ctx, rewardPeriods.CollateralType, previousRewardIndexes)
|
||||||
}
|
}
|
||||||
newRewardFactor := previousRewardFactor.Add(rewardFactor)
|
|
||||||
k.SetHardDelegatorRewardFactor(ctx, rewardPeriod.CollateralType, newRewardFactor)
|
newRewardIndexes := previousRewardIndexes
|
||||||
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
|
for _, rewardCoin := range rewardPeriods.RewardsPerSecond {
|
||||||
|
newRewards := rewardCoin.Amount.ToDec().Mul(timeElapsed.ToDec())
|
||||||
|
previousRewardIndex, found := previousRewardIndexes.GetRewardIndex(rewardCoin.Denom)
|
||||||
|
if !found {
|
||||||
|
previousRewardIndex = types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new reward factor and update reward index
|
||||||
|
rewardFactor := newRewards.Quo(totalBonded)
|
||||||
|
newRewardFactorValue := previousRewardIndex.RewardFactor.Add(rewardFactor)
|
||||||
|
newRewardIndex := types.NewRewardIndex(rewardCoin.Denom, newRewardFactorValue)
|
||||||
|
i, found := newRewardIndexes.GetFactorIndex(rewardCoin.Denom)
|
||||||
|
if found {
|
||||||
|
newRewardIndexes[i] = newRewardIndex
|
||||||
|
} else {
|
||||||
|
newRewardIndexes = append(newRewardIndexes, newRewardIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k.SetHardDelegatorRewardIndexes(ctx, rewardPeriods.CollateralType, newRewardIndexes)
|
||||||
|
k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriods.CollateralType, ctx.BlockTime())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,13 +73,14 @@ func (k Keeper) InitializeHardDelegatorReward(ctx sdk.Context, delegator sdk.Acc
|
|||||||
claim, _ = k.GetHardLiquidityProviderClaim(ctx, delegator)
|
claim, _ = k.GetHardLiquidityProviderClaim(ctx, delegator)
|
||||||
}
|
}
|
||||||
|
|
||||||
globalRewardFactor, found := k.GetHardDelegatorRewardFactor(ctx, types.BondDenom)
|
var delegatorRewardIndexes types.MultiRewardIndexes
|
||||||
|
globalRewardIndexes, found := k.GetHardDelegatorRewardIndexes(ctx, types.BondDenom)
|
||||||
if !found {
|
if !found {
|
||||||
// If there's no global delegator reward factor, initialize the claim with a delegator factor of zero.
|
globalRewardIndexes = types.RewardIndexes{}
|
||||||
globalRewardFactor = sdk.ZeroDec()
|
|
||||||
}
|
}
|
||||||
|
delegatorRewardIndexes = delegatorRewardIndexes.With(types.BondDenom, globalRewardIndexes)
|
||||||
|
|
||||||
claim.DelegatorRewardIndexes = types.RewardIndexes{types.NewRewardIndex(types.BondDenom, globalRewardFactor)}
|
claim.DelegatorRewardIndexes = delegatorRewardIndexes
|
||||||
k.SetHardLiquidityProviderClaim(ctx, claim)
|
k.SetHardLiquidityProviderClaim(ctx, claim)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +93,7 @@ func (k Keeper) SynchronizeHardDelegatorRewards(ctx sdk.Context, delegator sdk.A
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
globalRewardFactor, found := k.GetHardDelegatorRewardFactor(ctx, types.BondDenom)
|
globalRewardIndexes, found := k.GetHardDelegatorRewardIndexes(ctx, types.BondDenom)
|
||||||
if !found {
|
if !found {
|
||||||
// The global factor is only not found if
|
// The global factor is only not found if
|
||||||
// - the bond denom has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
|
// - the bond denom has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
|
||||||
@ -83,27 +104,25 @@ func (k Keeper) SynchronizeHardDelegatorRewards(ctx sdk.Context, delegator sdk.A
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userRewardFactor, found := claim.DelegatorRewardIndexes.Get(types.BondDenom)
|
userRewardIndexes, found := claim.DelegatorRewardIndexes.Get(types.BondDenom)
|
||||||
if !found {
|
if !found {
|
||||||
// Normally the factor should always be found, as it is added in InitializeHardDelegatorReward when a user delegates.
|
// Normally the factor should always be found, as it is added in InitializeHardDelegatorReward when a user delegates.
|
||||||
// However if there were no delegator rewards (ie no reward period in params) then a reward period is added, existing claims will not have the factor.
|
// However if there were no delegator rewards (ie no reward period in params) then a reward period is added, existing claims will not have the factor.
|
||||||
// So assume the factor is the starting value for any global factor: 0.
|
// So assume the factor is the starting value for any global factor: 0.
|
||||||
userRewardFactor = sdk.ZeroDec()
|
userRewardIndexes = types.RewardIndexes{}
|
||||||
}
|
}
|
||||||
|
|
||||||
totalDelegated := k.GetTotalDelegated(ctx, delegator, valAddr, shouldIncludeValidator)
|
totalDelegated := k.GetTotalDelegated(ctx, delegator, valAddr, shouldIncludeValidator)
|
||||||
|
|
||||||
rewardsEarned, err := k.CalculateSingleReward(userRewardFactor, globalRewardFactor, totalDelegated)
|
rewardsEarned, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, totalDelegated)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Global reward factors should never decrease, as it would lead to a negative update to claim.Rewards.
|
// 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.
|
// 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))
|
panic(fmt.Sprintf("corrupted global reward indexes found: %v", err))
|
||||||
}
|
}
|
||||||
newRewardsCoin := sdk.NewCoin(types.HardLiquidityRewardDenom, rewardsEarned)
|
|
||||||
|
|
||||||
claim.Reward = claim.Reward.Add(newRewardsCoin)
|
|
||||||
claim.DelegatorRewardIndexes = claim.DelegatorRewardIndexes.With(types.BondDenom, globalRewardFactor)
|
|
||||||
|
|
||||||
|
claim.Reward = claim.Reward.Add(rewardsEarned...)
|
||||||
|
claim.DelegatorRewardIndexes = claim.DelegatorRewardIndexes.With(types.BondDenom, globalRewardIndexes)
|
||||||
k.SetHardLiquidityProviderClaim(ctx, claim)
|
k.SetHardLiquidityProviderClaim(ctx, claim)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,10 @@ func TestInitializeHardDelegatorReward(t *testing.T) {
|
|||||||
suite.Run(t, new(InitializeHardDelegatorRewardTests))
|
suite.Run(t, new(InitializeHardDelegatorRewardTests))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *InitializeHardDelegatorRewardTests) storeGlobalDelegatorFactor(rewardIndexes types.RewardIndexes) {
|
// Hardcoded to use bond denom
|
||||||
factor := rewardIndexes[0]
|
func (suite *InitializeHardDelegatorRewardTests) storeGlobalDelegatorFactor(multiRewardIndexes types.MultiRewardIndexes) {
|
||||||
suite.keeper.SetHardDelegatorRewardFactor(suite.ctx, factor.CollateralType, factor.RewardFactor)
|
multiRewardIndex, _ := multiRewardIndexes.GetRewardIndex(types.BondDenom)
|
||||||
|
suite.keeper.SetHardDelegatorRewardIndexes(suite.ctx, types.BondDenom, multiRewardIndex.RewardIndexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *InitializeHardDelegatorRewardTests) TestClaimIndexesAreSetWhenClaimDoesNotExist() {
|
func (suite *InitializeHardDelegatorRewardTests) TestClaimIndexesAreSetWhenClaimDoesNotExist() {
|
||||||
@ -70,19 +71,30 @@ func (suite *InitializeHardDelegatorRewardTests) TestClaimIsSyncedAndIndexesAreS
|
|||||||
|
|
||||||
// Set the global factor to a value different to one in claim so
|
// Set the global factor to a value different to one in claim so
|
||||||
// we can detect if it is overwritten.
|
// we can detect if it is overwritten.
|
||||||
globalIndex := increaseRewardFactors(claim.DelegatorRewardIndexes)
|
rewardIndexes, _ := claim.DelegatorRewardIndexes.Get(types.BondDenom)
|
||||||
suite.storeGlobalDelegatorFactor(globalIndex)
|
globalIndexes := increaseRewardFactors(rewardIndexes)
|
||||||
|
|
||||||
|
// Update the claim object with the new global factor
|
||||||
|
bondIndex, _ := claim.DelegatorRewardIndexes.GetRewardIndexIndex(types.BondDenom)
|
||||||
|
claim.DelegatorRewardIndexes[bondIndex].RewardIndexes = globalIndexes
|
||||||
|
suite.storeGlobalDelegatorFactor(claim.DelegatorRewardIndexes)
|
||||||
|
|
||||||
suite.keeper.InitializeHardDelegatorReward(suite.ctx, claim.Owner)
|
suite.keeper.InitializeHardDelegatorReward(suite.ctx, claim.Owner)
|
||||||
|
|
||||||
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
||||||
suite.Equal(globalIndex, syncedClaim.DelegatorRewardIndexes)
|
suite.Equal(globalIndexes, syncedClaim.DelegatorRewardIndexes[bondIndex].RewardIndexes)
|
||||||
suite.Truef(syncedClaim.Reward.IsAllGT(claim.Reward), "'%s' not greater than '%s'", syncedClaim.Reward, claim.Reward)
|
suite.Truef(syncedClaim.Reward.IsAllGT(claim.Reward), "'%s' not greater than '%s'", syncedClaim.Reward, claim.Reward)
|
||||||
}
|
}
|
||||||
|
|
||||||
// arbitraryDelegatorRewardIndexes contains only one reward index as there is only every one bond denom
|
// arbitraryDelegatorRewardIndexes contains only one reward index as there is only every one bond denom
|
||||||
var arbitraryDelegatorRewardIndexes = types.RewardIndexes{
|
var arbitraryDelegatorRewardIndexes = types.MultiRewardIndexes{
|
||||||
types.NewRewardIndex(types.BondDenom, d("0.2")),
|
types.NewMultiRewardIndex(
|
||||||
|
types.BondDenom,
|
||||||
|
types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("0.2")),
|
||||||
|
types.NewRewardIndex("swp", d("0.2")),
|
||||||
|
},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeStakingKeeper struct {
|
type fakeStakingKeeper struct {
|
||||||
|
@ -28,9 +28,9 @@ func TestSynchronizeHardDelegatorReward(t *testing.T) {
|
|||||||
suite.Run(t, new(SynchronizeHardDelegatorRewardTests))
|
suite.Run(t, new(SynchronizeHardDelegatorRewardTests))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SynchronizeHardDelegatorRewardTests) storeGlobalDelegatorFactor(rewardIndexes types.RewardIndexes) {
|
func (suite *SynchronizeHardDelegatorRewardTests) storeGlobalDelegatorFactor(multiRewardIndexes types.MultiRewardIndexes) {
|
||||||
factor := rewardIndexes[0]
|
multiRewardIndex, _ := multiRewardIndexes.GetRewardIndex(types.BondDenom)
|
||||||
suite.keeper.SetHardDelegatorRewardFactor(suite.ctx, factor.CollateralType, factor.RewardFactor)
|
suite.keeper.SetHardDelegatorRewardIndexes(suite.ctx, types.BondDenom, multiRewardIndex.RewardIndexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SynchronizeHardDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGlobalFactorUnchanged() {
|
func (suite *SynchronizeHardDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGlobalFactorUnchanged() {
|
||||||
@ -68,14 +68,20 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestClaimIndexesAreUpdatedWhen
|
|||||||
}
|
}
|
||||||
suite.storeClaim(claim)
|
suite.storeClaim(claim)
|
||||||
|
|
||||||
globalIndexes := increaseRewardFactors(claim.DelegatorRewardIndexes)
|
rewardIndexes, _ := claim.DelegatorRewardIndexes.Get(types.BondDenom)
|
||||||
suite.storeGlobalDelegatorFactor(globalIndexes)
|
globalIndexes := increaseRewardFactors(rewardIndexes)
|
||||||
|
|
||||||
|
// Update the claim object with the new global factor
|
||||||
|
bondIndex, _ := claim.DelegatorRewardIndexes.GetRewardIndexIndex(types.BondDenom)
|
||||||
|
claim.DelegatorRewardIndexes[bondIndex].RewardIndexes = globalIndexes
|
||||||
|
suite.storeGlobalDelegatorFactor(claim.DelegatorRewardIndexes)
|
||||||
|
|
||||||
suite.keeper.SynchronizeHardDelegatorRewards(suite.ctx, claim.Owner, nil, false)
|
suite.keeper.SynchronizeHardDelegatorRewards(suite.ctx, claim.Owner, nil, false)
|
||||||
|
|
||||||
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
||||||
suite.Equal(globalIndexes, syncedClaim.DelegatorRewardIndexes)
|
suite.Equal(globalIndexes, syncedClaim.DelegatorRewardIndexes[bondIndex].RewardIndexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsUnchangedWhenGlobalFactorUnchanged() {
|
func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsUnchangedWhenGlobalFactorUnchanged() {
|
||||||
delegator := arbitraryAddress()
|
delegator := arbitraryAddress()
|
||||||
validatorAddress := arbitraryValidatorAddress()
|
validatorAddress := arbitraryValidatorAddress()
|
||||||
@ -98,9 +104,16 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsUnchangedWhenGloba
|
|||||||
Owner: delegator,
|
Owner: delegator,
|
||||||
Reward: arbitraryCoins(),
|
Reward: arbitraryCoins(),
|
||||||
},
|
},
|
||||||
DelegatorRewardIndexes: types.RewardIndexes{{
|
DelegatorRewardIndexes: types.MultiRewardIndexes{{
|
||||||
CollateralType: types.BondDenom,
|
CollateralType: types.BondDenom,
|
||||||
RewardFactor: d("0.1"),
|
RewardIndexes: types.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "hard", RewardFactor: d("0.1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "swp", RewardFactor: d("0.2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
suite.storeClaim(claim)
|
suite.storeClaim(claim)
|
||||||
@ -136,13 +149,20 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsIncreasedWhenNewRe
|
|||||||
Owner: delegator,
|
Owner: delegator,
|
||||||
Reward: arbitraryCoins(),
|
Reward: arbitraryCoins(),
|
||||||
},
|
},
|
||||||
DelegatorRewardIndexes: types.RewardIndexes{},
|
DelegatorRewardIndexes: types.MultiRewardIndexes{},
|
||||||
}
|
}
|
||||||
suite.storeClaim(claim)
|
suite.storeClaim(claim)
|
||||||
|
|
||||||
newGlobalIndexes := types.RewardIndexes{{
|
newGlobalIndexes := types.MultiRewardIndexes{{
|
||||||
CollateralType: types.BondDenom,
|
CollateralType: types.BondDenom,
|
||||||
RewardFactor: d("0.1"),
|
RewardIndexes: types.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "hard", RewardFactor: d("0.1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "swp", RewardFactor: d("0.2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
suite.storeGlobalDelegatorFactor(newGlobalIndexes)
|
suite.storeGlobalDelegatorFactor(newGlobalIndexes)
|
||||||
|
|
||||||
@ -152,7 +172,10 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsIncreasedWhenNewRe
|
|||||||
|
|
||||||
suite.Equal(newGlobalIndexes, syncedClaim.DelegatorRewardIndexes)
|
suite.Equal(newGlobalIndexes, syncedClaim.DelegatorRewardIndexes)
|
||||||
suite.Equal(
|
suite.Equal(
|
||||||
cs(c(types.HardLiquidityRewardDenom, 100)).Add(claim.Reward...),
|
cs(
|
||||||
|
c(types.HardLiquidityRewardDenom, 100),
|
||||||
|
c("swp", 200),
|
||||||
|
).Add(claim.Reward...),
|
||||||
syncedClaim.Reward,
|
syncedClaim.Reward,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -179,16 +202,33 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsIncreasedWhenGloba
|
|||||||
Owner: delegator,
|
Owner: delegator,
|
||||||
Reward: arbitraryCoins(),
|
Reward: arbitraryCoins(),
|
||||||
},
|
},
|
||||||
DelegatorRewardIndexes: types.RewardIndexes{{
|
DelegatorRewardIndexes: types.MultiRewardIndexes{{
|
||||||
CollateralType: types.BondDenom,
|
CollateralType: types.BondDenom,
|
||||||
RewardFactor: d("0.1"),
|
RewardIndexes: types.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "hard", RewardFactor: d("0.1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "swp", RewardFactor: d("0.2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
suite.storeClaim(claim)
|
suite.storeClaim(claim)
|
||||||
|
|
||||||
suite.storeGlobalDelegatorFactor(
|
suite.storeGlobalDelegatorFactor(
|
||||||
types.RewardIndexes{
|
types.MultiRewardIndexes{
|
||||||
types.NewRewardIndex(types.BondDenom, d("0.2")),
|
types.NewMultiRewardIndex(
|
||||||
|
types.BondDenom,
|
||||||
|
types.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "hard", RewardFactor: d("0.2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "swp", RewardFactor: d("0.4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -197,7 +237,10 @@ func (suite *SynchronizeHardDelegatorRewardTests) TestRewardIsIncreasedWhenGloba
|
|||||||
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
syncedClaim, _ := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, claim.Owner)
|
||||||
|
|
||||||
suite.Equal(
|
suite.Equal(
|
||||||
cs(c(types.HardLiquidityRewardDenom, 100)).Add(claim.Reward...),
|
cs(
|
||||||
|
c(types.HardLiquidityRewardDenom, 100),
|
||||||
|
c("swp", 200),
|
||||||
|
).Add(claim.Reward...),
|
||||||
syncedClaim.Reward,
|
syncedClaim.Reward,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ func (suite *DelegatorRewardsTestSuite) SetupWithGenState(authBuilder app.AuthGe
|
|||||||
|
|
||||||
func (suite *DelegatorRewardsTestSuite) TestAccumulateHardDelegatorRewards() {
|
func (suite *DelegatorRewardsTestSuite) TestAccumulateHardDelegatorRewards() {
|
||||||
type args struct {
|
type args struct {
|
||||||
delegation sdk.Coin
|
delegation sdk.Coin
|
||||||
rewardsPerSecond sdk.Coin
|
rewardsPerSecond sdk.Coins
|
||||||
timeElapsed int
|
timeElapsed int
|
||||||
expectedRewardFactor sdk.Dec
|
expectedRewardIndexes types.RewardIndexes
|
||||||
}
|
}
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
@ -79,28 +79,46 @@ func (suite *DelegatorRewardsTestSuite) TestAccumulateHardDelegatorRewards() {
|
|||||||
{
|
{
|
||||||
"7 seconds",
|
"7 seconds",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
timeElapsed: 7,
|
timeElapsed: 7,
|
||||||
expectedRewardFactor: d("0.428239000000000000"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("0.428239000000000000")),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"1 day",
|
"1 day",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
timeElapsed: 86400,
|
timeElapsed: 86400,
|
||||||
expectedRewardFactor: d("5285.692800000000000000"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("5285.692800000000000000")),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"0 seconds",
|
"0 seconds",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
timeElapsed: 0,
|
timeElapsed: 0,
|
||||||
expectedRewardFactor: d("0.0"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("0.0")),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple reward coins",
|
||||||
|
args{
|
||||||
|
delegation: c("ukava", 1_000_000),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("swp", 567889)),
|
||||||
|
timeElapsed: 7,
|
||||||
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("0.428239000000000000")),
|
||||||
|
types.NewRewardIndex("swp", d("1.987611500000000000")),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -127,24 +145,24 @@ func (suite *DelegatorRewardsTestSuite) TestAccumulateHardDelegatorRewards() {
|
|||||||
runAtTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * tc.args.timeElapsed))
|
runAtTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * tc.args.timeElapsed))
|
||||||
runCtx := suite.ctx.WithBlockTime(runAtTime)
|
runCtx := suite.ctx.WithBlockTime(runAtTime)
|
||||||
|
|
||||||
rewardPeriod, found := suite.keeper.GetHardDelegatorRewardPeriod(runCtx, tc.args.delegation.Denom)
|
rewardPeriods, found := suite.keeper.GetHardDelegatorRewardPeriods(runCtx, tc.args.delegation.Denom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
err = suite.keeper.AccumulateHardDelegatorRewards(runCtx, rewardPeriod)
|
err = suite.keeper.AccumulateHardDelegatorRewards(runCtx, rewardPeriods)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
rewardFactor, _ := suite.keeper.GetHardDelegatorRewardFactor(runCtx, tc.args.delegation.Denom)
|
rewardIndexes, _ := suite.keeper.GetHardDelegatorRewardIndexes(runCtx, tc.args.delegation.Denom)
|
||||||
suite.Require().Equal(tc.args.expectedRewardFactor, rewardFactor)
|
suite.Require().Equal(tc.args.expectedRewardIndexes, rewardIndexes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
||||||
type args struct {
|
type args struct {
|
||||||
delegation sdk.Coin
|
delegation sdk.Coin
|
||||||
rewardsPerSecond sdk.Coin
|
rewardsPerSecond sdk.Coins
|
||||||
blockTimes []int
|
blockTimes []int
|
||||||
expectedRewardFactor sdk.Dec
|
expectedRewardIndexes types.RewardIndexes
|
||||||
expectedRewards sdk.Coins
|
expectedRewards sdk.Coins
|
||||||
}
|
}
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
@ -155,31 +173,50 @@ func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
|||||||
{
|
{
|
||||||
"10 blocks",
|
"10 blocks",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
||||||
expectedRewardFactor: d("6.117700000000000000"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
expectedRewards: cs(c("hard", 6117700)),
|
types.NewRewardIndex("hard", d("6.117700000000000000")),
|
||||||
|
},
|
||||||
|
expectedRewards: cs(c("hard", 6117700)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"10 blocks - long block time",
|
"10 blocks - long block time",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
||||||
expectedRewardFactor: d("52856.928000000000000000"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
expectedRewards: cs(c("hard", 52856928000)),
|
types.NewRewardIndex("hard", d("52856.928000000000000000")),
|
||||||
|
},
|
||||||
|
expectedRewards: cs(c("hard", 52856928000)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"delegator reward index updated when reward is zero",
|
"delegator reward index updated when reward is zero",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1),
|
delegation: c("ukava", 1),
|
||||||
rewardsPerSecond: c("hard", 1),
|
rewardsPerSecond: cs(c("hard", 1)),
|
||||||
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
||||||
expectedRewardFactor: d("0.000099999900000100"),
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
expectedRewards: nil,
|
types.NewRewardIndex("hard", d("0.000099999900000100")),
|
||||||
|
},
|
||||||
|
expectedRewards: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple reward coins",
|
||||||
|
args{
|
||||||
|
delegation: c("ukava", 1_000_000),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("swp", 56789)),
|
||||||
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
||||||
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("6.117700000000000000")),
|
||||||
|
types.NewRewardIndex("swp", d("2.839450000000000000")),
|
||||||
|
},
|
||||||
|
expectedRewards: cs(c("hard", 6117700), c("swp", 2839450)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -215,7 +252,9 @@ func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
|||||||
// Check that Staking hooks initialized a HardLiquidityProviderClaim
|
// Check that Staking hooks initialized a HardLiquidityProviderClaim
|
||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(sdk.ZeroDec(), claim.DelegatorRewardIndexes[0].RewardFactor)
|
for _, rewardIndex := range claim.DelegatorRewardIndexes[0].RewardIndexes {
|
||||||
|
suite.Require().Equal(sdk.ZeroDec(), rewardIndex.RewardFactor)
|
||||||
|
}
|
||||||
|
|
||||||
// Run accumulator at several intervals
|
// Run accumulator at several intervals
|
||||||
var timeElapsed int
|
var timeElapsed int
|
||||||
@ -226,10 +265,10 @@ func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
|||||||
previousBlockTime = updatedBlockTime
|
previousBlockTime = updatedBlockTime
|
||||||
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
||||||
|
|
||||||
rewardPeriod, found := suite.keeper.GetHardDelegatorRewardPeriod(blockCtx, tc.args.delegation.Denom)
|
rewardPeriods, found := suite.keeper.GetHardDelegatorRewardPeriods(blockCtx, tc.args.delegation.Denom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
|
|
||||||
err := suite.keeper.AccumulateHardDelegatorRewards(blockCtx, rewardPeriod)
|
err := suite.keeper.AccumulateHardDelegatorRewards(blockCtx, rewardPeriods)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
}
|
}
|
||||||
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
||||||
@ -241,12 +280,17 @@ func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Check that reward factor and claim have been updated as expected
|
// Check that reward factor and claim have been updated as expected
|
||||||
rewardFactor, _ := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, tc.args.delegation.Denom)
|
rewardIndexes, _ := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, tc.args.delegation.Denom)
|
||||||
suite.Require().Equal(tc.args.expectedRewardFactor, rewardFactor)
|
for i, rewardPerSecond := range tc.args.rewardsPerSecond {
|
||||||
|
rewardFactor, _ := rewardIndexes.Get(rewardPerSecond.Denom)
|
||||||
|
suite.Require().Equal(tc.args.expectedRewardIndexes[i].RewardFactor, rewardFactor)
|
||||||
|
}
|
||||||
|
|
||||||
claim, found = suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found = suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(tc.args.expectedRewardFactor, claim.DelegatorRewardIndexes[0].RewardFactor)
|
for i, delegatorRewardIndex := range claim.DelegatorRewardIndexes[0].RewardIndexes {
|
||||||
|
suite.Require().Equal(tc.args.expectedRewardIndexes[i].RewardFactor, delegatorRewardIndex.RewardFactor)
|
||||||
|
}
|
||||||
suite.Require().Equal(tc.args.expectedRewards, claim.Reward)
|
suite.Require().Equal(tc.args.expectedRewards, claim.Reward)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -255,7 +299,7 @@ func (suite *DelegatorRewardsTestSuite) TestSynchronizeHardDelegatorReward() {
|
|||||||
func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchronization() {
|
func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchronization() {
|
||||||
type args struct {
|
type args struct {
|
||||||
delegation sdk.Coin
|
delegation sdk.Coin
|
||||||
rewardsPerSecond sdk.Coin
|
rewardsPerSecond sdk.Coins
|
||||||
blockTimes []int
|
blockTimes []int
|
||||||
expectedRewardIndexes types.RewardIndexes
|
expectedRewardIndexes types.RewardIndexes
|
||||||
expectedRewards sdk.Coins
|
expectedRewards sdk.Coins
|
||||||
@ -270,9 +314,9 @@ func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchroni
|
|||||||
"10 blocks",
|
"10 blocks",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
||||||
expectedRewardIndexes: types.RewardIndexes{types.NewRewardIndex("ukava", d("6.117700000000000000"))}, // Here the reward index stores data differently than inside a MultiRewardIndex
|
expectedRewardIndexes: types.RewardIndexes{types.NewRewardIndex("hard", d("6.117700000000000000"))},
|
||||||
expectedRewards: cs(c("hard", 6117700)),
|
expectedRewards: cs(c("hard", 6117700)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -280,12 +324,25 @@ func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchroni
|
|||||||
"10 blocks - long block time",
|
"10 blocks - long block time",
|
||||||
args{
|
args{
|
||||||
delegation: c("ukava", 1_000_000),
|
delegation: c("ukava", 1_000_000),
|
||||||
rewardsPerSecond: c("hard", 122354),
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
||||||
expectedRewardIndexes: types.RewardIndexes{types.NewRewardIndex("ukava", d("52856.928000000000000000"))},
|
expectedRewardIndexes: types.RewardIndexes{types.NewRewardIndex("hard", d("52856.928000000000000000"))},
|
||||||
expectedRewards: cs(c("hard", 52856928000)),
|
expectedRewards: cs(c("hard", 52856928000)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"multiple rewards coins",
|
||||||
|
args{
|
||||||
|
delegation: c("ukava", 1_000_000),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("swp", 56789)),
|
||||||
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
||||||
|
expectedRewardIndexes: types.RewardIndexes{
|
||||||
|
types.NewRewardIndex("hard", d("6.117700000000000000")),
|
||||||
|
types.NewRewardIndex("swp", d("2.839450000000000000")),
|
||||||
|
},
|
||||||
|
expectedRewards: cs(c("hard", 6117700), c("swp", 2839450)),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -311,7 +368,9 @@ func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchroni
|
|||||||
// Check that Staking hooks initialized a HardLiquidityProviderClaim
|
// Check that Staking hooks initialized a HardLiquidityProviderClaim
|
||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(sdk.ZeroDec(), claim.DelegatorRewardIndexes[0].RewardFactor)
|
for _, rewardIndex := range claim.DelegatorRewardIndexes[0].RewardIndexes {
|
||||||
|
suite.Require().Equal(sdk.ZeroDec(), rewardIndex.RewardFactor)
|
||||||
|
}
|
||||||
|
|
||||||
// Run accumulator at several intervals
|
// Run accumulator at several intervals
|
||||||
var timeElapsed int
|
var timeElapsed int
|
||||||
@ -323,9 +382,9 @@ func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchroni
|
|||||||
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
||||||
|
|
||||||
// Accumulate hard delegator rewards
|
// Accumulate hard delegator rewards
|
||||||
rewardPeriod, found := suite.keeper.GetHardDelegatorRewardPeriod(blockCtx, tc.args.delegation.Denom)
|
rewardPeriods, found := suite.keeper.GetHardDelegatorRewardPeriods(blockCtx, tc.args.delegation.Denom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
err := suite.keeper.AccumulateHardDelegatorRewards(blockCtx, rewardPeriod)
|
err := suite.keeper.AccumulateHardDelegatorRewards(blockCtx, rewardPeriods)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
}
|
}
|
||||||
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
||||||
@ -333,11 +392,12 @@ func (suite *DelegatorRewardsTestSuite) TestSimulateHardDelegatorRewardSynchroni
|
|||||||
|
|
||||||
// Check that the synced claim held in memory has properly simulated syncing
|
// Check that the synced claim held in memory has properly simulated syncing
|
||||||
syncedClaim := suite.keeper.SimulateHardSynchronization(suite.ctx, claim)
|
syncedClaim := suite.keeper.SimulateHardSynchronization(suite.ctx, claim)
|
||||||
for _, expectedRewardIndex := range tc.args.expectedRewardIndexes {
|
|
||||||
|
for i, expectedRewardIndex := range tc.args.expectedRewardIndexes {
|
||||||
// Check that the user's claim's reward index matches the expected reward index
|
// Check that the user's claim's reward index matches the expected reward index
|
||||||
rewardIndex, found := syncedClaim.DelegatorRewardIndexes.GetRewardIndex(expectedRewardIndex.CollateralType)
|
multiRewardIndex, found := syncedClaim.DelegatorRewardIndexes.Get(types.BondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(expectedRewardIndex, rewardIndex)
|
suite.Require().Equal(expectedRewardIndex, multiRewardIndex[i])
|
||||||
|
|
||||||
// Check that the user's claim holds the expected amount of reward coins
|
// Check that the user's claim holds the expected amount of reward coins
|
||||||
suite.Require().Equal(
|
suite.Require().Equal(
|
||||||
@ -395,7 +455,7 @@ func (suite *DelegatorRewardsTestSuite) TestUnbondingValidatorSyncsClaim() {
|
|||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9))).
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9))).
|
||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[2]), cs(c("ukava", 1e9)))
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[2]), cs(c("ukava", 1e9)))
|
||||||
|
|
||||||
rewardsPerSecond := c("hard", 122354)
|
rewardsPerSecond := cs(c("hard", 122354))
|
||||||
bondDenom := "ukava"
|
bondDenom := "ukava"
|
||||||
|
|
||||||
incentBuilder := NewIncentiveGenesisBuilder().
|
incentBuilder := NewIncentiveGenesisBuilder().
|
||||||
@ -446,14 +506,16 @@ func (suite *DelegatorRewardsTestSuite) TestUnbondingValidatorSyncsClaim() {
|
|||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
|
|
||||||
globalIndex, found := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
rewardIndexes, found := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
globalIndex, found := rewardIndexes.Get(rewardsPerSecond[0].Denom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, claimIndex.RewardFactor)
|
suite.Require().Equal(globalIndex, claimIndex.RewardIndexes[0].RewardFactor)
|
||||||
|
|
||||||
suite.Require().Equal(
|
suite.Require().Equal(
|
||||||
cs(c(rewardsPerSecond.Denom, 76471)),
|
cs(c(rewardsPerSecond[0].Denom, 76471)),
|
||||||
claim.Reward,
|
claim.Reward,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -471,9 +533,11 @@ func (suite *DelegatorRewardsTestSuite) TestUnbondingValidatorSyncsClaim() {
|
|||||||
// claim index has been updated to latest global value
|
// claim index has been updated to latest global value
|
||||||
laterClaimIndex, found := laterClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
laterClaimIndex, found := laterClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
globalIndex, found = suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
rewardIndexes, found = suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, laterClaimIndex.RewardFactor)
|
globalIndex, found = rewardIndexes.Get(rewardsPerSecond[0].Denom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.Require().Equal(globalIndex, laterClaimIndex.RewardIndexes[0].RewardFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a user has a delegation to an unbonded validator, when the validator becomes bonded, the user starts accumulating rewards
|
// given a user has a delegation to an unbonded validator, when the validator becomes bonded, the user starts accumulating rewards
|
||||||
@ -485,7 +549,7 @@ func (suite *DelegatorRewardsTestSuite) TestBondingValidatorSyncsClaim() {
|
|||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9))).
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9))).
|
||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[2]), cs(c("ukava", 1e9)))
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[2]), cs(c("ukava", 1e9)))
|
||||||
|
|
||||||
rewardsPerSecond := c("hard", 122354)
|
rewardsPerSecond := cs(c("hard", 122354))
|
||||||
bondDenom := "ukava"
|
bondDenom := "ukava"
|
||||||
|
|
||||||
incentBuilder := NewIncentiveGenesisBuilder().
|
incentBuilder := NewIncentiveGenesisBuilder().
|
||||||
@ -536,11 +600,13 @@ func (suite *DelegatorRewardsTestSuite) TestBondingValidatorSyncsClaim() {
|
|||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
|
|
||||||
globalIndex, found := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
rewardIndexes, found := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
globalIndex, found := rewardIndexes.Get(rewardsPerSecond[0].Denom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, claimIndex.RewardFactor)
|
suite.Require().Equal(globalIndex, claimIndex.RewardIndexes[0].RewardFactor)
|
||||||
|
|
||||||
suite.Require().Equal(
|
suite.Require().Equal(
|
||||||
sdk.Coins(nil),
|
sdk.Coins(nil),
|
||||||
@ -561,9 +627,11 @@ func (suite *DelegatorRewardsTestSuite) TestBondingValidatorSyncsClaim() {
|
|||||||
// claim index has been updated to latest global value
|
// claim index has been updated to latest global value
|
||||||
laterClaimIndex, found := laterClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
laterClaimIndex, found := laterClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
globalIndex, found = suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
rewardIndexes, found = suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, laterClaimIndex.RewardFactor)
|
globalIndex, found = rewardIndexes.Get(rewardsPerSecond[0].Denom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.Require().Equal(globalIndex, laterClaimIndex.RewardIndexes[0].RewardFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a validator is slashed delegators should have their claims synced
|
// If a validator is slashed delegators should have their claims synced
|
||||||
@ -573,7 +641,7 @@ func (suite *DelegatorRewardsTestSuite) TestSlashingValidatorSyncsClaim() {
|
|||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[0]), cs(c("ukava", 1e9))).
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[0]), cs(c("ukava", 1e9))).
|
||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9)))
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9)))
|
||||||
|
|
||||||
rewardsPerSecond := c("hard", 122354)
|
rewardsPerSecond := cs(c("hard", 122354))
|
||||||
bondDenom := "ukava"
|
bondDenom := "ukava"
|
||||||
|
|
||||||
incentBuilder := NewIncentiveGenesisBuilder().
|
incentBuilder := NewIncentiveGenesisBuilder().
|
||||||
@ -608,11 +676,11 @@ func (suite *DelegatorRewardsTestSuite) TestSlashingValidatorSyncsClaim() {
|
|||||||
// Check that claim has been created with synced reward index but no reward coins
|
// Check that claim has been created with synced reward index but no reward coins
|
||||||
initialClaim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
initialClaim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.True(found)
|
suite.True(found)
|
||||||
initialGlobalIndex, found := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
initialGlobalIndex, found := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
suite.True(found)
|
suite.True(found)
|
||||||
initialClaimIndex, found := initialClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
initialClaimIndex, found := initialClaim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.True(found)
|
suite.True(found)
|
||||||
suite.Require().Equal(initialGlobalIndex, initialClaimIndex.RewardFactor)
|
suite.Require().Equal(initialGlobalIndex, initialClaimIndex.RewardIndexes)
|
||||||
suite.True(initialClaim.Reward.Empty()) // Initial claim should not have any rewards
|
suite.True(initialClaim.Reward.Empty()) // Initial claim should not have any rewards
|
||||||
|
|
||||||
// Start a new block to accumulate some delegation rewards for the user.
|
// Start a new block to accumulate some delegation rewards for the user.
|
||||||
@ -631,20 +699,20 @@ func (suite *DelegatorRewardsTestSuite) TestSlashingValidatorSyncsClaim() {
|
|||||||
// Check that the user's claim has been synced. ie rewards added, index updated
|
// Check that the user's claim has been synced. ie rewards added, index updated
|
||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
globalIndex, found := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
globalIndex, found := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, claimIndex.RewardFactor)
|
suite.Require().Equal(globalIndex, claimIndex.RewardIndexes)
|
||||||
|
|
||||||
// Check that rewards were added
|
// Check that rewards were added
|
||||||
suite.Require().Equal(
|
suite.Require().Equal(
|
||||||
cs(c(rewardsPerSecond.Denom, 58264)),
|
cs(c(rewardsPerSecond[0].Denom, 58264)),
|
||||||
claim.Reward,
|
claim.Reward,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check that reward factor increased from initial value
|
// Check that reward factor increased from initial value
|
||||||
suite.True(claimIndex.RewardFactor.GT(initialClaimIndex.RewardFactor))
|
suite.True(claimIndex.RewardIndexes[0].RewardFactor.GT(initialClaimIndex.RewardIndexes[0].RewardFactor))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a delegation to a bonded validator, when a user redelegates everything to another (bonded) validator, the user's claim is synced
|
// Given a delegation to a bonded validator, when a user redelegates everything to another (bonded) validator, the user's claim is synced
|
||||||
@ -654,7 +722,7 @@ func (suite *DelegatorRewardsTestSuite) TestRedelegationSyncsClaim() {
|
|||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[0]), cs(c("ukava", 1e9))).
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[0]), cs(c("ukava", 1e9))).
|
||||||
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9)))
|
WithSimpleAccount(sdk.AccAddress(suite.validatorAddrs[1]), cs(c("ukava", 1e9)))
|
||||||
|
|
||||||
rewardsPerSecond := c("hard", 122354)
|
rewardsPerSecond := cs(c("hard", 122354))
|
||||||
bondDenom := "ukava"
|
bondDenom := "ukava"
|
||||||
|
|
||||||
incentBuilder := NewIncentiveGenesisBuilder().
|
incentBuilder := NewIncentiveGenesisBuilder().
|
||||||
@ -689,13 +757,13 @@ func (suite *DelegatorRewardsTestSuite) TestRedelegationSyncsClaim() {
|
|||||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[0])
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
|
|
||||||
globalIndex, found := suite.keeper.GetHardDelegatorRewardFactor(suite.ctx, bondDenom)
|
globalIndex, found := suite.keeper.GetHardDelegatorRewardIndexes(suite.ctx, bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
claimIndex, found := claim.DelegatorRewardIndexes.GetRewardIndex(bondDenom)
|
||||||
suite.Require().True(found)
|
suite.Require().True(found)
|
||||||
suite.Require().Equal(globalIndex, claimIndex.RewardFactor)
|
suite.Require().Equal(globalIndex, claimIndex.RewardIndexes)
|
||||||
suite.Require().Equal(
|
suite.Require().Equal(
|
||||||
cs(c(rewardsPerSecond.Denom, 76471)),
|
cs(c(rewardsPerSecond[0].Denom, 76471)),
|
||||||
claim.Reward,
|
claim.Reward,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -300,58 +300,56 @@ func (k Keeper) SimulateHardSynchronization(ctx sdk.Context, claim types.HardLiq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Simulate Hard delegator rewards
|
// 3. Simulate delegator rewards
|
||||||
delagatorFactor, found := k.GetHardDelegatorRewardFactor(ctx, types.BondDenom)
|
for _, ri := range claim.DelegatorRewardIndexes {
|
||||||
if !found {
|
// For each Delegator reward index (there's only one: the bond denom 'ukava')
|
||||||
return claim
|
globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardDelegatorRewardIndexes(ctx, ri.CollateralType)
|
||||||
}
|
if !foundGlobalRewardIndexes {
|
||||||
|
|
||||||
delegatorIndex, hasDelegatorRewardIndex := claim.HasDelegatorRewardIndex(types.BondDenom)
|
|
||||||
if !hasDelegatorRewardIndex {
|
|
||||||
return claim
|
|
||||||
}
|
|
||||||
|
|
||||||
userRewardFactor := claim.DelegatorRewardIndexes[delegatorIndex].RewardFactor
|
|
||||||
rewardsAccumulatedFactor := delagatorFactor.Sub(userRewardFactor)
|
|
||||||
if rewardsAccumulatedFactor.IsZero() {
|
|
||||||
return claim
|
|
||||||
}
|
|
||||||
claim.DelegatorRewardIndexes[delegatorIndex].RewardFactor = delagatorFactor
|
|
||||||
|
|
||||||
totalDelegated := sdk.ZeroDec()
|
|
||||||
|
|
||||||
delegations := k.stakingKeeper.GetDelegatorDelegations(ctx, claim.GetOwner(), 200)
|
|
||||||
for _, delegation := range delegations {
|
|
||||||
validator, found := k.stakingKeeper.GetValidator(ctx, delegation.GetValidatorAddr())
|
|
||||||
if !found {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delegators don't accumulate rewards if their validator is unbonded/slashed
|
userRewardIndexes, foundUserRewardIndexes := claim.DelegatorRewardIndexes.GetRewardIndex(ri.CollateralType)
|
||||||
if validator.GetStatus() != sdk.Bonded {
|
if !foundUserRewardIndexes {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if validator.GetTokens().IsZero() {
|
userRewardIndexIndex, foundUserRewardIndexIndex := claim.DelegatorRewardIndexes.GetRewardIndexIndex(ri.CollateralType)
|
||||||
|
if !foundUserRewardIndexIndex {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
delegatedTokens := validator.TokensFromShares(delegation.GetShares())
|
amtDelegated := k.GetTotalDelegated(ctx, claim.GetOwner(), sdk.ValAddress(claim.Owner.String()), true)
|
||||||
if delegatedTokens.IsZero() || delegatedTokens.IsNegative() {
|
|
||||||
continue
|
for _, globalRewardIndex := range globalRewardIndexes {
|
||||||
|
userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||||
|
if !foundUserRewardIndex {
|
||||||
|
userRewardIndex = types.NewRewardIndex(globalRewardIndex.CollateralType, sdk.ZeroDec())
|
||||||
|
userRewardIndexes.RewardIndexes = append(userRewardIndexes.RewardIndexes, userRewardIndex)
|
||||||
|
claim.DelegatorRewardIndexes[userRewardIndexIndex].RewardIndexes = append(claim.DelegatorRewardIndexes[userRewardIndexIndex].RewardIndexes, userRewardIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
globalRewardFactor := globalRewardIndex.RewardFactor
|
||||||
|
userRewardFactor := userRewardIndex.RewardFactor
|
||||||
|
rewardsAccumulatedFactor := globalRewardFactor.Sub(userRewardFactor)
|
||||||
|
if rewardsAccumulatedFactor.IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rewardsEarned := rewardsAccumulatedFactor.Mul(amtDelegated).RoundInt()
|
||||||
|
if rewardsEarned.IsZero() || rewardsEarned.IsNegative() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||||
|
if !foundFactorIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
claim.DelegatorRewardIndexes[userRewardIndexIndex].RewardIndexes[factorIndex].RewardFactor = globalRewardIndex.RewardFactor
|
||||||
|
newRewardsCoin := sdk.NewCoin(userRewardIndex.CollateralType, rewardsEarned)
|
||||||
|
claim.Reward = claim.Reward.Add(newRewardsCoin)
|
||||||
}
|
}
|
||||||
totalDelegated = totalDelegated.Add(delegatedTokens)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rewardsEarned := rewardsAccumulatedFactor.Mul(totalDelegated).RoundInt()
|
|
||||||
if rewardsEarned.IsZero() || rewardsEarned.IsNegative() {
|
|
||||||
return claim
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add rewards to delegator's hard claim
|
|
||||||
newRewardsCoin := sdk.NewCoin(types.HardLiquidityRewardDenom, rewardsEarned)
|
|
||||||
claim.Reward = claim.Reward.Add(newRewardsCoin)
|
|
||||||
|
|
||||||
return claim
|
return claim
|
||||||
}
|
}
|
||||||
|
|
||||||
|
965
x/incentive/legacy/v0_14/types.go
Normal file
965
x/incentive/legacy/v0_14/types.go
Normal file
@ -0,0 +1,965 @@
|
|||||||
|
package v0_14
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/params"
|
||||||
|
|
||||||
|
tmtime "github.com/tendermint/tendermint/types/time"
|
||||||
|
|
||||||
|
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
kavadistTypes "github.com/kava-labs/kava/x/kavadist/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Valid reward multipliers
|
||||||
|
const (
|
||||||
|
Small MultiplierName = "small"
|
||||||
|
Medium MultiplierName = "medium"
|
||||||
|
Large MultiplierName = "large"
|
||||||
|
USDXMintingClaimType = "usdx_minting"
|
||||||
|
HardLiquidityProviderClaimType = "hard_liquidity_provider"
|
||||||
|
BondDenom = "ukava"
|
||||||
|
ModuleName = "incentive"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parameter keys and default values
|
||||||
|
var (
|
||||||
|
KeyUSDXMintingRewardPeriods = []byte("USDXMintingRewardPeriods")
|
||||||
|
KeyHardSupplyRewardPeriods = []byte("HardSupplyRewardPeriods")
|
||||||
|
KeyHardBorrowRewardPeriods = []byte("HardBorrowRewardPeriods")
|
||||||
|
KeyHardDelegatorRewardPeriods = []byte("HardDelegatorRewardPeriods")
|
||||||
|
KeyClaimEnd = []byte("ClaimEnd")
|
||||||
|
KeyMultipliers = []byte("ClaimMultipliers")
|
||||||
|
DefaultActive = false
|
||||||
|
DefaultRewardPeriods = RewardPeriods{}
|
||||||
|
DefaultMultiRewardPeriods = MultiRewardPeriods{}
|
||||||
|
DefaultMultipliers = Multipliers{}
|
||||||
|
DefaultUSDXClaims = USDXMintingClaims{}
|
||||||
|
DefaultHardClaims = HardLiquidityProviderClaims{}
|
||||||
|
DefaultGenesisAccumulationTimes = GenesisAccumulationTimes{}
|
||||||
|
DefaultClaimEnd = tmtime.Canonical(time.Unix(1, 0))
|
||||||
|
GovDenom = cdptypes.DefaultGovDenom
|
||||||
|
PrincipalDenom = "usdx"
|
||||||
|
IncentiveMacc = kavadistTypes.ModuleName
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenesisState is the state that must be provided at genesis.
|
||||||
|
type GenesisState struct {
|
||||||
|
Params Params `json:"params" yaml:"params"`
|
||||||
|
USDXAccumulationTimes GenesisAccumulationTimes `json:"usdx_accumulation_times" yaml:"usdx_accumulation_times"`
|
||||||
|
HardSupplyAccumulationTimes GenesisAccumulationTimes `json:"hard_supply_accumulation_times" yaml:"hard_supply_accumulation_times"`
|
||||||
|
HardBorrowAccumulationTimes GenesisAccumulationTimes `json:"hard_borrow_accumulation_times" yaml:"hard_borrow_accumulation_times"`
|
||||||
|
HardDelegatorAccumulationTimes GenesisAccumulationTimes `json:"hard_delegator_accumulation_times" yaml:"hard_delegator_accumulation_times"`
|
||||||
|
USDXMintingClaims USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
|
||||||
|
HardLiquidityProviderClaims HardLiquidityProviderClaims `json:"hard_liquidity_provider_claims" yaml:"hard_liquidity_provider_claims"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGenesisState returns a new genesis state
|
||||||
|
func NewGenesisState(params Params, usdxAccumTimes, hardSupplyAccumTimes, hardBorrowAccumTimes, hardDelegatorAccumTimes GenesisAccumulationTimes, c USDXMintingClaims, hc HardLiquidityProviderClaims) GenesisState {
|
||||||
|
return GenesisState{
|
||||||
|
Params: params,
|
||||||
|
USDXAccumulationTimes: usdxAccumTimes,
|
||||||
|
HardSupplyAccumulationTimes: hardSupplyAccumTimes,
|
||||||
|
HardBorrowAccumulationTimes: hardBorrowAccumTimes,
|
||||||
|
HardDelegatorAccumulationTimes: hardDelegatorAccumTimes,
|
||||||
|
USDXMintingClaims: c,
|
||||||
|
HardLiquidityProviderClaims: hc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultGenesisState returns a default genesis state
|
||||||
|
func DefaultGenesisState() GenesisState {
|
||||||
|
return GenesisState{
|
||||||
|
Params: DefaultParams(),
|
||||||
|
USDXAccumulationTimes: GenesisAccumulationTimes{},
|
||||||
|
HardSupplyAccumulationTimes: GenesisAccumulationTimes{},
|
||||||
|
HardBorrowAccumulationTimes: GenesisAccumulationTimes{},
|
||||||
|
HardDelegatorAccumulationTimes: GenesisAccumulationTimes{},
|
||||||
|
USDXMintingClaims: DefaultUSDXClaims,
|
||||||
|
HardLiquidityProviderClaims: DefaultHardClaims,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs basic validation of genesis data returning an
|
||||||
|
// error for any failed validation criteria.
|
||||||
|
func (gs GenesisState) Validate() error {
|
||||||
|
if err := gs.Params.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gs.USDXAccumulationTimes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gs.HardSupplyAccumulationTimes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gs.HardBorrowAccumulationTimes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gs.HardDelegatorAccumulationTimes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gs.HardLiquidityProviderClaims.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return gs.USDXMintingClaims.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenesisAccumulationTime stores the previous reward distribution time and its corresponding collateral type
|
||||||
|
type GenesisAccumulationTime struct {
|
||||||
|
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||||
|
PreviousAccumulationTime time.Time `json:"previous_accumulation_time" yaml:"previous_accumulation_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGenesisAccumulationTime returns a new GenesisAccumulationTime
|
||||||
|
func NewGenesisAccumulationTime(ctype string, prevTime time.Time) GenesisAccumulationTime {
|
||||||
|
return GenesisAccumulationTime{
|
||||||
|
CollateralType: ctype,
|
||||||
|
PreviousAccumulationTime: prevTime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenesisAccumulationTimes slice of GenesisAccumulationTime
|
||||||
|
type GenesisAccumulationTimes []GenesisAccumulationTime
|
||||||
|
|
||||||
|
// Validate performs validation of GenesisAccumulationTimes
|
||||||
|
func (gats GenesisAccumulationTimes) Validate() error {
|
||||||
|
for _, gat := range gats {
|
||||||
|
if err := gat.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs validation of GenesisAccumulationTime
|
||||||
|
func (gat GenesisAccumulationTime) Validate() error {
|
||||||
|
if len(gat.CollateralType) == 0 {
|
||||||
|
return fmt.Errorf("genesis accumulation time's collateral type must be defined")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params governance parameters for the incentive module
|
||||||
|
type Params struct {
|
||||||
|
USDXMintingRewardPeriods RewardPeriods `json:"usdx_minting_reward_periods" yaml:"usdx_minting_reward_periods"`
|
||||||
|
HardSupplyRewardPeriods MultiRewardPeriods `json:"hard_supply_reward_periods" yaml:"hard_supply_reward_periods"`
|
||||||
|
HardBorrowRewardPeriods MultiRewardPeriods `json:"hard_borrow_reward_periods" yaml:"hard_borrow_reward_periods"`
|
||||||
|
HardDelegatorRewardPeriods RewardPeriods `json:"hard_delegator_reward_periods" yaml:"hard_delegator_reward_periods"`
|
||||||
|
ClaimMultipliers Multipliers `json:"claim_multipliers" yaml:"claim_multipliers"`
|
||||||
|
ClaimEnd time.Time `json:"claim_end" yaml:"claim_end"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewParams returns a new params object
|
||||||
|
func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow MultiRewardPeriods,
|
||||||
|
hardDelegator RewardPeriods, multipliers Multipliers, claimEnd time.Time) Params {
|
||||||
|
return Params{
|
||||||
|
USDXMintingRewardPeriods: usdxMinting,
|
||||||
|
HardSupplyRewardPeriods: hardSupply,
|
||||||
|
HardBorrowRewardPeriods: hardBorrow,
|
||||||
|
HardDelegatorRewardPeriods: hardDelegator,
|
||||||
|
ClaimMultipliers: multipliers,
|
||||||
|
ClaimEnd: claimEnd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultParams returns default params for incentive module
|
||||||
|
func DefaultParams() Params {
|
||||||
|
return NewParams(DefaultRewardPeriods, DefaultMultiRewardPeriods,
|
||||||
|
DefaultMultiRewardPeriods, DefaultRewardPeriods, DefaultMultipliers, DefaultClaimEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (p Params) String() string {
|
||||||
|
return fmt.Sprintf(`Params:
|
||||||
|
USDX Minting Reward Periods: %s
|
||||||
|
Hard Supply Reward Periods: %s
|
||||||
|
Hard Borrow Reward Periods: %s
|
||||||
|
Hard Delegator Reward Periods: %s
|
||||||
|
Claim Multipliers :%s
|
||||||
|
Claim End Time: %s
|
||||||
|
`, p.USDXMintingRewardPeriods, p.HardSupplyRewardPeriods, p.HardBorrowRewardPeriods,
|
||||||
|
p.HardDelegatorRewardPeriods, p.ClaimMultipliers, p.ClaimEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamKeyTable Key declaration for parameters
|
||||||
|
func ParamKeyTable() params.KeyTable {
|
||||||
|
return params.NewKeyTable().RegisterParamSet(&Params{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamSetPairs implements the ParamSet interface and returns all the key/value pairs
|
||||||
|
func (p *Params) ParamSetPairs() params.ParamSetPairs {
|
||||||
|
return params.ParamSetPairs{
|
||||||
|
params.NewParamSetPair(KeyUSDXMintingRewardPeriods, &p.USDXMintingRewardPeriods, validateRewardPeriodsParam),
|
||||||
|
params.NewParamSetPair(KeyHardSupplyRewardPeriods, &p.HardSupplyRewardPeriods, validateMultiRewardPeriodsParam),
|
||||||
|
params.NewParamSetPair(KeyHardBorrowRewardPeriods, &p.HardBorrowRewardPeriods, validateMultiRewardPeriodsParam),
|
||||||
|
params.NewParamSetPair(KeyHardDelegatorRewardPeriods, &p.HardDelegatorRewardPeriods, validateRewardPeriodsParam),
|
||||||
|
params.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
|
||||||
|
params.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersParam),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks that the parameters have valid values.
|
||||||
|
func (p Params) Validate() error {
|
||||||
|
|
||||||
|
if err := validateMultipliersParam(p.ClaimMultipliers); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateRewardPeriodsParam(p.USDXMintingRewardPeriods); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateMultiRewardPeriodsParam(p.HardSupplyRewardPeriods); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateMultiRewardPeriodsParam(p.HardBorrowRewardPeriods); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return validateRewardPeriodsParam(p.HardDelegatorRewardPeriods)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateRewardPeriodsParam(i interface{}) error {
|
||||||
|
rewards, ok := i.(RewardPeriods)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter type: %T", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewards.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateMultiRewardPeriodsParam(i interface{}) error {
|
||||||
|
rewards, ok := i.(MultiRewardPeriods)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter type: %T", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewards.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateMultipliersParam(i interface{}) error {
|
||||||
|
multipliers, ok := i.(Multipliers)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter type: %T", i)
|
||||||
|
}
|
||||||
|
return multipliers.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateClaimEndParam(i interface{}) error {
|
||||||
|
endTime, ok := i.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter type: %T", i)
|
||||||
|
}
|
||||||
|
if endTime.Unix() <= 0 {
|
||||||
|
return fmt.Errorf("end time should not be zero")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RewardPeriod stores the state of an ongoing reward
|
||||||
|
type RewardPeriod struct {
|
||||||
|
Active bool `json:"active" yaml:"active"`
|
||||||
|
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||||
|
Start time.Time `json:"start" yaml:"start"`
|
||||||
|
End time.Time `json:"end" yaml:"end"`
|
||||||
|
RewardsPerSecond sdk.Coin `json:"rewards_per_second" yaml:"rewards_per_second"` // per second reward payouts
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (rp RewardPeriod) String() string {
|
||||||
|
return fmt.Sprintf(`Reward Period:
|
||||||
|
Collateral Type: %s,
|
||||||
|
Start: %s,
|
||||||
|
End: %s,
|
||||||
|
Rewards Per Second: %s,
|
||||||
|
Active %t,
|
||||||
|
`, rp.CollateralType, rp.Start, rp.End, rp.RewardsPerSecond, rp.Active)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRewardPeriod returns a new RewardPeriod
|
||||||
|
func NewRewardPeriod(active bool, collateralType string, start time.Time, end time.Time, reward sdk.Coin) RewardPeriod {
|
||||||
|
return RewardPeriod{
|
||||||
|
Active: active,
|
||||||
|
CollateralType: collateralType,
|
||||||
|
Start: start,
|
||||||
|
End: end,
|
||||||
|
RewardsPerSecond: reward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs a basic check of a RewardPeriod fields.
|
||||||
|
func (rp RewardPeriod) Validate() error {
|
||||||
|
if rp.Start.Unix() <= 0 {
|
||||||
|
return errors.New("reward period start time cannot be 0")
|
||||||
|
}
|
||||||
|
if rp.End.Unix() <= 0 {
|
||||||
|
return errors.New("reward period end time cannot be 0")
|
||||||
|
}
|
||||||
|
if rp.Start.After(rp.End) {
|
||||||
|
return fmt.Errorf("end period time %s cannot be before start time %s", rp.End, rp.Start)
|
||||||
|
}
|
||||||
|
if !rp.RewardsPerSecond.IsValid() {
|
||||||
|
return fmt.Errorf("invalid reward amount: %s", rp.RewardsPerSecond)
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(rp.CollateralType) == "" {
|
||||||
|
return fmt.Errorf("reward period collateral type cannot be blank: %s", rp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RewardPeriods array of RewardPeriod
|
||||||
|
type RewardPeriods []RewardPeriod
|
||||||
|
|
||||||
|
// Validate checks if all the RewardPeriods are valid and there are no duplicated
|
||||||
|
// entries.
|
||||||
|
func (rps RewardPeriods) Validate() error {
|
||||||
|
seenPeriods := make(map[string]bool)
|
||||||
|
for _, rp := range rps {
|
||||||
|
if seenPeriods[rp.CollateralType] {
|
||||||
|
return fmt.Errorf("duplicated reward period with collateral type %s", rp.CollateralType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rp.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
seenPeriods[rp.CollateralType] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
|
||||||
|
type Multiplier struct {
|
||||||
|
Name MultiplierName `json:"name" yaml:"name"`
|
||||||
|
MonthsLockup int64 `json:"months_lockup" yaml:"months_lockup"`
|
||||||
|
Factor sdk.Dec `json:"factor" yaml:"factor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMultiplier returns a new Multiplier
|
||||||
|
func NewMultiplier(name MultiplierName, lockup int64, factor sdk.Dec) Multiplier {
|
||||||
|
return Multiplier{
|
||||||
|
Name: name,
|
||||||
|
MonthsLockup: lockup,
|
||||||
|
Factor: factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate multiplier param
|
||||||
|
func (m Multiplier) Validate() error {
|
||||||
|
if err := m.Name.IsValid(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if m.MonthsLockup < 0 {
|
||||||
|
return fmt.Errorf("expected non-negative lockup, got %d", m.MonthsLockup)
|
||||||
|
}
|
||||||
|
if m.Factor.IsNegative() {
|
||||||
|
return fmt.Errorf("expected non-negative factor, got %s", m.Factor.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (m Multiplier) String() string {
|
||||||
|
return fmt.Sprintf(`Claim Multiplier:
|
||||||
|
Name: %s
|
||||||
|
Months Lockup %d
|
||||||
|
Factor %s
|
||||||
|
`, m.Name, m.MonthsLockup, m.Factor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multipliers slice of Multiplier
|
||||||
|
type Multipliers []Multiplier
|
||||||
|
|
||||||
|
// Validate validates each multiplier
|
||||||
|
func (ms Multipliers) Validate() error {
|
||||||
|
for _, m := range ms {
|
||||||
|
if err := m.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (ms Multipliers) String() string {
|
||||||
|
out := "Claim Multipliers\n"
|
||||||
|
for _, s := range ms {
|
||||||
|
out += fmt.Sprintf("%s\n", s)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiplierName name for valid multiplier
|
||||||
|
type MultiplierName string
|
||||||
|
|
||||||
|
// IsValid checks if the input is one of the expected strings
|
||||||
|
func (mn MultiplierName) IsValid() error {
|
||||||
|
switch mn {
|
||||||
|
case Small, Medium, Large:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid multiplier name: %s", mn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Claim is an interface for handling common claim actions
|
||||||
|
type Claim interface {
|
||||||
|
GetOwner() sdk.AccAddress
|
||||||
|
GetReward() sdk.Coin
|
||||||
|
GetType() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Claims is a slice of Claim
|
||||||
|
type Claims []Claim
|
||||||
|
|
||||||
|
// BaseClaim is a common type shared by all Claims
|
||||||
|
type BaseClaim struct {
|
||||||
|
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||||
|
Reward sdk.Coin `json:"reward" yaml:"reward"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOwner is a getter for Claim Owner
|
||||||
|
func (c BaseClaim) GetOwner() sdk.AccAddress { return c.Owner }
|
||||||
|
|
||||||
|
// GetReward is a getter for Claim Reward
|
||||||
|
func (c BaseClaim) GetReward() sdk.Coin { return c.Reward }
|
||||||
|
|
||||||
|
// GetType returns the claim type, used to identify auctions in event attributes
|
||||||
|
func (c BaseClaim) GetType() string { return "base" }
|
||||||
|
|
||||||
|
// Validate performs a basic check of a BaseClaim fields
|
||||||
|
func (c BaseClaim) Validate() error {
|
||||||
|
if c.Owner.Empty() {
|
||||||
|
return errors.New("claim owner cannot be empty")
|
||||||
|
}
|
||||||
|
if !c.Reward.IsValid() {
|
||||||
|
return fmt.Errorf("invalid reward amount: %s", c.Reward)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (c BaseClaim) String() string {
|
||||||
|
return fmt.Sprintf(`Claim:
|
||||||
|
Owner: %s,
|
||||||
|
Reward: %s,
|
||||||
|
`, c.Owner, c.Reward)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseMultiClaim is a common type shared by all Claims with multiple reward denoms
|
||||||
|
type BaseMultiClaim struct {
|
||||||
|
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||||
|
Reward sdk.Coins `json:"reward" yaml:"reward"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOwner is a getter for Claim Owner
|
||||||
|
func (c BaseMultiClaim) GetOwner() sdk.AccAddress { return c.Owner }
|
||||||
|
|
||||||
|
// GetReward is a getter for Claim Reward
|
||||||
|
func (c BaseMultiClaim) GetReward() sdk.Coins { return c.Reward }
|
||||||
|
|
||||||
|
// GetType returns the claim type, used to identify auctions in event attributes
|
||||||
|
func (c BaseMultiClaim) GetType() string { return "base" }
|
||||||
|
|
||||||
|
// Validate performs a basic check of a BaseClaim fields
|
||||||
|
func (c BaseMultiClaim) Validate() error {
|
||||||
|
if c.Owner.Empty() {
|
||||||
|
return errors.New("claim owner cannot be empty")
|
||||||
|
}
|
||||||
|
if !c.Reward.IsValid() {
|
||||||
|
return fmt.Errorf("invalid reward amount: %s", c.Reward)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (c BaseMultiClaim) String() string {
|
||||||
|
return fmt.Sprintf(`Claim:
|
||||||
|
Owner: %s,
|
||||||
|
Reward: %s,
|
||||||
|
`, c.Owner, c.Reward)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------- Custom Claim Types --------------
|
||||||
|
|
||||||
|
// USDXMintingClaim is for USDX minting rewards
|
||||||
|
type USDXMintingClaim struct {
|
||||||
|
BaseClaim `json:"base_claim" yaml:"base_claim"`
|
||||||
|
RewardIndexes RewardIndexes `json:"reward_indexes" yaml:"reward_indexes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUSDXMintingClaim returns a new USDXMintingClaim
|
||||||
|
func NewUSDXMintingClaim(owner sdk.AccAddress, reward sdk.Coin, rewardIndexes RewardIndexes) USDXMintingClaim {
|
||||||
|
return USDXMintingClaim{
|
||||||
|
BaseClaim: BaseClaim{
|
||||||
|
Owner: owner,
|
||||||
|
Reward: reward,
|
||||||
|
},
|
||||||
|
RewardIndexes: rewardIndexes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType returns the claim's type
|
||||||
|
func (c USDXMintingClaim) GetType() string { return USDXMintingClaimType }
|
||||||
|
|
||||||
|
// GetReward returns the claim's reward coin
|
||||||
|
func (c USDXMintingClaim) GetReward() sdk.Coin { return c.Reward }
|
||||||
|
|
||||||
|
// GetOwner returns the claim's owner
|
||||||
|
func (c USDXMintingClaim) GetOwner() sdk.AccAddress { return c.Owner }
|
||||||
|
|
||||||
|
// Validate performs a basic check of a Claim fields
|
||||||
|
func (c USDXMintingClaim) Validate() error {
|
||||||
|
if err := c.RewardIndexes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.BaseClaim.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (c USDXMintingClaim) String() string {
|
||||||
|
return fmt.Sprintf(`%s
|
||||||
|
Reward Indexes: %s,
|
||||||
|
`, c.BaseClaim, c.RewardIndexes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasRewardIndex check if a claim has a reward index for the input collateral type
|
||||||
|
func (c USDXMintingClaim) HasRewardIndex(collateralType string) (int64, bool) {
|
||||||
|
for index, ri := range c.RewardIndexes {
|
||||||
|
if ri.CollateralType == collateralType {
|
||||||
|
return int64(index), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// USDXMintingClaims slice of USDXMintingClaim
|
||||||
|
type USDXMintingClaims []USDXMintingClaim
|
||||||
|
|
||||||
|
// Validate checks if all the claims are valid and there are no duplicated
|
||||||
|
// entries.
|
||||||
|
func (cs USDXMintingClaims) Validate() error {
|
||||||
|
for _, c := range cs {
|
||||||
|
if err := c.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner
|
||||||
|
type HardLiquidityProviderClaim struct {
|
||||||
|
BaseMultiClaim `json:"base_claim" yaml:"base_claim"`
|
||||||
|
SupplyRewardIndexes MultiRewardIndexes `json:"supply_reward_indexes" yaml:"supply_reward_indexes"`
|
||||||
|
BorrowRewardIndexes MultiRewardIndexes `json:"borrow_reward_indexes" yaml:"borrow_reward_indexes"`
|
||||||
|
DelegatorRewardIndexes RewardIndexes `json:"delegator_reward_indexes" yaml:"delegator_reward_indexes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
|
||||||
|
func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins, supplyRewardIndexes,
|
||||||
|
borrowRewardIndexes MultiRewardIndexes, delegatorRewardIndexes RewardIndexes) HardLiquidityProviderClaim {
|
||||||
|
return HardLiquidityProviderClaim{
|
||||||
|
BaseMultiClaim: BaseMultiClaim{
|
||||||
|
Owner: owner,
|
||||||
|
Reward: rewards,
|
||||||
|
},
|
||||||
|
SupplyRewardIndexes: supplyRewardIndexes,
|
||||||
|
BorrowRewardIndexes: borrowRewardIndexes,
|
||||||
|
DelegatorRewardIndexes: delegatorRewardIndexes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType returns the claim's type
|
||||||
|
func (c HardLiquidityProviderClaim) GetType() string { return HardLiquidityProviderClaimType }
|
||||||
|
|
||||||
|
// GetReward returns the claim's reward coin
|
||||||
|
func (c HardLiquidityProviderClaim) GetReward() sdk.Coins { return c.Reward }
|
||||||
|
|
||||||
|
// GetOwner returns the claim's owner
|
||||||
|
func (c HardLiquidityProviderClaim) GetOwner() sdk.AccAddress { return c.Owner }
|
||||||
|
|
||||||
|
// Validate performs a basic check of a HardLiquidityProviderClaim fields
|
||||||
|
func (c HardLiquidityProviderClaim) Validate() error {
|
||||||
|
if err := c.SupplyRewardIndexes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.BorrowRewardIndexes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.DelegatorRewardIndexes.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.BaseMultiClaim.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (c HardLiquidityProviderClaim) String() string {
|
||||||
|
return fmt.Sprintf(`%s
|
||||||
|
Supply Reward Indexes: %s,
|
||||||
|
Borrow Reward Indexes: %s,
|
||||||
|
Delegator Reward Indexes: %s,
|
||||||
|
`, c.BaseMultiClaim, c.SupplyRewardIndexes, c.BorrowRewardIndexes, c.DelegatorRewardIndexes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasSupplyRewardIndex check if a claim has a supply reward index for the input collateral type
|
||||||
|
func (c HardLiquidityProviderClaim) HasSupplyRewardIndex(denom string) (int64, bool) {
|
||||||
|
for index, ri := range c.SupplyRewardIndexes {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return int64(index), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasBorrowRewardIndex check if a claim has a borrow reward index for the input collateral type
|
||||||
|
func (c HardLiquidityProviderClaim) HasBorrowRewardIndex(denom string) (int64, bool) {
|
||||||
|
for index, ri := range c.BorrowRewardIndexes {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return int64(index), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDelegatorRewardIndex check if a claim has a delegator reward index for the input collateral type
|
||||||
|
func (c HardLiquidityProviderClaim) HasDelegatorRewardIndex(collateralType string) (int64, bool) {
|
||||||
|
for index, ri := range c.DelegatorRewardIndexes {
|
||||||
|
if ri.CollateralType == collateralType {
|
||||||
|
return int64(index), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HardLiquidityProviderClaims slice of HardLiquidityProviderClaim
|
||||||
|
type HardLiquidityProviderClaims []HardLiquidityProviderClaim
|
||||||
|
|
||||||
|
// Validate checks if all the claims are valid and there are no duplicated
|
||||||
|
// entries.
|
||||||
|
func (cs HardLiquidityProviderClaims) Validate() error {
|
||||||
|
for _, c := range cs {
|
||||||
|
if err := c.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- Reward periods are used by the params ----------------------
|
||||||
|
|
||||||
|
// MultiRewardPeriod supports multiple reward types
|
||||||
|
type MultiRewardPeriod struct {
|
||||||
|
Active bool `json:"active" yaml:"active"`
|
||||||
|
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||||
|
Start time.Time `json:"start" yaml:"start"`
|
||||||
|
End time.Time `json:"end" yaml:"end"`
|
||||||
|
RewardsPerSecond sdk.Coins `json:"rewards_per_second" yaml:"rewards_per_second"` // per second reward payouts
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (mrp MultiRewardPeriod) String() string {
|
||||||
|
return fmt.Sprintf(`Reward Period:
|
||||||
|
Collateral Type: %s,
|
||||||
|
Start: %s,
|
||||||
|
End: %s,
|
||||||
|
Rewards Per Second: %s,
|
||||||
|
Active %t,
|
||||||
|
`, mrp.CollateralType, mrp.Start, mrp.End, mrp.RewardsPerSecond, mrp.Active)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMultiRewardPeriod returns a new MultiRewardPeriod
|
||||||
|
func NewMultiRewardPeriod(active bool, collateralType string, start time.Time, end time.Time, reward sdk.Coins) MultiRewardPeriod {
|
||||||
|
return MultiRewardPeriod{
|
||||||
|
Active: active,
|
||||||
|
CollateralType: collateralType,
|
||||||
|
Start: start,
|
||||||
|
End: end,
|
||||||
|
RewardsPerSecond: reward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs a basic check of a MultiRewardPeriod.
|
||||||
|
func (mrp MultiRewardPeriod) Validate() error {
|
||||||
|
if mrp.Start.IsZero() {
|
||||||
|
return errors.New("reward period start time cannot be 0")
|
||||||
|
}
|
||||||
|
if mrp.End.IsZero() {
|
||||||
|
return errors.New("reward period end time cannot be 0")
|
||||||
|
}
|
||||||
|
if mrp.Start.After(mrp.End) {
|
||||||
|
return fmt.Errorf("end period time %s cannot be before start time %s", mrp.End, mrp.Start)
|
||||||
|
}
|
||||||
|
if !mrp.RewardsPerSecond.IsValid() {
|
||||||
|
return fmt.Errorf("invalid reward amount: %s", mrp.RewardsPerSecond)
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(mrp.CollateralType) == "" {
|
||||||
|
return fmt.Errorf("reward period collateral type cannot be blank: %s", mrp)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiRewardPeriods array of MultiRewardPeriod
|
||||||
|
type MultiRewardPeriods []MultiRewardPeriod
|
||||||
|
|
||||||
|
// GetMultiRewardPeriod fetches a MultiRewardPeriod from an array of MultiRewardPeriods by its denom
|
||||||
|
func (mrps MultiRewardPeriods) GetMultiRewardPeriod(denom string) (MultiRewardPeriod, bool) {
|
||||||
|
for _, rp := range mrps {
|
||||||
|
if rp.CollateralType == denom {
|
||||||
|
return rp, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MultiRewardPeriod{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMultiRewardPeriodIndex returns the index of a MultiRewardPeriod inside array MultiRewardPeriods
|
||||||
|
func (mrps MultiRewardPeriods) GetMultiRewardPeriodIndex(denom string) (int, bool) {
|
||||||
|
for i, rp := range mrps {
|
||||||
|
if rp.CollateralType == denom {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks if all the RewardPeriods are valid and there are no duplicated
|
||||||
|
// entries.
|
||||||
|
func (mrps MultiRewardPeriods) Validate() error {
|
||||||
|
seenPeriods := make(map[string]bool)
|
||||||
|
for _, rp := range mrps {
|
||||||
|
if seenPeriods[rp.CollateralType] {
|
||||||
|
return fmt.Errorf("duplicated reward period with collateral type %s", rp.CollateralType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rp.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
seenPeriods[rp.CollateralType] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- Reward indexes are used internally in the store ----------------------
|
||||||
|
|
||||||
|
// RewardIndex stores reward accumulation information
|
||||||
|
type RewardIndex struct {
|
||||||
|
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||||
|
RewardFactor sdk.Dec `json:"reward_factor" yaml:"reward_factor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRewardIndex returns a new RewardIndex
|
||||||
|
func NewRewardIndex(collateralType string, factor sdk.Dec) RewardIndex {
|
||||||
|
return RewardIndex{
|
||||||
|
CollateralType: collateralType,
|
||||||
|
RewardFactor: factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ri RewardIndex) String() string {
|
||||||
|
return fmt.Sprintf(`Collateral Type: %s, RewardFactor: %s`, ri.CollateralType, ri.RewardFactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates reward index
|
||||||
|
func (ri RewardIndex) Validate() error {
|
||||||
|
if ri.RewardFactor.IsNegative() {
|
||||||
|
return fmt.Errorf("reward factor value should be positive, is %s for %s", ri.RewardFactor, ri.CollateralType)
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(ri.CollateralType) == "" {
|
||||||
|
return fmt.Errorf("collateral type should not be empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RewardIndexes slice of RewardIndex
|
||||||
|
type RewardIndexes []RewardIndex
|
||||||
|
|
||||||
|
// GetRewardIndex fetches a RewardIndex by its denom
|
||||||
|
func (ris RewardIndexes) GetRewardIndex(denom string) (RewardIndex, bool) {
|
||||||
|
for _, ri := range ris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return ri, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RewardIndex{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fetches a RewardFactor by it's denom
|
||||||
|
func (ris RewardIndexes) Get(denom string) (sdk.Dec, bool) {
|
||||||
|
for _, ri := range ris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return ri.RewardFactor, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sdk.Dec{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a copy of the indexes with a new reward factor added
|
||||||
|
func (ris RewardIndexes) With(denom string, factor sdk.Dec) RewardIndexes {
|
||||||
|
newIndexes := make(RewardIndexes, len(ris))
|
||||||
|
copy(newIndexes, ris)
|
||||||
|
|
||||||
|
for i, ri := range newIndexes {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
newIndexes[i].RewardFactor = factor
|
||||||
|
return newIndexes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(newIndexes, NewRewardIndex(denom, factor))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFactorIndex gets the index of a specific reward index inside the array by its index
|
||||||
|
func (ris RewardIndexes) GetFactorIndex(denom string) (int, bool) {
|
||||||
|
for i, ri := range ris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validation for reward indexes
|
||||||
|
func (ris RewardIndexes) Validate() error {
|
||||||
|
for _, ri := range ris {
|
||||||
|
if err := ri.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiRewardIndex stores reward accumulation information on multiple reward types
|
||||||
|
type MultiRewardIndex struct {
|
||||||
|
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||||
|
RewardIndexes RewardIndexes `json:"reward_indexes" yaml:"reward_indexes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMultiRewardIndex returns a new MultiRewardIndex
|
||||||
|
func NewMultiRewardIndex(collateralType string, indexes RewardIndexes) MultiRewardIndex {
|
||||||
|
return MultiRewardIndex{
|
||||||
|
CollateralType: collateralType,
|
||||||
|
RewardIndexes: indexes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFactorIndex gets the index of a specific reward index inside the array by its index
|
||||||
|
func (mri MultiRewardIndex) GetFactorIndex(denom string) (int, bool) {
|
||||||
|
for i, ri := range mri.RewardIndexes {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mri MultiRewardIndex) String() string {
|
||||||
|
return fmt.Sprintf(`Collateral Type: %s, Reward Indexes: %s`, mri.CollateralType, mri.RewardIndexes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates multi-reward index
|
||||||
|
func (mri MultiRewardIndex) Validate() error {
|
||||||
|
for _, rf := range mri.RewardIndexes {
|
||||||
|
if rf.RewardFactor.IsNegative() {
|
||||||
|
return fmt.Errorf("reward index's factor value cannot be negative: %s", rf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(mri.CollateralType) == "" {
|
||||||
|
return fmt.Errorf("collateral type should not be empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiRewardIndexes slice of MultiRewardIndex
|
||||||
|
type MultiRewardIndexes []MultiRewardIndex
|
||||||
|
|
||||||
|
// GetRewardIndex fetches a RewardIndex from a MultiRewardIndex by its denom
|
||||||
|
func (mris MultiRewardIndexes) GetRewardIndex(denom string) (MultiRewardIndex, bool) {
|
||||||
|
for _, ri := range mris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return ri, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MultiRewardIndex{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fetches a RewardIndexes by it's denom
|
||||||
|
func (mris MultiRewardIndexes) Get(denom string) (RewardIndexes, bool) {
|
||||||
|
for _, mri := range mris {
|
||||||
|
if mri.CollateralType == denom {
|
||||||
|
return mri.RewardIndexes, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRewardIndexIndex fetches a specific reward index inside the array by its denom
|
||||||
|
func (mris MultiRewardIndexes) GetRewardIndexIndex(denom string) (int, bool) {
|
||||||
|
for i, ri := range mris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a copy of the indexes with a new RewardIndexes added
|
||||||
|
func (mris MultiRewardIndexes) With(denom string, indexes RewardIndexes) MultiRewardIndexes {
|
||||||
|
newIndexes := mris.copy()
|
||||||
|
|
||||||
|
for i, mri := range newIndexes {
|
||||||
|
if mri.CollateralType == denom {
|
||||||
|
newIndexes[i].RewardIndexes = indexes
|
||||||
|
return newIndexes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(newIndexes, NewMultiRewardIndex(denom, indexes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCollateralTypes returns a slice of containing all collateral types
|
||||||
|
func (mris MultiRewardIndexes) GetCollateralTypes() []string {
|
||||||
|
var collateralTypes []string
|
||||||
|
for _, ri := range mris {
|
||||||
|
collateralTypes = append(collateralTypes, ri.CollateralType)
|
||||||
|
}
|
||||||
|
return collateralTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRewardIndex removes a denom's reward interest factor value
|
||||||
|
func (mris MultiRewardIndexes) RemoveRewardIndex(denom string) MultiRewardIndexes {
|
||||||
|
for i, ri := range mris {
|
||||||
|
if ri.CollateralType == denom {
|
||||||
|
// copy the slice and underlying array to avoid altering the original
|
||||||
|
copy := mris.copy()
|
||||||
|
return append(copy[:i], copy[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mris
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validation for reward indexes
|
||||||
|
func (mris MultiRewardIndexes) Validate() error {
|
||||||
|
for _, mri := range mris {
|
||||||
|
if err := mri.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy returns a copy of the slice and underlying array
|
||||||
|
func (mris MultiRewardIndexes) copy() MultiRewardIndexes {
|
||||||
|
newIndexes := make(MultiRewardIndexes, len(mris))
|
||||||
|
copy(newIndexes, mris)
|
||||||
|
return newIndexes
|
||||||
|
}
|
@ -167,12 +167,12 @@ type HardLiquidityProviderClaim struct {
|
|||||||
BaseMultiClaim `json:"base_claim" yaml:"base_claim"`
|
BaseMultiClaim `json:"base_claim" yaml:"base_claim"`
|
||||||
SupplyRewardIndexes MultiRewardIndexes `json:"supply_reward_indexes" yaml:"supply_reward_indexes"`
|
SupplyRewardIndexes MultiRewardIndexes `json:"supply_reward_indexes" yaml:"supply_reward_indexes"`
|
||||||
BorrowRewardIndexes MultiRewardIndexes `json:"borrow_reward_indexes" yaml:"borrow_reward_indexes"`
|
BorrowRewardIndexes MultiRewardIndexes `json:"borrow_reward_indexes" yaml:"borrow_reward_indexes"`
|
||||||
DelegatorRewardIndexes RewardIndexes `json:"delegator_reward_indexes" yaml:"delegator_reward_indexes"`
|
DelegatorRewardIndexes MultiRewardIndexes `json:"delegator_reward_indexes" yaml:"delegator_reward_indexes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
|
// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
|
||||||
func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins, supplyRewardIndexes,
|
func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins, supplyRewardIndexes,
|
||||||
borrowRewardIndexes MultiRewardIndexes, delegatorRewardIndexes RewardIndexes) HardLiquidityProviderClaim {
|
borrowRewardIndexes, delegatorRewardIndexes MultiRewardIndexes) HardLiquidityProviderClaim {
|
||||||
return HardLiquidityProviderClaim{
|
return HardLiquidityProviderClaim{
|
||||||
BaseMultiClaim: BaseMultiClaim{
|
BaseMultiClaim: BaseMultiClaim{
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
|
@ -54,7 +54,7 @@ func TestGenesisStateValidate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
DefaultMultiRewardPeriods,
|
DefaultMultiRewardPeriods,
|
||||||
DefaultMultiRewardPeriods,
|
DefaultMultiRewardPeriods,
|
||||||
DefaultRewardPeriods,
|
DefaultMultiRewardPeriods,
|
||||||
Multipliers{
|
Multipliers{
|
||||||
NewMultiplier(Small, 1, sdk.MustNewDecFromStr("0.33")),
|
NewMultiplier(Small, 1, sdk.MustNewDecFromStr("0.33")),
|
||||||
},
|
},
|
||||||
|
@ -27,11 +27,11 @@ var (
|
|||||||
USDXMintingRewardFactorKeyPrefix = []byte{0x02} // prefix for key that stores USDX minting reward factors
|
USDXMintingRewardFactorKeyPrefix = []byte{0x02} // prefix for key that stores USDX minting reward factors
|
||||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = []byte{0x03} // prefix for key that stores the blocktime
|
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = []byte{0x03} // prefix for key that stores the blocktime
|
||||||
HardLiquidityClaimKeyPrefix = []byte{0x04} // prefix for keys that store Hard liquidity claims
|
HardLiquidityClaimKeyPrefix = []byte{0x04} // prefix for keys that store Hard liquidity claims
|
||||||
HardSupplyRewardIndexesKeyPrefix = []byte{0x05} // prefix for key that stores Hard supply reward factors
|
HardSupplyRewardIndexesKeyPrefix = []byte{0x05} // prefix for key that stores Hard supply reward indexes
|
||||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = []byte{0x06} // prefix for key that stores the previous time Hard supply rewards accrued
|
PreviousHardSupplyRewardAccrualTimeKeyPrefix = []byte{0x06} // prefix for key that stores the previous time Hard supply rewards accrued
|
||||||
HardBorrowRewardIndexesKeyPrefix = []byte{0x07} // prefix for key that stores Hard borrow reward factors
|
HardBorrowRewardIndexesKeyPrefix = []byte{0x07} // prefix for key that stores Hard borrow reward indexes
|
||||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = []byte{0x08} // prefix for key that stores the previous time Hard borrow rewards accrued
|
PreviousHardBorrowRewardAccrualTimeKeyPrefix = []byte{0x08} // prefix for key that stores the previous time Hard borrow rewards accrued
|
||||||
HardDelegatorRewardFactorKeyPrefix = []byte{0x09} // prefix for key that stores Hard delegator reward factors
|
HardDelegatorRewardIndexesKeyPrefix = []byte{0x09} // prefix for key that stores Hard delegator reward indexes
|
||||||
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = []byte{0x10} // prefix for key that stores the previous time Hard delegator rewards accrued
|
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = []byte{0x10} // prefix for key that stores the previous time Hard delegator rewards accrued
|
||||||
|
|
||||||
USDXMintingRewardDenom = "ukava"
|
USDXMintingRewardDenom = "ukava"
|
||||||
|
@ -48,14 +48,14 @@ type Params struct {
|
|||||||
USDXMintingRewardPeriods RewardPeriods `json:"usdx_minting_reward_periods" yaml:"usdx_minting_reward_periods"`
|
USDXMintingRewardPeriods RewardPeriods `json:"usdx_minting_reward_periods" yaml:"usdx_minting_reward_periods"`
|
||||||
HardSupplyRewardPeriods MultiRewardPeriods `json:"hard_supply_reward_periods" yaml:"hard_supply_reward_periods"`
|
HardSupplyRewardPeriods MultiRewardPeriods `json:"hard_supply_reward_periods" yaml:"hard_supply_reward_periods"`
|
||||||
HardBorrowRewardPeriods MultiRewardPeriods `json:"hard_borrow_reward_periods" yaml:"hard_borrow_reward_periods"`
|
HardBorrowRewardPeriods MultiRewardPeriods `json:"hard_borrow_reward_periods" yaml:"hard_borrow_reward_periods"`
|
||||||
HardDelegatorRewardPeriods RewardPeriods `json:"hard_delegator_reward_periods" yaml:"hard_delegator_reward_periods"`
|
HardDelegatorRewardPeriods MultiRewardPeriods `json:"hard_delegator_reward_periods" yaml:"hard_delegator_reward_periods"`
|
||||||
ClaimMultipliers Multipliers `json:"claim_multipliers" yaml:"claim_multipliers"`
|
ClaimMultipliers Multipliers `json:"claim_multipliers" yaml:"claim_multipliers"`
|
||||||
ClaimEnd time.Time `json:"claim_end" yaml:"claim_end"`
|
ClaimEnd time.Time `json:"claim_end" yaml:"claim_end"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewParams returns a new params object
|
// NewParams returns a new params object
|
||||||
func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow MultiRewardPeriods,
|
func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow, hardDelegator MultiRewardPeriods,
|
||||||
hardDelegator RewardPeriods, multipliers Multipliers, claimEnd time.Time) Params {
|
multipliers Multipliers, claimEnd time.Time) Params {
|
||||||
return Params{
|
return Params{
|
||||||
USDXMintingRewardPeriods: usdxMinting,
|
USDXMintingRewardPeriods: usdxMinting,
|
||||||
HardSupplyRewardPeriods: hardSupply,
|
HardSupplyRewardPeriods: hardSupply,
|
||||||
@ -69,7 +69,9 @@ func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow MultiRewardPeri
|
|||||||
// DefaultParams returns default params for incentive module
|
// DefaultParams returns default params for incentive module
|
||||||
func DefaultParams() Params {
|
func DefaultParams() Params {
|
||||||
return NewParams(DefaultRewardPeriods, DefaultMultiRewardPeriods,
|
return NewParams(DefaultRewardPeriods, DefaultMultiRewardPeriods,
|
||||||
DefaultMultiRewardPeriods, DefaultRewardPeriods, DefaultMultipliers, DefaultClaimEnd)
|
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
|
||||||
|
DefaultMultipliers, DefaultClaimEnd,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements fmt.Stringer
|
// String implements fmt.Stringer
|
||||||
@ -96,7 +98,7 @@ func (p *Params) ParamSetPairs() params.ParamSetPairs {
|
|||||||
params.NewParamSetPair(KeyUSDXMintingRewardPeriods, &p.USDXMintingRewardPeriods, validateRewardPeriodsParam),
|
params.NewParamSetPair(KeyUSDXMintingRewardPeriods, &p.USDXMintingRewardPeriods, validateRewardPeriodsParam),
|
||||||
params.NewParamSetPair(KeyHardSupplyRewardPeriods, &p.HardSupplyRewardPeriods, validateMultiRewardPeriodsParam),
|
params.NewParamSetPair(KeyHardSupplyRewardPeriods, &p.HardSupplyRewardPeriods, validateMultiRewardPeriodsParam),
|
||||||
params.NewParamSetPair(KeyHardBorrowRewardPeriods, &p.HardBorrowRewardPeriods, validateMultiRewardPeriodsParam),
|
params.NewParamSetPair(KeyHardBorrowRewardPeriods, &p.HardBorrowRewardPeriods, validateMultiRewardPeriodsParam),
|
||||||
params.NewParamSetPair(KeyHardDelegatorRewardPeriods, &p.HardDelegatorRewardPeriods, validateRewardPeriodsParam),
|
params.NewParamSetPair(KeyHardDelegatorRewardPeriods, &p.HardDelegatorRewardPeriods, validateMultiRewardPeriodsParam),
|
||||||
params.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
|
params.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
|
||||||
params.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersParam),
|
params.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersParam),
|
||||||
}
|
}
|
||||||
@ -121,7 +123,7 @@ func (p Params) Validate() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return validateRewardPeriodsParam(p.HardDelegatorRewardPeriods)
|
return validateMultiRewardPeriodsParam(p.HardDelegatorRewardPeriods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateRewardPeriodsParam(i interface{}) error {
|
func validateRewardPeriodsParam(i interface{}) error {
|
||||||
|
@ -23,7 +23,7 @@ func (suite *ParamTestSuite) TestParamValidation() {
|
|||||||
usdxMintingRewardPeriods types.RewardPeriods
|
usdxMintingRewardPeriods types.RewardPeriods
|
||||||
hardSupplyRewardPeriods types.MultiRewardPeriods
|
hardSupplyRewardPeriods types.MultiRewardPeriods
|
||||||
hardBorrowRewardPeriods types.MultiRewardPeriods
|
hardBorrowRewardPeriods types.MultiRewardPeriods
|
||||||
hardDelegatorRewardPeriods types.RewardPeriods
|
hardDelegatorRewardPeriods types.MultiRewardPeriods
|
||||||
multipliers types.Multipliers
|
multipliers types.Multipliers
|
||||||
end time.Time
|
end time.Time
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ func (suite *ParamTestSuite) TestParamValidation() {
|
|||||||
usdxMintingRewardPeriods: types.DefaultRewardPeriods,
|
usdxMintingRewardPeriods: types.DefaultRewardPeriods,
|
||||||
hardSupplyRewardPeriods: types.DefaultMultiRewardPeriods,
|
hardSupplyRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
hardBorrowRewardPeriods: types.DefaultMultiRewardPeriods,
|
hardBorrowRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
|
hardDelegatorRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
multipliers: types.DefaultMultipliers,
|
multipliers: types.DefaultMultipliers,
|
||||||
end: types.DefaultClaimEnd,
|
end: types.DefaultClaimEnd,
|
||||||
},
|
},
|
||||||
@ -70,7 +70,7 @@ func (suite *ParamTestSuite) TestParamValidation() {
|
|||||||
},
|
},
|
||||||
hardSupplyRewardPeriods: types.DefaultMultiRewardPeriods,
|
hardSupplyRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
hardBorrowRewardPeriods: types.DefaultMultiRewardPeriods,
|
hardBorrowRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
|
hardDelegatorRewardPeriods: types.DefaultMultiRewardPeriods,
|
||||||
end: time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC),
|
end: time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC),
|
||||||
},
|
},
|
||||||
errArgs{
|
errArgs{
|
||||||
|
@ -117,22 +117,22 @@ func NewQueryRewardFactorsParams(denom string) QueryRewardFactorsParams {
|
|||||||
|
|
||||||
// RewardFactor is a unique type returned by reward factor queries
|
// RewardFactor is a unique type returned by reward factor queries
|
||||||
type RewardFactor struct {
|
type RewardFactor struct {
|
||||||
Denom string `json:"denom" yaml:"denom"`
|
Denom string `json:"denom" yaml:"denom"`
|
||||||
USDXMintingRewardFactor sdk.Dec `json:"usdx_minting_reward_factor" yaml:"usdx_minting_reward_factor"`
|
USDXMintingRewardFactor sdk.Dec `json:"usdx_minting_reward_factor" yaml:"usdx_minting_reward_factor"`
|
||||||
HardSupplyRewardFactors RewardIndexes `json:"hard_supply_reward_factors" yaml:"hard_supply_reward_factors"`
|
HardSupplyRewardFactors RewardIndexes `json:"hard_supply_reward_factors" yaml:"hard_supply_reward_factors"`
|
||||||
HardBorrowRewardFactors RewardIndexes `json:"hard_borrow_reward_factors" yaml:"hard_borrow_reward_factors"`
|
HardBorrowRewardFactors RewardIndexes `json:"hard_borrow_reward_factors" yaml:"hard_borrow_reward_factors"`
|
||||||
HardDelegatorRewardFactor sdk.Dec `json:"hard_delegator_reward_factor" yaml:"hard_delegator_reward_factor"`
|
HardDelegatorRewardFactors RewardIndexes `json:"hard_delegator_reward_factors" yaml:"hard_delegator_reward_factors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRewardFactor returns a new instance of RewardFactor
|
// NewRewardFactor returns a new instance of RewardFactor
|
||||||
func NewRewardFactor(denom string, usdxMintingRewardFactor sdk.Dec, hardSupplyRewardFactors,
|
func NewRewardFactor(denom string, usdxMintingRewardFactor sdk.Dec, hardSupplyRewardFactors,
|
||||||
hardBorrowRewardFactors RewardIndexes, hardDelegatorRewardFactor sdk.Dec) RewardFactor {
|
hardBorrowRewardFactors, hardDelegatorRewardFactors RewardIndexes) RewardFactor {
|
||||||
return RewardFactor{
|
return RewardFactor{
|
||||||
Denom: denom,
|
Denom: denom,
|
||||||
USDXMintingRewardFactor: usdxMintingRewardFactor,
|
USDXMintingRewardFactor: usdxMintingRewardFactor,
|
||||||
HardSupplyRewardFactors: hardSupplyRewardFactors,
|
HardSupplyRewardFactors: hardSupplyRewardFactors,
|
||||||
HardBorrowRewardFactors: hardBorrowRewardFactors,
|
HardBorrowRewardFactors: hardBorrowRewardFactors,
|
||||||
HardDelegatorRewardFactor: hardDelegatorRewardFactor,
|
HardDelegatorRewardFactors: hardDelegatorRewardFactors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user