mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 09:57:27 +00:00 
			
		
		
		
	Fix hard incentive state in migrations (#1001)
* extract hard claim migration function * tidy up claim delegator index migration * fix invalid hard claims * fix comment missed in merge conflict reolution * fix tests
This commit is contained in:
		
							parent
							
								
									3d65ba7caa
								
							
						
					
					
						commit
						7d85361240
					
				@ -2,18 +2,21 @@ package v0_15
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/cosmos/cosmos-sdk/codec"
 | 
						"github.com/cosmos/cosmos-sdk/codec"
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v0_15hard "github.com/kava-labs/kava/x/hard/types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
						v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
				
			||||||
	v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
						v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
				
			||||||
	v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
						v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Incentive migrates from a v0.14 incentive genesis state to a v0.15 incentive genesis state
 | 
					// Incentive migrates from a v0.14 incentive genesis state to a v0.15 incentive genesis state
 | 
				
			||||||
func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v0_15cdp.CDPs) v0_15incentive.GenesisState {
 | 
					func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v0_15cdp.CDPs, hardGS v0_15hard.GenesisState) v0_15incentive.GenesisState {
 | 
				
			||||||
	// Migrate params
 | 
						// Migrate params
 | 
				
			||||||
	claimMultipliers := v0_15incentive.Multipliers{}
 | 
						claimMultipliers := v0_15incentive.Multipliers{}
 | 
				
			||||||
	for _, m := range incentiveGS.Params.ClaimMultipliers {
 | 
						for _, m := range incentiveGS.Params.ClaimMultipliers {
 | 
				
			||||||
@ -99,37 +102,20 @@ func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v
 | 
				
			|||||||
	usdxMintingClaims = addRewards(usdxMintingClaims, missedRewards)
 | 
						usdxMintingClaims = addRewards(usdxMintingClaims, missedRewards)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Migrate Hard protocol claims (includes creating new Delegator claims)
 | 
						// Migrate Hard protocol claims (includes creating new Delegator claims)
 | 
				
			||||||
	hardClaims := v0_15incentive.HardLiquidityProviderClaims{}
 | 
						hardClaims, delegatorClaims, err := migrateHardLiquidityProviderClaims(incentiveGS.HardLiquidityProviderClaims)
 | 
				
			||||||
	delegatorClaims := v0_15incentive.DelegatorClaims{}
 | 
						if err != nil {
 | 
				
			||||||
	for _, claim := range incentiveGS.HardLiquidityProviderClaims {
 | 
							panic(fmt.Sprintf("could not migrate hard claims: %v", err.Error()))
 | 
				
			||||||
		// Migrate supply multi reward indexes
 | 
					 | 
				
			||||||
		supplyMultiRewardIndexes := migrateMultiRewardIndexes(claim.SupplyRewardIndexes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Migrate borrow multi reward indexes
 | 
					 | 
				
			||||||
		borrowMultiRewardIndexes := migrateMultiRewardIndexes(claim.BorrowRewardIndexes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Migrate delegator reward indexes to multi reward indexes inside DelegatorClaims
 | 
					 | 
				
			||||||
		delegatorMultiRewardIndexes := v0_15incentive.MultiRewardIndexes{}
 | 
					 | 
				
			||||||
		delegatorRewardIndexes := v0_15incentive.RewardIndexes{}
 | 
					 | 
				
			||||||
		for _, ri := range claim.DelegatorRewardIndexes {
 | 
					 | 
				
			||||||
			// TODO add checks to ensure old reward indexes are as expected
 | 
					 | 
				
			||||||
			delegatorRewardIndex := v0_15incentive.NewRewardIndex(v0_14incentive.HardLiquidityRewardDenom, ri.RewardFactor)
 | 
					 | 
				
			||||||
			delegatorRewardIndexes = append(delegatorRewardIndexes, delegatorRewardIndex)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// TODO should this include indexes if none exist on the old claim?
 | 
					 | 
				
			||||||
		delegatorMultiRewardIndex := v0_15incentive.NewMultiRewardIndex(v0_14incentive.BondDenom, delegatorRewardIndexes)
 | 
					 | 
				
			||||||
		delegatorMultiRewardIndexes = append(delegatorMultiRewardIndexes, delegatorMultiRewardIndex)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// TODO: It's impossible to distinguish between rewards from delegation vs. liquidity providing
 | 
					 | 
				
			||||||
		//		 as they're all combined inside claim.Reward, so I'm just putting them all inside
 | 
					 | 
				
			||||||
		// 		 the hard claim to avoid duplicating rewards.
 | 
					 | 
				
			||||||
		delegatorClaim := v0_15incentive.NewDelegatorClaim(claim.Owner, sdk.NewCoins(), delegatorMultiRewardIndexes)
 | 
					 | 
				
			||||||
		delegatorClaims = append(delegatorClaims, delegatorClaim)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		hardClaim := v0_15incentive.NewHardLiquidityProviderClaim(claim.Owner, claim.Reward,
 | 
					 | 
				
			||||||
			supplyMultiRewardIndexes, borrowMultiRewardIndexes)
 | 
					 | 
				
			||||||
		hardClaims = append(hardClaims, hardClaim)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						hardClaims = addMissingHardClaims(
 | 
				
			||||||
 | 
							hardClaims,
 | 
				
			||||||
 | 
							hardGS.Deposits, hardGS.Borrows,
 | 
				
			||||||
 | 
							hardSupplyGenesisRewardState.MultiRewardIndexes, hardBorrowGenesisRewardState.MultiRewardIndexes,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						hardClaims = alignClaimIndexes(
 | 
				
			||||||
 | 
							hardClaims,
 | 
				
			||||||
 | 
							hardGS.Deposits, hardGS.Borrows,
 | 
				
			||||||
 | 
							hardSupplyGenesisRewardState.MultiRewardIndexes, hardBorrowGenesisRewardState.MultiRewardIndexes,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add Swap Claims
 | 
						// Add Swap Claims
 | 
				
			||||||
	swapClaims := v0_15incentive.DefaultSwapClaims
 | 
						swapClaims := v0_15incentive.DefaultSwapClaims
 | 
				
			||||||
@ -148,6 +134,61 @@ func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func migrateHardLiquidityProviderClaims(oldClaims v0_14incentive.HardLiquidityProviderClaims) (v0_15incentive.HardLiquidityProviderClaims, v0_15incentive.DelegatorClaims, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hardClaims := v0_15incentive.HardLiquidityProviderClaims{}
 | 
				
			||||||
 | 
						delegatorClaims := v0_15incentive.DelegatorClaims{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, claim := range oldClaims {
 | 
				
			||||||
 | 
							// Migrate supply multi reward indexes
 | 
				
			||||||
 | 
							supplyMultiRewardIndexes := migrateMultiRewardIndexes(claim.SupplyRewardIndexes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Migrate borrow multi reward indexes
 | 
				
			||||||
 | 
							borrowMultiRewardIndexes := migrateMultiRewardIndexes(claim.BorrowRewardIndexes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Migrate delegator reward indexes to multi reward indexes inside DelegatorClaims
 | 
				
			||||||
 | 
							delegatorMultiRewardIndexes, err := migrateDelegatorRewardIndexes(claim.DelegatorRewardIndexes)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, nil, fmt.Errorf("invalid claim found '%s': %w", claim.Owner, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// It's impossible to distinguish between rewards from delegation vs. liquidity provisioning
 | 
				
			||||||
 | 
							// as they're all combined inside claim.Reward, so put them all inside the hard claim to
 | 
				
			||||||
 | 
							// avoid duplicating rewards.
 | 
				
			||||||
 | 
							delegatorClaim := v0_15incentive.NewDelegatorClaim(claim.Owner, sdk.NewCoins(), delegatorMultiRewardIndexes)
 | 
				
			||||||
 | 
							delegatorClaims = append(delegatorClaims, delegatorClaim)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hardClaim := v0_15incentive.NewHardLiquidityProviderClaim(claim.Owner, claim.Reward,
 | 
				
			||||||
 | 
								supplyMultiRewardIndexes, borrowMultiRewardIndexes)
 | 
				
			||||||
 | 
							hardClaims = append(hardClaims, hardClaim)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hardClaims, delegatorClaims, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func migrateDelegatorRewardIndexes(oldIndexes v0_14incentive.RewardIndexes) (v0_15incentive.MultiRewardIndexes, error) {
 | 
				
			||||||
 | 
						newRIs := v0_15incentive.RewardIndexes{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(oldIndexes) > 1 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("delegator claims should not have more than one rewarded denom")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(oldIndexes) > 0 {
 | 
				
			||||||
 | 
							oldRI := oldIndexes[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if oldRI.CollateralType != v0_15incentive.BondDenom {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("delegator claims should only reward staked '%s', not '%s'", v0_15incentive.BondDenom, oldRI.CollateralType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							newRIs = newRIs.With(v0_14incentive.HardLiquidityRewardDenom, oldRI.RewardFactor)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newIndexes := v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
							v0_15incentive.NewMultiRewardIndex(v0_15incentive.BondDenom, newRIs),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return newIndexes, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// migrateUSDXMintingClaims converts the a slice of v0.14 USDX minting claims into v0.15 USDX minting claims.
 | 
					// migrateUSDXMintingClaims converts the a slice of v0.14 USDX minting claims into v0.15 USDX minting claims.
 | 
				
			||||||
// As both types are the same underneath, this just converts types and does no other modification.
 | 
					// As both types are the same underneath, this just converts types and does no other modification.
 | 
				
			||||||
func migrateUSDXMintingClaims(oldClaims v0_14incentive.USDXMintingClaims) v0_15incentive.USDXMintingClaims {
 | 
					func migrateUSDXMintingClaims(oldClaims v0_14incentive.USDXMintingClaims) v0_15incentive.USDXMintingClaims {
 | 
				
			||||||
@ -277,3 +318,153 @@ func migrateRewardIndexes(oldIndexes v0_14incentive.RewardIndexes) v0_15incentiv
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return newIndexes
 | 
						return newIndexes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// addMissingHardClaims checks for hard deposits and borrows without claims. If found it creates new
 | 
				
			||||||
 | 
					// claims with indexes set to the global indexes so rewards start accumulating from launch.
 | 
				
			||||||
 | 
					func addMissingHardClaims(hardClaims v0_15incentive.HardLiquidityProviderClaims, deposits v0_15hard.Deposits, borrows v0_15hard.Borrows, depositGlobalIndexes, borrowGlobalIndexes v0_15incentive.MultiRewardIndexes) v0_15incentive.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						missingClaims := map[string]v0_15incentive.HardLiquidityProviderClaim{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, deposit := range deposits {
 | 
				
			||||||
 | 
							_, found := getHardClaimByOwner(hardClaims, deposit.Depositor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								missingClaims[deposit.Depositor.String()] = v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
									deposit.Depositor,
 | 
				
			||||||
 | 
									sdk.NewCoins(), // do not calculate missing rewards
 | 
				
			||||||
 | 
									getIndexesForCoins(deposit.Amount, depositGlobalIndexes),
 | 
				
			||||||
 | 
									v0_15incentive.MultiRewardIndexes{}, // the depositor may also have a borrow, this will be added below
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, borrow := range borrows {
 | 
				
			||||||
 | 
							_, found := getHardClaimByOwner(hardClaims, borrow.Borrower)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								c, ok := missingClaims[borrow.Borrower.String()]
 | 
				
			||||||
 | 
								borrowIndexes := getIndexesForCoins(borrow.Amount, borrowGlobalIndexes)
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									c.BorrowRewardIndexes = borrowIndexes
 | 
				
			||||||
 | 
									missingClaims[borrow.Borrower.String()] = c
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									missingClaims[borrow.Borrower.String()] = v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
										borrow.Borrower,
 | 
				
			||||||
 | 
										sdk.NewCoins(),                      // do not calculate missing rewards
 | 
				
			||||||
 | 
										v0_15incentive.MultiRewardIndexes{}, // this borrow does not have any deposits as it would have been found above
 | 
				
			||||||
 | 
										borrowIndexes,
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// New claims need to be sorted to ensure the output genesis state is the same for everyone.
 | 
				
			||||||
 | 
						// Sorting by address should be give deterministic order as the addresses are unique.
 | 
				
			||||||
 | 
						sortedNewClaims := make(v0_15incentive.HardLiquidityProviderClaims, 0, len(missingClaims))
 | 
				
			||||||
 | 
						for _, claim := range missingClaims {
 | 
				
			||||||
 | 
							sortedNewClaims = append(sortedNewClaims, claim)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sort.Slice(sortedNewClaims, func(i, j int) bool {
 | 
				
			||||||
 | 
							return sortedNewClaims[i].Owner.String() < sortedNewClaims[j].Owner.String()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return append(hardClaims, sortedNewClaims...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getIndexesForCoins returns indexes with collateral types matching the coins denoms. RewardIndexes values are taken
 | 
				
			||||||
 | 
					// from the provided indexes, or left empty if not found.
 | 
				
			||||||
 | 
					func getIndexesForCoins(coins sdk.Coins, indexes v0_15incentive.MultiRewardIndexes) v0_15incentive.MultiRewardIndexes {
 | 
				
			||||||
 | 
						newIndexes := v0_15incentive.MultiRewardIndexes{}
 | 
				
			||||||
 | 
						for _, c := range coins {
 | 
				
			||||||
 | 
							ri, found := indexes.Get(c.Denom)
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								ri = v0_15incentive.RewardIndexes{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							newIndexes = newIndexes.With(c.Denom, ri)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return newIndexes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getHardClaimByOwner picks out the first claim matching an address.
 | 
				
			||||||
 | 
					func getHardClaimByOwner(claims v0_15incentive.HardLiquidityProviderClaims, owner sdk.AccAddress) (v0_15incentive.HardLiquidityProviderClaim, bool) {
 | 
				
			||||||
 | 
						for _, claim := range claims {
 | 
				
			||||||
 | 
							if claim.Owner.Equals(owner) {
 | 
				
			||||||
 | 
								return claim, true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v0_15incentive.HardLiquidityProviderClaim{}, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getHardDepositByOwner picks out the first deposit matching an address.
 | 
				
			||||||
 | 
					func getHardDepositByOwner(deposits v0_15hard.Deposits, owner sdk.AccAddress) (v0_15hard.Deposit, bool) {
 | 
				
			||||||
 | 
						for _, deposit := range deposits {
 | 
				
			||||||
 | 
							if deposit.Depositor.Equals(owner) {
 | 
				
			||||||
 | 
								return deposit, true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v0_15hard.Deposit{}, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getHardBorrowByOwner picks out the first borrow matching an address.
 | 
				
			||||||
 | 
					func getHardBorrowByOwner(borrows v0_15hard.Borrows, owner sdk.AccAddress) (v0_15hard.Borrow, bool) {
 | 
				
			||||||
 | 
						for _, borrow := range borrows {
 | 
				
			||||||
 | 
							if borrow.Borrower.Equals(owner) {
 | 
				
			||||||
 | 
								return borrow, true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v0_15hard.Borrow{}, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// alignClaimIndexes fixes the supply and borrow indexes on the hard claims to ensure they match the deposits and borrows.
 | 
				
			||||||
 | 
					func alignClaimIndexes(claims v0_15incentive.HardLiquidityProviderClaims, deposits v0_15hard.Deposits, borrows v0_15hard.Borrows, depositGlobalIndexes, borrowGlobalIndexes v0_15incentive.MultiRewardIndexes) v0_15incentive.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
						newClaims := make(v0_15incentive.HardLiquidityProviderClaims, 0, len(claims))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, claim := range claims {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							deposit, found := getHardDepositByOwner(deposits, claim.Owner)
 | 
				
			||||||
 | 
							amt := deposit.Amount
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								amt = sdk.NewCoins()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							claim.SupplyRewardIndexes = alignIndexes(claim.SupplyRewardIndexes, amt, depositGlobalIndexes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							borrow, found := getHardBorrowByOwner(borrows, claim.Owner)
 | 
				
			||||||
 | 
							amt = borrow.Amount
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								amt = sdk.NewCoins()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							claim.BorrowRewardIndexes = alignIndexes(claim.BorrowRewardIndexes, amt, depositGlobalIndexes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							newClaims = append(newClaims, claim)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return newClaims
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// alignIndexes adds or remove items from indexes so all the collateral types match the coins denoms.
 | 
				
			||||||
 | 
					// Missing index values are filled from globalIndexes if found. Otherwise they're set to empty.
 | 
				
			||||||
 | 
					// It preserves the order of the original index to avoid unnecessary churn in the migrated claims.
 | 
				
			||||||
 | 
					func alignIndexes(indexes v0_15incentive.MultiRewardIndexes, coins sdk.Coins, globalIndexes v0_15incentive.MultiRewardIndexes) v0_15incentive.MultiRewardIndexes {
 | 
				
			||||||
 | 
						newIndexes := indexes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// add missing indexes
 | 
				
			||||||
 | 
						for _, coin := range coins {
 | 
				
			||||||
 | 
							if _, found := indexes.Get(coin.Denom); !found {
 | 
				
			||||||
 | 
								ri, f := globalIndexes.Get(coin.Denom)
 | 
				
			||||||
 | 
								if !f {
 | 
				
			||||||
 | 
									ri = v0_15incentive.RewardIndexes{}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								newIndexes = newIndexes.With(coin.Denom, ri)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// remove extra indexes
 | 
				
			||||||
 | 
						for _, index := range indexes {
 | 
				
			||||||
 | 
							if coins.AmountOf(index.CollateralType).Equal(sdk.ZeroInt()) {
 | 
				
			||||||
 | 
								// RemoveRewardIndex returns a copy of the underlying array so the loop is not distupted
 | 
				
			||||||
 | 
								newIndexes = newIndexes.RemoveRewardIndex(index.CollateralType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return newIndexes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,9 @@ import (
 | 
				
			|||||||
	"github.com/stretchr/testify/require"
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
						v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
				
			||||||
 | 
						v0_15hard "github.com/kava-labs/kava/x/hard/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/incentive"
 | 
						"github.com/kava-labs/kava/x/incentive"
 | 
				
			||||||
 | 
						v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
				
			||||||
	v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
						v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,6 +17,347 @@ import (
 | 
				
			|||||||
// It is an alias for sdk.MustNewDecFromStr.
 | 
					// It is an alias for sdk.MustNewDecFromStr.
 | 
				
			||||||
var d = sdk.MustNewDecFromStr
 | 
					var d = sdk.MustNewDecFromStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMigrateDelegatorRewardIndexes(t *testing.T) {
 | 
				
			||||||
 | 
						type expect struct {
 | 
				
			||||||
 | 
							err     bool
 | 
				
			||||||
 | 
							indexes v0_15incentive.MultiRewardIndexes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							name     string
 | 
				
			||||||
 | 
							oldRIs   v0_14incentive.RewardIndexes
 | 
				
			||||||
 | 
							expected expect
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "single index is migrated correctly",
 | 
				
			||||||
 | 
								oldRIs: v0_14incentive.RewardIndexes{{
 | 
				
			||||||
 | 
									CollateralType: "ukava",
 | 
				
			||||||
 | 
									RewardFactor:   sdk.MustNewDecFromStr("0.1"),
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
 | 
								expected: expect{
 | 
				
			||||||
 | 
									indexes: v0_15incentive.MultiRewardIndexes{{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes: v0_15incentive.RewardIndexes{{
 | 
				
			||||||
 | 
											CollateralType: "hard",
 | 
				
			||||||
 | 
											RewardFactor:   sdk.MustNewDecFromStr("0.1"),
 | 
				
			||||||
 | 
										}},
 | 
				
			||||||
 | 
									}},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:   "empty index is migrated correctly",
 | 
				
			||||||
 | 
								oldRIs: v0_14incentive.RewardIndexes{},
 | 
				
			||||||
 | 
								expected: expect{
 | 
				
			||||||
 | 
									indexes: v0_15incentive.MultiRewardIndexes{{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  v0_15incentive.RewardIndexes{},
 | 
				
			||||||
 | 
									}},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "too many indexes errors",
 | 
				
			||||||
 | 
								oldRIs: v0_14incentive.RewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardFactor:   sdk.MustNewDecFromStr("0.1"),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "btcb",
 | 
				
			||||||
 | 
										RewardFactor:   sdk.MustNewDecFromStr("0.2"),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: expect{
 | 
				
			||||||
 | 
									err: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "incorrect rewarded denom errors",
 | 
				
			||||||
 | 
								oldRIs: v0_14incentive.RewardIndexes{{
 | 
				
			||||||
 | 
									CollateralType: "btcb",
 | 
				
			||||||
 | 
									RewardFactor:   sdk.MustNewDecFromStr("0.1"),
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
 | 
								expected: expect{
 | 
				
			||||||
 | 
									err: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range testCases {
 | 
				
			||||||
 | 
							t.Run(tc.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								actualIndexes, err := migrateDelegatorRewardIndexes(tc.oldRIs)
 | 
				
			||||||
 | 
								if tc.expected.err {
 | 
				
			||||||
 | 
									require.Error(t, err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									require.Equal(t, tc.expected.indexes, actualIndexes)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAddMissingHardClaims_Basic(t *testing.T) {
 | 
				
			||||||
 | 
						claims := v0_15incentive.HardLiquidityProviderClaims{
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						deposits := v0_15hard.Deposits{
 | 
				
			||||||
 | 
							v0_15hard.NewDeposit(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15hard.NewDeposit(
 | 
				
			||||||
 | 
								sdk.AccAddress("address2"),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						borrows := v0_15hard.Borrows{
 | 
				
			||||||
 | 
							v0_15hard.NewBorrow(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								nil, // only need the owner address for this test
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15hard.NewBorrow(
 | 
				
			||||||
 | 
								sdk.AccAddress("address3"),
 | 
				
			||||||
 | 
								nil, // only need the owner address for this test
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						actualClaims := addMissingHardClaims(claims, deposits, borrows, nil, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expectedClaims := v0_15incentive.HardLiquidityProviderClaims{
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address3"),
 | 
				
			||||||
 | 
								sdk.NewCoins(),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address2"),
 | 
				
			||||||
 | 
								sdk.NewCoins(),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						require.Equal(t, expectedClaims, actualClaims)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAlignClaimIndexes_Basic(t *testing.T) {
 | 
				
			||||||
 | 
						claims := v0_15incentive.HardLiquidityProviderClaims{
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "busd",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "xrpb",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						deposits := v0_15hard.Deposits{
 | 
				
			||||||
 | 
							v0_15hard.NewDeposit(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("ukava", 1)),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15hard.NewDeposit(
 | 
				
			||||||
 | 
								sdk.AccAddress("address2"),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						borrows := v0_15hard.Borrows{
 | 
				
			||||||
 | 
							v0_15hard.NewBorrow(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("xrpb", 1)),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							v0_15hard.NewBorrow(
 | 
				
			||||||
 | 
								sdk.AccAddress("address3"),
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
								nil,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						actualClaims := alignClaimIndexes(claims, deposits, borrows, nil, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expectedClaims := v0_15incentive.HardLiquidityProviderClaims{
 | 
				
			||||||
 | 
							v0_15incentive.NewHardLiquidityProviderClaim(
 | 
				
			||||||
 | 
								sdk.AccAddress("address1"),
 | 
				
			||||||
 | 
								sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{{
 | 
				
			||||||
 | 
									CollateralType: "ukava",
 | 
				
			||||||
 | 
									RewardIndexes:  nil,
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
 | 
								v0_15incentive.MultiRewardIndexes{{
 | 
				
			||||||
 | 
									CollateralType: "xrpb",
 | 
				
			||||||
 | 
									RewardIndexes:  nil,
 | 
				
			||||||
 | 
								}},
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						require.Equal(t, expectedClaims, actualClaims)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAlignIndexes(t *testing.T) {
 | 
				
			||||||
 | 
						globalRI := v0_15incentive.RewardIndexes{{
 | 
				
			||||||
 | 
							CollateralType: "hard",
 | 
				
			||||||
 | 
							RewardFactor:   sdk.OneDec(),
 | 
				
			||||||
 | 
						}}
 | 
				
			||||||
 | 
						globalIndexes := v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								CollateralType: "ukava",
 | 
				
			||||||
 | 
								RewardIndexes:  globalRI,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								CollateralType: "hard",
 | 
				
			||||||
 | 
								RewardIndexes:  globalRI,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							name     string
 | 
				
			||||||
 | 
							indexes  v0_15incentive.MultiRewardIndexes
 | 
				
			||||||
 | 
							coins    sdk.Coins
 | 
				
			||||||
 | 
							expected v0_15incentive.MultiRewardIndexes
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "indexes matching coins are unchanged",
 | 
				
			||||||
 | 
								indexes: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard", // not in alphabetic order
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("ukava", 1)),
 | 
				
			||||||
 | 
								expected: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard", // order is preserved
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "missing indexes are added from global values",
 | 
				
			||||||
 | 
								indexes: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("ukava", 1)),
 | 
				
			||||||
 | 
								expected: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  globalRI,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "extra indexes are removed",
 | 
				
			||||||
 | 
								indexes: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1)),
 | 
				
			||||||
 | 
								expected: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "missing indexes are added even when not in global values",
 | 
				
			||||||
 | 
								indexes: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("btcb", 1)),
 | 
				
			||||||
 | 
								expected: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "btcb",
 | 
				
			||||||
 | 
										RewardIndexes:  v0_15incentive.RewardIndexes{},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "empty coins results in empty indexes",
 | 
				
			||||||
 | 
								indexes: v0_15incentive.MultiRewardIndexes{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "ukava",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CollateralType: "hard",
 | 
				
			||||||
 | 
										RewardIndexes:  nil,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								coins:    sdk.NewCoins(),
 | 
				
			||||||
 | 
								expected: v0_15incentive.MultiRewardIndexes{},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range testCases {
 | 
				
			||||||
 | 
							t.Run(tc.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								require.Equal(t, tc.expected, alignIndexes(tc.indexes, tc.coins, globalIndexes))
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestReplaceUSDXClaimIndexes(t *testing.T) {
 | 
					func TestReplaceUSDXClaimIndexes(t *testing.T) {
 | 
				
			||||||
	claims := incentive.USDXMintingClaims{
 | 
						claims := incentive.USDXMintingClaims{
 | 
				
			||||||
		incentive.NewUSDXMintingClaim(
 | 
							incentive.NewUSDXMintingClaim(
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ import (
 | 
				
			|||||||
	v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
						v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
				
			||||||
	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
 | 
						v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
 | 
				
			||||||
	v0_15committee "github.com/kava-labs/kava/x/committee/types"
 | 
						v0_15committee "github.com/kava-labs/kava/x/committee/types"
 | 
				
			||||||
 | 
						v0_15hard "github.com/kava-labs/kava/x/hard/types"
 | 
				
			||||||
	v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
						v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
				
			||||||
	v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
						v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/kavadist"
 | 
						"github.com/kava-labs/kava/x/kavadist"
 | 
				
			||||||
@ -78,11 +79,14 @@ func MigrateAppState(v0_14AppState genutil.AppMap) {
 | 
				
			|||||||
		v0_14Codec.MustUnmarshalJSON(v0_14AppState[v0_14incentive.ModuleName], &incentiveGenState)
 | 
							v0_14Codec.MustUnmarshalJSON(v0_14AppState[v0_14incentive.ModuleName], &incentiveGenState)
 | 
				
			||||||
		delete(v0_14AppState, v0_14incentive.ModuleName)
 | 
							delete(v0_14AppState, v0_14incentive.ModuleName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var hardGenState v0_15hard.GenesisState // v0_14 hard genesis state is the same as v0_15
 | 
				
			||||||
 | 
							v0_15Codec.MustUnmarshalJSON(v0_14AppState[v0_15hard.ModuleName], &hardGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// unmarshal all cdps using v0_15 types as there has been no changes since v0_14
 | 
							// unmarshal all cdps using v0_15 types as there has been no changes since v0_14
 | 
				
			||||||
		var cdpGenState v0_15cdp.GenesisState
 | 
							var cdpGenState v0_15cdp.GenesisState
 | 
				
			||||||
		v0_15Codec.MustUnmarshalJSON(v0_14AppState[v0_15cdp.ModuleName], &cdpGenState)
 | 
							v0_15Codec.MustUnmarshalJSON(v0_14AppState[v0_15cdp.ModuleName], &cdpGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		v0_14AppState[v0_15incentive.ModuleName] = v0_15Codec.MustMarshalJSON(Incentive(v0_15Codec, incentiveGenState, cdpGenState.CDPs))
 | 
							v0_14AppState[v0_15incentive.ModuleName] = v0_15Codec.MustMarshalJSON(Incentive(v0_15Codec, incentiveGenState, cdpGenState.CDPs, hardGenState))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Migrate commmittee app state
 | 
						// Migrate commmittee app state
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ import (
 | 
				
			|||||||
	v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
						v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
 | 
				
			||||||
	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
 | 
						v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
 | 
				
			||||||
	v0_15committee "github.com/kava-labs/kava/x/committee/types"
 | 
						v0_15committee "github.com/kava-labs/kava/x/committee/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/hard"
 | 
						v0_15hard "github.com/kava-labs/kava/x/hard/types"
 | 
				
			||||||
	v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
						v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
 | 
				
			||||||
	v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
						v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/swap"
 | 
						"github.com/kava-labs/kava/x/swap"
 | 
				
			||||||
@ -80,14 +80,86 @@ func TestIncentive_Full(t *testing.T) {
 | 
				
			|||||||
	var oldIncentiveGenState v0_14incentive.GenesisState
 | 
						var oldIncentiveGenState v0_14incentive.GenesisState
 | 
				
			||||||
	cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
 | 
						cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var oldHardGenState v0_15hard.GenesisState
 | 
				
			||||||
 | 
						cdc.MustUnmarshalJSON(oldState[v0_15hard.ModuleName], &oldHardGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var oldCDPGenState v0_15cdp.GenesisState
 | 
						var oldCDPGenState v0_15cdp.GenesisState
 | 
				
			||||||
	cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
 | 
						cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs)
 | 
						newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs, oldHardGenState)
 | 
				
			||||||
	require.NoError(t, newGenState.Validate())
 | 
						require.NoError(t, newGenState.Validate())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO check params, indexes, and accumulation times
 | 
						// TODO check params, indexes, and accumulation times
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ensure every hard deposit has a claim with correct indexes
 | 
				
			||||||
 | 
						for _, deposit := range oldHardGenState.Deposits {
 | 
				
			||||||
 | 
							foundClaim := false
 | 
				
			||||||
 | 
							for _, claim := range newGenState.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
								if claim.Owner.Equals(deposit.Depositor) {
 | 
				
			||||||
 | 
									foundClaim = true
 | 
				
			||||||
 | 
									// check indexes are valid
 | 
				
			||||||
 | 
									err := collateralTypesMatch(deposit.Amount, claim.SupplyRewardIndexes)
 | 
				
			||||||
 | 
									require.NoErrorf(t, err, "invalid claim %s, %s", claim, deposit)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							require.True(t, foundClaim, "missing claim for hard deposit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// also ensure hard deposit indexes are valid
 | 
				
			||||||
 | 
							for _, i := range deposit.Index {
 | 
				
			||||||
 | 
								require.Truef(t, i.Value.GTE(sdk.OneDec()), "found invalid hard deposit index %s", deposit)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ensure every hard borrow has a claim with correct indexes
 | 
				
			||||||
 | 
						for _, borrow := range oldHardGenState.Borrows {
 | 
				
			||||||
 | 
							foundClaim := false
 | 
				
			||||||
 | 
							for _, claim := range newGenState.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
								if claim.Owner.Equals(borrow.Borrower) {
 | 
				
			||||||
 | 
									foundClaim = true
 | 
				
			||||||
 | 
									// check indexes are valid
 | 
				
			||||||
 | 
									err := collateralTypesMatch(borrow.Amount, claim.BorrowRewardIndexes)
 | 
				
			||||||
 | 
									require.NoErrorf(t, err, "invalid claim %s, %s", claim, borrow)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							require.True(t, foundClaim, "missing claim for hard borrow")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// also ensure hard borrow indexes are valid
 | 
				
			||||||
 | 
							for _, i := range borrow.Index {
 | 
				
			||||||
 | 
								require.Truef(t, i.Value.GTE(sdk.OneDec()), "found invalid hard borrow index %s", borrow)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ensure all claim indexes are ≤ global values
 | 
				
			||||||
 | 
						for _, claim := range newGenState.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, ri := range claim.BorrowRewardIndexes {
 | 
				
			||||||
 | 
								global, found := newGenState.HardBorrowRewardState.MultiRewardIndexes.Get(ri.CollateralType)
 | 
				
			||||||
 | 
								if !found {
 | 
				
			||||||
 | 
									global = v0_15incentive.RewardIndexes{}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								require.Truef(t, indexesAllLessThanOrEqual(ri.RewardIndexes, global), "invalid claim supply indexes %s %s", ri.RewardIndexes, global)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, ri := range claim.SupplyRewardIndexes {
 | 
				
			||||||
 | 
								global, found := newGenState.HardSupplyRewardState.MultiRewardIndexes.Get(ri.CollateralType)
 | 
				
			||||||
 | 
								if !found {
 | 
				
			||||||
 | 
									global = v0_15incentive.RewardIndexes{}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								require.Truef(t, indexesAllLessThanOrEqual(ri.RewardIndexes, global), "invalid claim borrow indexes %s %s", ri.RewardIndexes, global)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ensure (synced) reward amounts are unchanged
 | 
				
			||||||
 | 
						for _, claim := range newGenState.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
							for _, oldClaim := range oldIncentiveGenState.HardLiquidityProviderClaims {
 | 
				
			||||||
 | 
								if oldClaim.Owner.Equals(claim.Owner) {
 | 
				
			||||||
 | 
									require.Equal(t, claim.Reward, oldClaim.Reward)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Ensure the usdx claim indexes match global
 | 
						// Ensure the usdx claim indexes match global
 | 
				
			||||||
	globalIndexes := newGenState.USDXRewardState.MultiRewardIndexes
 | 
						globalIndexes := newGenState.USDXRewardState.MultiRewardIndexes
 | 
				
			||||||
	for _, claim := range newGenState.USDXMintingClaims {
 | 
						for _, claim := range newGenState.USDXMintingClaims {
 | 
				
			||||||
@ -152,11 +224,41 @@ func TestIncentive_Full(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.HardLiquidityProviderClaims))
 | 
					 | 
				
			||||||
	// 1 new DelegatorClaim should have been created for each existing HardLiquidityProviderClaim
 | 
						// 1 new DelegatorClaim should have been created for each existing HardLiquidityProviderClaim
 | 
				
			||||||
	require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.DelegatorClaims))
 | 
						require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.DelegatorClaims))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// collateralTypesMatch checks if the set of coin denoms is equal to the set of CollateralTypes in the indexes.
 | 
				
			||||||
 | 
					func collateralTypesMatch(coins sdk.Coins, indexes v0_15incentive.MultiRewardIndexes) error {
 | 
				
			||||||
 | 
						for _, index := range indexes {
 | 
				
			||||||
 | 
							if coins.AmountOf(index.CollateralType).Equal(sdk.ZeroInt()) {
 | 
				
			||||||
 | 
								return fmt.Errorf("index contains denom not found in coins")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, coin := range coins {
 | 
				
			||||||
 | 
							_, found := indexes.Get(coin.Denom)
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								return fmt.Errorf("coins contain denom not found in indexes")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// indexesAllLessThanOrEqual computes if all factors in A are ≤ factors in B.
 | 
				
			||||||
 | 
					// Missing indexes are taken to be zero.
 | 
				
			||||||
 | 
					func indexesAllLessThanOrEqual(indexesA, indexesB v0_15incentive.RewardIndexes) bool {
 | 
				
			||||||
 | 
						allLT := true
 | 
				
			||||||
 | 
						for _, ri := range indexesA {
 | 
				
			||||||
 | 
							factor, found := indexesB.Get(ri.CollateralType)
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								// value not found is same as it being zero
 | 
				
			||||||
 | 
								factor = sdk.ZeroDec()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							allLT = allLT && ri.RewardFactor.LTE(factor)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return allLT
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestIncentive_Full_TotalRewards(t *testing.T) {
 | 
					func TestIncentive_Full_TotalRewards(t *testing.T) {
 | 
				
			||||||
	t.Skip() // skip to avoid having to commit a large genesis file to the repo
 | 
						t.Skip() // skip to avoid having to commit a large genesis file to the repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -171,10 +273,13 @@ func TestIncentive_Full_TotalRewards(t *testing.T) {
 | 
				
			|||||||
	var oldIncentiveGenState v0_14incentive.GenesisState
 | 
						var oldIncentiveGenState v0_14incentive.GenesisState
 | 
				
			||||||
	cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
 | 
						cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var oldHardGenState v0_15hard.GenesisState
 | 
				
			||||||
 | 
						cdc.MustUnmarshalJSON(oldState[v0_15hard.ModuleName], &oldHardGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var oldCDPGenState v0_15cdp.GenesisState
 | 
						var oldCDPGenState v0_15cdp.GenesisState
 | 
				
			||||||
	cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
 | 
						cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs)
 | 
						newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs, oldHardGenState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// total previous rewards
 | 
						// total previous rewards
 | 
				
			||||||
	oldTotalRewards := sdk.NewCoins() // total synced unclaimed rewards
 | 
						oldTotalRewards := sdk.NewCoins() // total synced unclaimed rewards
 | 
				
			||||||
@ -228,7 +333,7 @@ func TestIncentive_SwpLPRewards(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	newGenState := v0_15incentive.GenesisState{}
 | 
						newGenState := v0_15incentive.GenesisState{}
 | 
				
			||||||
	require.NotPanics(t, func() {
 | 
						require.NotPanics(t, func() {
 | 
				
			||||||
		newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{})
 | 
							newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{}, v0_15hard.DefaultGenesisState())
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	err = newGenState.Validate()
 | 
						err = newGenState.Validate()
 | 
				
			||||||
	require.NoError(t, err)
 | 
						require.NoError(t, err)
 | 
				
			||||||
@ -264,7 +369,7 @@ func TestIncentive_SwpDelegatorRewards(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	newGenState := v0_15incentive.GenesisState{}
 | 
						newGenState := v0_15incentive.GenesisState{}
 | 
				
			||||||
	require.NotPanics(t, func() {
 | 
						require.NotPanics(t, func() {
 | 
				
			||||||
		newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{})
 | 
							newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{}, v0_15hard.DefaultGenesisState())
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, rp := range newGenState.Params.DelegatorRewardPeriods {
 | 
						for _, rp := range newGenState.Params.DelegatorRewardPeriods {
 | 
				
			||||||
@ -279,7 +384,12 @@ func TestIncentive_SwpDelegatorRewards(t *testing.T) {
 | 
				
			|||||||
func TestIncentive_SwpPoolsValid(t *testing.T) {
 | 
					func TestIncentive_SwpPoolsValid(t *testing.T) {
 | 
				
			||||||
	bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json"))
 | 
						bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json"))
 | 
				
			||||||
	require.NoError(t, err)
 | 
						require.NoError(t, err)
 | 
				
			||||||
	appState := genutil.AppMap{v0_14incentive.ModuleName: bz, v0_15cdp.ModuleName: app.MakeCodec().MustMarshalJSON(v0_15cdp.DefaultGenesisState())}
 | 
					
 | 
				
			||||||
 | 
						appState := genutil.AppMap{
 | 
				
			||||||
 | 
							v0_14incentive.ModuleName: bz,
 | 
				
			||||||
 | 
							v0_15cdp.ModuleName:       app.MakeCodec().MustMarshalJSON(v0_15cdp.DefaultGenesisState()),
 | 
				
			||||||
 | 
							v0_15hard.ModuleName:      app.MakeCodec().MustMarshalJSON(v0_15hard.DefaultGenesisState()),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MigrateAppState(appState)
 | 
						MigrateAppState(appState)
 | 
				
			||||||
	cdc := app.MakeCodec()
 | 
						cdc := app.MakeCodec()
 | 
				
			||||||
@ -439,7 +549,7 @@ func TestAuth_MakeAirdropMap(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestAuth_TestAllDepositorsIncluded(t *testing.T) {
 | 
					func TestAuth_TestAllDepositorsIncluded(t *testing.T) {
 | 
				
			||||||
	var deposits hard.Deposits
 | 
						var deposits v0_15hard.Deposits
 | 
				
			||||||
	cdc := app.MakeCodec()
 | 
						cdc := app.MakeCodec()
 | 
				
			||||||
	bz, err := ioutil.ReadFile("./data/hard-deposits-block-1543671.json")
 | 
						bz, err := ioutil.ReadFile("./data/hard-deposits-block-1543671.json")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user