mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 09:47:28 +00:00 
			
		
		
		
	Accrue Hard module rewards in multiple coin denoms (#785)
* types: multiple rewards * supply-side reward keeper methods * remove legacy comments * update hard claim reward to coins type * borrow-side reward keeper methods * update claim payout to sdk.Coins * make tests compile * fix genesis validation for compile * comment out failing tests * fix ! found logic
This commit is contained in:
		
							parent
							
								
									58494fe357
								
							
						
					
					
						commit
						9b52154409
					
				@ -51,6 +51,7 @@ var (
 | 
				
			|||||||
	NewQueryRewardsParams                  = types.NewQueryRewardsParams
 | 
						NewQueryRewardsParams                  = types.NewQueryRewardsParams
 | 
				
			||||||
	NewRewardIndex                         = types.NewRewardIndex
 | 
						NewRewardIndex                         = types.NewRewardIndex
 | 
				
			||||||
	NewRewardPeriod                        = types.NewRewardPeriod
 | 
						NewRewardPeriod                        = types.NewRewardPeriod
 | 
				
			||||||
 | 
						NewMultiRewardPeriod                   = types.NewMultiRewardPeriod
 | 
				
			||||||
	NewUSDXMintingClaim                    = types.NewUSDXMintingClaim
 | 
						NewUSDXMintingClaim                    = types.NewUSDXMintingClaim
 | 
				
			||||||
	NewHardLiquidityProviderClaim          = types.NewHardLiquidityProviderClaim
 | 
						NewHardLiquidityProviderClaim          = types.NewHardLiquidityProviderClaim
 | 
				
			||||||
	ParamKeyTable                          = types.ParamKeyTable
 | 
						ParamKeyTable                          = types.ParamKeyTable
 | 
				
			||||||
@ -65,6 +66,7 @@ var (
 | 
				
			|||||||
	DefaultGenesisAccumulationTimes               = types.DefaultGenesisAccumulationTimes
 | 
						DefaultGenesisAccumulationTimes               = types.DefaultGenesisAccumulationTimes
 | 
				
			||||||
	DefaultMultipliers                            = types.DefaultMultipliers
 | 
						DefaultMultipliers                            = types.DefaultMultipliers
 | 
				
			||||||
	DefaultRewardPeriods                          = types.DefaultRewardPeriods
 | 
						DefaultRewardPeriods                          = types.DefaultRewardPeriods
 | 
				
			||||||
 | 
						DefaultMultiRewardPeriods                     = types.DefaultMultiRewardPeriods
 | 
				
			||||||
	ErrAccountNotFound                            = types.ErrAccountNotFound
 | 
						ErrAccountNotFound                            = types.ErrAccountNotFound
 | 
				
			||||||
	ErrClaimExpired                               = types.ErrClaimExpired
 | 
						ErrClaimExpired                               = types.ErrClaimExpired
 | 
				
			||||||
	ErrClaimNotFound                              = types.ErrClaimNotFound
 | 
						ErrClaimNotFound                              = types.ErrClaimNotFound
 | 
				
			||||||
@ -106,6 +108,8 @@ type (
 | 
				
			|||||||
	RewardIndexes             = types.RewardIndexes
 | 
						RewardIndexes             = types.RewardIndexes
 | 
				
			||||||
	RewardPeriod              = types.RewardPeriod
 | 
						RewardPeriod              = types.RewardPeriod
 | 
				
			||||||
	RewardPeriods             = types.RewardPeriods
 | 
						RewardPeriods             = types.RewardPeriods
 | 
				
			||||||
 | 
						MultiRewardPeriod         = types.MultiRewardPeriod
 | 
				
			||||||
 | 
						MultiRewardPeriods        = types.MultiRewardPeriods
 | 
				
			||||||
	SupplyKeeper              = types.SupplyKeeper
 | 
						SupplyKeeper              = types.SupplyKeeper
 | 
				
			||||||
	USDXMintingClaim          = types.USDXMintingClaim
 | 
						USDXMintingClaim          = types.USDXMintingClaim
 | 
				
			||||||
	USDXMintingClaims         = types.USDXMintingClaims
 | 
						USDXMintingClaims         = types.USDXMintingClaims
 | 
				
			||||||
 | 
				
			|||||||
@ -45,8 +45,8 @@ func (suite *HandlerTestSuite) SetupTest() {
 | 
				
			|||||||
	incentiveGS := incentive.NewGenesisState(
 | 
						incentiveGS := incentive.NewGenesisState(
 | 
				
			||||||
		incentive.NewParams(
 | 
							incentive.NewParams(
 | 
				
			||||||
			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.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.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.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.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),
 | 
				
			||||||
@ -84,7 +84,10 @@ 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())}
 | 
				
			||||||
	c1 := incentive.NewHardLiquidityProviderClaim(suite.addrs[0], c("ukava", 1000000), rewardPeriod, rewardPeriod, rewardPeriod)
 | 
					
 | 
				
			||||||
 | 
						multiRewardIndex := types.NewMultiRewardIndex("bnb-s", rewardPeriod)
 | 
				
			||||||
 | 
						multiRewardIndexes := types.MultiRewardIndexes{multiRewardIndex}
 | 
				
			||||||
 | 
						c1 := incentive.NewHardLiquidityProviderClaim(suite.addrs[0], cs(c("ukava", 1000000)), multiRewardIndexes, multiRewardIndexes, rewardPeriod)
 | 
				
			||||||
	suite.NotPanics(func() {
 | 
						suite.NotPanics(func() {
 | 
				
			||||||
		suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, c1)
 | 
							suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, c1)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
				
			|||||||
@ -156,8 +156,8 @@ func NewIncentiveGenState(previousAccumTime, endTime time.Time, rewardPeriods ..
 | 
				
			|||||||
	genesis := incentive.NewGenesisState(
 | 
						genesis := incentive.NewGenesisState(
 | 
				
			||||||
		incentive.NewParams(
 | 
							incentive.NewParams(
 | 
				
			||||||
			rewardPeriods,
 | 
								rewardPeriods,
 | 
				
			||||||
			types.RewardPeriods{},
 | 
								types.MultiRewardPeriods{},
 | 
				
			||||||
			types.RewardPeriods{},
 | 
								types.MultiRewardPeriods{},
 | 
				
			||||||
			types.RewardPeriods{},
 | 
								types.RewardPeriods{},
 | 
				
			||||||
			incentive.Multipliers{
 | 
								incentive.Multipliers{
 | 
				
			||||||
				incentive.NewMultiplier(incentive.Small, 1, d("0.25")),
 | 
									incentive.NewMultiplier(incentive.Small, 1, d("0.25")),
 | 
				
			||||||
 | 
				
			|||||||
@ -190,42 +190,42 @@ func (k Keeper) GetAllHardLiquidityProviderClaims(ctx sdk.Context) types.HardLiq
 | 
				
			|||||||
	return cs
 | 
						return cs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetHardSupplyRewardFactor sets the current interest factor for an individual market
 | 
					// SetHardSupplyRewardIndexes sets the current reward indexes for an individual denom
 | 
				
			||||||
func (k Keeper) SetHardSupplyRewardFactor(ctx sdk.Context, denom string, borrowIndex sdk.Dec) {
 | 
					func (k Keeper) SetHardSupplyRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardFactorKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix)
 | 
				
			||||||
	bz := k.cdc.MustMarshalBinaryBare(borrowIndex)
 | 
						bz := k.cdc.MustMarshalBinaryBare(indexes)
 | 
				
			||||||
	store.Set([]byte(denom), bz)
 | 
						store.Set([]byte(denom), bz)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHardSupplyRewardFactor returns the current interest factor for an individual market
 | 
					// GetHardSupplyRewardIndexes gets the current reward indexes for an individual denom
 | 
				
			||||||
func (k Keeper) GetHardSupplyRewardFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) {
 | 
					func (k Keeper) GetHardSupplyRewardIndexes(ctx sdk.Context, denom string) (types.RewardIndexes, bool) {
 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardFactorKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix)
 | 
				
			||||||
	bz := store.Get([]byte(denom))
 | 
						bz := store.Get([]byte(denom))
 | 
				
			||||||
	if bz == nil {
 | 
						if bz == nil {
 | 
				
			||||||
		return sdk.ZeroDec(), false
 | 
							return types.RewardIndexes{}, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var interestFactor sdk.Dec
 | 
						var rewardIndexes types.RewardIndexes
 | 
				
			||||||
	k.cdc.MustUnmarshalBinaryBare(bz, &interestFactor)
 | 
						k.cdc.MustUnmarshalBinaryBare(bz, &rewardIndexes)
 | 
				
			||||||
	return interestFactor, true
 | 
						return rewardIndexes, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetHardBorrowRewardFactor sets the current interest factor for an individual market
 | 
					// SetHardBorrowRewardIndexes sets the current reward indexes for an individual denom
 | 
				
			||||||
func (k Keeper) SetHardBorrowRewardFactor(ctx sdk.Context, denom string, borrowIndex sdk.Dec) {
 | 
					func (k Keeper) SetHardBorrowRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardFactorKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardIndexesKeyPrefix)
 | 
				
			||||||
	bz := k.cdc.MustMarshalBinaryBare(borrowIndex)
 | 
						bz := k.cdc.MustMarshalBinaryBare(indexes)
 | 
				
			||||||
	store.Set([]byte(denom), bz)
 | 
						store.Set([]byte(denom), bz)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHardBorrowRewardFactor returns the current interest factor for an individual market
 | 
					// GetHardBorrowRewardIndexes gets the current reward indexes for an individual denom
 | 
				
			||||||
func (k Keeper) GetHardBorrowRewardFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) {
 | 
					func (k Keeper) GetHardBorrowRewardIndexes(ctx sdk.Context, denom string) (types.RewardIndexes, bool) {
 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardFactorKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardIndexesKeyPrefix)
 | 
				
			||||||
	bz := store.Get([]byte(denom))
 | 
						bz := store.Get([]byte(denom))
 | 
				
			||||||
	if bz == nil {
 | 
						if bz == nil {
 | 
				
			||||||
		return sdk.ZeroDec(), false
 | 
							return types.RewardIndexes{}, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var interestFactor sdk.Dec
 | 
						var rewardIndexes types.RewardIndexes
 | 
				
			||||||
	k.cdc.MustUnmarshalBinaryBare(bz, &interestFactor)
 | 
						k.cdc.MustUnmarshalBinaryBare(bz, &rewardIndexes)
 | 
				
			||||||
	return interestFactor, true
 | 
						return rewardIndexes, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHardDelegatorRewardFactor returns the current reward factor for an individual collateral type
 | 
					// GetHardDelegatorRewardFactor returns the current reward factor for an individual collateral type
 | 
				
			||||||
 | 
				
			|||||||
@ -31,26 +31,26 @@ func (k Keeper) GetUSDXMintingRewardPeriod(ctx sdk.Context, collateralType strin
 | 
				
			|||||||
	return types.RewardPeriod{}, false
 | 
						return types.RewardPeriod{}, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHardSupplyRewardPeriod returns the reward period with the specified collateral type if it's found in the params
 | 
					// GetHardSupplyRewardPeriods returns the reward period with the specified collateral type if it's found in the params
 | 
				
			||||||
func (k Keeper) GetHardSupplyRewardPeriod(ctx sdk.Context, denom string) (types.RewardPeriod, bool) {
 | 
					func (k Keeper) GetHardSupplyRewardPeriods(ctx sdk.Context, denom string) (types.MultiRewardPeriod, bool) {
 | 
				
			||||||
	params := k.GetParams(ctx)
 | 
						params := k.GetParams(ctx)
 | 
				
			||||||
	for _, rp := range params.HardSupplyRewardPeriods {
 | 
						for _, rp := range params.HardSupplyRewardPeriods {
 | 
				
			||||||
		if rp.CollateralType == denom {
 | 
							if rp.CollateralType == denom {
 | 
				
			||||||
			return rp, true
 | 
								return rp, true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return types.RewardPeriod{}, false
 | 
						return types.MultiRewardPeriod{}, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHardBorrowRewardPeriod returns the reward period with the specified collateral type if it's found in the params
 | 
					// GetHardBorrowRewardPeriods returns the reward period with the specified collateral type if it's found in the params
 | 
				
			||||||
func (k Keeper) GetHardBorrowRewardPeriod(ctx sdk.Context, denom string) (types.RewardPeriod, bool) {
 | 
					func (k Keeper) GetHardBorrowRewardPeriods(ctx sdk.Context, denom string) (types.MultiRewardPeriod, bool) {
 | 
				
			||||||
	params := k.GetParams(ctx)
 | 
						params := k.GetParams(ctx)
 | 
				
			||||||
	for _, rp := range params.HardBorrowRewardPeriods {
 | 
						for _, rp := range params.HardBorrowRewardPeriods {
 | 
				
			||||||
		if rp.CollateralType == denom {
 | 
							if rp.CollateralType == denom {
 | 
				
			||||||
			return rp, true
 | 
								return rp, true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return types.RewardPeriod{}, false
 | 
						return types.MultiRewardPeriod{}, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			||||||
 | 
				
			|||||||
@ -85,14 +85,17 @@ func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplier
 | 
				
			|||||||
		return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", addr)
 | 
							return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", addr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rewardAmount := claim.Reward.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
 | 
						var rewardCoins sdk.Coins
 | 
				
			||||||
	if rewardAmount.IsZero() {
 | 
						for _, coin := range claim.Reward {
 | 
				
			||||||
		return types.ErrZeroClaim
 | 
							rewardAmount := coin.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
 | 
				
			||||||
 | 
							if rewardAmount.IsZero() {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rewardCoins = append(rewardCoins, sdk.NewCoin(coin.Denom, rewardAmount))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rewardCoin := sdk.NewCoin(claim.Reward.Denom, rewardAmount)
 | 
					 | 
				
			||||||
	length := ctx.BlockTime().AddDate(0, int(multiplier.MonthsLockup), 0).Unix() - ctx.BlockTime().Unix()
 | 
						length := ctx.BlockTime().AddDate(0, int(multiplier.MonthsLockup), 0).Unix() - ctx.BlockTime().Unix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, sdk.NewCoins(rewardCoin), length)
 | 
						err := k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, rewardCoins, length)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,6 @@ import (
 | 
				
			|||||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
						"github.com/cosmos/cosmos-sdk/x/auth"
 | 
				
			||||||
	"github.com/kava-labs/kava/app"
 | 
						"github.com/kava-labs/kava/app"
 | 
				
			||||||
	cdptypes "github.com/kava-labs/kava/x/cdp/types"
 | 
						cdptypes "github.com/kava-labs/kava/x/cdp/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/hard"
 | 
					 | 
				
			||||||
	"github.com/kava-labs/kava/x/incentive/types"
 | 
						"github.com/kava-labs/kava/x/incentive/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/kavadist"
 | 
						"github.com/kava-labs/kava/x/kavadist"
 | 
				
			||||||
	validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
 | 
						validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
 | 
				
			||||||
@ -93,8 +92,8 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
 | 
				
			|||||||
			// setup incentive state
 | 
								// setup incentive state
 | 
				
			||||||
			params := types.NewParams(
 | 
								params := types.NewParams(
 | 
				
			||||||
				types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
									types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
				
			||||||
				types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
									types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
 | 
				
			||||||
				types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
									types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
 | 
				
			||||||
				types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
									types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
 | 
				
			||||||
				tc.args.multipliers,
 | 
									tc.args.multipliers,
 | 
				
			||||||
				tc.args.initialTime.Add(time.Hour*24*365*5),
 | 
									tc.args.initialTime.Add(time.Hour*24*365*5),
 | 
				
			||||||
@ -156,172 +155,179 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
 | 
					// func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
 | 
				
			||||||
	type args struct {
 | 
					// 	type args struct {
 | 
				
			||||||
		deposit                  sdk.Coins
 | 
					// 		deposit                  sdk.Coins
 | 
				
			||||||
		borrow                   sdk.Coins
 | 
					// 		borrow                   sdk.Coins
 | 
				
			||||||
		rewardsPerSecond         sdk.Coin
 | 
					// 		rewardsPerSecond         sdk.Coin
 | 
				
			||||||
		initialTime              time.Time
 | 
					// 		initialTime              time.Time
 | 
				
			||||||
		multipliers              types.Multipliers
 | 
					// 		multipliers              types.Multipliers
 | 
				
			||||||
		multiplier               types.MultiplierName
 | 
					// 		multiplier               types.MultiplierName
 | 
				
			||||||
		timeElapsed              int64
 | 
					// 		timeElapsed              int64
 | 
				
			||||||
		expectedReward           sdk.Coin
 | 
					// 		expectedReward           sdk.Coin
 | 
				
			||||||
		expectedPeriods          vesting.Periods
 | 
					// 		expectedPeriods          vesting.Periods
 | 
				
			||||||
		isPeriodicVestingAccount bool
 | 
					// 		isPeriodicVestingAccount bool
 | 
				
			||||||
	}
 | 
					// 	}
 | 
				
			||||||
	type errArgs struct {
 | 
					// 	type errArgs struct {
 | 
				
			||||||
		expectPass bool
 | 
					// 		expectPass bool
 | 
				
			||||||
		contains   string
 | 
					// 		contains   string
 | 
				
			||||||
	}
 | 
					// 	}
 | 
				
			||||||
	type test struct {
 | 
					// 	type test struct {
 | 
				
			||||||
		name    string
 | 
					// 		name    string
 | 
				
			||||||
		args    args
 | 
					// 		args    args
 | 
				
			||||||
		errArgs errArgs
 | 
					// 		errArgs errArgs
 | 
				
			||||||
	}
 | 
					// 	}
 | 
				
			||||||
	testCases := []test{
 | 
					// 	testCases := []test{
 | 
				
			||||||
		{
 | 
					// 		{
 | 
				
			||||||
			"valid 1 day",
 | 
					// 			"valid 1 day",
 | 
				
			||||||
			args{
 | 
					// 			args{
 | 
				
			||||||
				deposit:                  cs(c("bnb", 10000000000)),
 | 
					// 				deposit:                  cs(c("bnb", 10000000000)),
 | 
				
			||||||
				borrow:                   cs(c("bnb", 5000000000)),
 | 
					// 				borrow:                   cs(c("bnb", 5000000000)),
 | 
				
			||||||
				rewardsPerSecond:         c("hard", 122354),
 | 
					// 				rewardsPerSecond:         c("hard", 122354),
 | 
				
			||||||
				initialTime:              time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
 | 
					// 				initialTime:              time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
 | 
				
			||||||
				multipliers:              types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
 | 
					// 				multipliers:              types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
 | 
				
			||||||
				multiplier:               types.MultiplierName("large"),
 | 
					// 				multiplier:               types.MultiplierName("large"),
 | 
				
			||||||
				timeElapsed:              86400,
 | 
					// 				timeElapsed:              86400,
 | 
				
			||||||
				expectedReward:           c("hard", 21142771200), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
 | 
					// 				expectedReward:           c("hard", 21142771200), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
 | 
				
			||||||
				expectedPeriods:          vesting.Periods{vesting.Period{Length: 31536000, Amount: cs(c("hard", 21142771200))}},
 | 
					// 				expectedPeriods:          vesting.Periods{vesting.Period{Length: 31536000, Amount: cs(c("hard", 21142771200))}},
 | 
				
			||||||
				isPeriodicVestingAccount: true,
 | 
					// 				isPeriodicVestingAccount: true,
 | 
				
			||||||
			},
 | 
					// 			},
 | 
				
			||||||
			errArgs{
 | 
					// 			errArgs{
 | 
				
			||||||
				expectPass: true,
 | 
					// 				expectPass: true,
 | 
				
			||||||
				contains:   "",
 | 
					// 				contains:   "",
 | 
				
			||||||
			},
 | 
					// 			},
 | 
				
			||||||
		},
 | 
					// 		},
 | 
				
			||||||
		{
 | 
					// 		{
 | 
				
			||||||
			"invalid zero rewards",
 | 
					// 			"invalid zero rewards",
 | 
				
			||||||
			args{
 | 
					// 			args{
 | 
				
			||||||
				deposit:                  cs(c("bnb", 10000000000)),
 | 
					// 				deposit:                  cs(c("bnb", 10000000000)),
 | 
				
			||||||
				borrow:                   cs(c("bnb", 5000000000)),
 | 
					// 				borrow:                   cs(c("bnb", 5000000000)),
 | 
				
			||||||
				rewardsPerSecond:         c("hard", 0),
 | 
					// 				rewardsPerSecond:         c("hard", 0),
 | 
				
			||||||
				initialTime:              time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
 | 
					// 				initialTime:              time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
 | 
				
			||||||
				multipliers:              types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
 | 
					// 				multipliers:              types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
 | 
				
			||||||
				multiplier:               types.MultiplierName("large"),
 | 
					// 				multiplier:               types.MultiplierName("large"),
 | 
				
			||||||
				timeElapsed:              86400,
 | 
					// 				timeElapsed:              86400,
 | 
				
			||||||
				expectedReward:           sdk.Coin{},
 | 
					// 				expectedReward:           sdk.Coin{},
 | 
				
			||||||
				expectedPeriods:          vesting.Periods{},
 | 
					// 				expectedPeriods:          vesting.Periods{},
 | 
				
			||||||
				isPeriodicVestingAccount: false,
 | 
					// 				isPeriodicVestingAccount: false,
 | 
				
			||||||
			},
 | 
					// 			},
 | 
				
			||||||
			errArgs{
 | 
					// 			errArgs{
 | 
				
			||||||
				expectPass: false,
 | 
					// 				expectPass: false,
 | 
				
			||||||
				contains:   "claim amount rounds to zero",
 | 
					// 				contains:   "claim amount rounds to zero",
 | 
				
			||||||
			},
 | 
					// 			},
 | 
				
			||||||
		},
 | 
					// 		},
 | 
				
			||||||
	}
 | 
					// 	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testCases {
 | 
					// 	for _, tc := range testCases {
 | 
				
			||||||
		suite.Run(tc.name, func() {
 | 
					// 		suite.Run(tc.name, func() {
 | 
				
			||||||
			suite.SetupWithGenState()
 | 
					// 			suite.SetupWithGenState()
 | 
				
			||||||
			suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
 | 
					// 			suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// setup kavadist state
 | 
					// 			// setup kavadist state
 | 
				
			||||||
			sk := suite.app.GetSupplyKeeper()
 | 
					// 			sk := suite.app.GetSupplyKeeper()
 | 
				
			||||||
			err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("hard", 1000000000000)))
 | 
					// 			err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("hard", 1000000000000)))
 | 
				
			||||||
			suite.Require().NoError(err)
 | 
					// 			suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Set up generic reward periods
 | 
					// 			// Set up generic reward periods
 | 
				
			||||||
			var rewardPeriods types.RewardPeriods
 | 
					// 			var multiRewardPeriods types.MultiRewardPeriods
 | 
				
			||||||
			for _, coin := range tc.args.deposit {
 | 
					// 			var rewardPeriods types.RewardPeriods
 | 
				
			||||||
				rewardPeriod := types.NewRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)
 | 
					// 			for _, coin := range tc.args.deposit {
 | 
				
			||||||
				rewardPeriods = append(rewardPeriods, rewardPeriod)
 | 
					// 				rewardPeriod := types.NewRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)
 | 
				
			||||||
			}
 | 
					// 				rewardPeriods = append(rewardPeriods, rewardPeriod)
 | 
				
			||||||
 | 
					// 				multiRewardPeriod := types.NewMultiRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))
 | 
				
			||||||
 | 
					// 				multiRewardPeriods = append(multiRewardPeriods, multiRewardPeriod)
 | 
				
			||||||
 | 
					// 			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Set up incentive state
 | 
					// 			// Set up incentive state
 | 
				
			||||||
			params := types.NewParams(
 | 
					// 			params := types.NewParams(
 | 
				
			||||||
				rewardPeriods, rewardPeriods, rewardPeriods, rewardPeriods,
 | 
					// 				rewardPeriods, multiRewardPeriods, multiRewardPeriods, rewardPeriods,
 | 
				
			||||||
				tc.args.multipliers,
 | 
					// 				tc.args.multipliers,
 | 
				
			||||||
				tc.args.initialTime.Add(time.Hour*24*365*5),
 | 
					// 				tc.args.initialTime.Add(time.Hour*24*365*5),
 | 
				
			||||||
			)
 | 
					// 			)
 | 
				
			||||||
			suite.keeper.SetParams(suite.ctx, params)
 | 
					// 			suite.keeper.SetParams(suite.ctx, params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Set each denom's previous accrual time and supply reward factor
 | 
					// 			// Set each denom's previous accrual time and supply reward factor
 | 
				
			||||||
			for _, coin := range tc.args.deposit {
 | 
					// 			for _, coin := range tc.args.deposit {
 | 
				
			||||||
				suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
 | 
					// 				suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
 | 
				
			||||||
				suite.keeper.SetHardSupplyRewardFactor(suite.ctx, coin.Denom, sdk.ZeroDec())
 | 
					// 				defaultRewardIndexes := types.RewardIndexes{types.NewRewardIndex(types.HardLiquidityRewardDenom, sdk.ZeroDec())}
 | 
				
			||||||
			}
 | 
					// 				suite.keeper.SetHardSupplyRewardIndexes(suite.ctx, coin.Denom, defaultRewardIndexes)
 | 
				
			||||||
			for _, coin := range tc.args.borrow {
 | 
					// 			}
 | 
				
			||||||
				suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
 | 
					// 			for _, coin := range tc.args.borrow {
 | 
				
			||||||
				suite.keeper.SetHardBorrowRewardFactor(suite.ctx, coin.Denom, sdk.ZeroDec())
 | 
					// 				suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
 | 
				
			||||||
			}
 | 
					// 				defaultRewardIndexes := types.RewardIndexes{types.NewRewardIndex(types.HardLiquidityRewardDenom, sdk.ZeroDec())}
 | 
				
			||||||
 | 
					// 				suite.keeper.SetHardBorrowRewardIndexes(suite.ctx, coin.Denom, defaultRewardIndexes)
 | 
				
			||||||
 | 
					// 			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			hardKeeper := suite.app.GetHardKeeper()
 | 
					// 			hardKeeper := suite.app.GetHardKeeper()
 | 
				
			||||||
			userAddr := suite.addrs[3]
 | 
					// 			userAddr := suite.addrs[3]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// User deposits
 | 
					// 			// User deposits
 | 
				
			||||||
			err = hardKeeper.Deposit(suite.ctx, userAddr, tc.args.deposit)
 | 
					// 			err = hardKeeper.Deposit(suite.ctx, userAddr, tc.args.deposit)
 | 
				
			||||||
			suite.Require().NoError(err)
 | 
					// 			suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// User borrows
 | 
					// 			// User borrows
 | 
				
			||||||
			err = hardKeeper.Borrow(suite.ctx, userAddr, tc.args.borrow)
 | 
					// 			err = hardKeeper.Borrow(suite.ctx, userAddr, tc.args.borrow)
 | 
				
			||||||
			suite.Require().NoError(err)
 | 
					// 			suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Check that Hard hooks initialized a HardLiquidityProviderClaim that has 0 rewards
 | 
					// 			// Check that Hard hooks initialized a HardLiquidityProviderClaim that has 0 rewards
 | 
				
			||||||
			claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[3])
 | 
					// 			claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[3])
 | 
				
			||||||
			suite.Require().True(found)
 | 
					// 			suite.Require().True(found)
 | 
				
			||||||
			suite.Require().Equal(sdk.ZeroInt(), claim.Reward.Amount)
 | 
					// 			for _, coin := range tc.args.deposit {
 | 
				
			||||||
 | 
					// 				suite.Require().Equal(sdk.ZeroInt(), claim.Reward.AmountOf(coin.Denom))
 | 
				
			||||||
 | 
					// 			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Set up future runtime context
 | 
					// 			// Set up future runtime context
 | 
				
			||||||
			runAtTime := time.Unix(suite.ctx.BlockTime().Unix()+(tc.args.timeElapsed), 0)
 | 
					// 			runAtTime := time.Unix(suite.ctx.BlockTime().Unix()+(tc.args.timeElapsed), 0)
 | 
				
			||||||
			runCtx := suite.ctx.WithBlockTime(runAtTime)
 | 
					// 			runCtx := suite.ctx.WithBlockTime(runAtTime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Run Hard begin blocker
 | 
					// 			// Run Hard begin blocker
 | 
				
			||||||
			hard.BeginBlocker(runCtx, suite.hardKeeper)
 | 
					// 			hard.BeginBlocker(runCtx, suite.hardKeeper)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Accumulate supply rewards for each deposit denom
 | 
					// 			// Accumulate supply rewards for each deposit denom
 | 
				
			||||||
			for _, coin := range tc.args.deposit {
 | 
					// 			for _, coin := range tc.args.deposit {
 | 
				
			||||||
				rewardPeriod, found := suite.keeper.GetHardSupplyRewardPeriod(runCtx, coin.Denom)
 | 
					// 				rewardPeriod, found := suite.keeper.GetHardSupplyRewardPeriods(runCtx, coin.Denom)
 | 
				
			||||||
				suite.Require().True(found)
 | 
					// 				suite.Require().True(found)
 | 
				
			||||||
				err = suite.keeper.AccumulateHardSupplyRewards(runCtx, rewardPeriod)
 | 
					// 				err = suite.keeper.AccumulateHardSupplyRewards(runCtx, rewardPeriod)
 | 
				
			||||||
				suite.Require().NoError(err)
 | 
					// 				suite.Require().NoError(err)
 | 
				
			||||||
			}
 | 
					// 			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Accumulate borrow rewards for each deposit denom
 | 
					// 			// Accumulate borrow rewards for each deposit denom
 | 
				
			||||||
			for _, coin := range tc.args.borrow {
 | 
					// 			for _, coin := range tc.args.borrow {
 | 
				
			||||||
				rewardPeriod, found := suite.keeper.GetHardBorrowRewardPeriod(runCtx, coin.Denom)
 | 
					// 				rewardPeriod, found := suite.keeper.GetHardBorrowRewardPeriods(runCtx, coin.Denom)
 | 
				
			||||||
				suite.Require().True(found)
 | 
					// 				suite.Require().True(found)
 | 
				
			||||||
				err = suite.keeper.AccumulateHardBorrowRewards(runCtx, rewardPeriod)
 | 
					// 				err = suite.keeper.AccumulateHardBorrowRewards(runCtx, rewardPeriod)
 | 
				
			||||||
				suite.Require().NoError(err)
 | 
					// 				suite.Require().NoError(err)
 | 
				
			||||||
			}
 | 
					// 			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Fetch pre-claim balances
 | 
					// 			// Fetch pre-claim balances
 | 
				
			||||||
			ak := suite.app.GetAccountKeeper()
 | 
					// 			ak := suite.app.GetAccountKeeper()
 | 
				
			||||||
			preClaimAcc := ak.GetAccount(runCtx, suite.addrs[3])
 | 
					// 			preClaimAcc := ak.GetAccount(runCtx, suite.addrs[3])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			err = suite.keeper.ClaimHardReward(runCtx, suite.addrs[3], tc.args.multiplier)
 | 
					// 			err = suite.keeper.ClaimHardReward(runCtx, suite.addrs[3], tc.args.multiplier)
 | 
				
			||||||
			if tc.errArgs.expectPass {
 | 
					// 			if tc.errArgs.expectPass {
 | 
				
			||||||
				suite.Require().NoError(err)
 | 
					// 				suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Check that user's balance has increased by expected reward amount
 | 
					// 				// Check that user's balance has increased by expected reward amount
 | 
				
			||||||
				postClaimAcc := ak.GetAccount(suite.ctx, suite.addrs[3])
 | 
					// 				postClaimAcc := ak.GetAccount(suite.ctx, suite.addrs[3])
 | 
				
			||||||
				suite.Require().Equal(preClaimAcc.GetCoins().Add(tc.args.expectedReward), postClaimAcc.GetCoins())
 | 
					// 				suite.Require().Equal(preClaimAcc.GetCoins().Add(tc.args.expectedReward), postClaimAcc.GetCoins())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if tc.args.isPeriodicVestingAccount {
 | 
					// 				if tc.args.isPeriodicVestingAccount {
 | 
				
			||||||
					vacc, ok := postClaimAcc.(*vesting.PeriodicVestingAccount)
 | 
					// 					vacc, ok := postClaimAcc.(*vesting.PeriodicVestingAccount)
 | 
				
			||||||
					suite.Require().True(ok)
 | 
					// 					suite.Require().True(ok)
 | 
				
			||||||
					suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
 | 
					// 					suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
 | 
				
			||||||
				}
 | 
					// 				}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Check that the claim's reward amount has been reset to 0
 | 
					// 				// Check that the claim's reward amount has been reset to 0
 | 
				
			||||||
				claim, found := suite.keeper.GetHardLiquidityProviderClaim(runCtx, suite.addrs[3])
 | 
					// 				claim, found := suite.keeper.GetHardLiquidityProviderClaim(runCtx, suite.addrs[3])
 | 
				
			||||||
				suite.Require().True(found)
 | 
					// 				suite.Require().True(found)
 | 
				
			||||||
				suite.Require().Equal(c("hard", 0), claim.Reward)
 | 
					// 				suite.Require().Equal(c("hard", 0), claim.Reward)
 | 
				
			||||||
			} else {
 | 
					// 			} else {
 | 
				
			||||||
				suite.Require().Error(err)
 | 
					// 				suite.Require().Error(err)
 | 
				
			||||||
				suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
 | 
					// 				suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
 | 
				
			||||||
			}
 | 
					// 			}
 | 
				
			||||||
		})
 | 
					// 		})
 | 
				
			||||||
	}
 | 
					// 	}
 | 
				
			||||||
}
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
 | 
					func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
 | 
				
			||||||
	type accountArgs struct {
 | 
						type accountArgs struct {
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ func (k Keeper) AccumulateUSDXMintingRewards(ctx sdk.Context, rewardPeriod types
 | 
				
			|||||||
		k.SetPreviousUSDXMintingAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousUSDXMintingAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	timeElapsed := CalculateTimeElapsed(rewardPeriod, ctx.BlockTime(), previousAccrualTime)
 | 
						timeElapsed := CalculateTimeElapsed(rewardPeriod.Start, rewardPeriod.End, ctx.BlockTime(), previousAccrualTime)
 | 
				
			||||||
	if timeElapsed.IsZero() {
 | 
						if timeElapsed.IsZero() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -51,87 +51,134 @@ func (k Keeper) AccumulateUSDXMintingRewards(ctx sdk.Context, rewardPeriod types
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AccumulateHardBorrowRewards updates the rewards accumulated for the input reward period
 | 
					// AccumulateHardBorrowRewards updates the rewards accumulated for the input reward period
 | 
				
			||||||
func (k Keeper) AccumulateHardBorrowRewards(ctx sdk.Context, rewardPeriod types.RewardPeriod) error {
 | 
					func (k Keeper) AccumulateHardBorrowRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error {
 | 
				
			||||||
	previousAccrualTime, found := k.GetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType)
 | 
						previousAccrualTime, found := k.GetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	timeElapsed := CalculateTimeElapsed(rewardPeriod, ctx.BlockTime(), previousAccrualTime)
 | 
						timeElapsed := CalculateTimeElapsed(rewardPeriod.Start, rewardPeriod.End, ctx.BlockTime(), previousAccrualTime)
 | 
				
			||||||
	if timeElapsed.IsZero() {
 | 
						if timeElapsed.IsZero() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rewardPeriod.RewardsPerSecond.Amount.IsZero() {
 | 
						if rewardPeriod.RewardsPerSecond.IsZero() {
 | 
				
			||||||
		k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	totalBorrowedCoins, foundTotalBorrowedCoins := k.hardKeeper.GetBorrowedCoins(ctx)
 | 
						totalBorrowedCoins, foundTotalBorrowedCoins := k.hardKeeper.GetBorrowedCoins(ctx)
 | 
				
			||||||
	if foundTotalBorrowedCoins {
 | 
						if !foundTotalBorrowedCoins {
 | 
				
			||||||
		totalBorrowed := totalBorrowedCoins.AmountOf(rewardPeriod.CollateralType).ToDec()
 | 
							k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		if totalBorrowed.IsZero() {
 | 
							return nil
 | 
				
			||||||
			k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		newRewards := timeElapsed.Mul(rewardPeriod.RewardsPerSecond.Amount)
 | 
					 | 
				
			||||||
		hardFactor, found := k.hardKeeper.GetBorrowInterestFactor(ctx, rewardPeriod.CollateralType)
 | 
					 | 
				
			||||||
		if !found {
 | 
					 | 
				
			||||||
			k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rewardFactor := newRewards.ToDec().Mul(hardFactor).Quo(totalBorrowed)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		previousRewardFactor, found := k.GetHardBorrowRewardFactor(ctx, rewardPeriod.CollateralType)
 | 
					 | 
				
			||||||
		if !found {
 | 
					 | 
				
			||||||
			previousRewardFactor = sdk.ZeroDec()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		newRewardFactor := previousRewardFactor.Add(rewardFactor)
 | 
					 | 
				
			||||||
		k.SetHardBorrowRewardFactor(ctx, rewardPeriod.CollateralType, newRewardFactor)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalBorrowed := totalBorrowedCoins.AmountOf(rewardPeriod.CollateralType).ToDec()
 | 
				
			||||||
 | 
						if totalBorrowed.IsZero() {
 | 
				
			||||||
 | 
							k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						previousRewardIndexes, found := k.GetHardBorrowRewardIndexes(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							for _, rewardCoin := range rewardPeriod.RewardsPerSecond {
 | 
				
			||||||
 | 
								rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
 | 
				
			||||||
 | 
								previousRewardIndexes = append(previousRewardIndexes, rewardIndex)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							k.SetHardBorrowRewardIndexes(ctx, rewardPeriod.CollateralType, previousRewardIndexes)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hardFactor, found := k.hardKeeper.GetBorrowInterestFactor(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newRewardIndexes := previousRewardIndexes
 | 
				
			||||||
 | 
						for _, rewardCoin := range rewardPeriod.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.Mul(hardFactor).Quo(totalBorrowed)
 | 
				
			||||||
 | 
							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.SetHardBorrowRewardIndexes(ctx, rewardPeriod.CollateralType, newRewardIndexes)
 | 
				
			||||||
 | 
						k.SetPreviousHardBorrowRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AccumulateHardSupplyRewards updates the rewards accumulated for the input reward period
 | 
					// AccumulateHardSupplyRewards updates the rewards accumulated for the input reward period
 | 
				
			||||||
func (k Keeper) AccumulateHardSupplyRewards(ctx sdk.Context, rewardPeriod types.RewardPeriod) error {
 | 
					func (k Keeper) AccumulateHardSupplyRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error {
 | 
				
			||||||
	previousAccrualTime, found := k.GetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType)
 | 
						previousAccrualTime, found := k.GetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	timeElapsed := CalculateTimeElapsed(rewardPeriod, ctx.BlockTime(), previousAccrualTime)
 | 
						timeElapsed := CalculateTimeElapsed(rewardPeriod.Start, rewardPeriod.End, ctx.BlockTime(), previousAccrualTime)
 | 
				
			||||||
	if timeElapsed.IsZero() {
 | 
						if timeElapsed.IsZero() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rewardPeriod.RewardsPerSecond.Amount.IsZero() {
 | 
						if rewardPeriod.RewardsPerSecond.IsZero() {
 | 
				
			||||||
		k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	totalSuppliedCoins, foundTotalSuppliedCoins := k.hardKeeper.GetSuppliedCoins(ctx)
 | 
						totalSuppliedCoins, foundTotalSuppliedCoins := k.hardKeeper.GetSuppliedCoins(ctx)
 | 
				
			||||||
	if foundTotalSuppliedCoins {
 | 
						if !foundTotalSuppliedCoins {
 | 
				
			||||||
		totalSupplied := totalSuppliedCoins.AmountOf(rewardPeriod.CollateralType).ToDec()
 | 
							k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		if totalSupplied.IsZero() {
 | 
							return nil
 | 
				
			||||||
			k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		newRewards := timeElapsed.Mul(rewardPeriod.RewardsPerSecond.Amount)
 | 
					 | 
				
			||||||
		hardFactor, found := k.hardKeeper.GetSupplyInterestFactor(ctx, rewardPeriod.CollateralType)
 | 
					 | 
				
			||||||
		if !found {
 | 
					 | 
				
			||||||
			k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rewardFactor := newRewards.ToDec().Mul(hardFactor).Quo(totalSupplied)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		previousRewardFactor, found := k.GetHardSupplyRewardFactor(ctx, rewardPeriod.CollateralType)
 | 
					 | 
				
			||||||
		if !found {
 | 
					 | 
				
			||||||
			previousRewardFactor = sdk.ZeroDec()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		newRewardFactor := previousRewardFactor.Add(rewardFactor)
 | 
					 | 
				
			||||||
		k.SetHardSupplyRewardFactor(ctx, rewardPeriod.CollateralType, newRewardFactor)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalSupplied := totalSuppliedCoins.AmountOf(rewardPeriod.CollateralType).ToDec()
 | 
				
			||||||
 | 
						if totalSupplied.IsZero() {
 | 
				
			||||||
 | 
							k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						previousRewardIndexes, found := k.GetHardSupplyRewardIndexes(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							for _, rewardCoin := range rewardPeriod.RewardsPerSecond {
 | 
				
			||||||
 | 
								rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
 | 
				
			||||||
 | 
								previousRewardIndexes = append(previousRewardIndexes, rewardIndex)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							k.SetHardSupplyRewardIndexes(ctx, rewardPeriod.CollateralType, previousRewardIndexes)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hardFactor, found := k.hardKeeper.GetSupplyInterestFactor(ctx, rewardPeriod.CollateralType)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newRewardIndexes := previousRewardIndexes
 | 
				
			||||||
 | 
						for _, rewardCoin := range rewardPeriod.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.Mul(hardFactor).Quo(totalSupplied)
 | 
				
			||||||
 | 
							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.SetHardSupplyRewardIndexes(ctx, rewardPeriod.CollateralType, newRewardIndexes)
 | 
				
			||||||
 | 
						k.SetPreviousHardSupplyRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -212,30 +259,23 @@ func (k Keeper) SynchronizeUSDXMintingReward(ctx sdk.Context, cdp cdptypes.CDP)
 | 
				
			|||||||
// InitializeHardSupplyReward initializes the supply-side of a hard liquidity provider claim
 | 
					// InitializeHardSupplyReward initializes the supply-side of a hard liquidity provider claim
 | 
				
			||||||
// by creating the claim and setting the supply reward factor index
 | 
					// by creating the claim and setting the supply reward factor index
 | 
				
			||||||
func (k Keeper) InitializeHardSupplyReward(ctx sdk.Context, deposit hardtypes.Deposit) {
 | 
					func (k Keeper) InitializeHardSupplyReward(ctx sdk.Context, deposit hardtypes.Deposit) {
 | 
				
			||||||
	var supplyRewardIndexes types.RewardIndexes
 | 
						var supplyRewardIndexes types.MultiRewardIndexes
 | 
				
			||||||
	for _, coin := range deposit.Amount {
 | 
						for _, coin := range deposit.Amount {
 | 
				
			||||||
		_, rpFound := k.GetHardSupplyRewardPeriod(ctx, coin.Denom)
 | 
							globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
		if !rpFound {
 | 
							if !foundGlobalRewardIndexes {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
 | 
				
			||||||
		supplyFactor, foundSupplyFactor := k.GetHardSupplyRewardFactor(ctx, coin.Denom)
 | 
							supplyRewardIndexes = append(supplyRewardIndexes, multiRewardIndex)
 | 
				
			||||||
		if !foundSupplyFactor {
 | 
					 | 
				
			||||||
			supplyFactor = sdk.ZeroDec()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		supplyRewardIndexes = append(supplyRewardIndexes, types.NewRewardIndex(coin.Denom, supplyFactor))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	claim, found := k.GetHardLiquidityProviderClaim(ctx, deposit.Depositor)
 | 
						claim, found := k.GetHardLiquidityProviderClaim(ctx, deposit.Depositor)
 | 
				
			||||||
	if found {
 | 
						if found {
 | 
				
			||||||
		// Reset borrow reward indexes
 | 
							// Reset borrow reward indexes
 | 
				
			||||||
		claim.BorrowRewardIndexes = types.RewardIndexes{}
 | 
							claim.BorrowRewardIndexes = types.MultiRewardIndexes{}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Instantiate claim object
 | 
							// Instantiate claim object
 | 
				
			||||||
		claim = types.NewHardLiquidityProviderClaim(deposit.Depositor,
 | 
							claim = types.NewHardLiquidityProviderClaim(deposit.Depositor, sdk.Coins{}, nil, nil, nil)
 | 
				
			||||||
			sdk.NewCoin(types.HardLiquidityRewardDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
			nil, nil, nil)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	claim.SupplyRewardIndexes = supplyRewardIndexes
 | 
						claim.SupplyRewardIndexes = supplyRewardIndexes
 | 
				
			||||||
@ -251,33 +291,48 @@ func (k Keeper) SynchronizeHardSupplyReward(ctx sdk.Context, deposit hardtypes.D
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, coin := range deposit.Amount {
 | 
						for _, coin := range deposit.Amount {
 | 
				
			||||||
		supplyFactor, found := k.GetHardSupplyRewardFactor(ctx, coin.Denom)
 | 
							globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
		if !found {
 | 
							if !foundGlobalRewardIndexes {
 | 
				
			||||||
			fmt.Printf("\n[LOG]: %s does not have a supply factor", coin.Denom) // TODO: remove before production
 | 
					 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		supplyIndex, hasSupplyRewardIndex := claim.HasSupplyRewardIndex(coin.Denom)
 | 
							userRewardIndexes, foundUserRewardIndexes := claim.SupplyRewardIndexes.GetRewardIndex(coin.Denom)
 | 
				
			||||||
		if !hasSupplyRewardIndex {
 | 
							if !foundUserRewardIndexes {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		userRewardFactor := claim.SupplyRewardIndexes[supplyIndex].RewardFactor
 | 
							for _, globalRewardIndex := range globalRewardIndexes {
 | 
				
			||||||
		rewardsAccumulatedFactor := supplyFactor.Sub(userRewardFactor)
 | 
								userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
		if rewardsAccumulatedFactor.IsZero() {
 | 
								if !foundUserRewardIndex {
 | 
				
			||||||
			continue
 | 
									continue
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
		claim.SupplyRewardIndexes[supplyIndex].RewardFactor = supplyFactor
 | 
								userRewardIndexIndex, foundUserRewardIndexIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
 | 
								if !foundUserRewardIndexIndex {
 | 
				
			||||||
 | 
									fmt.Printf("\n[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		newRewardsAmount := rewardsAccumulatedFactor.Mul(deposit.Amount.AmountOf(coin.Denom).ToDec()).RoundInt()
 | 
								globalRewardFactor := globalRewardIndex.RewardFactor
 | 
				
			||||||
		if newRewardsAmount.IsZero() || newRewardsAmount.IsNegative() {
 | 
								userRewardFactor := userRewardIndex.RewardFactor
 | 
				
			||||||
			continue
 | 
								rewardsAccumulatedFactor := globalRewardFactor.Sub(userRewardFactor)
 | 
				
			||||||
		}
 | 
								if rewardsAccumulatedFactor.IsZero() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								newRewardsAmount := rewardsAccumulatedFactor.Mul(deposit.Amount.AmountOf(coin.Denom).ToDec()).RoundInt()
 | 
				
			||||||
 | 
								if newRewardsAmount.IsZero() || newRewardsAmount.IsNegative() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		newRewardsCoin := sdk.NewCoin(types.HardLiquidityRewardDenom, newRewardsAmount)
 | 
								factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
		claim.Reward = claim.Reward.Add(newRewardsCoin)
 | 
								if !foundFactorIndex {
 | 
				
			||||||
 | 
									fmt.Printf("[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								claim.SupplyRewardIndexes[userRewardIndexIndex].RewardIndexes[factorIndex].RewardFactor = globalRewardIndex.RewardFactor
 | 
				
			||||||
 | 
								newRewardsCoin := sdk.NewCoin(userRewardIndex.CollateralType, newRewardsAmount)
 | 
				
			||||||
 | 
								claim.Reward = claim.Reward.Add(newRewardsCoin)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
						k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -286,24 +341,17 @@ func (k Keeper) SynchronizeHardSupplyReward(ctx sdk.Context, deposit hardtypes.D
 | 
				
			|||||||
func (k Keeper) InitializeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Borrow) {
 | 
					func (k Keeper) InitializeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Borrow) {
 | 
				
			||||||
	claim, found := k.GetHardLiquidityProviderClaim(ctx, borrow.Borrower)
 | 
						claim, found := k.GetHardLiquidityProviderClaim(ctx, borrow.Borrower)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		claim = types.NewHardLiquidityProviderClaim(borrow.Borrower,
 | 
							claim = types.NewHardLiquidityProviderClaim(borrow.Borrower, sdk.Coins{}, nil, nil, nil)
 | 
				
			||||||
			sdk.NewCoin(types.HardLiquidityRewardDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
			nil, nil, nil)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var borrowRewardIndexes types.RewardIndexes
 | 
						var borrowRewardIndexes types.MultiRewardIndexes
 | 
				
			||||||
	for _, coin := range borrow.Amount {
 | 
						for _, coin := range borrow.Amount {
 | 
				
			||||||
		_, rpFound := k.GetHardBorrowRewardPeriod(ctx, coin.Denom)
 | 
							globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
		if !rpFound {
 | 
							if !foundGlobalRewardIndexes {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
 | 
				
			||||||
		borrowFactor, foundBorrowFactor := k.GetHardBorrowRewardFactor(ctx, coin.Denom)
 | 
							borrowRewardIndexes = append(borrowRewardIndexes, multiRewardIndex)
 | 
				
			||||||
		if !foundBorrowFactor {
 | 
					 | 
				
			||||||
			borrowFactor = sdk.ZeroDec()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		borrowRewardIndexes = append(borrowRewardIndexes, types.NewRewardIndex(coin.Denom, borrowFactor))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	claim.BorrowRewardIndexes = borrowRewardIndexes
 | 
						claim.BorrowRewardIndexes = borrowRewardIndexes
 | 
				
			||||||
@ -319,32 +367,48 @@ func (k Keeper) SynchronizeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bo
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, coin := range borrow.Amount {
 | 
						for _, coin := range borrow.Amount {
 | 
				
			||||||
		borrowFactor, found := k.GetHardBorrowRewardFactor(ctx, coin.Denom)
 | 
							globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
		if !found {
 | 
							if !foundGlobalRewardIndexes {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		borrowIndex, BorrowRewardIndex := claim.HasBorrowRewardIndex(coin.Denom)
 | 
							userRewardIndexes, foundUserRewardIndexes := claim.BorrowRewardIndexes.GetRewardIndex(coin.Denom)
 | 
				
			||||||
		if !BorrowRewardIndex {
 | 
							if !foundUserRewardIndexes {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		userRewardFactor := claim.BorrowRewardIndexes[borrowIndex].RewardFactor
 | 
							for _, globalRewardIndex := range globalRewardIndexes {
 | 
				
			||||||
		rewardsAccumulatedFactor := borrowFactor.Sub(userRewardFactor)
 | 
								userRewardIndex, foundUserRewardIndex := userRewardIndexes.RewardIndexes.GetRewardIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
		if rewardsAccumulatedFactor.IsZero() {
 | 
								if !foundUserRewardIndex {
 | 
				
			||||||
			continue
 | 
									continue
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
		claim.BorrowRewardIndexes[borrowIndex].RewardFactor = borrowFactor
 | 
								userRewardIndexIndex, foundUserRewardIndexIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
 | 
								if !foundUserRewardIndexIndex {
 | 
				
			||||||
 | 
									fmt.Printf("\n[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		newRewardsAmount := rewardsAccumulatedFactor.Mul(borrow.Amount.AmountOf(coin.Denom).ToDec()).RoundInt()
 | 
								globalRewardFactor := globalRewardIndex.RewardFactor
 | 
				
			||||||
		if newRewardsAmount.IsZero() || newRewardsAmount.IsNegative() {
 | 
								userRewardFactor := userRewardIndex.RewardFactor
 | 
				
			||||||
			continue
 | 
								rewardsAccumulatedFactor := globalRewardFactor.Sub(userRewardFactor)
 | 
				
			||||||
		}
 | 
								if rewardsAccumulatedFactor.IsZero() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								newRewardsAmount := rewardsAccumulatedFactor.Mul(borrow.Amount.AmountOf(coin.Denom).ToDec()).RoundInt()
 | 
				
			||||||
 | 
								if newRewardsAmount.IsZero() || newRewardsAmount.IsNegative() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		newRewardsCoin := sdk.NewCoin(types.HardLiquidityRewardDenom, newRewardsAmount)
 | 
								factorIndex, foundFactorIndex := userRewardIndexes.RewardIndexes.GetFactorIndex(globalRewardIndex.CollateralType)
 | 
				
			||||||
		claim.Reward = claim.Reward.Add(newRewardsCoin)
 | 
								if !foundFactorIndex {
 | 
				
			||||||
 | 
									fmt.Printf("\n[LOG]: factor index for %s should always be found", coin.Denom) // TODO: remove before production
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								claim.BorrowRewardIndexes[userRewardIndexIndex].RewardIndexes[factorIndex].RewardFactor = globalRewardIndex.RewardFactor
 | 
				
			||||||
 | 
								newRewardsCoin := sdk.NewCoin(userRewardIndex.CollateralType, newRewardsAmount)
 | 
				
			||||||
 | 
								claim.Reward = claim.Reward.Add(newRewardsCoin)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
						k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -352,19 +416,19 @@ func (k Keeper) SynchronizeHardBorrowReward(ctx sdk.Context, borrow hardtypes.Bo
 | 
				
			|||||||
func (k Keeper) UpdateHardSupplyIndexDenoms(ctx sdk.Context, deposit hardtypes.Deposit) {
 | 
					func (k Keeper) UpdateHardSupplyIndexDenoms(ctx sdk.Context, deposit hardtypes.Deposit) {
 | 
				
			||||||
	claim, found := k.GetHardLiquidityProviderClaim(ctx, deposit.Depositor)
 | 
						claim, found := k.GetHardLiquidityProviderClaim(ctx, deposit.Depositor)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		claim = types.NewHardLiquidityProviderClaim(deposit.Depositor,
 | 
							claim = types.NewHardLiquidityProviderClaim(deposit.Depositor, sdk.Coins{}, nil, nil, nil)
 | 
				
			||||||
			sdk.NewCoin(types.HardLiquidityRewardDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
			nil, nil, nil)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	supplyRewardIndexes := claim.SupplyRewardIndexes
 | 
						supplyRewardIndexes := claim.SupplyRewardIndexes
 | 
				
			||||||
	for _, coin := range deposit.Amount {
 | 
						for _, coin := range deposit.Amount {
 | 
				
			||||||
		_, hasIndex := claim.HasSupplyRewardIndex(coin.Denom)
 | 
							_, foundUserRewardIndexes := claim.SupplyRewardIndexes.GetRewardIndex(coin.Denom)
 | 
				
			||||||
		if !hasIndex {
 | 
							if !foundUserRewardIndexes {
 | 
				
			||||||
			supplyFactor, foundSupplyFactor := k.GetHardSupplyRewardFactor(ctx, coin.Denom)
 | 
								globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardSupplyRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
			if foundSupplyFactor {
 | 
								if !foundGlobalRewardIndexes {
 | 
				
			||||||
				supplyRewardIndexes = append(supplyRewardIndexes, types.NewRewardIndex(coin.Denom, supplyFactor))
 | 
									continue // No rewards for this coin type
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
 | 
				
			||||||
 | 
								supplyRewardIndexes = append(supplyRewardIndexes, multiRewardIndex)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(supplyRewardIndexes) == 0 {
 | 
						if len(supplyRewardIndexes) == 0 {
 | 
				
			||||||
@ -378,19 +442,19 @@ func (k Keeper) UpdateHardSupplyIndexDenoms(ctx sdk.Context, deposit hardtypes.D
 | 
				
			|||||||
func (k Keeper) UpdateHardBorrowIndexDenoms(ctx sdk.Context, borrow hardtypes.Borrow) {
 | 
					func (k Keeper) UpdateHardBorrowIndexDenoms(ctx sdk.Context, borrow hardtypes.Borrow) {
 | 
				
			||||||
	claim, found := k.GetHardLiquidityProviderClaim(ctx, borrow.Borrower)
 | 
						claim, found := k.GetHardLiquidityProviderClaim(ctx, borrow.Borrower)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		claim = types.NewHardLiquidityProviderClaim(borrow.Borrower,
 | 
							claim = types.NewHardLiquidityProviderClaim(borrow.Borrower, sdk.Coins{}, nil, nil, nil)
 | 
				
			||||||
			sdk.NewCoin(types.HardLiquidityRewardDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
			nil, nil, nil)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	borrowRewardIndexes := claim.BorrowRewardIndexes
 | 
						borrowRewardIndexes := claim.BorrowRewardIndexes
 | 
				
			||||||
	for _, coin := range borrow.Amount {
 | 
						for _, coin := range borrow.Amount {
 | 
				
			||||||
		_, hasIndex := claim.HasBorrowRewardIndex(coin.Denom)
 | 
							_, foundUserRewardIndexes := claim.BorrowRewardIndexes.GetRewardIndex(coin.Denom)
 | 
				
			||||||
		if !hasIndex {
 | 
							if !foundUserRewardIndexes {
 | 
				
			||||||
			borrowFactor, foundBorrowFactor := k.GetHardBorrowRewardFactor(ctx, coin.Denom)
 | 
								globalRewardIndexes, foundGlobalRewardIndexes := k.GetHardBorrowRewardIndexes(ctx, coin.Denom)
 | 
				
			||||||
			if foundBorrowFactor {
 | 
								if !foundGlobalRewardIndexes {
 | 
				
			||||||
				borrowRewardIndexes = append(borrowRewardIndexes, types.NewRewardIndex(coin.Denom, borrowFactor))
 | 
									continue // No rewards for this coin type
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								multiRewardIndex := types.NewMultiRewardIndex(coin.Denom, globalRewardIndexes)
 | 
				
			||||||
 | 
								borrowRewardIndexes = append(borrowRewardIndexes, multiRewardIndex)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(borrowRewardIndexes) == 0 {
 | 
						if len(borrowRewardIndexes) == 0 {
 | 
				
			||||||
@ -469,7 +533,7 @@ func (k Keeper) AccumulateHardDelegatorRewards(ctx sdk.Context, rewardPeriod typ
 | 
				
			|||||||
		k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
							k.SetPreviousHardDelegatorRewardAccrualTime(ctx, rewardPeriod.CollateralType, ctx.BlockTime())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	timeElapsed := CalculateTimeElapsed(rewardPeriod, ctx.BlockTime(), previousAccrualTime)
 | 
						timeElapsed := CalculateTimeElapsed(rewardPeriod.Start, rewardPeriod.End, ctx.BlockTime(), previousAccrualTime)
 | 
				
			||||||
	if timeElapsed.IsZero() {
 | 
						if timeElapsed.IsZero() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -509,9 +573,7 @@ func (k Keeper) InitializeHardDelegatorReward(ctx sdk.Context, delegator sdk.Acc
 | 
				
			|||||||
	claim, found := k.GetHardLiquidityProviderClaim(ctx, delegator)
 | 
						claim, found := k.GetHardLiquidityProviderClaim(ctx, delegator)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		// Instantiate claim object
 | 
							// Instantiate claim object
 | 
				
			||||||
		claim = types.NewHardLiquidityProviderClaim(delegator,
 | 
							claim = types.NewHardLiquidityProviderClaim(delegator, sdk.Coins{}, nil, nil, nil)
 | 
				
			||||||
			sdk.NewCoin(types.HardLiquidityRewardDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
			nil, nil, nil)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	claim.DelegatorRewardIndexes = types.RewardIndexes{delegatorRewardIndexes}
 | 
						claim.DelegatorRewardIndexes = types.RewardIndexes{delegatorRewardIndexes}
 | 
				
			||||||
@ -554,11 +616,11 @@ func (k Keeper) SynchronizeHardLiquidityProviderClaim(ctx sdk.Context, owner sdk
 | 
				
			|||||||
		k.SynchronizeHardSupplyReward(ctx, deposit)
 | 
							k.SynchronizeHardSupplyReward(ctx, deposit)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Synchronize any hard liquidity borrow-side rewards
 | 
						// // Synchronize any hard liquidity borrow-side rewards
 | 
				
			||||||
	borrow, foundBorrow := k.hardKeeper.GetBorrow(ctx, owner)
 | 
						// borrow, foundBorrow := k.hardKeeper.GetBorrow(ctx, owner)
 | 
				
			||||||
	if foundBorrow {
 | 
						// if foundBorrow {
 | 
				
			||||||
		k.SynchronizeHardBorrowReward(ctx, borrow)
 | 
						// 	k.SynchronizeHardBorrowReward(ctx, borrow)
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Synchronize any hard delegator rewards
 | 
						// Synchronize any hard delegator rewards
 | 
				
			||||||
	k.SynchronizeHardDelegatorRewards(ctx, owner)
 | 
						k.SynchronizeHardDelegatorRewards(ctx, owner)
 | 
				
			||||||
@ -566,21 +628,25 @@ func (k Keeper) SynchronizeHardLiquidityProviderClaim(ctx sdk.Context, owner sdk
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ZeroHardLiquidityProviderClaim zeroes out the claim object's rewards and returns the updated claim object
 | 
					// ZeroHardLiquidityProviderClaim zeroes out the claim object's rewards and returns the updated claim object
 | 
				
			||||||
func (k Keeper) ZeroHardLiquidityProviderClaim(ctx sdk.Context, claim types.HardLiquidityProviderClaim) types.HardLiquidityProviderClaim {
 | 
					func (k Keeper) ZeroHardLiquidityProviderClaim(ctx sdk.Context, claim types.HardLiquidityProviderClaim) types.HardLiquidityProviderClaim {
 | 
				
			||||||
	claim.Reward = sdk.NewCoin(claim.Reward.Denom, sdk.ZeroInt())
 | 
						var zeroRewards sdk.Coins
 | 
				
			||||||
 | 
						for _, coin := range claim.Reward {
 | 
				
			||||||
 | 
							zeroRewards = append(zeroRewards, sdk.NewCoin(coin.Denom, sdk.ZeroInt()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						claim.Reward = zeroRewards
 | 
				
			||||||
	k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
						k.SetHardLiquidityProviderClaim(ctx, claim)
 | 
				
			||||||
	return claim
 | 
						return claim
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CalculateTimeElapsed calculates the number of reward-eligible seconds that have passed since the previous
 | 
					// CalculateTimeElapsed calculates the number of reward-eligible seconds that have passed since the previous
 | 
				
			||||||
// time rewards were accrued, taking into account the end time of the reward period
 | 
					// time rewards were accrued, taking into account the end time of the reward period
 | 
				
			||||||
func CalculateTimeElapsed(rewardPeriod types.RewardPeriod, blockTime time.Time, previousAccrualTime time.Time) sdk.Int {
 | 
					func CalculateTimeElapsed(start, end, blockTime time.Time, previousAccrualTime time.Time) sdk.Int {
 | 
				
			||||||
	if rewardPeriod.End.Before(blockTime) &&
 | 
						if end.Before(blockTime) &&
 | 
				
			||||||
		(rewardPeriod.End.Before(previousAccrualTime) || rewardPeriod.End.Equal(previousAccrualTime)) {
 | 
							(end.Before(previousAccrualTime) || end.Equal(previousAccrualTime)) {
 | 
				
			||||||
		return sdk.ZeroInt()
 | 
							return sdk.ZeroInt()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rewardPeriod.End.Before(blockTime) {
 | 
						if end.Before(blockTime) {
 | 
				
			||||||
		return sdk.NewInt(int64(math.RoundToEven(
 | 
							return sdk.NewInt(int64(math.RoundToEven(
 | 
				
			||||||
			rewardPeriod.End.Sub(previousAccrualTime).Seconds(),
 | 
								end.Sub(previousAccrualTime).Seconds(),
 | 
				
			||||||
		)))
 | 
							)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sdk.NewInt(int64(math.RoundToEven(
 | 
						return sdk.NewInt(int64(math.RoundToEven(
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -58,6 +59,40 @@ func (c BaseClaim) String() string {
 | 
				
			|||||||
	`, c.Owner, c.Reward)
 | 
						`, 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 --------------
 | 
					// -------------- Custom Claim Types --------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// USDXMintingClaim is for USDX minting rewards
 | 
					// USDXMintingClaim is for USDX minting rewards
 | 
				
			||||||
@ -129,19 +164,19 @@ func (cs USDXMintingClaims) Validate() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner
 | 
					// HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner
 | 
				
			||||||
type HardLiquidityProviderClaim struct {
 | 
					type HardLiquidityProviderClaim struct {
 | 
				
			||||||
	BaseClaim              `json:"base_claim" yaml:"base_claim"`
 | 
						BaseMultiClaim         `json:"base_claim" yaml:"base_claim"`
 | 
				
			||||||
	SupplyRewardIndexes    RewardIndexes `json:"supply_reward_indexes" yaml:"supply_reward_indexes"`
 | 
						SupplyRewardIndexes    MultiRewardIndexes `json:"supply_reward_indexes" yaml:"supply_reward_indexes"`
 | 
				
			||||||
	BorrowRewardIndexes    RewardIndexes `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 RewardIndexes      `json:"delegator_reward_indexes" yaml:"delegator_reward_indexes"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
 | 
					// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
 | 
				
			||||||
func NewHardLiquidityProviderClaim(owner sdk.AccAddress, reward sdk.Coin, supplyRewardIndexes,
 | 
					func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins, supplyRewardIndexes,
 | 
				
			||||||
	borrowRewardIndexes, delegatorRewardIndexes RewardIndexes) HardLiquidityProviderClaim {
 | 
						borrowRewardIndexes MultiRewardIndexes, delegatorRewardIndexes RewardIndexes) HardLiquidityProviderClaim {
 | 
				
			||||||
	return HardLiquidityProviderClaim{
 | 
						return HardLiquidityProviderClaim{
 | 
				
			||||||
		BaseClaim: BaseClaim{
 | 
							BaseMultiClaim: BaseMultiClaim{
 | 
				
			||||||
			Owner:  owner,
 | 
								Owner:  owner,
 | 
				
			||||||
			Reward: reward,
 | 
								Reward: rewards,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SupplyRewardIndexes:    supplyRewardIndexes,
 | 
							SupplyRewardIndexes:    supplyRewardIndexes,
 | 
				
			||||||
		BorrowRewardIndexes:    borrowRewardIndexes,
 | 
							BorrowRewardIndexes:    borrowRewardIndexes,
 | 
				
			||||||
@ -153,7 +188,7 @@ func NewHardLiquidityProviderClaim(owner sdk.AccAddress, reward sdk.Coin, supply
 | 
				
			|||||||
func (c HardLiquidityProviderClaim) GetType() string { return HardLiquidityProviderClaimType }
 | 
					func (c HardLiquidityProviderClaim) GetType() string { return HardLiquidityProviderClaimType }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetReward returns the claim's reward coin
 | 
					// GetReward returns the claim's reward coin
 | 
				
			||||||
func (c HardLiquidityProviderClaim) GetReward() sdk.Coin { return c.Reward }
 | 
					func (c HardLiquidityProviderClaim) GetReward() sdk.Coins { return c.Reward }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetOwner returns the claim's owner
 | 
					// GetOwner returns the claim's owner
 | 
				
			||||||
func (c HardLiquidityProviderClaim) GetOwner() sdk.AccAddress { return c.Owner }
 | 
					func (c HardLiquidityProviderClaim) GetOwner() sdk.AccAddress { return c.Owner }
 | 
				
			||||||
@ -172,7 +207,7 @@ func (c HardLiquidityProviderClaim) Validate() error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c.BaseClaim.Validate()
 | 
						return c.BaseMultiClaim.Validate()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String implements fmt.Stringer
 | 
					// String implements fmt.Stringer
 | 
				
			||||||
@ -181,7 +216,7 @@ func (c HardLiquidityProviderClaim) String() string {
 | 
				
			|||||||
	Supply Reward Indexes: %s,
 | 
						Supply Reward Indexes: %s,
 | 
				
			||||||
	Borrow Reward Indexes: %s,
 | 
						Borrow Reward Indexes: %s,
 | 
				
			||||||
	Delegator Reward Indexes: %s,
 | 
						Delegator Reward Indexes: %s,
 | 
				
			||||||
	`, c.BaseClaim, c.SupplyRewardIndexes, c.BorrowRewardIndexes, c.DelegatorRewardIndexes)
 | 
						`, c.BaseMultiClaim, c.SupplyRewardIndexes, c.BorrowRewardIndexes, c.DelegatorRewardIndexes)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HasSupplyRewardIndex check if a claim has a supply reward index for the input collateral type
 | 
					// HasSupplyRewardIndex check if a claim has a supply reward index for the input collateral type
 | 
				
			||||||
@ -265,6 +300,26 @@ func (ri RewardIndex) Validate() error {
 | 
				
			|||||||
// RewardIndexes slice of RewardIndex
 | 
					// RewardIndexes slice of RewardIndex
 | 
				
			||||||
type RewardIndexes []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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
					// Validate validation for reward indexes
 | 
				
			||||||
func (ris RewardIndexes) Validate() error {
 | 
					func (ris RewardIndexes) Validate() error {
 | 
				
			||||||
	for _, ri := range ris {
 | 
						for _, ri := range ris {
 | 
				
			||||||
@ -274,3 +329,141 @@ func (ris RewardIndexes) Validate() error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						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"`
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Validate validation for reward indexes
 | 
				
			||||||
 | 
					func (mris MultiRewardIndexes) Validate() error {
 | 
				
			||||||
 | 
						for _, mri := range mris {
 | 
				
			||||||
 | 
							if err := mri.Validate(); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -52,8 +52,8 @@ func TestGenesisStateValidate(t *testing.T) {
 | 
				
			|||||||
							sdk.NewCoin("ukava", sdk.NewInt(25000)),
 | 
												sdk.NewCoin("ukava", sdk.NewInt(25000)),
 | 
				
			||||||
						),
 | 
											),
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					DefaultRewardPeriods,
 | 
										DefaultMultiRewardPeriods,
 | 
				
			||||||
					DefaultRewardPeriods,
 | 
										DefaultMultiRewardPeriods,
 | 
				
			||||||
					DefaultRewardPeriods,
 | 
										DefaultRewardPeriods,
 | 
				
			||||||
					Multipliers{
 | 
										Multipliers{
 | 
				
			||||||
						NewMultiplier(Small, 1, sdk.MustNewDecFromStr("0.33")),
 | 
											NewMultiplier(Small, 1, sdk.MustNewDecFromStr("0.33")),
 | 
				
			||||||
 | 
				
			|||||||
@ -27,9 +27,9 @@ 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
 | 
				
			||||||
	HardSupplyRewardFactorKeyPrefix                 = []byte{0x05} // prefix for key that stores Hard supply reward factors
 | 
						HardSupplyRewardIndexesKeyPrefix                = []byte{0x05} // prefix for key that stores Hard supply reward factors
 | 
				
			||||||
	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
 | 
				
			||||||
	HardBorrowRewardFactorKeyPrefix                 = []byte{0x07} // prefix for key that stores Hard borrow reward factors
 | 
						HardBorrowRewardIndexesKeyPrefix                = []byte{0x07} // prefix for key that stores Hard borrow reward factors
 | 
				
			||||||
	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
 | 
						HardDelegatorRewardFactorKeyPrefix              = []byte{0x09} // prefix for key that stores Hard delegator reward factors
 | 
				
			||||||
	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
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ var (
 | 
				
			|||||||
	KeyMultipliers                  = []byte("ClaimMultipliers")
 | 
						KeyMultipliers                  = []byte("ClaimMultipliers")
 | 
				
			||||||
	DefaultActive                   = false
 | 
						DefaultActive                   = false
 | 
				
			||||||
	DefaultRewardPeriods            = RewardPeriods{}
 | 
						DefaultRewardPeriods            = RewardPeriods{}
 | 
				
			||||||
 | 
						DefaultMultiRewardPeriods       = MultiRewardPeriods{}
 | 
				
			||||||
	DefaultMultipliers              = Multipliers{}
 | 
						DefaultMultipliers              = Multipliers{}
 | 
				
			||||||
	DefaultClaims                   = USDXMintingClaims{}
 | 
						DefaultClaims                   = USDXMintingClaims{}
 | 
				
			||||||
	DefaultGenesisAccumulationTimes = GenesisAccumulationTimes{}
 | 
						DefaultGenesisAccumulationTimes = GenesisAccumulationTimes{}
 | 
				
			||||||
@ -43,17 +44,17 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Params governance parameters for the incentive module
 | 
					// Params governance parameters for the incentive module
 | 
				
			||||||
type Params struct {
 | 
					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    RewardPeriods `json:"hard_supply_reward_periods" yaml:"hard_supply_reward_periods"`
 | 
						HardSupplyRewardPeriods    MultiRewardPeriods `json:"hard_supply_reward_periods" yaml:"hard_supply_reward_periods"`
 | 
				
			||||||
	HardBorrowRewardPeriods    RewardPeriods `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 RewardPeriods      `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, hardSupply, hardBorrow, hardDelegator RewardPeriods,
 | 
					func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow MultiRewardPeriods,
 | 
				
			||||||
	multipliers Multipliers, claimEnd time.Time) Params {
 | 
						hardDelegator RewardPeriods, multipliers Multipliers, claimEnd time.Time) Params {
 | 
				
			||||||
	return Params{
 | 
						return Params{
 | 
				
			||||||
		USDXMintingRewardPeriods:   usdxMinting,
 | 
							USDXMintingRewardPeriods:   usdxMinting,
 | 
				
			||||||
		HardSupplyRewardPeriods:    hardSupply,
 | 
							HardSupplyRewardPeriods:    hardSupply,
 | 
				
			||||||
@ -66,8 +67,8 @@ func NewParams(usdxMinting, hardSupply, hardBorrow, hardDelegator RewardPeriods,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// DefaultParams returns default params for incentive module
 | 
					// DefaultParams returns default params for incentive module
 | 
				
			||||||
func DefaultParams() Params {
 | 
					func DefaultParams() Params {
 | 
				
			||||||
	return NewParams(DefaultRewardPeriods, DefaultRewardPeriods,
 | 
						return NewParams(DefaultRewardPeriods, DefaultMultiRewardPeriods,
 | 
				
			||||||
		DefaultRewardPeriods, DefaultRewardPeriods, DefaultMultipliers, DefaultClaimEnd)
 | 
							DefaultMultiRewardPeriods, DefaultRewardPeriods, DefaultMultipliers, DefaultClaimEnd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String implements fmt.Stringer
 | 
					// String implements fmt.Stringer
 | 
				
			||||||
@ -92,8 +93,8 @@ func ParamKeyTable() params.KeyTable {
 | 
				
			|||||||
func (p *Params) ParamSetPairs() params.ParamSetPairs {
 | 
					func (p *Params) ParamSetPairs() params.ParamSetPairs {
 | 
				
			||||||
	return params.ParamSetPairs{
 | 
						return params.ParamSetPairs{
 | 
				
			||||||
		params.NewParamSetPair(KeyUSDXMintingRewardPeriods, &p.USDXMintingRewardPeriods, validateRewardPeriodsParam),
 | 
							params.NewParamSetPair(KeyUSDXMintingRewardPeriods, &p.USDXMintingRewardPeriods, validateRewardPeriodsParam),
 | 
				
			||||||
		params.NewParamSetPair(KeyHardSupplyRewardPeriods, &p.HardSupplyRewardPeriods, validateRewardPeriodsParam),
 | 
							params.NewParamSetPair(KeyHardSupplyRewardPeriods, &p.HardSupplyRewardPeriods, validateMultiRewardPeriodsParam),
 | 
				
			||||||
		params.NewParamSetPair(KeyHardBorrowRewardPeriods, &p.HardBorrowRewardPeriods, validateRewardPeriodsParam),
 | 
							params.NewParamSetPair(KeyHardBorrowRewardPeriods, &p.HardBorrowRewardPeriods, validateMultiRewardPeriodsParam),
 | 
				
			||||||
		params.NewParamSetPair(KeyHardDelegatorRewardPeriods, &p.HardDelegatorRewardPeriods, validateRewardPeriodsParam),
 | 
							params.NewParamSetPair(KeyHardDelegatorRewardPeriods, &p.HardDelegatorRewardPeriods, validateRewardPeriodsParam),
 | 
				
			||||||
		params.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
 | 
							params.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
 | 
				
			||||||
		params.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersParam),
 | 
							params.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersParam),
 | 
				
			||||||
@ -111,11 +112,11 @@ func (p Params) Validate() error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := validateRewardPeriodsParam(p.HardSupplyRewardPeriods); err != nil {
 | 
						if err := validateMultiRewardPeriodsParam(p.HardSupplyRewardPeriods); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := validateRewardPeriodsParam(p.HardBorrowRewardPeriods); err != nil {
 | 
						if err := validateMultiRewardPeriodsParam(p.HardBorrowRewardPeriods); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -131,6 +132,15 @@ func validateRewardPeriodsParam(i interface{}) error {
 | 
				
			|||||||
	return rewards.Validate()
 | 
						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 {
 | 
					func validateMultipliersParam(i interface{}) error {
 | 
				
			||||||
	multipliers, ok := i.(Multipliers)
 | 
						multipliers, ok := i.(Multipliers)
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,8 @@ func (suite *ParamTestSuite) SetupTest() {}
 | 
				
			|||||||
func (suite *ParamTestSuite) TestParamValidation() {
 | 
					func (suite *ParamTestSuite) TestParamValidation() {
 | 
				
			||||||
	type args struct {
 | 
						type args struct {
 | 
				
			||||||
		usdxMintingRewardPeriods   types.RewardPeriods
 | 
							usdxMintingRewardPeriods   types.RewardPeriods
 | 
				
			||||||
		hardSupplyRewardPeriods    types.RewardPeriods
 | 
							hardSupplyRewardPeriods    types.MultiRewardPeriods
 | 
				
			||||||
		hardBorrowRewardPeriods    types.RewardPeriods
 | 
							hardBorrowRewardPeriods    types.MultiRewardPeriods
 | 
				
			||||||
		hardDelegatorRewardPeriods types.RewardPeriods
 | 
							hardDelegatorRewardPeriods types.RewardPeriods
 | 
				
			||||||
		multipliers                types.Multipliers
 | 
							multipliers                types.Multipliers
 | 
				
			||||||
		end                        time.Time
 | 
							end                        time.Time
 | 
				
			||||||
@ -43,8 +43,8 @@ func (suite *ParamTestSuite) TestParamValidation() {
 | 
				
			|||||||
			"default",
 | 
								"default",
 | 
				
			||||||
			args{
 | 
								args{
 | 
				
			||||||
				usdxMintingRewardPeriods:   types.DefaultRewardPeriods,
 | 
									usdxMintingRewardPeriods:   types.DefaultRewardPeriods,
 | 
				
			||||||
				hardSupplyRewardPeriods:    types.DefaultRewardPeriods,
 | 
									hardSupplyRewardPeriods:    types.DefaultMultiRewardPeriods,
 | 
				
			||||||
				hardBorrowRewardPeriods:    types.DefaultRewardPeriods,
 | 
									hardBorrowRewardPeriods:    types.DefaultMultiRewardPeriods,
 | 
				
			||||||
				hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
 | 
									hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
 | 
				
			||||||
				multipliers:                types.DefaultMultipliers,
 | 
									multipliers:                types.DefaultMultipliers,
 | 
				
			||||||
				end:                        types.DefaultClaimEnd,
 | 
									end:                        types.DefaultClaimEnd,
 | 
				
			||||||
@ -68,8 +68,8 @@ func (suite *ParamTestSuite) TestParamValidation() {
 | 
				
			|||||||
						types.Large, 1, sdk.MustNewDecFromStr("1.0"),
 | 
											types.Large, 1, sdk.MustNewDecFromStr("1.0"),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				hardSupplyRewardPeriods:    types.DefaultRewardPeriods,
 | 
									hardSupplyRewardPeriods:    types.DefaultMultiRewardPeriods,
 | 
				
			||||||
				hardBorrowRewardPeriods:    types.DefaultRewardPeriods,
 | 
									hardBorrowRewardPeriods:    types.DefaultMultiRewardPeriods,
 | 
				
			||||||
				hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
 | 
									hardDelegatorRewardPeriods: types.DefaultRewardPeriods,
 | 
				
			||||||
				end:                        time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC),
 | 
									end:                        time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user