mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 18:27:26 +00:00 
			
		
		
		
	Add GetSynchronizedClaim and swap adapter (#1386)
* Add source adapters to keeper, implement GetSynchronizedClaim * Iterate acc shares sorted * Add swap adapter, update tests to use swap claimtype * Add swap adapter test * Add tests for non-empty pools * Iterate over source ids instead of sorted keys
This commit is contained in:
		
							parent
							
								
									c2061f626e
								
							
						
					
					
						commit
						f52a581ea9
					
				
							
								
								
									
										46
									
								
								x/incentive/keeper/adapters/swap/adapter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								x/incentive/keeper/adapters/swap/adapter.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| package swap | ||||
| 
 | ||||
| import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| var _ types.SourceAdapter = SourceAdapter{} | ||||
| 
 | ||||
| type SourceAdapter struct { | ||||
| 	keeper types.SwapKeeper | ||||
| } | ||||
| 
 | ||||
| func NewSourceAdapter(keeper types.SwapKeeper) SourceAdapter { | ||||
| 	return SourceAdapter{ | ||||
| 		keeper: keeper, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (f SourceAdapter) TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec { | ||||
| 	shares, found := f.keeper.GetPoolShares(ctx, sourceID) | ||||
| 	if !found { | ||||
| 		shares = sdk.ZeroInt() | ||||
| 	} | ||||
| 
 | ||||
| 	return shares.ToDec() | ||||
| } | ||||
| 
 | ||||
| func (f SourceAdapter) OwnerSharesBySource( | ||||
| 	ctx sdk.Context, | ||||
| 	owner sdk.AccAddress, | ||||
| 	sourceIDs []string, | ||||
| ) map[string]sdk.Dec { | ||||
| 	shares := make(map[string]sdk.Dec) | ||||
| 	for _, id := range sourceIDs { | ||||
| 		s, found := f.keeper.GetDepositorSharesAmount(ctx, owner, id) | ||||
| 		if !found { | ||||
| 			s = sdk.ZeroInt() | ||||
| 		} | ||||
| 
 | ||||
| 		shares[id] = s.ToDec() | ||||
| 	} | ||||
| 
 | ||||
| 	return shares | ||||
| } | ||||
							
								
								
									
										283
									
								
								x/incentive/keeper/adapters/swap/adapter_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								x/incentive/keeper/adapters/swap/adapter_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,283 @@ | ||||
| package swap_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters/swap" | ||||
| 	swaptypes "github.com/kava-labs/kava/x/swap/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| type SwapAdapterTestSuite struct { | ||||
| 	suite.Suite | ||||
| 
 | ||||
| 	app app.TestApp | ||||
| 	ctx sdk.Context | ||||
| 
 | ||||
| 	genesisTime time.Time | ||||
| 	addrs       []sdk.AccAddress | ||||
| } | ||||
| 
 | ||||
| func TestSwapAdapterTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(SwapAdapterTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *SwapAdapterTestSuite) SetupTest() { | ||||
| 	config := sdk.GetConfig() | ||||
| 	app.SetBech32AddressPrefixes(config) | ||||
| 
 | ||||
| 	_, suite.addrs = app.GeneratePrivKeyAddressPairs(5) | ||||
| 
 | ||||
| 	suite.genesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC) | ||||
| 	suite.app = app.NewTestApp() | ||||
| 
 | ||||
| 	suite.ctx = suite.app.NewContext(true, tmprototypes.Header{Time: suite.genesisTime}) | ||||
| } | ||||
| 
 | ||||
| func (suite *SwapAdapterTestSuite) TestSwapAdapter_OwnerSharesBySource_Empty() { | ||||
| 	adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper()) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name          string | ||||
| 		giveOwner     sdk.AccAddress | ||||
| 		giveSourceIDs []string | ||||
| 		wantShares    map[string]sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"empty requests", | ||||
| 			suite.addrs[0], | ||||
| 			[]string{}, | ||||
| 			map[string]sdk.Dec{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"empty pools are zero", | ||||
| 			suite.addrs[0], | ||||
| 			[]string{ | ||||
| 				"pool1", | ||||
| 				"pool2", | ||||
| 				"pool3", | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				"pool1": sdk.ZeroDec(), | ||||
| 				"pool2": sdk.ZeroDec(), | ||||
| 				"pool3": sdk.ZeroDec(), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		suite.Run(tt.name, func() { | ||||
| 			shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs) | ||||
| 
 | ||||
| 			suite.Equal(tt.wantShares, shares) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *SwapAdapterTestSuite) TestSwapAdapter_OwnerSharesBySource() { | ||||
| 	poolDenomA := "ukava" | ||||
| 	poolDenomB := "usdx" | ||||
| 
 | ||||
| 	swapKeeper := suite.app.GetSwapKeeper() | ||||
| 	swapKeeper.SetParams(suite.ctx, swaptypes.NewParams( | ||||
| 		swaptypes.NewAllowedPools( | ||||
| 			swaptypes.NewAllowedPool(poolDenomA, poolDenomB), | ||||
| 		), | ||||
| 		sdk.ZeroDec(), | ||||
| 	)) | ||||
| 
 | ||||
| 	suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 	suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	err := swapKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoin(poolDenomA, sdk.NewInt(100)), | ||||
| 		sdk.NewCoin(poolDenomB, sdk.NewInt(100)), | ||||
| 		sdk.NewDecWithPrec(1, 1), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = swapKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoin(poolDenomA, sdk.NewInt(250)), | ||||
| 		sdk.NewCoin(poolDenomB, sdk.NewInt(250)), | ||||
| 		sdk.NewDecWithPrec(1, 0), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper()) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name          string | ||||
| 		giveOwner     sdk.AccAddress | ||||
| 		giveSourceIDs []string | ||||
| 		wantShares    map[string]sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"depositor has shares", | ||||
| 			suite.addrs[0], | ||||
| 			[]string{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB), | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB): sdk.NewDecWithPrec(100, 0), | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"depositor has shares - including empty deposits", | ||||
| 			suite.addrs[1], | ||||
| 			[]string{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB), | ||||
| 				"pool2", | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB): sdk.NewDecWithPrec(250, 0), | ||||
| 				"pool2":                                  sdk.ZeroDec(), | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"non-depositor has zero shares", | ||||
| 			suite.addrs[2], | ||||
| 			[]string{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB), | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				swaptypes.PoolID(poolDenomA, poolDenomB): sdk.ZeroDec(), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		suite.Run(tt.name, func() { | ||||
| 			shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs) | ||||
| 
 | ||||
| 			suite.Equal(tt.wantShares, shares) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *SwapAdapterTestSuite) TestSwapAdapter_TotalSharesBySource_Empty() { | ||||
| 	adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper()) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name         string | ||||
| 		giveSourceID string | ||||
| 		wantShares   sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"empty/invalid pools are zero", | ||||
| 			"pool1", | ||||
| 			sdk.ZeroDec(), | ||||
| 		}, | ||||
| 		{ | ||||
| 			"invalid request returns zero", | ||||
| 			"", | ||||
| 			sdk.ZeroDec(), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		suite.Run(tt.name, func() { | ||||
| 			shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID) | ||||
| 
 | ||||
| 			suite.Equal(tt.wantShares, shares) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *SwapAdapterTestSuite) TestSwapAdapter_TotalSharesBySource() { | ||||
| 	poolDenomA := "ukava" | ||||
| 	poolDenomB := "usdx" | ||||
| 
 | ||||
| 	swapKeeper := suite.app.GetSwapKeeper() | ||||
| 	swapKeeper.SetParams(suite.ctx, swaptypes.NewParams( | ||||
| 		swaptypes.NewAllowedPools( | ||||
| 			swaptypes.NewAllowedPool(poolDenomA, poolDenomB), | ||||
| 		), | ||||
| 		sdk.ZeroDec(), | ||||
| 	)) | ||||
| 
 | ||||
| 	suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 	suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	err := swapKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoin(poolDenomA, sdk.NewInt(100)), | ||||
| 		sdk.NewCoin(poolDenomB, sdk.NewInt(100)), | ||||
| 		sdk.NewDecWithPrec(1, 1), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = swapKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoin(poolDenomA, sdk.NewInt(250)), | ||||
| 		sdk.NewCoin(poolDenomB, sdk.NewInt(250)), | ||||
| 		sdk.NewDecWithPrec(1, 0), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper()) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name         string | ||||
| 		giveSourceID string | ||||
| 		wantShares   sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"total shares", | ||||
| 			swaptypes.PoolID(poolDenomA, poolDenomB), | ||||
| 			sdk.NewDecWithPrec(350, 0), | ||||
| 		}, | ||||
| 		{ | ||||
| 			"empty or invalid pool empty", | ||||
| 			"pool2", | ||||
| 			sdk.ZeroDec(), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		suite.Run(tt.name, func() { | ||||
| 			shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID) | ||||
| 
 | ||||
| 			suite.Equal(tt.wantShares, shares) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -1,12 +1,14 @@ | ||||
| package keeper | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters/swap" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| @ -25,6 +27,8 @@ type Keeper struct { | ||||
| 	liquidKeeper  types.LiquidKeeper | ||||
| 	earnKeeper    types.EarnKeeper | ||||
| 
 | ||||
| 	adapters map[types.ClaimType]types.SourceAdapter | ||||
| 
 | ||||
| 	// Keepers used for APY queries
 | ||||
| 	mintKeeper      types.MintKeeper | ||||
| 	distrKeeper     types.DistrKeeper | ||||
| @ -43,18 +47,23 @@ func NewKeeper( | ||||
| 	} | ||||
| 
 | ||||
| 	return Keeper{ | ||||
| 		accountKeeper:   ak, | ||||
| 		cdc:             cdc, | ||||
| 		key:             key, | ||||
| 		paramSubspace:   paramstore, | ||||
| 		bankKeeper:      bk, | ||||
| 		cdpKeeper:       cdpk, | ||||
| 		hardKeeper:      hk, | ||||
| 		stakingKeeper:   stk, | ||||
| 		swapKeeper:      swpk, | ||||
| 		savingsKeeper:   svk, | ||||
| 		liquidKeeper:    lqk, | ||||
| 		earnKeeper:      ek, | ||||
| 		accountKeeper: ak, | ||||
| 		cdc:           cdc, | ||||
| 		key:           key, | ||||
| 		paramSubspace: paramstore, | ||||
| 		bankKeeper:    bk, | ||||
| 		cdpKeeper:     cdpk, | ||||
| 		hardKeeper:    hk, | ||||
| 		stakingKeeper: stk, | ||||
| 		swapKeeper:    swpk, | ||||
| 		savingsKeeper: svk, | ||||
| 		liquidKeeper:  lqk, | ||||
| 		earnKeeper:    ek, | ||||
| 
 | ||||
| 		adapters: map[types.ClaimType]types.SourceAdapter{ | ||||
| 			types.CLAIM_TYPE_SWAP: swap.NewSourceAdapter(swpk), | ||||
| 		}, | ||||
| 
 | ||||
| 		mintKeeper:      mk, | ||||
| 		distrKeeper:     dk, | ||||
| 		pricefeedKeeper: pfk, | ||||
| @ -885,6 +894,15 @@ func (k Keeper) IterateEarnRewardAccrualTimes(ctx sdk.Context, cb func(string, t | ||||
| // -----------------------------------------------------------------------------
 | ||||
| // New deduplicated methods
 | ||||
| 
 | ||||
| func (k Keeper) GetSourceAdapter(claimType types.ClaimType) types.SourceAdapter { | ||||
| 	fetcher, found := k.adapters[claimType] | ||||
| 	if !found { | ||||
| 		panic(fmt.Sprintf("no source share fetcher for claim type %s", claimType)) | ||||
| 	} | ||||
| 
 | ||||
| 	return fetcher | ||||
| } | ||||
| 
 | ||||
| // GetClaim returns the claim in the store corresponding the the owner and
 | ||||
| // claimType, and a boolean for if the claim was found
 | ||||
| func (k Keeper) GetClaim( | ||||
|  | ||||
| @ -36,7 +36,7 @@ func (k Keeper) SynchronizeClaim( | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| 	owner sdk.AccAddress, | ||||
| 	shares sdk.Int, | ||||
| 	shares sdk.Dec, | ||||
| ) { | ||||
| 	claim, found := k.GetClaim(ctx, claimType, owner) | ||||
| 	if !found { | ||||
| @ -53,7 +53,7 @@ func (k *Keeper) synchronizeClaim( | ||||
| 	claim types.Claim, | ||||
| 	sourceID string, | ||||
| 	owner sdk.AccAddress, | ||||
| 	shares sdk.Int, | ||||
| 	shares sdk.Dec, | ||||
| ) types.Claim { | ||||
| 	globalRewardIndexes, found := k.GetRewardIndexesOfClaimType(ctx, claim.Type, sourceID) | ||||
| 	if !found { | ||||
| @ -74,7 +74,7 @@ func (k *Keeper) synchronizeClaim( | ||||
| 		userRewardIndexes = types.RewardIndexes{} | ||||
| 	} | ||||
| 
 | ||||
| 	newRewards, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, shares.ToDec()) | ||||
| 	newRewards, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, shares) | ||||
| 	if err != nil { | ||||
| 		// Global reward factors should never decrease, as it would lead to a negative update to claim.Rewards.
 | ||||
| 		// This panics if a global reward factor decreases or disappears between the old and new indexes.
 | ||||
| @ -86,3 +86,33 @@ func (k *Keeper) synchronizeClaim( | ||||
| 
 | ||||
| 	return claim | ||||
| } | ||||
| 
 | ||||
| // GetSynchronizedClaim fetches a claim from the store and syncs rewards for all
 | ||||
| // rewarded sourceIDs.
 | ||||
| func (k Keeper) GetSynchronizedClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	owner sdk.AccAddress, | ||||
| ) (types.Claim, bool) { | ||||
| 	claim, found := k.GetClaim(ctx, claimType, owner) | ||||
| 	if !found { | ||||
| 		return types.Claim{}, false | ||||
| 	} | ||||
| 
 | ||||
| 	// Fetch all source IDs from indexes
 | ||||
| 	var sourceIDs []string | ||||
| 	k.IterateRewardIndexesByClaimType(ctx, claimType, func(rewardIndexes types.TypedRewardIndexes) bool { | ||||
| 		sourceIDs = append(sourceIDs, rewardIndexes.CollateralType) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	adapter := k.GetSourceAdapter(claimType) | ||||
| 	accShares := adapter.OwnerSharesBySource(ctx, owner, sourceIDs) | ||||
| 
 | ||||
| 	// Synchronize claim for each source ID
 | ||||
| 	for _, sourceID := range sourceIDs { | ||||
| 		claim = k.synchronizeClaim(ctx, claim, sourceID, owner, accShares[sourceID]) | ||||
| 	} | ||||
| 
 | ||||
| 	return claim, true | ||||
| } | ||||
|  | ||||
| @ -68,7 +68,7 @@ func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesHaveIncreas | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes updated from global
 | ||||
| @ -110,7 +110,7 @@ func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenGlobalIndexesUnchanged | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// claim should have the same rewards and indexes as before
 | ||||
| @ -169,7 +169,7 @@ func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardAdded() { | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, newlyRewardcollateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, newlyRewardcollateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// the new indexes should be added to the claim, but the old ones should be unchanged
 | ||||
| @ -203,7 +203,7 @@ func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenNoReward() { | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	suite.Equal(claim, syncedClaim) | ||||
| @ -256,7 +256,7 @@ func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardDenomAdded() { | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes should have the new reward denom added
 | ||||
| @ -310,7 +310,7 @@ func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesIncreasedAn | ||||
| 
 | ||||
| 	userShares := i(0) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares) | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes updated from global
 | ||||
| @ -318,3 +318,155 @@ func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesIncreasedAn | ||||
| 	// reward is unchanged
 | ||||
| 	suite.Equal(claim.Reward, syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUnchangedWhenNoGlobalIndexes() { | ||||
| 	collateralType_1 := "btcb:usdx" | ||||
| 	owner := arbitraryAddress() | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper(). | ||||
| 		addDeposit(collateralType_1, owner, i(1e9)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  owner, | ||||
| 		Reward: nil, | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType_1, | ||||
| 				RewardIndexes:  nil, // this state only happens because Init stores empty indexes
 | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	// no global indexes for any pool
 | ||||
| 
 | ||||
| 	syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	suite.True(f) | ||||
| 
 | ||||
| 	// indexes are unchanged
 | ||||
| 	suite.Equal(claim.RewardIndexes, syncedClaim.RewardIndexes) | ||||
| 	// reward is unchanged
 | ||||
| 	suite.Equal(claim.Reward, syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexAndHasNoSourceShares() { | ||||
| 	collateralType_1 := "btcb:usdx" | ||||
| 	collateralType_2 := "ukava:usdx" | ||||
| 	owner := arbitraryAddress() | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 
 | ||||
| 	// owner has no shares in any pool
 | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, newFakeSwapKeeper(), nil, nil, nil) | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  owner, | ||||
| 		Reward: arbitraryCoins(), | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType_1, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "rewarddenom1", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType_1, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom1", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: collateralType_2, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom2", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	suite.True(f) | ||||
| 
 | ||||
| 	// indexes updated from global
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// reward is unchanged
 | ||||
| 	suite.Equal(claim.Reward, syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexButHasSourceShares() { | ||||
| 	collateralType_1 := "btcb:usdx" | ||||
| 	collateralType_2 := "ukava:usdx" | ||||
| 	owner := arbitraryAddress() | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper(). | ||||
| 		addDeposit(collateralType_1, owner, i(1e9)). | ||||
| 		addDeposit(collateralType_2, owner, i(1e9)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  owner, | ||||
| 		Reward: arbitraryCoins(), | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType_1, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "rewarddenom1", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType_1, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom1", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: collateralType_2, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom2", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	suite.True(f) | ||||
| 
 | ||||
| 	// indexes updated from global
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// reward is incremented
 | ||||
| 	expectedReward := cs(c("rewarddenom1", 1_000_001_000_000), c("rewarddenom2", 2_000_002_000_000)) | ||||
| 	suite.Equal(claim.Reward.Add(expectedReward...), syncedClaim.Reward) | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Derrick Lee
						Derrick Lee