mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 16:37:54 +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 ( | ||||
| 	"fmt" | ||||
| 	"sort" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	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_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14" | ||||
| 	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
 | ||||
| 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
 | ||||
| 	claimMultipliers := v0_15incentive.Multipliers{} | ||||
| 	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) | ||||
| 
 | ||||
| 	// Migrate Hard protocol claims (includes creating new Delegator claims)
 | ||||
| 	hardClaims := v0_15incentive.HardLiquidityProviderClaims{} | ||||
| 	delegatorClaims := v0_15incentive.DelegatorClaims{} | ||||
| 	for _, claim := range incentiveGS.HardLiquidityProviderClaims { | ||||
| 		// 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, delegatorClaims, err := migrateHardLiquidityProviderClaims(incentiveGS.HardLiquidityProviderClaims) | ||||
| 	if err != nil { | ||||
| 		panic(fmt.Sprintf("could not migrate hard claims: %v", err.Error())) | ||||
| 	} | ||||
| 	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
 | ||||
| 	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.
 | ||||
| // 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 { | ||||
| @ -277,3 +318,153 @@ func migrateRewardIndexes(oldIndexes v0_14incentive.RewardIndexes) v0_15incentiv | ||||
| 	} | ||||
| 	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" | ||||
| 
 | ||||
| 	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" | ||||
| 	v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14" | ||||
| 	v0_15incentive "github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| @ -15,6 +17,347 @@ import ( | ||||
| // It is an alias for 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) { | ||||
| 	claims := incentive.USDXMintingClaims{ | ||||
| 		incentive.NewUSDXMintingClaim( | ||||
|  | ||||
| @ -17,6 +17,7 @@ import ( | ||||
| 	v0_15cdp "github.com/kava-labs/kava/x/cdp/types" | ||||
| 	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14" | ||||
| 	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_15incentive "github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"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) | ||||
| 		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
 | ||||
| 		var cdpGenState v0_15cdp.GenesisState | ||||
| 		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
 | ||||
|  | ||||
| @ -21,7 +21,7 @@ import ( | ||||
| 	v0_15cdp "github.com/kava-labs/kava/x/cdp/types" | ||||
| 	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14" | ||||
| 	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_15incentive "github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"github.com/kava-labs/kava/x/swap" | ||||
| @ -80,14 +80,86 @@ func TestIncentive_Full(t *testing.T) { | ||||
| 	var oldIncentiveGenState v0_14incentive.GenesisState | ||||
| 	cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState) | ||||
| 
 | ||||
| 	var oldHardGenState v0_15hard.GenesisState | ||||
| 	cdc.MustUnmarshalJSON(oldState[v0_15hard.ModuleName], &oldHardGenState) | ||||
| 
 | ||||
| 	var oldCDPGenState v0_15cdp.GenesisState | ||||
| 	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()) | ||||
| 
 | ||||
| 	// 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
 | ||||
| 	globalIndexes := newGenState.USDXRewardState.MultiRewardIndexes | ||||
| 	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
 | ||||
| 	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) { | ||||
| 	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 | ||||
| 	cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState) | ||||
| 
 | ||||
| 	var oldHardGenState v0_15hard.GenesisState | ||||
| 	cdc.MustUnmarshalJSON(oldState[v0_15hard.ModuleName], &oldHardGenState) | ||||
| 
 | ||||
| 	var oldCDPGenState v0_15cdp.GenesisState | ||||
| 	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
 | ||||
| 	oldTotalRewards := sdk.NewCoins() // total synced unclaimed rewards
 | ||||
| @ -228,7 +333,7 @@ func TestIncentive_SwpLPRewards(t *testing.T) { | ||||
| 
 | ||||
| 	newGenState := v0_15incentive.GenesisState{} | ||||
| 	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() | ||||
| 	require.NoError(t, err) | ||||
| @ -264,7 +369,7 @@ func TestIncentive_SwpDelegatorRewards(t *testing.T) { | ||||
| 
 | ||||
| 	newGenState := v0_15incentive.GenesisState{} | ||||
| 	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 { | ||||
| @ -279,7 +384,12 @@ func TestIncentive_SwpDelegatorRewards(t *testing.T) { | ||||
| func TestIncentive_SwpPoolsValid(t *testing.T) { | ||||
| 	bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json")) | ||||
| 	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) | ||||
| 	cdc := app.MakeCodec() | ||||
| @ -439,7 +549,7 @@ func TestAuth_MakeAirdropMap(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestAuth_TestAllDepositorsIncluded(t *testing.T) { | ||||
| 	var deposits hard.Deposits | ||||
| 	var deposits v0_15hard.Deposits | ||||
| 	cdc := app.MakeCodec() | ||||
| 	bz, err := ioutil.ReadFile("./data/hard-deposits-block-1543671.json") | ||||
| 	if err != nil { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ruaridh
						Ruaridh