mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
Allocate Hard supply/borrow rewards to legacy suppliers/borrowers (#833)
* initialize hard supply reward for empty rewards * add god committee to integration test * organize claim types, add helper methods * reorder integration test's god committee * legacy suppliers earn rewards + tests * update InitializeHardBorrowReward + test * remove formatting comments from tests * allocate rewards to legacy borrowers + test * apply change to update index denom methods * Update querier to show synced rewards for legacy deposits/borrows (#834) * update simulated sync method to show rewards for legacy deposits/borrows * more explicity debuging logs * revisions Co-authored-by: Kevin Davis <karzak@users.noreply.github.com>
This commit is contained in:
parent
c5fc1c6b4f
commit
6045a94b39
@ -4,9 +4,14 @@ import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/cdp"
|
||||
committeetypes "github.com/kava-labs/kava/x/committee/types"
|
||||
"github.com/kava-labs/kava/x/hard"
|
||||
"github.com/kava-labs/kava/x/pricefeed"
|
||||
)
|
||||
@ -109,6 +114,7 @@ func NewPricefeedGenStateMulti() app.GenesisState {
|
||||
{MarketID: "xrp:usd", BaseAsset: "xrp", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
{MarketID: "bnb:usd", BaseAsset: "bnb", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
{MarketID: "busd:usd", BaseAsset: "busd", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
{MarketID: "zzz:usd", BaseAsset: "zzz", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
},
|
||||
},
|
||||
PostedPrices: []pricefeed.PostedPrice{
|
||||
@ -142,6 +148,12 @@ func NewPricefeedGenStateMulti() app.GenesisState {
|
||||
Price: sdk.OneDec(),
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
{
|
||||
MarketID: "zzz:usd",
|
||||
OracleAddress: sdk.AccAddress{},
|
||||
Price: sdk.MustNewDecFromStr("2.00"),
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
},
|
||||
}
|
||||
return app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pfGenesis)}
|
||||
@ -158,6 +170,7 @@ func NewHardGenStateMulti() app.GenesisState {
|
||||
hard.NewMoneyMarket("bnb", hard.NewBorrowLimit(false, borrowLimit, loanToValue), "bnb:usd", sdk.NewInt(1000000), hard.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
hard.NewMoneyMarket("btcb", hard.NewBorrowLimit(false, borrowLimit, loanToValue), "btc:usd", sdk.NewInt(1000000), hard.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
hard.NewMoneyMarket("xrp", hard.NewBorrowLimit(false, borrowLimit, loanToValue), "xrp:usd", sdk.NewInt(1000000), hard.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
hard.NewMoneyMarket("zzz", hard.NewBorrowLimit(false, borrowLimit, loanToValue), "zzz:usd", sdk.NewInt(1000000), hard.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
},
|
||||
sdk.NewDec(10),
|
||||
), hard.DefaultAccumulationTimes, hard.DefaultDeposits, hard.DefaultBorrows,
|
||||
@ -166,3 +179,72 @@ func NewHardGenStateMulti() app.GenesisState {
|
||||
|
||||
return app.GenesisState{hard.ModuleName: hard.ModuleCdc.MustMarshalJSON(hardGS)}
|
||||
}
|
||||
|
||||
func NewAuthGenState(addresses []sdk.AccAddress, coins sdk.Coins) app.GenesisState {
|
||||
coinsList := []sdk.Coins{}
|
||||
for range addresses {
|
||||
coinsList = append(coinsList, coins)
|
||||
}
|
||||
|
||||
// Load up our primary user address
|
||||
if len(addresses) >= 4 {
|
||||
coinsList[3] = sdk.NewCoins(
|
||||
sdk.NewCoin("bnb", sdk.NewInt(1000000000000000)),
|
||||
sdk.NewCoin("ukava", sdk.NewInt(1000000000000000)),
|
||||
sdk.NewCoin("btcb", sdk.NewInt(1000000000000000)),
|
||||
sdk.NewCoin("xrp", sdk.NewInt(1000000000000000)),
|
||||
sdk.NewCoin("zzz", sdk.NewInt(1000000000000000)),
|
||||
)
|
||||
}
|
||||
|
||||
return app.NewAuthGenState(addresses, coinsList)
|
||||
}
|
||||
|
||||
func NewStakingGenesisState() app.GenesisState {
|
||||
genState := staking.DefaultGenesisState()
|
||||
genState.Params.BondDenom = "ukava"
|
||||
return app.GenesisState{
|
||||
staking.ModuleName: staking.ModuleCdc.MustMarshalJSON(genState),
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupWithGenState() {
|
||||
config := sdk.GetConfig()
|
||||
app.SetBech32AddressPrefixes(config)
|
||||
|
||||
_, allAddrs := app.GeneratePrivKeyAddressPairs(10)
|
||||
suite.addrs = allAddrs[:5]
|
||||
for _, a := range allAddrs[5:] {
|
||||
suite.validatorAddrs = append(suite.validatorAddrs, sdk.ValAddress(a))
|
||||
}
|
||||
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
tApp.InitializeFromGenesisStates(
|
||||
NewAuthGenState(allAddrs, cs(c("ukava", 5_000_000))),
|
||||
NewStakingGenesisState(),
|
||||
NewPricefeedGenStateMulti(),
|
||||
NewCDPGenStateMulti(),
|
||||
NewHardGenStateMulti(),
|
||||
)
|
||||
|
||||
// Set up a god committee
|
||||
committeeModKeeper := tApp.GetCommitteeKeeper()
|
||||
godCommittee := committeetypes.Committee{
|
||||
ID: 1,
|
||||
Description: "This committee is for testing.",
|
||||
Members: suite.addrs[:2],
|
||||
Permissions: []committeetypes.Permission{committeetypes.GodPermission{}},
|
||||
VoteThreshold: d("0.667"),
|
||||
ProposalDuration: time.Hour * 24 * 7,
|
||||
}
|
||||
committeeModKeeper.SetCommittee(ctx, godCommittee)
|
||||
|
||||
suite.app = tApp
|
||||
suite.ctx = ctx
|
||||
suite.keeper = tApp.GetIncentiveKeeper()
|
||||
suite.hardKeeper = tApp.GetHardKeeper()
|
||||
suite.stakingKeeper = tApp.GetStakingKeeper()
|
||||
suite.committeeKeeper = committeeModKeeper
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
committeekeeper "github.com/kava-labs/kava/x/committee/keeper"
|
||||
hardkeeper "github.com/kava-labs/kava/x/hard/keeper"
|
||||
"github.com/kava-labs/kava/x/incentive/keeper"
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
@ -28,6 +29,7 @@ type KeeperTestSuite struct {
|
||||
keeper keeper.Keeper
|
||||
hardKeeper hardkeeper.Keeper
|
||||
stakingKeeper stakingkeeper.Keeper
|
||||
committeeKeeper committeekeeper.Keeper
|
||||
app app.TestApp
|
||||
ctx sdk.Context
|
||||
addrs []sdk.AccAddress
|
||||
|
@ -262,10 +262,12 @@ func (k Keeper) InitializeHardSupplyReward(ctx sdk.Context, deposit hardtypes.De
|
||||
var supplyRewardIndexes types.MultiRewardIndexes
|
||||
for _, coin := range deposit.Amount {
|
||||
globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
|
||||
if !foundGlobalRewardIndexes {
|
||||
continue
|
||||
var multiRewardIndex types.MultiRewardIndex
|
||||
if foundGlobalRewardIndexes {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
} else {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, types.RewardIndexes{})
|
||||
}
|
||||
multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
supplyRewardIndexes = append(supplyRewardIndexes, multiRewardIndex)
|
||||
}
|
||||
|
||||
@ -296,8 +298,8 @@ func (k Keeper) SynchronizeHardSupplyReward(ctx sdk.Context, deposit hardtypes.D
|
||||
continue
|
||||
}
|
||||
|
||||
userRewardIndexes, foundUserRewardIndexes := claim.SupplyRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserRewardIndexes {
|
||||
userMultiRewardIndex, foundUserMultiRewardIndex := claim.SupplyRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserMultiRewardIndex {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -308,9 +310,14 @@ func (k Keeper) SynchronizeHardSupplyReward(ctx sdk.Context, deposit hardtypes.D
|
||||
}
|
||||
|
||||
for _, globalRewardIndex := range globalRewardIndexes {
|
||||
userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
userRewardIndex, foundUserRewardIndex := userMultiRewardIndex.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
if !foundUserRewardIndex {
|
||||
continue
|
||||
// User deposited this coin type before it had rewards. When new rewards are added, legacy depositors
|
||||
// should immediately begin earning rewards. Enable users to do so by updating their claim with the global
|
||||
// reward index denom and start their reward factor at 0.0
|
||||
userRewardIndex = types.NewRewardIndex(globalRewardIndex.CollateralType, sdk.ZeroDec())
|
||||
userMultiRewardIndex.RewardIndexes = append(userMultiRewardIndex.RewardIndexes, userRewardIndex)
|
||||
claim.SupplyRewardIndexes[userRewardIndexIndex] = userMultiRewardIndex
|
||||
}
|
||||
|
||||
globalRewardFactor := globalRewardIndex.RewardFactor
|
||||
@ -324,7 +331,7 @@ func (k Keeper) SynchronizeHardSupplyReward(ctx sdk.Context, deposit hardtypes.D
|
||||
continue
|
||||
}
|
||||
|
||||
factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
factorIndex, foundFactorIndex := userMultiRewardIndex.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
if !foundFactorIndex {
|
||||
fmt.Printf("[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
|
||||
continue
|
||||
@ -348,10 +355,12 @@ func (k Keeper) InitializeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bor
|
||||
var borrowRewardIndexes types.MultiRewardIndexes
|
||||
for _, coin := range borrow.Amount {
|
||||
globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
|
||||
if !foundGlobalRewardIndexes {
|
||||
continue
|
||||
var multiRewardIndex types.MultiRewardIndex
|
||||
if foundGlobalRewardIndexes {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
} else {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, types.RewardIndexes{})
|
||||
}
|
||||
multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
borrowRewardIndexes = append(borrowRewardIndexes, multiRewardIndex)
|
||||
}
|
||||
|
||||
@ -373,8 +382,8 @@ func (k Keeper) SynchronizeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bo
|
||||
continue
|
||||
}
|
||||
|
||||
userRewardIndexes, foundUserRewardIndexes := claim.BorrowRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserRewardIndexes {
|
||||
userMultiRewardIndex, foundUserMultiRewardIndex := claim.BorrowRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserMultiRewardIndex {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -385,9 +394,14 @@ func (k Keeper) SynchronizeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bo
|
||||
}
|
||||
|
||||
for _, globalRewardIndex := range globalRewardIndexes {
|
||||
userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
userRewardIndex, foundUserRewardIndex := userMultiRewardIndex.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
if !foundUserRewardIndex {
|
||||
continue
|
||||
// User borrowed this coin type before it had rewards. When new rewards are added, legacy borrowers
|
||||
// should immediately begin earning rewards. Enable users to do so by updating their claim with the global
|
||||
// reward index denom and start their reward factor at 0.0
|
||||
userRewardIndex = types.NewRewardIndex(globalRewardIndex.CollateralType, sdk.ZeroDec())
|
||||
userMultiRewardIndex.RewardIndexes = append(userMultiRewardIndex.RewardIndexes, userRewardIndex)
|
||||
claim.BorrowRewardIndexes[userRewardIndexIndex] = userMultiRewardIndex
|
||||
}
|
||||
|
||||
globalRewardFactor := globalRewardIndex.RewardFactor
|
||||
@ -401,7 +415,7 @@ func (k Keeper) SynchronizeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bo
|
||||
continue
|
||||
}
|
||||
|
||||
factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
factorIndex, foundFactorIndex := userMultiRewardIndex.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
if !foundFactorIndex {
|
||||
fmt.Printf("\n[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
|
||||
continue
|
||||
@ -425,11 +439,13 @@ func (k Keeper) UpdateHardSupplyIndexDenoms(ctx sdk.Context, deposit hardtypes.D
|
||||
for _, coin := range deposit.Amount {
|
||||
_, foundUserRewardIndexes := claim.SupplyRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserRewardIndexes {
|
||||
globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
|
||||
if !foundGlobalRewardIndexes {
|
||||
continue // No rewards for this coin type
|
||||
globalSupplyRewardIndexes, foundGlobalSupplyRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
|
||||
var multiRewardIndex types.MultiRewardIndex
|
||||
if foundGlobalSupplyRewardIndexes {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, globalSupplyRewardIndexes)
|
||||
} else {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, types.RewardIndexes{})
|
||||
}
|
||||
multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
supplyRewardIndexes = append(supplyRewardIndexes, multiRewardIndex)
|
||||
}
|
||||
}
|
||||
@ -451,11 +467,13 @@ func (k Keeper) UpdateHardBorrowIndexDenoms(ctx sdk.Context, borrow hardtypes.Bo
|
||||
for _, coin := range borrow.Amount {
|
||||
_, foundUserRewardIndexes := claim.BorrowRewardIndexes.GetRewardIndex(coin.Denom)
|
||||
if !foundUserRewardIndexes {
|
||||
globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
|
||||
if !foundGlobalRewardIndexes {
|
||||
continue // No rewards for this coin type
|
||||
globalBorrowRewardIndexes, foundGlobalBorrowRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
|
||||
var multiRewardIndex types.MultiRewardIndex
|
||||
if foundGlobalBorrowRewardIndexes {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, globalBorrowRewardIndexes)
|
||||
} else {
|
||||
multiRewardIndex = types.NewMultiRewardIndex(coin.Denom, types.RewardIndexes{})
|
||||
}
|
||||
multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
|
||||
borrowRewardIndexes = append(borrowRewardIndexes, multiRewardIndex)
|
||||
}
|
||||
}
|
||||
@ -678,14 +696,16 @@ func (k Keeper) SimulateHardSynchronization(ctx sdk.Context, claim types.HardLiq
|
||||
|
||||
userRewardIndexIndex, foundUserRewardIndexIndex := claim.SupplyRewardIndexes.GetRewardIndexIndex(ri.CollateralType)
|
||||
if !foundUserRewardIndexIndex {
|
||||
fmt.Printf("\n[LOG]: factor index for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
fmt.Printf("\n[LOG]: claim.SupplyRewardIndexes.GetRewardIndexIndex for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
continue
|
||||
}
|
||||
|
||||
for _, globalRewardIndex := range globalRewardIndexes {
|
||||
userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
if !foundUserRewardIndex {
|
||||
continue
|
||||
userRewardIndex = types.NewRewardIndex(globalRewardIndex.CollateralType, sdk.ZeroDec())
|
||||
userRewardIndexes.RewardIndexes = append(userRewardIndexes.RewardIndexes, userRewardIndex)
|
||||
claim.SupplyRewardIndexes[userRewardIndexIndex].RewardIndexes = append(claim.SupplyRewardIndexes[userRewardIndexIndex].RewardIndexes, userRewardIndex)
|
||||
}
|
||||
|
||||
globalRewardFactor := globalRewardIndex.RewardFactor
|
||||
@ -705,7 +725,7 @@ func (k Keeper) SimulateHardSynchronization(ctx sdk.Context, claim types.HardLiq
|
||||
|
||||
factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
if !foundFactorIndex {
|
||||
fmt.Printf("[LOG]: factor index for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
fmt.Printf("[LOG]: userRewardIndexes.RewardIndexes.GetFactorIndex for %s should always be found", globalRewardIndex.CollateralType) // TODO: remove before production
|
||||
continue
|
||||
}
|
||||
claim.SupplyRewardIndexes[userRewardIndexIndex].RewardIndexes[factorIndex].RewardFactor = globalRewardIndex.RewardFactor
|
||||
@ -728,14 +748,16 @@ func (k Keeper) SimulateHardSynchronization(ctx sdk.Context, claim types.HardLiq
|
||||
|
||||
userRewardIndexIndex, foundUserRewardIndexIndex := claim.BorrowRewardIndexes.GetRewardIndexIndex(ri.CollateralType)
|
||||
if !foundUserRewardIndexIndex {
|
||||
fmt.Printf("\n[LOG]: factor index for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
fmt.Printf("\n[LOG]: claim.BorrowRewardIndexes.GetRewardIndexIndex for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
continue
|
||||
}
|
||||
|
||||
for _, globalRewardIndex := range globalRewardIndexes {
|
||||
userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
|
||||
if !foundUserRewardIndex {
|
||||
continue
|
||||
userRewardIndex = types.NewRewardIndex(globalRewardIndex.CollateralType, sdk.ZeroDec())
|
||||
userRewardIndexes.RewardIndexes = append(userRewardIndexes.RewardIndexes, userRewardIndex)
|
||||
claim.BorrowRewardIndexes[userRewardIndexIndex].RewardIndexes = append(claim.BorrowRewardIndexes[userRewardIndexIndex].RewardIndexes, userRewardIndex)
|
||||
}
|
||||
|
||||
globalRewardFactor := globalRewardIndex.RewardFactor
|
||||
@ -755,7 +777,7 @@ func (k Keeper) SimulateHardSynchronization(ctx sdk.Context, claim types.HardLiq
|
||||
|
||||
factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
|
||||
if !foundFactorIndex {
|
||||
fmt.Printf("[LOG]: factor index for %s should always be found", ri.CollateralType) // TODO: remove before production
|
||||
fmt.Printf("[LOG]: userRewardIndexes.RewardIndexes.GetFactorIndex for %s should always be found", globalRewardIndex.CollateralType) // TODO: remove before production
|
||||
continue
|
||||
}
|
||||
claim.BorrowRewardIndexes[userRewardIndexIndex].RewardIndexes[factorIndex].RewardFactor = globalRewardIndex.RewardFactor
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -264,9 +264,101 @@ func (cs HardLiquidityProviderClaims) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// -------------- Subcomponents of Custom Claim Types --------------
|
||||
// ---------------------- Reward periods are used by the params ----------------------
|
||||
|
||||
// TODO: refactor RewardPeriod name from 'collateralType' to 'denom'
|
||||
// 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 {
|
||||
@ -330,80 +422,6 @@ func (ris RewardIndexes) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// MultiRewardIndex stores reward accumulation information on multiple reward types
|
||||
type MultiRewardIndex struct {
|
||||
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||
|
Loading…
Reference in New Issue
Block a user