mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-04-04 15:55:23 +00:00 
			
		
		
		
	Revert incentive refactor commits (#1433)
* Revert "Add incentive migrations for earn rewards (#1406)" This reverts commit937e5f339f. * Revert "Use different accumulator for earn (#1395)" This reverts commitcf009647e6. * Revert "Add base earn incentive accumulator (#1393)" This reverts commit44a90a8ef9. * Revert "Add generic incentive `AccumulateRewards` method (#1392)" This reverts commitdce631d3de. * Revert "Add GetSynchronizedClaim and swap adapter (#1386)" This reverts commitf52a581ea9. * Revert "Add Initialize/Synchronize Claim methods (#1383)" This reverts commitc2061f626e. * Revert "Add source adapter interface definition (#1377)" This reverts commit2abb2ce606. * Revert "Add incentive RewardIndexes types and state methods (#1381)" This reverts commit4a3002b09c. * Revert "Add AccrualTime type and state methods (#1379)" This reverts commitdf1c2ffc34. * Revert "Add incentive claim state methods (#1375)" This reverts commit90735e29ed. * Revert "Add generic Claim type (#1371)" This reverts commit45fc1a7643. * Regerate protos and minor revert fixes
This commit is contained in:
		
							parent
							
								
									e4b4a7c62e
								
							
						
					
					
						commit
						4b8e224f6a
					
				| @ -59,16 +59,13 @@ var ( | ||||
| // TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
 | ||||
| // This file also contains test helpers. Ideally they would be in separate package.
 | ||||
| // Basic Usage:
 | ||||
| //
 | ||||
| // 	Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
 | ||||
| //
 | ||||
| // Advanced Usage:
 | ||||
| //
 | ||||
| // 	Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
 | ||||
| // 	However this leads to a lot of duplicated logic similar to InitGenesis methods.
 | ||||
| // 	So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
 | ||||
| //	and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
 | ||||
| //	Creating the genesis states can be cumbersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
 | ||||
| // 	Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
 | ||||
| type TestApp struct { | ||||
| 	App | ||||
| } | ||||
| @ -122,10 +119,6 @@ func (tApp TestApp) GetRouterKeeper() routerkeeper.Keeper       { return tApp.ro | ||||
| func (tApp TestApp) GetKavamintKeeper() kavamintkeeper.Keeper   { return tApp.kavamintKeeper } | ||||
| func (tApp TestApp) GetCommunityKeeper() communitykeeper.Keeper { return tApp.communityKeeper } | ||||
| 
 | ||||
| func (tApp TestApp) GetKeys() map[string]*sdk.KVStoreKey { | ||||
| 	return tApp.keys | ||||
| } | ||||
| 
 | ||||
| // LegacyAmino returns the app's amino codec.
 | ||||
| func (app *App) LegacyAmino() *codec.LegacyAmino { | ||||
| 	return app.legacyAmino | ||||
|  | ||||
| @ -327,7 +327,6 @@ | ||||
| - [kava/incentive/v1beta1/claims.proto](#kava/incentive/v1beta1/claims.proto) | ||||
|     - [BaseClaim](#kava.incentive.v1beta1.BaseClaim) | ||||
|     - [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim) | ||||
|     - [Claim](#kava.incentive.v1beta1.Claim) | ||||
|     - [DelegatorClaim](#kava.incentive.v1beta1.DelegatorClaim) | ||||
|     - [EarnClaim](#kava.incentive.v1beta1.EarnClaim) | ||||
|     - [HardLiquidityProviderClaim](#kava.incentive.v1beta1.HardLiquidityProviderClaim) | ||||
| @ -337,21 +336,16 @@ | ||||
|     - [RewardIndexesProto](#kava.incentive.v1beta1.RewardIndexesProto) | ||||
|     - [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim) | ||||
|     - [SwapClaim](#kava.incentive.v1beta1.SwapClaim) | ||||
|     - [TypedRewardIndexes](#kava.incentive.v1beta1.TypedRewardIndexes) | ||||
|     - [USDXMintingClaim](#kava.incentive.v1beta1.USDXMintingClaim) | ||||
|    | ||||
|     - [ClaimType](#kava.incentive.v1beta1.ClaimType) | ||||
|    | ||||
| - [kava/incentive/v1beta1/params.proto](#kava/incentive/v1beta1/params.proto) | ||||
|     - [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | ||||
|     - [Multiplier](#kava.incentive.v1beta1.Multiplier) | ||||
|     - [MultipliersPerDenom](#kava.incentive.v1beta1.MultipliersPerDenom) | ||||
|     - [Params](#kava.incentive.v1beta1.Params) | ||||
|     - [RewardPeriod](#kava.incentive.v1beta1.RewardPeriod) | ||||
|     - [TypedMultiRewardPeriod](#kava.incentive.v1beta1.TypedMultiRewardPeriod) | ||||
|    | ||||
| - [kava/incentive/v1beta1/genesis.proto](#kava/incentive/v1beta1/genesis.proto) | ||||
|     - [AccrualTime](#kava.incentive.v1beta1.AccrualTime) | ||||
|     - [AccumulationTime](#kava.incentive.v1beta1.AccumulationTime) | ||||
|     - [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | ||||
|     - [GenesisState](#kava.incentive.v1beta1.GenesisState) | ||||
| @ -4705,24 +4699,6 @@ BaseMultiClaim is a claim with multiple reward coin types | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.Claim"></a> | ||||
| 
 | ||||
| ### Claim | ||||
| Claim stores any generic rewards that can be claimed by owner | ||||
| 
 | ||||
| 
 | ||||
| | Field | Type | Label | Description | | ||||
| | ----- | ---- | ----- | ----------- | | ||||
| | `type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) |  |  | | ||||
| | `owner` | [bytes](#bytes) |  |  | | ||||
| | `reward` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated |  | | ||||
| | `reward_indexes` | [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex) | repeated |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.DelegatorClaim"></a> | ||||
| 
 | ||||
| ### DelegatorClaim | ||||
| @ -4866,24 +4842,6 @@ SwapClaim stores the swap rewards that can be claimed by owner | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.TypedRewardIndexes"></a> | ||||
| 
 | ||||
| ### TypedRewardIndexes | ||||
| TypedRewardIndexes defines a RewardIndexes slice with its corresponding | ||||
| claim and collateral type | ||||
| 
 | ||||
| 
 | ||||
| | Field | Type | Label | Description | | ||||
| | ----- | ---- | ----- | ----------- | | ||||
| | `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) |  |  | | ||||
| | `collateral_type` | [string](#string) |  |  | | ||||
| | `reward_indexes` | [RewardIndex](#kava.incentive.v1beta1.RewardIndex) | repeated |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.USDXMintingClaim"></a> | ||||
| 
 | ||||
| ### USDXMintingClaim | ||||
| @ -4901,24 +4859,6 @@ USDXMintingClaim is for USDX minting rewards | ||||
| 
 | ||||
|  <!-- end messages --> | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.ClaimType"></a> | ||||
| 
 | ||||
| ### ClaimType | ||||
| ClaimType is the type of claim | ||||
| 
 | ||||
| | Name | Number | Description | | ||||
| | ---- | ------ | ----------- | | ||||
| | CLAIM_TYPE_UNSPECIFIED | 0 | indicates an invalid claim type | | ||||
| | CLAIM_TYPE_HARD_BORROW | 1 | claim type for hard borrow rewards | | ||||
| | CLAIM_TYPE_HARD_SUPPLY | 2 | claim type for hard supply rewards | | ||||
| | CLAIM_TYPE_DELEGATOR | 3 | claim type for delegator rewards | | ||||
| | CLAIM_TYPE_EARN | 4 | claim type for earn rewards | | ||||
| | CLAIM_TYPE_SAVINGS | 5 | claim type for savings rewards | | ||||
| | CLAIM_TYPE_SWAP | 6 | claim type for swap rewards | | ||||
| | CLAIM_TYPE_USDX_MINTING | 7 | claim type for usdx minting rewards | | ||||
| 
 | ||||
| 
 | ||||
|  <!-- end enums --> | ||||
| 
 | ||||
|  <!-- end HasExtensions --> | ||||
| @ -4956,8 +4896,7 @@ MultiRewardPeriod supports multiple reward types | ||||
| <a name="kava.incentive.v1beta1.Multiplier"></a> | ||||
| 
 | ||||
| ### Multiplier | ||||
| Multiplier amount the claim rewards get increased by, along with how long the | ||||
| claim rewards are locked | ||||
| Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked | ||||
| 
 | ||||
| 
 | ||||
| | Field | Type | Label | Description | | ||||
| @ -5004,7 +4943,6 @@ Params | ||||
| | `claim_end` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) |  |  | | ||||
| | `savings_reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated |  | | ||||
| | `earn_reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated |  | | ||||
| | `reward_periods` | [TypedMultiRewardPeriod](#kava.incentive.v1beta1.TypedMultiRewardPeriod) | repeated |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -5029,22 +4967,6 @@ RewardPeriod stores the state of an ongoing reward | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.TypedMultiRewardPeriod"></a> | ||||
| 
 | ||||
| ### TypedMultiRewardPeriod | ||||
| TypedMultiRewardPeriod stores mutiple reward types of a claim type | ||||
| 
 | ||||
| 
 | ||||
| | Field | Type | Label | Description | | ||||
| | ----- | ---- | ----- | ----------- | | ||||
| | `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) |  |  | | ||||
| | `reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  <!-- end messages --> | ||||
| 
 | ||||
|  <!-- end enums --> | ||||
| @ -5062,25 +4984,6 @@ TypedMultiRewardPeriod stores mutiple reward types of a claim type | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.AccrualTime"></a> | ||||
| 
 | ||||
| ### AccrualTime | ||||
| AccrualTime stores the previous reward distribution time and its | ||||
| corresponding collateral type and claim type. This is the new version of | ||||
| AccumulationTime that is used for the new claim types. | ||||
| 
 | ||||
| 
 | ||||
| | Field | Type | Label | Description | | ||||
| | ----- | ---- | ----- | ----------- | | ||||
| | `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) |  |  | | ||||
| | `collateral_type` | [string](#string) |  |  | | ||||
| | `previous_accumulation_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) |  |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <a name="kava.incentive.v1beta1.AccumulationTime"></a> | ||||
| 
 | ||||
| ### AccumulationTime | ||||
| @ -5135,9 +5038,6 @@ GenesisState is the state that must be provided at genesis. | ||||
| | `savings_claims` | [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim) | repeated |  | | ||||
| | `earn_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) |  |  | | ||||
| | `earn_claims` | [EarnClaim](#kava.incentive.v1beta1.EarnClaim) | repeated |  | | ||||
| | `claims` | [Claim](#kava.incentive.v1beta1.Claim) | repeated |  | | ||||
| | `accrual_times` | [AccrualTime](#kava.incentive.v1beta1.AccrualTime) | repeated |  | | ||||
| | `reward_indexes` | [TypedRewardIndexes](#kava.incentive.v1beta1.TypedRewardIndexes) | repeated |  | | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -12,6 +12,8 @@ option (gogoproto.goproto_getters_all) = false; | ||||
| 
 | ||||
| // BaseClaim is a claim with a single reward coin types | ||||
| message BaseClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   bytes owner = 1 [ | ||||
|     (cosmos_proto.scalar) = "cosmos.AddressBytes", | ||||
|     (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" | ||||
| @ -22,6 +24,8 @@ message BaseClaim { | ||||
| 
 | ||||
| // BaseMultiClaim is a claim with multiple reward coin types | ||||
| message BaseMultiClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   bytes owner = 1 [ | ||||
|     (cosmos_proto.scalar) = "cosmos.AddressBytes", | ||||
|     (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" | ||||
| @ -51,17 +55,6 @@ message RewardIndexesProto { | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // TypedRewardIndexes defines a RewardIndexes slice with its corresponding | ||||
| // claim and collateral type | ||||
| message TypedRewardIndexes { | ||||
|   ClaimType claim_type = 1; | ||||
|   string collateral_type = 2; | ||||
|   repeated RewardIndex reward_indexes = 3 [ | ||||
|     (gogoproto.castrepeated) = "RewardIndexes", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // MultiRewardIndex stores reward accumulation information on multiple reward types | ||||
| message MultiRewardIndex { | ||||
|   string collateral_type = 1; | ||||
| @ -84,6 +77,8 @@ message MultiRewardIndexesProto { | ||||
| 
 | ||||
| // USDXMintingClaim is for USDX minting rewards | ||||
| message USDXMintingClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -97,6 +92,8 @@ message USDXMintingClaim { | ||||
| 
 | ||||
| // HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner | ||||
| message HardLiquidityProviderClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseMultiClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -115,6 +112,8 @@ message HardLiquidityProviderClaim { | ||||
| 
 | ||||
| // DelegatorClaim stores delegation rewards that can be claimed by owner | ||||
| message DelegatorClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseMultiClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -128,6 +127,8 @@ message DelegatorClaim { | ||||
| 
 | ||||
| // SwapClaim stores the swap rewards that can be claimed by owner | ||||
| message SwapClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseMultiClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -141,6 +142,8 @@ message SwapClaim { | ||||
| 
 | ||||
| // SavingsClaim stores the savings rewards that can be claimed by owner | ||||
| message SavingsClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseMultiClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -154,6 +157,8 @@ message SavingsClaim { | ||||
| 
 | ||||
| // EarnClaim stores the earn rewards that can be claimed by owner | ||||
| message EarnClaim { | ||||
|   option (cosmos_proto.implements_interface) = "Claim"; | ||||
| 
 | ||||
|   BaseMultiClaim base_claim = 1 [ | ||||
|     (gogoproto.embed) = true, | ||||
|     (gogoproto.nullable) = false | ||||
| @ -164,45 +169,3 @@ message EarnClaim { | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // ClaimType is the type of claim | ||||
| enum ClaimType { | ||||
|   option (gogoproto.goproto_enum_prefix) = false; | ||||
| 
 | ||||
|   // indicates an invalid claim type | ||||
|   CLAIM_TYPE_UNSPECIFIED = 0; | ||||
|   // claim type for hard borrow rewards | ||||
|   CLAIM_TYPE_HARD_BORROW = 1; | ||||
|   // claim type for hard supply rewards | ||||
|   CLAIM_TYPE_HARD_SUPPLY = 2; | ||||
|   // claim type for delegator rewards | ||||
|   CLAIM_TYPE_DELEGATOR = 3; | ||||
|   // claim type for earn rewards | ||||
|   CLAIM_TYPE_EARN = 4; | ||||
|   // claim type for savings rewards | ||||
|   CLAIM_TYPE_SAVINGS = 5; | ||||
|   // claim type for swap rewards | ||||
|   CLAIM_TYPE_SWAP = 6; | ||||
|   // claim type for usdx minting rewards | ||||
|   CLAIM_TYPE_USDX_MINTING = 7; | ||||
| } | ||||
| 
 | ||||
| // Claim stores any generic rewards that can be claimed by owner | ||||
| message Claim { | ||||
|   ClaimType type = 1; | ||||
| 
 | ||||
|   bytes owner = 2 [ | ||||
|     (cosmos_proto.scalar) = "cosmos.AddressBytes", | ||||
|     (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" | ||||
|   ]; | ||||
| 
 | ||||
|   repeated cosmos.base.v1beta1.Coin reward = 3 [ | ||||
|     (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| 
 | ||||
|   repeated MultiRewardIndex reward_indexes = 4 [ | ||||
|     (gogoproto.castrepeated) = "MultiRewardIndexes", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
|  | ||||
| @ -14,8 +14,6 @@ option (gogoproto.goproto_getters_all) = false; | ||||
| 
 | ||||
| // AccumulationTime stores the previous reward distribution time and its corresponding collateral type | ||||
| message AccumulationTime { | ||||
|   option deprecated = true; | ||||
| 
 | ||||
|   string collateral_type = 1; | ||||
| 
 | ||||
|   google.protobuf.Timestamp previous_accumulation_time = 2 [ | ||||
| @ -24,18 +22,6 @@ message AccumulationTime { | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // AccrualTime stores the previous reward distribution time and its | ||||
| // corresponding collateral type and claim type. This is the new version of | ||||
| // AccumulationTime that is used for the new claim types. | ||||
| message AccrualTime { | ||||
|   ClaimType claim_type = 1; | ||||
|   string collateral_type = 2; | ||||
|   google.protobuf.Timestamp previous_accumulation_time = 3 [ | ||||
|     (gogoproto.nullable) = false, | ||||
|     (gogoproto.stdtime) = true | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // GenesisRewardState groups together the global state for a particular reward so it can be exported in genesis. | ||||
| message GenesisRewardState { | ||||
|   repeated AccumulationTime accumulation_times = 1 [ | ||||
| @ -100,19 +86,4 @@ message GenesisState { | ||||
|     (gogoproto.castrepeated) = "EarnClaims", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| 
 | ||||
|   repeated Claim claims = 15 [ | ||||
|     (gogoproto.castrepeated) = "Claims", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| 
 | ||||
|   repeated AccrualTime accrual_times = 16 [ | ||||
|     (gogoproto.castrepeated) = "AccrualTimes", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| 
 | ||||
|   repeated TypedRewardIndexes reward_indexes = 17 [ | ||||
|     (gogoproto.castrepeated) = "TypedRewardIndexesList", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,6 @@ package kava.incentive.v1beta1; | ||||
| import "cosmos/base/v1beta1/coin.proto"; | ||||
| import "gogoproto/gogo.proto"; | ||||
| import "google/protobuf/timestamp.proto"; | ||||
| import "kava/incentive/v1beta1/claims.proto"; | ||||
| 
 | ||||
| option go_package = "github.com/kava-labs/kava/x/incentive/types"; | ||||
| option (gogoproto.goproto_getters_all) = false; | ||||
| @ -50,17 +49,7 @@ message MultiRewardPeriod { | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // TypedMultiRewardPeriod stores mutiple reward types of a claim type | ||||
| message TypedMultiRewardPeriod { | ||||
|   ClaimType claim_type = 1; | ||||
|   repeated MultiRewardPeriod reward_periods = 2 [ | ||||
|     (gogoproto.castrepeated) = "MultiRewardPeriods", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| // Multiplier amount the claim rewards get increased by, along with how long the | ||||
| // claim rewards are locked | ||||
| // Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked | ||||
| message Multiplier { | ||||
|   string name = 1; | ||||
| 
 | ||||
| @ -129,9 +118,4 @@ message Params { | ||||
|     (gogoproto.castrepeated) = "MultiRewardPeriods", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| 
 | ||||
|   repeated TypedMultiRewardPeriod reward_periods = 10 [ | ||||
|     (gogoproto.castrepeated) = "TypedMultiRewardPeriods", | ||||
|     (gogoproto.nullable) = false | ||||
|   ]; | ||||
| } | ||||
|  | ||||
| @ -35,13 +35,4 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { | ||||
| 			panic(fmt.Sprintf("failed to accumulate earn rewards: %s", err)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// New generic RewardPeriods
 | ||||
| 	for _, mrp := range params.RewardPeriods { | ||||
| 		for _, rp := range mrp.RewardPeriods { | ||||
| 			if err := k.AccumulateRewards(ctx, mrp.ClaimType, rp); err != nil { | ||||
| 				panic(fmt.Errorf("failed to accumulate rewards for claim type %s: %w", mrp.ClaimType, err)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -44,28 +44,6 @@ func InitGenesis( | ||||
| 
 | ||||
| 	k.SetParams(ctx, gs.Params) | ||||
| 
 | ||||
| 	// Set Claims of all types
 | ||||
| 	for _, claim := range gs.Claims { | ||||
| 		k.Store.SetClaim(ctx, claim) | ||||
| 	} | ||||
| 
 | ||||
| 	// Set AccrualTimes of all types
 | ||||
| 	for _, accrualTime := range gs.AccrualTimes { | ||||
| 		k.Store.SetRewardAccrualTime( | ||||
| 			ctx, | ||||
| 			accrualTime.ClaimType, | ||||
| 			accrualTime.CollateralType, | ||||
| 			accrualTime.PreviousAccumulationTime, | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	// Set RewardIndexes of all types
 | ||||
| 	for _, rewardIndex := range gs.RewardIndexes { | ||||
| 		k.Store.SetRewardIndexes(ctx, rewardIndex.ClaimType, rewardIndex.CollateralType, rewardIndex.RewardIndexes) | ||||
| 	} | ||||
| 
 | ||||
| 	// Legacy claims and indexes below
 | ||||
| 
 | ||||
| 	// USDX Minting
 | ||||
| 	for _, claim := range gs.USDXMintingClaims { | ||||
| 		k.SetUSDXMintingClaim(ctx, claim) | ||||
| @ -168,10 +146,6 @@ func InitGenesis( | ||||
| func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { | ||||
| 	params := k.GetParams(ctx) | ||||
| 
 | ||||
| 	claims := k.Store.GetAllClaims(ctx) | ||||
| 	accrualTimes := k.Store.GetAllRewardAccrualTimes(ctx) | ||||
| 	rewardIndexes := k.Store.GetRewardIndexes(ctx) | ||||
| 
 | ||||
| 	usdxClaims := k.GetAllUSDXMintingClaims(ctx) | ||||
| 	usdxRewardState := getUSDXMintingGenesisRewardState(ctx, k) | ||||
| 
 | ||||
| @ -196,9 +170,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { | ||||
| 		// Reward states
 | ||||
| 		usdxRewardState, hardSupplyRewardState, hardBorrowRewardState, delegatorRewardState, swapRewardState, savingsRewardState, earnRewardState, | ||||
| 		// Claims
 | ||||
| 		claims, usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, earnClaims, | ||||
| 		accrualTimes, | ||||
| 		rewardIndexes, | ||||
| 		usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, earnClaims, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -94,7 +94,6 @@ func (suite *GenesisTestSuite) SetupTest() { | ||||
| 				}, | ||||
| 			}, | ||||
| 			suite.genesisTime.Add(5*oneYear), | ||||
| 			types.DefaultTypedMultiRewardPeriods, | ||||
| 		), | ||||
| 		types.DefaultGenesisRewardState, | ||||
| 		types.DefaultGenesisRewardState, | ||||
| @ -103,15 +102,12 @@ func (suite *GenesisTestSuite) SetupTest() { | ||||
| 		types.DefaultGenesisRewardState, | ||||
| 		types.DefaultGenesisRewardState, | ||||
| 		types.DefaultGenesisRewardState, | ||||
| 		types.DefaultClaims, | ||||
| 		types.DefaultUSDXClaims, | ||||
| 		types.DefaultHardClaims, | ||||
| 		types.DefaultDelegatorClaims, | ||||
| 		types.DefaultSwapClaims, | ||||
| 		types.DefaultSavingsClaims, | ||||
| 		types.DefaultEarnClaims, | ||||
| 		types.DefaultAccrualTimes, | ||||
| 		types.DefaultTypedRewardIndexesList, | ||||
| 	) | ||||
| 
 | ||||
| 	cdc := suite.app.AppCodec() | ||||
| @ -166,14 +162,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() { | ||||
| 				}, | ||||
| 			}, | ||||
| 			genesisTime.Add(5*oneYear), | ||||
| 			types.TypedMultiRewardPeriods{ | ||||
| 				types.NewTypedMultiRewardPeriod( | ||||
| 					types.CLAIM_TYPE_SWAP, | ||||
| 					types.MultiRewardPeriods{ | ||||
| 						types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354))), | ||||
| 					}, | ||||
| 				), | ||||
| 			}, | ||||
| 		), | ||||
| 		types.NewGenesisRewardState( | ||||
| 			types.AccumulationTimes{ | ||||
| @ -231,14 +219,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() { | ||||
| 				types.NewMultiRewardIndex("usdx", types.RewardIndexes{{CollateralType: "usdx", RewardFactor: d("0.2")}}), | ||||
| 			}, | ||||
| 		), | ||||
| 		types.Claims{ | ||||
| 			types.NewClaim( | ||||
| 				types.CLAIM_TYPE_USDX_MINTING, | ||||
| 				suite.addrs[3], | ||||
| 				nil, | ||||
| 				types.MultiRewardIndexes{{CollateralType: "btcb/usdx", RewardIndexes: types.RewardIndexes{{CollateralType: "swap", RewardFactor: d("0.0")}}}}, | ||||
| 			), | ||||
| 		}, | ||||
| 		types.USDXMintingClaims{ | ||||
| 			types.NewUSDXMintingClaim( | ||||
| 				suite.addrs[0], | ||||
| @ -293,14 +273,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() { | ||||
| 				types.MultiRewardIndexes{{CollateralType: "usdx", RewardIndexes: types.RewardIndexes{{CollateralType: "earn", RewardFactor: d("0.0")}}}}, | ||||
| 			), | ||||
| 		}, | ||||
| 		types.AccrualTimes{ | ||||
| 			types.NewAccrualTime(types.CLAIM_TYPE_USDX_MINTING, "usdx", genesisTime.Add(-2*time.Hour)), | ||||
| 		}, | ||||
| 		types.TypedRewardIndexesList{ | ||||
| 			types.NewTypedRewardIndexes(types.CLAIM_TYPE_EARN, "ukava", types.RewardIndexes{ | ||||
| 				types.NewRewardIndex("ukava", d("0.1")), | ||||
| 			}), | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	tApp := app.NewTestApp() | ||||
|  | ||||
| @ -1,19 +0,0 @@ | ||||
| package accumulators_test | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| ) | ||||
| 
 | ||||
| var distantFuture = time.Date(9000, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 
 | ||||
| func i(in int64) sdk.Int                    { return sdk.NewInt(in) } | ||||
| func d(str string) sdk.Dec                  { return sdk.MustNewDecFromStr(str) } | ||||
| func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) } | ||||
| func dc(denom string, amount string) sdk.DecCoin { | ||||
| 	return sdk.NewDecCoinFromDec(denom, sdk.MustNewDecFromStr(amount)) | ||||
| } | ||||
| func cs(coins ...sdk.Coin) sdk.Coins        { return sdk.NewCoins(coins...) } | ||||
| func toDcs(coins ...sdk.Coin) sdk.DecCoins  { return sdk.NewDecCoinsFromCoins(coins...) } | ||||
| func dcs(coins ...sdk.DecCoin) sdk.DecCoins { return sdk.NewDecCoins(coins...) } | ||||
| @ -1,63 +0,0 @@ | ||||
| package accumulators | ||||
| 
 | ||||
| import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/store" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // BasicAccumulator is a default implementation of the RewardAccumulator
 | ||||
| // interface. This applies to all claim types except for those with custom
 | ||||
| // accumulator logic e.g. Earn.
 | ||||
| type BasicAccumulator struct { | ||||
| 	store    store.IncentiveStore | ||||
| 	adapters adapters.SourceAdapters | ||||
| } | ||||
| 
 | ||||
| var _ types.RewardAccumulator = BasicAccumulator{} | ||||
| 
 | ||||
| // NewBasicAccumulator returns a new BasicAccumulator.
 | ||||
| func NewBasicAccumulator( | ||||
| 	store store.IncentiveStore, | ||||
| 	adapters adapters.SourceAdapters, | ||||
| ) BasicAccumulator { | ||||
| 	return BasicAccumulator{ | ||||
| 		store:    store, | ||||
| 		adapters: adapters, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AccumulateRewards calculates new rewards to distribute this block and updates
 | ||||
| // the global indexes to reflect this. The provided rewardPeriod must be valid
 | ||||
| // to avoid panics in calculating time durations.
 | ||||
| func (k BasicAccumulator) AccumulateRewards( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	rewardPeriod types.MultiRewardPeriod, | ||||
| ) error { | ||||
| 	previousAccrualTime, found := k.store.GetRewardAccrualTime(ctx, claimType, rewardPeriod.CollateralType) | ||||
| 	if !found { | ||||
| 		previousAccrualTime = ctx.BlockTime() | ||||
| 	} | ||||
| 
 | ||||
| 	indexes, found := k.store.GetRewardIndexesOfClaimType(ctx, claimType, rewardPeriod.CollateralType) | ||||
| 	if !found { | ||||
| 		indexes = types.RewardIndexes{} | ||||
| 	} | ||||
| 
 | ||||
| 	acc := types.NewAccumulator(previousAccrualTime, indexes) | ||||
| 
 | ||||
| 	totalSource := k.adapters.TotalSharesBySource(ctx, claimType, rewardPeriod.CollateralType) | ||||
| 
 | ||||
| 	acc.Accumulate(rewardPeriod, totalSource, ctx.BlockTime()) | ||||
| 
 | ||||
| 	k.store.SetRewardAccrualTime(ctx, claimType, rewardPeriod.CollateralType, acc.PreviousAccumulationTime) | ||||
| 	if len(acc.Indexes) > 0 { | ||||
| 		// the store panics when setting empty or nil indexes
 | ||||
| 		k.store.SetRewardIndexes(ctx, claimType, rewardPeriod.CollateralType, acc.Indexes) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -1,402 +0,0 @@ | ||||
| package accumulators_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/testutil" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 	swaptypes "github.com/kava-labs/kava/x/swap/types" | ||||
| ) | ||||
| 
 | ||||
| type BasicAccumulatorTestSuite struct { | ||||
| 	testutil.IntegrationTester | ||||
| 
 | ||||
| 	keeper    testutil.TestKeeper | ||||
| 	userAddrs []sdk.AccAddress | ||||
| 	valAddrs  []sdk.ValAddress | ||||
| 
 | ||||
| 	pool string | ||||
| } | ||||
| 
 | ||||
| func TestBasicAccumulatorTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(BasicAccumulatorTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) SetupTest() { | ||||
| 	suite.IntegrationTester.SetupTest() | ||||
| 
 | ||||
| 	suite.keeper = testutil.TestKeeper{ | ||||
| 		Keeper: suite.App.GetIncentiveKeeper(), | ||||
| 	} | ||||
| 
 | ||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(5) | ||||
| 	suite.userAddrs = addrs[0:2] | ||||
| 	suite.valAddrs = []sdk.ValAddress{ | ||||
| 		sdk.ValAddress(addrs[2]), | ||||
| 		sdk.ValAddress(addrs[3]), | ||||
| 	} | ||||
| 
 | ||||
| 	poolDenomA := "btc" | ||||
| 	poolDenomB := "usdx" | ||||
| 
 | ||||
| 	// Setup app with test state
 | ||||
| 	authBuilder := app.NewAuthBankGenesisBuilder(). | ||||
| 		WithSimpleAccount(addrs[0], cs( | ||||
| 			c("ukava", 1e12), | ||||
| 			c(poolDenomA, 1e12), | ||||
| 			c(poolDenomB, 1e12), | ||||
| 		)). | ||||
| 		WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[3], cs(c("ukava", 1e12))) | ||||
| 
 | ||||
| 	incentiveBuilder := testutil.NewIncentiveGenesisBuilder(). | ||||
| 		WithGenesisTime(suite.GenesisTime). | ||||
| 		WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs()) | ||||
| 
 | ||||
| 	savingsBuilder := testutil.NewSavingsGenesisBuilder(). | ||||
| 		WithSupportedDenoms("bkava") | ||||
| 
 | ||||
| 	earnBuilder := testutil.NewEarnGenesisBuilder(). | ||||
| 		WithAllowedVaults(earntypes.AllowedVault{ | ||||
| 			Denom:             "bkava", | ||||
| 			Strategies:        earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS}, | ||||
| 			IsPrivateVault:    false, | ||||
| 			AllowedDepositors: nil, | ||||
| 		}) | ||||
| 
 | ||||
| 	stakingBuilder := testutil.NewStakingGenesisBuilder() | ||||
| 
 | ||||
| 	kavamintBuilder := testutil.NewKavamintGenesisBuilder(). | ||||
| 		WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")). | ||||
| 		WithPreviousBlockTime(suite.GenesisTime) | ||||
| 
 | ||||
| 	suite.StartChainWithBuilders( | ||||
| 		authBuilder, | ||||
| 		incentiveBuilder, | ||||
| 		savingsBuilder, | ||||
| 		earnBuilder, | ||||
| 		stakingBuilder, | ||||
| 		kavamintBuilder, | ||||
| 	) | ||||
| 
 | ||||
| 	suite.pool = swaptypes.PoolID(poolDenomA, poolDenomB) | ||||
| 
 | ||||
| 	swapKeeper := suite.App.GetSwapKeeper() | ||||
| 	swapKeeper.SetParams(suite.Ctx, swaptypes.NewParams( | ||||
| 		swaptypes.NewAllowedPools( | ||||
| 			swaptypes.NewAllowedPool(poolDenomA, poolDenomB), | ||||
| 		), | ||||
| 		sdk.ZeroDec(), | ||||
| 	)) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func TestAccumulateSwapRewards(t *testing.T) { | ||||
| 	suite.Run(t, new(BasicAccumulatorTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestStateUpdatedWhenBlockTimeHasIncreased() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0")) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	suite.keeper.StoreGlobalIndexes( | ||||
| 		suite.Ctx, | ||||
| 		types.CLAIM_TYPE_SWAP, | ||||
| 		types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: pool, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "swap", | ||||
| 						RewardFactor:   d("0.02"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						CollateralType: "ukava", | ||||
| 						RewardFactor:   d("0.04"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	newAccrualTime := previousAccrualTime.Add(1 * time.Hour) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(newAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, newAccrualTime) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "swap", | ||||
| 			RewardFactor:   d("7.22"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("3.64"), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestStateUnchangedWhenBlockTimeHasNotIncreased() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0")) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.StoreGlobalIndexes( | ||||
| 		suite.Ctx, | ||||
| 		types.CLAIM_TYPE_SWAP, | ||||
| 		previousIndexes, | ||||
| 	) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(previousAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 	expected, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestNoAccumulationWhenSourceSharesAreZero() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.StoreGlobalIndexes( | ||||
| 		suite.Ctx, | ||||
| 		types.CLAIM_TYPE_SWAP, previousIndexes) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := previousAccrualTime.Add(7 * time.Second) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	err := suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime) | ||||
| 	expected, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestStateAddedWhenStateDoesNotExist() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0")) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	firstAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// After the first accumulation only the current block time should be stored.
 | ||||
| 	// The indexes will be empty as no time has passed since the previous block because it didn't exist.
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, nil) | ||||
| 
 | ||||
| 	secondAccrualTime := firstAccrualTime.Add(10 * time.Second) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(secondAccrualTime) | ||||
| 
 | ||||
| 	err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// After the second accumulation both current block time and indexes should be stored.
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, secondAccrualTime) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "swap", | ||||
| 			RewardFactor:   d("0.02"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("0.01"), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestNoPanicWhenStateDoesNotExist() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(), | ||||
| 	) | ||||
| 
 | ||||
| 	accrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(accrualTime) | ||||
| 
 | ||||
| 	// Accumulate with no swap shares and no rewards per second will result in no increment to the indexes.
 | ||||
| 	// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
 | ||||
| 	// Check there is no panic.
 | ||||
| 	suite.NotPanics(func() { | ||||
| 		err := suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 		suite.Require().NoError(err) | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, accrualTime) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, nil) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestNoAccumulationWhenBeforeStartTime() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0")) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.StoreGlobalIndexes( | ||||
| 		suite.Ctx, | ||||
| 		types.CLAIM_TYPE_SWAP, previousIndexes) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := previousAccrualTime.Add(10 * time.Second) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		firstAccrualTime.Add(time.Nanosecond), // start time after accrual time
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// The accrual time should be updated, but the indexes unchanged
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime) | ||||
| 	expectedIndexes, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expectedIndexes) | ||||
| } | ||||
| 
 | ||||
| func (suite *BasicAccumulatorTestSuite) TestPanicWhenCurrentTimeLessThanPrevious() { | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0")) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := time.Time{} | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Time{}, // start time after accrual time
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	suite.Panics(func() { | ||||
| 		suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period) | ||||
| 	}) | ||||
| } | ||||
| @ -1,245 +0,0 @@ | ||||
| package accumulators | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"sort" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||||
| 
 | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/store" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // EarnAccumulator is an accumulator for Earn claim types. This includes
 | ||||
| // claiming staking rewards and reward distribution for liquid kava.
 | ||||
| type EarnAccumulator struct { | ||||
| 	store        store.IncentiveStore | ||||
| 	liquidKeeper types.LiquidKeeper | ||||
| 	earnKeeper   types.EarnKeeper | ||||
| 	adapters     adapters.SourceAdapters | ||||
| } | ||||
| 
 | ||||
| var _ types.RewardAccumulator = EarnAccumulator{} | ||||
| 
 | ||||
| // NewEarnAccumulator returns a new EarnAccumulator.
 | ||||
| func NewEarnAccumulator( | ||||
| 	store store.IncentiveStore, | ||||
| 	liquidKeeper types.LiquidKeeper, | ||||
| 	earnKeeper types.EarnKeeper, | ||||
| 	adapters adapters.SourceAdapters, | ||||
| ) EarnAccumulator { | ||||
| 	return EarnAccumulator{ | ||||
| 		store:        store, | ||||
| 		liquidKeeper: liquidKeeper, | ||||
| 		earnKeeper:   earnKeeper, | ||||
| 		adapters:     adapters, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AccumulateRewards calculates new rewards to distribute this block and updates
 | ||||
| // the global indexes to reflect this. The provided rewardPeriod must be valid
 | ||||
| // to avoid panics in calculating time durations.
 | ||||
| func (a EarnAccumulator) AccumulateRewards( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	rewardPeriod types.MultiRewardPeriod, | ||||
| ) error { | ||||
| 	if claimType != types.CLAIM_TYPE_EARN { | ||||
| 		panic(fmt.Sprintf( | ||||
| 			"invalid claim type for earn accumulator, expected %s but got %s", | ||||
| 			types.CLAIM_TYPE_EARN, | ||||
| 			claimType, | ||||
| 		)) | ||||
| 	} | ||||
| 
 | ||||
| 	if rewardPeriod.CollateralType == "bkava" { | ||||
| 		return a.accumulateEarnBkavaRewards(ctx, rewardPeriod) | ||||
| 	} | ||||
| 
 | ||||
| 	// Non bkava vaults use the basic accumulator.
 | ||||
| 	return NewBasicAccumulator(a.store, a.adapters).AccumulateRewards(ctx, claimType, rewardPeriod) | ||||
| } | ||||
| 
 | ||||
| // accumulateEarnBkavaRewards does the same as AccumulateEarnRewards but for
 | ||||
| // *all* bkava vaults.
 | ||||
| func (k EarnAccumulator) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error { | ||||
| 	// All bkava vault denoms
 | ||||
| 	bkavaVaultsDenoms := make(map[string]bool) | ||||
| 
 | ||||
| 	// bkava vault denoms from earn records (non-empty vaults)
 | ||||
| 	k.earnKeeper.IterateVaultRecords(ctx, func(record earntypes.VaultRecord) (stop bool) { | ||||
| 		if k.liquidKeeper.IsDerivativeDenom(ctx, record.TotalShares.Denom) { | ||||
| 			bkavaVaultsDenoms[record.TotalShares.Denom] = true | ||||
| 		} | ||||
| 
 | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	// bkava vault denoms from past incentive indexes, may include vaults
 | ||||
| 	// that were fully withdrawn.
 | ||||
| 	k.store.IterateRewardIndexesByClaimType( | ||||
| 		ctx, | ||||
| 		types.CLAIM_TYPE_EARN, | ||||
| 		func(reward types.TypedRewardIndexes) (stop bool) { | ||||
| 			if k.liquidKeeper.IsDerivativeDenom(ctx, reward.CollateralType) { | ||||
| 				bkavaVaultsDenoms[reward.CollateralType] = true | ||||
| 			} | ||||
| 
 | ||||
| 			return false | ||||
| 		}) | ||||
| 
 | ||||
| 	totalBkavaValue, err := k.liquidKeeper.GetTotalDerivativeValue(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	i := 0 | ||||
| 	sortedBkavaVaultsDenoms := make([]string, len(bkavaVaultsDenoms)) | ||||
| 	for vaultDenom := range bkavaVaultsDenoms { | ||||
| 		sortedBkavaVaultsDenoms[i] = vaultDenom | ||||
| 		i++ | ||||
| 	} | ||||
| 
 | ||||
| 	// Sort the vault denoms to ensure deterministic iteration order.
 | ||||
| 	sort.Strings(sortedBkavaVaultsDenoms) | ||||
| 
 | ||||
| 	// Accumulate rewards for each bkava vault.
 | ||||
| 	for _, bkavaDenom := range sortedBkavaVaultsDenoms { | ||||
| 		derivativeValue, err := k.liquidKeeper.GetDerivativeValue(ctx, bkavaDenom) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		k.accumulateBkavaEarnRewards( | ||||
| 			ctx, | ||||
| 			bkavaDenom, | ||||
| 			rewardPeriod.Start, | ||||
| 			rewardPeriod.End, | ||||
| 			GetProportionalRewardsPerSecond( | ||||
| 				rewardPeriod, | ||||
| 				totalBkavaValue.Amount, | ||||
| 				derivativeValue.Amount, | ||||
| 			), | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func GetProportionalRewardsPerSecond( | ||||
| 	rewardPeriod types.MultiRewardPeriod, | ||||
| 	totalBkavaSupply sdk.Int, | ||||
| 	singleBkavaSupply sdk.Int, | ||||
| ) sdk.DecCoins { | ||||
| 	// Rate per bkava-xxx = rewardsPerSecond * % of bkava-xxx
 | ||||
| 	//                    = rewardsPerSecond * (bkava-xxx / total bkava)
 | ||||
| 	//                    = (rewardsPerSecond * bkava-xxx) / total bkava
 | ||||
| 
 | ||||
| 	newRate := sdk.NewDecCoins() | ||||
| 
 | ||||
| 	// Prevent division by zero, if there are no total shares then there are no
 | ||||
| 	// rewards.
 | ||||
| 	if totalBkavaSupply.IsZero() { | ||||
| 		return newRate | ||||
| 	} | ||||
| 
 | ||||
| 	for _, rewardCoin := range rewardPeriod.RewardsPerSecond { | ||||
| 		scaledAmount := rewardCoin.Amount.ToDec(). | ||||
| 			Mul(singleBkavaSupply.ToDec()). | ||||
| 			Quo(totalBkavaSupply.ToDec()) | ||||
| 
 | ||||
| 		newRate = newRate.Add(sdk.NewDecCoinFromDec(rewardCoin.Denom, scaledAmount)) | ||||
| 	} | ||||
| 
 | ||||
| 	return newRate | ||||
| } | ||||
| 
 | ||||
| func (k EarnAccumulator) accumulateBkavaEarnRewards( | ||||
| 	ctx sdk.Context, | ||||
| 	collateralType string, | ||||
| 	periodStart time.Time, | ||||
| 	periodEnd time.Time, | ||||
| 	periodRewardsPerSecond sdk.DecCoins, | ||||
| ) { | ||||
| 	// Collect staking rewards for this validator, does not have any start/end
 | ||||
| 	// period time restrictions.
 | ||||
| 	stakingRewards := k.collectDerivativeStakingRewards(ctx, collateralType) | ||||
| 
 | ||||
| 	// Collect incentive rewards
 | ||||
| 	// **Total rewards** for vault per second, NOT per share
 | ||||
| 	perSecondRewards := k.collectPerSecondRewards( | ||||
| 		ctx, | ||||
| 		collateralType, | ||||
| 		periodStart, | ||||
| 		periodEnd, | ||||
| 		periodRewardsPerSecond, | ||||
| 	) | ||||
| 
 | ||||
| 	// **Total rewards** for vault per second, NOT per share
 | ||||
| 	rewards := stakingRewards.Add(perSecondRewards...) | ||||
| 
 | ||||
| 	// Distribute rewards by incrementing indexes
 | ||||
| 	indexes, found := k.store.GetRewardIndexesOfClaimType(ctx, types.CLAIM_TYPE_EARN, collateralType) | ||||
| 	if !found { | ||||
| 		indexes = types.RewardIndexes{} | ||||
| 	} | ||||
| 
 | ||||
| 	totalSourceShares := k.adapters.TotalSharesBySource(ctx, types.CLAIM_TYPE_EARN, collateralType) | ||||
| 	var increment types.RewardIndexes | ||||
| 	if totalSourceShares.GT(sdk.ZeroDec()) { | ||||
| 		// Divide total rewards by total shares to get the reward **per share**
 | ||||
| 		// Leave as nil if no source shares
 | ||||
| 		increment = types.NewRewardIndexesFromCoins(rewards).Quo(totalSourceShares) | ||||
| 	} | ||||
| 	updatedIndexes := indexes.Add(increment) | ||||
| 
 | ||||
| 	if len(updatedIndexes) > 0 { | ||||
| 		// the store panics when setting empty or nil indexes
 | ||||
| 		k.store.SetRewardIndexes(ctx, types.CLAIM_TYPE_EARN, collateralType, updatedIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (k EarnAccumulator) collectDerivativeStakingRewards(ctx sdk.Context, collateralType string) sdk.DecCoins { | ||||
| 	rewards, err := k.liquidKeeper.CollectStakingRewardsByDenom(ctx, collateralType, types.IncentiveMacc) | ||||
| 	if err != nil { | ||||
| 		if !errors.Is(err, distrtypes.ErrNoValidatorDistInfo) && | ||||
| 			!errors.Is(err, distrtypes.ErrEmptyDelegationDistInfo) { | ||||
| 			panic(fmt.Sprintf("failed to collect staking rewards for %s: %s", collateralType, err)) | ||||
| 		} | ||||
| 
 | ||||
| 		// otherwise there's no validator or delegation yet
 | ||||
| 		rewards = nil | ||||
| 	} | ||||
| 	return sdk.NewDecCoinsFromCoins(rewards...) | ||||
| } | ||||
| 
 | ||||
| func (k EarnAccumulator) collectPerSecondRewards( | ||||
| 	ctx sdk.Context, | ||||
| 	collateralType string, | ||||
| 	periodStart time.Time, | ||||
| 	periodEnd time.Time, | ||||
| 	periodRewardsPerSecond sdk.DecCoins, | ||||
| ) sdk.DecCoins { | ||||
| 	previousAccrualTime, found := k.store.GetRewardAccrualTime(ctx, types.CLAIM_TYPE_EARN, collateralType) | ||||
| 	if !found { | ||||
| 		previousAccrualTime = ctx.BlockTime() | ||||
| 	} | ||||
| 
 | ||||
| 	rewards, accumulatedTo := types.CalculatePerSecondRewards( | ||||
| 		periodStart, | ||||
| 		periodEnd, | ||||
| 		periodRewardsPerSecond, | ||||
| 		previousAccrualTime, | ||||
| 		ctx.BlockTime(), | ||||
| 	) | ||||
| 
 | ||||
| 	k.store.SetRewardAccrualTime(ctx, types.CLAIM_TYPE_EARN, collateralType, accumulatedTo) | ||||
| 
 | ||||
| 	// Don't need to move funds as they're assumed to be in the IncentiveMacc module account already.
 | ||||
| 	return rewards | ||||
| } | ||||
| @ -1,665 +0,0 @@ | ||||
| package accumulators_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 	abci "github.com/tendermint/tendermint/abci/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/accumulators" | ||||
| 	"github.com/kava-labs/kava/x/incentive/testutil" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| type AccumulateEarnRewardsIntegrationTests struct { | ||||
| 	testutil.IntegrationTester | ||||
| 
 | ||||
| 	keeper    testutil.TestKeeper | ||||
| 	userAddrs []sdk.AccAddress | ||||
| 	valAddrs  []sdk.ValAddress | ||||
| } | ||||
| 
 | ||||
| func TestAccumulateEarnRewardsIntegrationTests(t *testing.T) { | ||||
| 	suite.Run(t, new(AccumulateEarnRewardsIntegrationTests)) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) SetupTest() { | ||||
| 	suite.IntegrationTester.SetupTest() | ||||
| 
 | ||||
| 	suite.keeper = testutil.TestKeeper{ | ||||
| 		Keeper: suite.App.GetIncentiveKeeper(), | ||||
| 	} | ||||
| 
 | ||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(5) | ||||
| 	suite.userAddrs = addrs[0:2] | ||||
| 	suite.valAddrs = []sdk.ValAddress{ | ||||
| 		sdk.ValAddress(addrs[2]), | ||||
| 		sdk.ValAddress(addrs[3]), | ||||
| 	} | ||||
| 
 | ||||
| 	// Setup app with test state
 | ||||
| 	authBuilder := app.NewAuthBankGenesisBuilder(). | ||||
| 		WithSimpleAccount(addrs[0], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[3], cs(c("ukava", 1e12))) | ||||
| 
 | ||||
| 	incentiveBuilder := testutil.NewIncentiveGenesisBuilder(). | ||||
| 		WithGenesisTime(suite.GenesisTime). | ||||
| 		WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs()) | ||||
| 
 | ||||
| 	savingsBuilder := testutil.NewSavingsGenesisBuilder(). | ||||
| 		WithSupportedDenoms("bkava") | ||||
| 
 | ||||
| 	earnBuilder := testutil.NewEarnGenesisBuilder(). | ||||
| 		WithAllowedVaults(earntypes.AllowedVault{ | ||||
| 			Denom:             "bkava", | ||||
| 			Strategies:        earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS}, | ||||
| 			IsPrivateVault:    false, | ||||
| 			AllowedDepositors: nil, | ||||
| 		}) | ||||
| 
 | ||||
| 	stakingBuilder := testutil.NewStakingGenesisBuilder() | ||||
| 
 | ||||
| 	kavamintBuilder := testutil.NewKavamintGenesisBuilder(). | ||||
| 		WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")). | ||||
| 		WithPreviousBlockTime(suite.GenesisTime) | ||||
| 
 | ||||
| 	suite.StartChainWithBuilders( | ||||
| 		authBuilder, | ||||
| 		incentiveBuilder, | ||||
| 		savingsBuilder, | ||||
| 		earnBuilder, | ||||
| 		stakingBuilder, | ||||
| 		kavamintBuilder, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUpdatedWhenBlockTimeHasIncreased() { | ||||
| 	suite.AddIncentiveMultiRewardPeriod( | ||||
| 		types.CLAIM_TYPE_EARN, | ||||
| 		types.NewMultiRewardPeriod( | ||||
| 			true, | ||||
| 			"bkava",         // reward period is set for "bkava" to apply to all vaults
 | ||||
| 			time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 			distantFuture, | ||||
| 			cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 800000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 200000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: derivative0.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: derivative1.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	val0 := suite.GetAbciValidator(suite.valAddrs[0]) | ||||
| 	val1 := suite.GetAbciValidator(suite.valAddrs[1]) | ||||
| 
 | ||||
| 	// Mint tokens, distribute to validators, claim staking rewards
 | ||||
| 	// 1 hour later
 | ||||
| 	_, resBeginBlock := suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{ | ||||
| 					{ | ||||
| 						Validator:       val0, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Validator:       val1, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock) | ||||
| 
 | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 0") | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1") | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	stakingRewardIndexes0 := validatorRewards[suite.valAddrs[0].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative0.Amount.ToDec()) | ||||
| 
 | ||||
| 	stakingRewardIndexes1 := validatorRewards[suite.valAddrs[1].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative1.Amount.ToDec()) | ||||
| 
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("7.22"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("3.64").Add(stakingRewardIndexes0), | ||||
| 		}, | ||||
| 	}) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("7.22"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("3.64").Add(stakingRewardIndexes1), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUpdatedWhenBlockTimeHasIncreased_partialDeposit() { | ||||
| 	suite.AddIncentiveMultiRewardPeriod( | ||||
| 		types.CLAIM_TYPE_EARN, | ||||
| 		types.NewMultiRewardPeriod( | ||||
| 			true, | ||||
| 			"bkava",         // reward period is set for "bkava" to apply to all vaults
 | ||||
| 			time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 			distantFuture, | ||||
| 			cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	// 800000bkava0 minted, 700000 deposited
 | ||||
| 	// 200000bkava1 minted, 100000 deposited
 | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 800000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 200000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	depositAmount0 := c(derivative0.Denom, 700000) | ||||
| 	depositAmount1 := c(derivative1.Denom, 100000) | ||||
| 
 | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], depositAmount0, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], depositAmount1, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: derivative0.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: derivative1.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes) | ||||
| 
 | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	val0 := suite.GetAbciValidator(suite.valAddrs[0]) | ||||
| 	val1 := suite.GetAbciValidator(suite.valAddrs[1]) | ||||
| 
 | ||||
| 	// Mint tokens, distribute to validators, claim staking rewards
 | ||||
| 	// 1 hour later
 | ||||
| 	_, resBeginBlock := suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{ | ||||
| 					{ | ||||
| 						Validator:       val0, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Validator:       val1, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock) | ||||
| 
 | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 0") | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1") | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	// Divided by deposit amounts, not bank supply amounts
 | ||||
| 	stakingRewardIndexes0 := validatorRewards[suite.valAddrs[0].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(depositAmount0.Amount.ToDec()) | ||||
| 
 | ||||
| 	stakingRewardIndexes1 := validatorRewards[suite.valAddrs[1].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(depositAmount1.Amount.ToDec()) | ||||
| 
 | ||||
| 	// Slightly increased rewards due to less bkava deposited
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("8.248571428571428571"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("4.154285714285714286").Add(stakingRewardIndexes0), | ||||
| 		}, | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("14.42"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("7.24").Add(stakingRewardIndexes1), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() { | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: derivative0.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: derivative1.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, previousIndexes) | ||||
| 
 | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		"bkava", | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	// Must manually accumulate rewards as BeginBlockers only run when the block time increases
 | ||||
| 	// This does not run any x/mint or x/distribution BeginBlockers
 | ||||
| 	earnKeeper := suite.App.GetEarnKeeper() | ||||
| 	err = accumulators. | ||||
| 		NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters). | ||||
| 		AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_EARN, period) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	expected, f := previousIndexes.Get(derivative0.Denom) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, expected) | ||||
| 
 | ||||
| 	expected, f = previousIndexes.Get(derivative1.Denom) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestNoAccumulationWhenSourceSharesAreZero() { | ||||
| 	suite.AddIncentiveMultiRewardPeriod( | ||||
| 		types.CLAIM_TYPE_EARN, | ||||
| 		types.NewMultiRewardPeriod( | ||||
| 			true, | ||||
| 			"bkava",         // reward period is set for "bkava" to apply to all vaults
 | ||||
| 			time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 			distantFuture, | ||||
| 			cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// No earn deposits
 | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: derivative0.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: derivative1.Denom, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "earn", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, previousIndexes) | ||||
| 
 | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	val0 := suite.GetAbciValidator(suite.valAddrs[0]) | ||||
| 	val1 := suite.GetAbciValidator(suite.valAddrs[1]) | ||||
| 
 | ||||
| 	// Mint tokens, distribute to validators, claim staking rewards
 | ||||
| 	// 1 hour later
 | ||||
| 	_, _ = suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{ | ||||
| 					{ | ||||
| 						Validator:       val0, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Validator:       val1, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	expected, f := previousIndexes.Get(derivative0.Denom) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, expected) | ||||
| 
 | ||||
| 	expected, f = previousIndexes.Get(derivative1.Denom) | ||||
| 	suite.True(f) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestStateAddedWhenStateDoesNotExist() { | ||||
| 	suite.AddIncentiveMultiRewardPeriod( | ||||
| 		types.CLAIM_TYPE_EARN, | ||||
| 		types.NewMultiRewardPeriod( | ||||
| 			true, | ||||
| 			"bkava",         // reward period is set for "bkava" to apply to all vaults
 | ||||
| 			time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 			distantFuture, | ||||
| 			cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 		), | ||||
| 	) | ||||
| 
 | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	val0 := suite.GetAbciValidator(suite.valAddrs[0]) | ||||
| 	val1 := suite.GetAbciValidator(suite.valAddrs[1]) | ||||
| 
 | ||||
| 	_, resBeginBlock := suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{ | ||||
| 					{ | ||||
| 						Validator:       val0, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Validator:       val1, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	// After the second accumulation both current block time and indexes should be stored.
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	validatorRewards0, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock) | ||||
| 
 | ||||
| 	firstStakingRewardIndexes0 := validatorRewards0[suite.valAddrs[0].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative0.Amount.ToDec()) | ||||
| 
 | ||||
| 	firstStakingRewardIndexes1 := validatorRewards0[suite.valAddrs[1].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative1.Amount.ToDec()) | ||||
| 
 | ||||
| 	// After the first accumulation only the current block time should be stored.
 | ||||
| 	// The indexes will be empty as no time has passed since the previous block because it didn't exist.
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	// First accumulation can have staking rewards, but no other rewards
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   firstStakingRewardIndexes0, | ||||
| 		}, | ||||
| 	}) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   firstStakingRewardIndexes1, | ||||
| 		}, | ||||
| 	}) | ||||
| 
 | ||||
| 	_, resBeginBlock = suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{ | ||||
| 					{ | ||||
| 						Validator:       val0, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Validator:       val1, | ||||
| 						SignedLastBlock: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	// After the second accumulation both current block time and indexes should be stored.
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	validatorRewards1, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock) | ||||
| 
 | ||||
| 	secondStakingRewardIndexes0 := validatorRewards1[suite.valAddrs[0].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative0.Amount.ToDec()) | ||||
| 
 | ||||
| 	secondStakingRewardIndexes1 := validatorRewards1[suite.valAddrs[1].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(derivative1.Amount.ToDec()) | ||||
| 
 | ||||
| 	// Second accumulation has both staking rewards and incentive rewards
 | ||||
| 	// ukava incentive rewards: 3600 * 1000 / (2 * 1000000) == 1.8
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			// Incentive rewards + both staking rewards
 | ||||
| 			RewardFactor: d("1.8").Add(firstStakingRewardIndexes0).Add(secondStakingRewardIndexes0), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("3.6"), | ||||
| 		}, | ||||
| 	}) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			// Incentive rewards + both staking rewards
 | ||||
| 			RewardFactor: d("1.8").Add(firstStakingRewardIndexes1).Add(secondStakingRewardIndexes1), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "earn", | ||||
| 			RewardFactor:   d("3.6"), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestNoPanicWhenStateDoesNotExist() { | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000)) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		"bkava", | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(), | ||||
| 	) | ||||
| 
 | ||||
| 	// Accumulate with no earn shares and no rewards per second will result in no increment to the indexes.
 | ||||
| 	// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
 | ||||
| 	// Check there is no panic.
 | ||||
| 	suite.NotPanics(func() { | ||||
| 		// This does not update any state, as there are no bkava vaults
 | ||||
| 		// to iterate over, denoms are unknown
 | ||||
| 		err := suite.keeper.AccumulateEarnRewards(suite.Ctx, period) | ||||
| 		suite.NoError(err) | ||||
| 	}) | ||||
| 
 | ||||
| 	// Times are not stored for vaults with no state
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, time.Time{}) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, time.Time{}) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, nil) | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, nil) | ||||
| } | ||||
| @ -1,192 +0,0 @@ | ||||
| package accumulators_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/testutil" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 	abci "github.com/tendermint/tendermint/abci/types" | ||||
| ) | ||||
| 
 | ||||
| type EarnAccumulatorStakingRewardsTestSuite struct { | ||||
| 	testutil.IntegrationTester | ||||
| 
 | ||||
| 	keeper    testutil.TestKeeper | ||||
| 	userAddrs []sdk.AccAddress | ||||
| 	valAddrs  []sdk.ValAddress | ||||
| } | ||||
| 
 | ||||
| func TestEarnStakingRewardsIntegrationTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(EarnAccumulatorStakingRewardsTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *EarnAccumulatorStakingRewardsTestSuite) SetupTest() { | ||||
| 	suite.IntegrationTester.SetupTest() | ||||
| 
 | ||||
| 	suite.keeper = testutil.TestKeeper{ | ||||
| 		Keeper: suite.App.GetIncentiveKeeper(), | ||||
| 	} | ||||
| 
 | ||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(5) | ||||
| 	suite.userAddrs = addrs[0:2] | ||||
| 	suite.valAddrs = []sdk.ValAddress{ | ||||
| 		sdk.ValAddress(addrs[2]), | ||||
| 		sdk.ValAddress(addrs[3]), | ||||
| 	} | ||||
| 
 | ||||
| 	// Setup app with test state
 | ||||
| 	authBuilder := app.NewAuthBankGenesisBuilder(). | ||||
| 		WithSimpleAccount(addrs[0], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))). | ||||
| 		WithSimpleAccount(addrs[3], cs(c("ukava", 1e12))) | ||||
| 
 | ||||
| 	incentiveBuilder := testutil.NewIncentiveGenesisBuilder(). | ||||
| 		WithGenesisTime(suite.GenesisTime). | ||||
| 		WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs()) | ||||
| 
 | ||||
| 	savingsBuilder := testutil.NewSavingsGenesisBuilder(). | ||||
| 		WithSupportedDenoms("bkava") | ||||
| 
 | ||||
| 	earnBuilder := testutil.NewEarnGenesisBuilder(). | ||||
| 		WithAllowedVaults(earntypes.AllowedVault{ | ||||
| 			Denom:             "bkava", | ||||
| 			Strategies:        earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS}, | ||||
| 			IsPrivateVault:    false, | ||||
| 			AllowedDepositors: nil, | ||||
| 		}) | ||||
| 
 | ||||
| 	stakingBuilder := testutil.NewStakingGenesisBuilder() | ||||
| 
 | ||||
| 	kavamintBuilder := testutil.NewKavamintGenesisBuilder(). | ||||
| 		WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")). | ||||
| 		WithPreviousBlockTime(suite.GenesisTime) | ||||
| 
 | ||||
| 	suite.StartChainWithBuilders( | ||||
| 		authBuilder, | ||||
| 		incentiveBuilder, | ||||
| 		savingsBuilder, | ||||
| 		earnBuilder, | ||||
| 		stakingBuilder, | ||||
| 		kavamintBuilder, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *EarnAccumulatorStakingRewardsTestSuite) TestStakingRewardsDistributed() { | ||||
| 	// derivative 1: 8 total staked, 7 to earn, 1 not in earn
 | ||||
| 	// derivative 2: 2 total staked, 1 to earn, 1 not in earn
 | ||||
| 	userMintAmount0 := c("ukava", 8e9) | ||||
| 	userMintAmount1 := c("ukava", 2e9) | ||||
| 
 | ||||
| 	userDepositAmount0 := i(7e9) | ||||
| 	userDepositAmount1 := i(1e9) | ||||
| 
 | ||||
| 	// Create two validators
 | ||||
| 	derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], userMintAmount0) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[1], userMintAmount1) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], sdk.NewCoin(derivative0.Denom, userDepositAmount0), earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 	err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], sdk.NewCoin(derivative1.Denom, userDepositAmount1), earntypes.STRATEGY_TYPE_SAVINGS) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// Get derivative denoms
 | ||||
| 	lq := suite.App.GetLiquidKeeper() | ||||
| 	vaultDenom1 := lq.GetLiquidStakingTokenDenom(suite.valAddrs[0]) | ||||
| 	vaultDenom2 := lq.GetLiquidStakingTokenDenom(suite.valAddrs[1]) | ||||
| 
 | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockTime(previousAccrualTime) | ||||
| 
 | ||||
| 	initialVault1RewardFactor := d("0.04") | ||||
| 	initialVault2RewardFactor := d("0.04") | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: vaultDenom1, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   initialVault1RewardFactor, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: vaultDenom2, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   initialVault2RewardFactor, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes) | ||||
| 
 | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1, suite.Ctx.BlockTime()) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2, suite.Ctx.BlockTime()) | ||||
| 	suite.App.GetKavamintKeeper().SetPreviousBlockTime(suite.Ctx, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	val := suite.GetAbciValidator(suite.valAddrs[0]) | ||||
| 
 | ||||
| 	// Mint tokens, distribute to validators, claim staking rewards
 | ||||
| 	// 1 hour later
 | ||||
| 	_, resBeginBlock := suite.NextBlockAfterWithReq( | ||||
| 		1*time.Hour, | ||||
| 		abci.RequestEndBlock{}, | ||||
| 		abci.RequestBeginBlock{ | ||||
| 			LastCommitInfo: abci.LastCommitInfo{ | ||||
| 				Votes: []abci.VoteInfo{{ | ||||
| 					Validator:       val, | ||||
| 					SignedLastBlock: true, | ||||
| 				}}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, vaultDenom1, suite.Ctx.BlockTime()) | ||||
| 	suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, vaultDenom2, suite.Ctx.BlockTime()) | ||||
| 
 | ||||
| 	validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock) | ||||
| 
 | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1") | ||||
| 	suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 2") | ||||
| 
 | ||||
| 	// Total staking rewards / total source shares (**deposited in earn** not total minted)
 | ||||
| 	// types.RewardIndexes.Quo() uses Dec.Quo() which uses bankers rounding.
 | ||||
| 	// So we need to use Dec.Quo() to also round vs Dec.QuoInt() which truncates
 | ||||
| 	expectedIndexes1 := validatorRewards[suite.valAddrs[0].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(userDepositAmount0.ToDec()) | ||||
| 
 | ||||
| 	expectedIndexes2 := validatorRewards[suite.valAddrs[1].String()]. | ||||
| 		AmountOf("ukava"). | ||||
| 		ToDec(). | ||||
| 		Quo(userDepositAmount1.ToDec()) | ||||
| 
 | ||||
| 	// Only contains staking rewards
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, vaultDenom1, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   initialVault1RewardFactor.Add(expectedIndexes1), | ||||
| 		}, | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, vaultDenom2, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   initialVault2RewardFactor.Add(expectedIndexes2), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| @ -1,50 +0,0 @@ | ||||
| package accumulators_test | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/accumulators" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| func (suite *AccumulateEarnRewardsIntegrationTests) TestEarnAccumulator_OnlyEarnClaimType() { | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		"bkava", | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	earnKeeper := suite.App.GetEarnKeeper() | ||||
| 
 | ||||
| 	for _, claimTypeValue := range types.ClaimType_value { | ||||
| 		claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 		if claimType == types.CLAIM_TYPE_EARN { | ||||
| 			suite.NotPanics(func() { | ||||
| 				err := accumulators. | ||||
| 					NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters). | ||||
| 					AccumulateRewards(suite.Ctx, claimType, period) | ||||
| 				suite.NoError(err) | ||||
| 			}) | ||||
| 
 | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		suite.PanicsWithValue( | ||||
| 			fmt.Sprintf( | ||||
| 				"invalid claim type for earn accumulator, expected %s but got %s", | ||||
| 				types.CLAIM_TYPE_EARN, | ||||
| 				claimType, | ||||
| 			), | ||||
| 			func() { | ||||
| 				err := accumulators. | ||||
| 					NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters). | ||||
| 					AccumulateRewards(suite.Ctx, claimType, period) | ||||
| 				suite.NoError(err) | ||||
| 			}, | ||||
| 		) | ||||
| 	} | ||||
| } | ||||
| @ -1,81 +0,0 @@ | ||||
| package adapters | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters/earn" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters/swap" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // SourceAdapters is a collection of source adapters.
 | ||||
| type SourceAdapters struct { | ||||
| 	adapters map[types.ClaimType]types.SourceAdapter | ||||
| } | ||||
| 
 | ||||
| // SourceShare is a single share from a source with it's corresponding ID.
 | ||||
| type SourceShare struct { | ||||
| 	ID     string | ||||
| 	Shares sdk.Dec | ||||
| } | ||||
| 
 | ||||
| // NewSourceAdapters returns a new SourceAdapters instance with all available
 | ||||
| // source adapters.
 | ||||
| func NewSourceAdapters( | ||||
| 	swapKeeper types.SwapKeeper, | ||||
| 	earnKeeper types.EarnKeeper, | ||||
| ) SourceAdapters { | ||||
| 	return SourceAdapters{ | ||||
| 		adapters: map[types.ClaimType]types.SourceAdapter{ | ||||
| 			types.CLAIM_TYPE_SWAP: swap.NewSourceAdapter(swapKeeper), | ||||
| 			types.CLAIM_TYPE_EARN: earn.NewSourceAdapter(earnKeeper), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // OwnerSharesBySource returns a slice of SourceShares for each sourceID from a
 | ||||
| // specified owner. The slice is sorted by sourceID.
 | ||||
| func (a SourceAdapters) OwnerSharesBySource( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	owner sdk.AccAddress, | ||||
| 	sourceIDs []string, | ||||
| ) []SourceShare { | ||||
| 	adapter, found := a.adapters[claimType] | ||||
| 	if !found { | ||||
| 		panic(fmt.Sprintf("no source share fetcher for claim type %s", claimType)) | ||||
| 	} | ||||
| 
 | ||||
| 	ownerShares := adapter.OwnerSharesBySource(ctx, owner, sourceIDs) | ||||
| 
 | ||||
| 	var shares []SourceShare | ||||
| 	for _, sourceID := range sourceIDs { | ||||
| 		singleShares, found := ownerShares[sourceID] | ||||
| 		if !found { | ||||
| 			panic(fmt.Sprintf("no source shares for claimType %s and source %s", claimType, sourceID)) | ||||
| 		} | ||||
| 
 | ||||
| 		shares = append(shares, SourceShare{ | ||||
| 			ID:     sourceID, | ||||
| 			Shares: singleShares, | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	return shares | ||||
| } | ||||
| 
 | ||||
| // TotalSharesBySource returns the total shares of a given claimType and sourceID.
 | ||||
| func (a SourceAdapters) TotalSharesBySource( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| ) sdk.Dec { | ||||
| 	adapter, found := a.adapters[claimType] | ||||
| 	if !found { | ||||
| 		panic(fmt.Sprintf("no source share fetcher for claim type %s", claimType)) | ||||
| 	} | ||||
| 
 | ||||
| 	return adapter.TotalSharesBySource(ctx, sourceID) | ||||
| } | ||||
| @ -1,48 +0,0 @@ | ||||
| package earn | ||||
| 
 | ||||
| import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| var _ types.SourceAdapter = SourceAdapter{} | ||||
| 
 | ||||
| type SourceAdapter struct { | ||||
| 	keeper types.EarnKeeper | ||||
| } | ||||
| 
 | ||||
| func NewSourceAdapter(keeper types.EarnKeeper) SourceAdapter { | ||||
| 	return SourceAdapter{ | ||||
| 		keeper: keeper, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (f SourceAdapter) TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec { | ||||
| 	vaultShares, found := f.keeper.GetVaultTotalShares(ctx, sourceID) | ||||
| 	if !found { | ||||
| 		return sdk.ZeroDec() | ||||
| 	} | ||||
| 
 | ||||
| 	return vaultShares.Amount | ||||
| } | ||||
| 
 | ||||
| func (f SourceAdapter) OwnerSharesBySource( | ||||
| 	ctx sdk.Context, | ||||
| 	owner sdk.AccAddress, | ||||
| 	sourceIDs []string, | ||||
| ) map[string]sdk.Dec { | ||||
| 	accountShares, found := f.keeper.GetVaultAccountShares(ctx, owner) | ||||
| 	if !found { | ||||
| 		accountShares = earntypes.VaultShares{} | ||||
| 	} | ||||
| 
 | ||||
| 	shares := make(map[string]sdk.Dec) | ||||
| 	for _, id := range sourceIDs { | ||||
| 		// Sets shares to zero if not found
 | ||||
| 		shares[id] = accountShares.AmountOf(id) | ||||
| 	} | ||||
| 
 | ||||
| 	return shares | ||||
| } | ||||
| @ -1,298 +0,0 @@ | ||||
| package earn_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" | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters/earn" | ||||
| 	savingstypes "github.com/kava-labs/kava/x/savings/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| type EarnAdapterTestSuite struct { | ||||
| 	suite.Suite | ||||
| 
 | ||||
| 	app app.TestApp | ||||
| 	ctx sdk.Context | ||||
| 
 | ||||
| 	genesisTime time.Time | ||||
| 	addrs       []sdk.AccAddress | ||||
| } | ||||
| 
 | ||||
| func TestEarnAdapterTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(EarnAdapterTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *EarnAdapterTestSuite) 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 *EarnAdapterTestSuite) TestEarnAdapter_OwnerSharesBySource_Empty() { | ||||
| 	ek := suite.app.GetEarnKeeper() | ||||
| 	adapter := earn.NewSourceAdapter(&ek) | ||||
| 
 | ||||
| 	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 vaults are zero", | ||||
| 			suite.addrs[0], | ||||
| 			[]string{ | ||||
| 				"vault1", | ||||
| 				"vault2", | ||||
| 				"vault3", | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				"vault1": sdk.ZeroDec(), | ||||
| 				"vault2": sdk.ZeroDec(), | ||||
| 				"vault3": 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 *EarnAdapterTestSuite) TestEarnAdapter_OwnerSharesBySource() { | ||||
| 	vaultDenomA := "ukava" | ||||
| 	vaultDenomB := "usdx" | ||||
| 
 | ||||
| 	savingsKeeper := suite.app.GetSavingsKeeper() | ||||
| 	savingsKeeper.SetParams(suite.ctx, savingstypes.NewParams([]string{vaultDenomA, vaultDenomB})) | ||||
| 
 | ||||
| 	earnKeeper := suite.app.GetEarnKeeper() | ||||
| 	earnKeeper.SetParams(suite.ctx, earntypes.NewParams( | ||||
| 		earntypes.AllowedVaults{ | ||||
| 			earntypes.NewAllowedVault( | ||||
| 				"ukava", | ||||
| 				earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS}, | ||||
| 				false, | ||||
| 				nil, | ||||
| 			), | ||||
| 		}, | ||||
| 	)) | ||||
| 
 | ||||
| 	suite.NoError(suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	)) | ||||
| 	suite.NoError(suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	)) | ||||
| 
 | ||||
| 	err := earnKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoin(vaultDenomA, sdk.NewInt(100)), | ||||
| 		earntypes.STRATEGY_TYPE_SAVINGS, | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = earnKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoin(vaultDenomA, sdk.NewInt(250)), | ||||
| 		earntypes.STRATEGY_TYPE_SAVINGS, | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	ek := suite.app.GetEarnKeeper() | ||||
| 	adapter := earn.NewSourceAdapter(&ek) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name          string | ||||
| 		giveOwner     sdk.AccAddress | ||||
| 		giveSourceIDs []string | ||||
| 		wantShares    map[string]sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"depositor has shares", | ||||
| 			suite.addrs[0], | ||||
| 			[]string{ | ||||
| 				vaultDenomA, | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				vaultDenomA: sdk.NewDecWithPrec(100, 0), | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"depositor has shares - including empty deposits", | ||||
| 			suite.addrs[1], | ||||
| 			[]string{ | ||||
| 				vaultDenomA, | ||||
| 				"vault2", | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				vaultDenomA: sdk.NewDecWithPrec(250, 0), | ||||
| 				"vault2":    sdk.ZeroDec(), | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"non-depositor has zero shares", | ||||
| 			suite.addrs[2], | ||||
| 			[]string{ | ||||
| 				vaultDenomA, | ||||
| 			}, | ||||
| 			map[string]sdk.Dec{ | ||||
| 				vaultDenomA: 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 *EarnAdapterTestSuite) TestEarnAdapter_TotalSharesBySource_Empty() { | ||||
| 	ek := suite.app.GetEarnKeeper() | ||||
| 	adapter := earn.NewSourceAdapter(&ek) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name         string | ||||
| 		giveSourceID string | ||||
| 		wantShares   sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"empty/invalid vaults are zero", | ||||
| 			"vault1", | ||||
| 			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 *EarnAdapterTestSuite) TestEarnAdapter_TotalSharesBySource() { | ||||
| 	vaultDenomA := "ukava" | ||||
| 	vaultDenomB := "usdx" | ||||
| 
 | ||||
| 	savingsKeeper := suite.app.GetSavingsKeeper() | ||||
| 	savingsKeeper.SetParams(suite.ctx, savingstypes.NewParams([]string{vaultDenomA, vaultDenomB})) | ||||
| 
 | ||||
| 	earnKeeper := suite.app.GetEarnKeeper() | ||||
| 	earnKeeper.SetParams(suite.ctx, earntypes.NewParams( | ||||
| 		earntypes.AllowedVaults{ | ||||
| 			earntypes.NewAllowedVault( | ||||
| 				vaultDenomA, | ||||
| 				earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS}, | ||||
| 				false, | ||||
| 				nil, | ||||
| 			), | ||||
| 		}, | ||||
| 	)) | ||||
| 
 | ||||
| 	suite.NoError(suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	)) | ||||
| 	suite.NoError(suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	)) | ||||
| 
 | ||||
| 	err := earnKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoin(vaultDenomA, sdk.NewInt(100)), | ||||
| 		earntypes.STRATEGY_TYPE_SAVINGS, | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = earnKeeper.Deposit( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoin(vaultDenomA, sdk.NewInt(250)), | ||||
| 		earntypes.STRATEGY_TYPE_SAVINGS, | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	ek := suite.app.GetEarnKeeper() | ||||
| 	adapter := earn.NewSourceAdapter(&ek) | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name         string | ||||
| 		giveSourceID string | ||||
| 		wantShares   sdk.Dec | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"total shares", | ||||
| 			vaultDenomA, | ||||
| 			sdk.NewDecWithPrec(350, 0), | ||||
| 		}, | ||||
| 		{ | ||||
| 			"empty or invalid vault empty", | ||||
| 			"vault2", | ||||
| 			sdk.ZeroDec(), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		suite.Run(tt.name, func() { | ||||
| 			shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID) | ||||
| 
 | ||||
| 			suite.Equal(tt.wantShares, shares) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -1,46 +0,0 @@ | ||||
| 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 | ||||
| } | ||||
| @ -1,286 +0,0 @@ | ||||
| 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(), | ||||
| 	)) | ||||
| 
 | ||||
| 	err := suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	err = suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[1], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	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.NoError(suite.app.FundAccount( | ||||
| 		suite.ctx, | ||||
| 		suite.addrs[0], | ||||
| 		sdk.NewCoins( | ||||
| 			sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)), | ||||
| 			sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)), | ||||
| 		), | ||||
| 	)) | ||||
| 	suite.NoError(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) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -7,8 +7,6 @@ import ( | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/adapters" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/store" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| @ -27,9 +25,6 @@ type Keeper struct { | ||||
| 	liquidKeeper  types.LiquidKeeper | ||||
| 	earnKeeper    types.EarnKeeper | ||||
| 
 | ||||
| 	Adapters adapters.SourceAdapters | ||||
| 	Store    store.IncentiveStore | ||||
| 
 | ||||
| 	// Keepers used for APY queries
 | ||||
| 	kavamintKeeper  types.KavamintKeeper | ||||
| 	distrKeeper     types.DistrKeeper | ||||
| @ -61,12 +56,6 @@ func NewKeeper( | ||||
| 		liquidKeeper:  lqk, | ||||
| 		earnKeeper:    ek, | ||||
| 
 | ||||
| 		Adapters: adapters.NewSourceAdapters( | ||||
| 			swpk, | ||||
| 			ek, | ||||
| 		), | ||||
| 		Store: store.NewIncentiveStore(cdc, key), | ||||
| 
 | ||||
| 		kavamintKeeper:  kmk, | ||||
| 		distrKeeper:     dk, | ||||
| 		pricefeedKeeper: pfk, | ||||
|  | ||||
| @ -1,427 +0,0 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestGetSetDeleteClaims() { | ||||
| 	suite.SetupApp() | ||||
| 
 | ||||
| 	for claimTypeName, claimTypeValue := range types.ClaimType_value { | ||||
| 		suite.Run(claimTypeName, func() { | ||||
| 			claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 			c := types.NewClaim( | ||||
| 				claimType, | ||||
| 				suite.addrs[0], | ||||
| 				arbitraryCoins(), | ||||
| 				nonEmptyMultiRewardIndexes, | ||||
| 			) | ||||
| 
 | ||||
| 			_, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0]) | ||||
| 			suite.Require().False(found) | ||||
| 
 | ||||
| 			suite.Require().NotPanics(func() { | ||||
| 				suite.keeper.Store.SetClaim(suite.ctx, c) | ||||
| 			}) | ||||
| 			testC, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0]) | ||||
| 			suite.Require().True(found) | ||||
| 			suite.Require().Equal(c, testC) | ||||
| 
 | ||||
| 			// Check that other claim types do not exist for the same address
 | ||||
| 			for otherClaimTypeName, otherClaimTypeValue := range types.ClaimType_value { | ||||
| 				// Skip the current claim type
 | ||||
| 				if otherClaimTypeValue == claimTypeValue { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 				otherClaimType := types.ClaimType(otherClaimTypeValue) | ||||
| 				_, found := suite.keeper.Store.GetClaim(suite.ctx, otherClaimType, suite.addrs[0]) | ||||
| 				suite.Require().False(found, "claim type %s should not exist", otherClaimTypeName) | ||||
| 			} | ||||
| 
 | ||||
| 			suite.Require().NotPanics(func() { | ||||
| 				suite.keeper.Store.DeleteClaim(suite.ctx, claimType, suite.addrs[0]) | ||||
| 			}) | ||||
| 			_, found = suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0]) | ||||
| 			suite.Require().False(found) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestIterateClaims() { | ||||
| 	suite.SetupApp() | ||||
| 	var claims types.Claims | ||||
| 
 | ||||
| 	// Add 2 of each type of claim
 | ||||
| 	for _, claimTypeValue := range types.ClaimType_value { | ||||
| 		c := types.Claims{ | ||||
| 			types.NewClaim(types.ClaimType(claimTypeValue), suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes), | ||||
| 			types.NewClaim(types.ClaimType(claimTypeValue), suite.addrs[1], nil, nil), | ||||
| 		} | ||||
| 		claims = append(claims, c...) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, claim := range claims { | ||||
| 		suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, claimTypeValue := range types.ClaimType_value { | ||||
| 		claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 		// Claims of specific claim type only should be returned
 | ||||
| 		claims := suite.keeper.Store.GetClaims(suite.ctx, claimType) | ||||
| 		suite.Require().Len(claims, 2) | ||||
| 		suite.Require().Equalf( | ||||
| 			claims, types.Claims{ | ||||
| 				types.NewClaim(claimType, suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes), | ||||
| 				types.NewClaim(claimType, suite.addrs[1], nil, nil), | ||||
| 			}, | ||||
| 			"GetClaims(%s) should only return claims of those type", claimType, | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	allClaims := suite.keeper.Store.GetAllClaims(suite.ctx) | ||||
| 	suite.Require().Len(allClaims, len(claims)) | ||||
| 	suite.Require().ElementsMatch(allClaims, claims, "GetAllClaims() should return claims of all types") | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestGetSetRewardAccrualTimes() { | ||||
| 	testCases := []struct { | ||||
| 		name        string | ||||
| 		subKey      string | ||||
| 		accrualTime time.Time | ||||
| 		panics      bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:        "normal time can be written and read", | ||||
| 			subKey:      "btc/usdx", | ||||
| 			accrualTime: time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:        "zero time can be written and read", | ||||
| 			subKey:      "btc/usdx", | ||||
| 			accrualTime: time.Time{}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			suite.SetupApp() | ||||
| 
 | ||||
| 			_, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey) | ||||
| 			suite.False(found) | ||||
| 
 | ||||
| 			setFunc := func() { | ||||
| 				suite.keeper.Store.SetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey, tc.accrualTime) | ||||
| 			} | ||||
| 			if tc.panics { | ||||
| 				suite.Panics(setFunc) | ||||
| 				return | ||||
| 			} else { | ||||
| 				suite.NotPanics(setFunc) | ||||
| 			} | ||||
| 
 | ||||
| 			for _, claimTypeValue := range types.ClaimType_value { | ||||
| 				claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 				if claimType == types.CLAIM_TYPE_USDX_MINTING { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 				_, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, claimType, tc.subKey) | ||||
| 				suite.False(found, "reward accrual time for claim type %s should not exist", claimType) | ||||
| 			} | ||||
| 
 | ||||
| 			storedTime, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey) | ||||
| 			suite.True(found) | ||||
| 			suite.Equal(tc.accrualTime, storedTime) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestGetSetRewardIndexes() { | ||||
| 	testCases := []struct { | ||||
| 		name           string | ||||
| 		collateralType string | ||||
| 		indexes        types.RewardIndexes | ||||
| 		wantIndex      types.RewardIndexes | ||||
| 		panics         bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:           "two factors can be written and read", | ||||
| 			collateralType: "btc/usdx", | ||||
| 			indexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "hard", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantIndex: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "hard", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:           "indexes with empty pool name panics", | ||||
| 			collateralType: "", | ||||
| 			indexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "hard", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			panics: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			// this test is to detect any changes in behavior
 | ||||
| 			name:           "setting empty indexes does not panic", | ||||
| 			collateralType: "btc/usdx", | ||||
| 			// Marshalling empty slice results in [] bytes, unmarshalling the []
 | ||||
| 			// empty bytes results in a nil slice instead of an empty slice
 | ||||
| 			indexes:   types.RewardIndexes{}, | ||||
| 			wantIndex: nil, | ||||
| 			panics:    false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			// this test is to detect any changes in behavior
 | ||||
| 			name:           "setting nil indexes does not panic", | ||||
| 			collateralType: "btc/usdx", | ||||
| 			indexes:        nil, | ||||
| 			wantIndex:      nil, | ||||
| 			panics:         false, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			suite.SetupApp() | ||||
| 
 | ||||
| 			_, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType) | ||||
| 			suite.False(found) | ||||
| 
 | ||||
| 			setFunc := func() { | ||||
| 				suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType, tc.indexes) | ||||
| 			} | ||||
| 			if tc.panics { | ||||
| 				suite.Panics(setFunc) | ||||
| 				return | ||||
| 			} else { | ||||
| 				suite.NotPanics(setFunc) | ||||
| 			} | ||||
| 
 | ||||
| 			storedIndexes, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType) | ||||
| 			suite.True(found) | ||||
| 			suite.Equal(tc.wantIndex, storedIndexes) | ||||
| 
 | ||||
| 			for _, otherClaimTypeValue := range types.ClaimType_value { | ||||
| 				// Skip swap
 | ||||
| 				if types.ClaimType(otherClaimTypeValue) == types.CLAIM_TYPE_SWAP { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 				otherClaimType := types.ClaimType(otherClaimTypeValue) | ||||
| 
 | ||||
| 				// Other claim types should not be affected
 | ||||
| 				_, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, otherClaimType, tc.collateralType) | ||||
| 				suite.False(found) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestIterateRewardAccrualTimes() { | ||||
| 	suite.SetupApp() | ||||
| 
 | ||||
| 	expectedAccrualTimes := nonEmptyAccrualTimes | ||||
| 
 | ||||
| 	for _, at := range expectedAccrualTimes { | ||||
| 		suite.keeper.Store.SetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, at.denom, at.time) | ||||
| 	} | ||||
| 
 | ||||
| 	var actualAccrualTimes []accrualtime | ||||
| 	suite.keeper.Store.IterateRewardAccrualTimesByClaimType(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, func(denom string, accrualTime time.Time) bool { | ||||
| 		actualAccrualTimes = append(actualAccrualTimes, accrualtime{denom: denom, time: accrualTime}) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.ElementsMatch(expectedAccrualTimes, actualAccrualTimes) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestIterateAllRewardAccrualTimes() { | ||||
| 	suite.SetupApp() | ||||
| 
 | ||||
| 	var expectedAccrualTimes types.AccrualTimes | ||||
| 
 | ||||
| 	for _, claimTypeValue := range types.ClaimType_value { | ||||
| 		claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 		// Skip invalid claim type
 | ||||
| 		if claimType.Validate() != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		for _, at := range nonEmptyAccrualTimes { | ||||
| 			suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, at.denom, at.time) | ||||
| 
 | ||||
| 			expectedAccrualTimes = append(expectedAccrualTimes, types.NewAccrualTime( | ||||
| 				claimType, | ||||
| 
 | ||||
| 				at.denom, | ||||
| 				at.time, | ||||
| 			)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var actualAccrualTimes types.AccrualTimes | ||||
| 	suite.keeper.Store.IterateRewardAccrualTimes( | ||||
| 		suite.ctx, | ||||
| 		func(accrualTime types.AccrualTime) bool { | ||||
| 			actualAccrualTimes = append(actualAccrualTimes, accrualTime) | ||||
| 			return false | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	suite.ElementsMatch(expectedAccrualTimes, actualAccrualTimes) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestIterateRewardIndexes() { | ||||
| 	suite.SetupApp() | ||||
| 	swapMultiIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "bnb", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.0000002"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "btcb", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "hard", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	earnMultiIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "usdc", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "usdc", | ||||
| 					RewardFactor:   d("0.0000002"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, mi := range swapMultiIndexes { | ||||
| 		suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_SWAP, mi.CollateralType, mi.RewardIndexes) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, mi := range earnMultiIndexes { | ||||
| 		// These should be excluded when iterating over swap indexes
 | ||||
| 		suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_EARN, mi.CollateralType, mi.RewardIndexes) | ||||
| 	} | ||||
| 
 | ||||
| 	actualMultiIndexesMap := make(map[types.ClaimType]types.MultiRewardIndexes) | ||||
| 	suite.keeper.Store.IterateRewardIndexesByClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, func(rewardIndex types.TypedRewardIndexes) bool { | ||||
| 		actualMultiIndexesMap[rewardIndex.ClaimType] = actualMultiIndexesMap[rewardIndex.ClaimType].With(rewardIndex.CollateralType, rewardIndex.RewardIndexes) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.Require().Len(actualMultiIndexesMap, 1, "iteration should only include 1 claim type") | ||||
| 	suite.Require().Equal(swapMultiIndexes, actualMultiIndexesMap[types.CLAIM_TYPE_SWAP]) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) TestIterateAllRewardIndexes() { | ||||
| 	suite.SetupApp() | ||||
| 	multiIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.0000002"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "usdc", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "hard", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, claimTypeValue := range types.ClaimType_value { | ||||
| 		if types.ClaimType(claimTypeValue) == types.CLAIM_TYPE_UNSPECIFIED { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		claimType := types.ClaimType(claimTypeValue) | ||||
| 
 | ||||
| 		for _, mi := range multiIndexes { | ||||
| 			suite.keeper.Store.SetRewardIndexes(suite.ctx, claimType, mi.CollateralType, mi.RewardIndexes) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	actualMultiIndexesMap := make(map[types.ClaimType]types.MultiRewardIndexes) | ||||
| 	suite.keeper.Store.IterateRewardIndexes(suite.ctx, func(rewardIndex types.TypedRewardIndexes) bool { | ||||
| 		actualMultiIndexesMap[rewardIndex.ClaimType] = actualMultiIndexesMap[rewardIndex.ClaimType].With(rewardIndex.CollateralType, rewardIndex.RewardIndexes) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	// -1 to exclude the unspecified type
 | ||||
| 	suite.Require().Len(actualMultiIndexesMap, len(types.ClaimType_value)-1) | ||||
| 
 | ||||
| 	for claimType, actualMultiIndexes := range actualMultiIndexesMap { | ||||
| 		suite.Require().NoError(claimType.Validate()) | ||||
| 		suite.Require().Equal(multiIndexes, actualMultiIndexes) | ||||
| 	} | ||||
| } | ||||
| @ -1,137 +0,0 @@ | ||||
| package keeper | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/accumulators" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // AccumulateRewards calculates new rewards to distribute this block and updates the global indexes to reflect this.
 | ||||
| // The provided rewardPeriod must be valid to avoid panics in calculating time durations.
 | ||||
| func (k Keeper) AccumulateRewards( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	rewardPeriod types.MultiRewardPeriod, | ||||
| ) error { | ||||
| 	var accumulator types.RewardAccumulator | ||||
| 
 | ||||
| 	switch claimType { | ||||
| 	case types.CLAIM_TYPE_EARN: | ||||
| 		accumulator = accumulators.NewEarnAccumulator(k.Store, k.liquidKeeper, k.earnKeeper, k.Adapters) | ||||
| 	default: | ||||
| 		accumulator = accumulators.NewBasicAccumulator(k.Store, k.Adapters) | ||||
| 	} | ||||
| 
 | ||||
| 	return accumulator.AccumulateRewards(ctx, claimType, rewardPeriod) | ||||
| } | ||||
| 
 | ||||
| // InitializeClaim creates a new claim with zero rewards and indexes matching
 | ||||
| // the global indexes. If the claim already exists it just updates the indexes.
 | ||||
| func (k Keeper) InitializeClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| 	owner sdk.AccAddress, | ||||
| ) { | ||||
| 	claim, found := k.Store.GetClaim(ctx, claimType, owner) | ||||
| 	if !found { | ||||
| 		claim = types.NewClaim(claimType, owner, sdk.Coins{}, nil) | ||||
| 	} | ||||
| 
 | ||||
| 	globalRewardIndexes, found := k.Store.GetRewardIndexesOfClaimType(ctx, claimType, sourceID) | ||||
| 	if !found { | ||||
| 		globalRewardIndexes = types.RewardIndexes{} | ||||
| 	} | ||||
| 
 | ||||
| 	claim.RewardIndexes = claim.RewardIndexes.With(sourceID, globalRewardIndexes) | ||||
| 	k.Store.SetClaim(ctx, claim) | ||||
| } | ||||
| 
 | ||||
| // SynchronizeClaim updates the claim object by adding any accumulated rewards
 | ||||
| // and updating the reward index value.
 | ||||
| func (k Keeper) SynchronizeClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| 	owner sdk.AccAddress, | ||||
| 	shares sdk.Dec, | ||||
| ) { | ||||
| 	claim, found := k.Store.GetClaim(ctx, claimType, owner) | ||||
| 	if !found { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	claim = k.synchronizeClaim(ctx, claim, sourceID, owner, shares) | ||||
| 	k.Store.SetClaim(ctx, claim) | ||||
| } | ||||
| 
 | ||||
| // synchronizeClaim updates the reward and indexes in a claim for one sourceID.
 | ||||
| func (k *Keeper) synchronizeClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claim types.Claim, | ||||
| 	sourceID string, | ||||
| 	owner sdk.AccAddress, | ||||
| 	shares sdk.Dec, | ||||
| ) types.Claim { | ||||
| 	globalRewardIndexes, found := k.Store.GetRewardIndexesOfClaimType(ctx, claim.Type, sourceID) | ||||
| 	if !found { | ||||
| 		// The global factor is only not found if
 | ||||
| 		// - the pool has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
 | ||||
| 		// - OR it was wrongly deleted from state (factors should never be removed while unsynced claims exist)
 | ||||
| 		// If not found we could either skip this sync, or assume the global factor is zero.
 | ||||
| 		// Skipping will avoid storing unnecessary factors in the claim for non rewarded pools.
 | ||||
| 		// And in the event a global factor is wrongly deleted, it will avoid this function panicking when calculating rewards.
 | ||||
| 		return claim | ||||
| 	} | ||||
| 
 | ||||
| 	userRewardIndexes, found := claim.RewardIndexes.Get(sourceID) | ||||
| 	if !found { | ||||
| 		// Normally the reward indexes should always be found.
 | ||||
| 		// But if a pool was not rewarded then becomes rewarded (ie a reward period is added to params), then the indexes will be missing from claims for that pool.
 | ||||
| 		// So given the reward period was just added, assume the starting value for any global reward indexes, which is an empty slice.
 | ||||
| 		userRewardIndexes = types.RewardIndexes{} | ||||
| 	} | ||||
| 
 | ||||
| 	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.
 | ||||
| 		panic(fmt.Sprintf("corrupted global reward indexes found: %v", err)) | ||||
| 	} | ||||
| 
 | ||||
| 	claim.Reward = claim.Reward.Add(newRewards...) | ||||
| 	claim.RewardIndexes = claim.RewardIndexes.With(sourceID, globalRewardIndexes) | ||||
| 
 | ||||
| 	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.Store.GetClaim(ctx, claimType, owner) | ||||
| 	if !found { | ||||
| 		return types.Claim{}, false | ||||
| 	} | ||||
| 
 | ||||
| 	// Fetch all source IDs from indexes
 | ||||
| 	var sourceIDs []string | ||||
| 	k.Store.IterateRewardIndexesByClaimType(ctx, claimType, func(rewardIndexes types.TypedRewardIndexes) bool { | ||||
| 		sourceIDs = append(sourceIDs, rewardIndexes.CollateralType) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	accShares := k.Adapters.OwnerSharesBySource(ctx, claimType, owner, sourceIDs) | ||||
| 
 | ||||
| 	// Synchronize claim for each source ID
 | ||||
| 	for _, share := range accShares { | ||||
| 		claim = k.synchronizeClaim(ctx, claim, share.ID, owner, share.Shares) | ||||
| 	} | ||||
| 
 | ||||
| 	return claim, true | ||||
| } | ||||
| @ -1,334 +0,0 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| type AccumulateTestSuite struct { | ||||
| 	unitTester | ||||
| } | ||||
| 
 | ||||
| func TestAccumulateTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(AccumulateTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) storedTimeEquals( | ||||
| 	claimType types.ClaimType, | ||||
| 	poolID string, | ||||
| 	expected time.Time, | ||||
| ) { | ||||
| 	storedTime, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, claimType, poolID) | ||||
| 	suite.True(found) | ||||
| 	suite.Equal(expected, storedTime) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) storedIndexesEquals( | ||||
| 	claimType types.ClaimType, | ||||
| 	poolID string, | ||||
| 	expected types.RewardIndexes, | ||||
| ) { | ||||
| 	storedIndexes, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, claimType, poolID) | ||||
| 	suite.Equal(found, expected != nil) | ||||
| 	if found { | ||||
| 		suite.Equal(expected, storedIndexes) | ||||
| 	} else { | ||||
| 		suite.Empty(storedIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestStateUpdatedWhenBlockTimeHasIncreased() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	suite.storeGlobalIndexes(claimType, types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	}) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	newAccrualTime := previousAccrualTime.Add(1 * time.Hour) | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(newAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.storedTimeEquals(claimType, pool, newAccrualTime) | ||||
| 	suite.storedIndexesEquals(claimType, pool, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "swap", | ||||
| 			RewardFactor:   d("7.22"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("3.64"), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestStateUnchangedWhenBlockTimeHasNotIncreased() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, previousIndexes) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(previousAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.storedTimeEquals(claimType, pool, previousAccrualTime) | ||||
| 	expected, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.storedIndexesEquals(claimType, pool, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestNoAccumulationWhenSourceSharesAreZero() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper() // no pools, so no source shares
 | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, previousIndexes) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := previousAccrualTime.Add(7 * time.Second) | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
 | ||||
| 	) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| 	suite.storedTimeEquals(claimType, pool, firstAccrualTime) | ||||
| 	expected, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.storedIndexesEquals(claimType, pool, expected) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestStateAddedWhenStateDoesNotExist() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	firstAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// After the first accumulation only the current block time should be stored.
 | ||||
| 	// The indexes will be empty as no time has passed since the previous block because it didn't exist.
 | ||||
| 	suite.storedTimeEquals(claimType, pool, firstAccrualTime) | ||||
| 	suite.storedIndexesEquals(claimType, pool, nil) | ||||
| 
 | ||||
| 	secondAccrualTime := firstAccrualTime.Add(10 * time.Second) | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(secondAccrualTime) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// After the second accumulation both current block time and indexes should be stored.
 | ||||
| 	suite.storedTimeEquals(claimType, pool, secondAccrualTime) | ||||
| 	suite.storedIndexesEquals(claimType, pool, types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "swap", | ||||
| 			RewardFactor:   d("0.02"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: "ukava", | ||||
| 			RewardFactor:   d("0.01"), | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestNoPanicWhenStateDoesNotExist() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper() | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Unix(0, 0), // ensure the test is within start and end times
 | ||||
| 		distantFuture, | ||||
| 		cs(), | ||||
| 	) | ||||
| 
 | ||||
| 	accrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(accrualTime) | ||||
| 
 | ||||
| 	// Accumulate with no swap shares and no rewards per second will result in no increment to the indexes.
 | ||||
| 	// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
 | ||||
| 	// Check there is no panic.
 | ||||
| 	suite.NotPanics(func() { | ||||
| 		suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 	}) | ||||
| 
 | ||||
| 	suite.storedTimeEquals(claimType, pool, accrualTime) | ||||
| 	suite.storedIndexesEquals(claimType, pool, nil) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestNoAccumulationWhenBeforeStartTime() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	previousIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: pool, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "swap", | ||||
| 					RewardFactor:   d("0.02"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "ukava", | ||||
| 					RewardFactor:   d("0.04"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, previousIndexes) | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := previousAccrualTime.Add(10 * time.Second) | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		firstAccrualTime.Add(time.Nanosecond), // start time after accrual time
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 
 | ||||
| 	// The accrual time should be updated, but the indexes unchanged
 | ||||
| 	suite.storedTimeEquals(claimType, pool, firstAccrualTime) | ||||
| 	expectedIndexes, f := previousIndexes.Get(pool) | ||||
| 	suite.True(f) | ||||
| 	suite.storedIndexesEquals(claimType, pool, expectedIndexes) | ||||
| } | ||||
| 
 | ||||
| func (suite *AccumulateTestSuite) TestPanicWhenCurrentTimeLessThanPrevious() { | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	pool := "btc:usdx" | ||||
| 
 | ||||
| 	swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) | ||||
| 	suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil) | ||||
| 
 | ||||
| 	previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime) | ||||
| 
 | ||||
| 	firstAccrualTime := time.Time{} | ||||
| 
 | ||||
| 	period := types.NewMultiRewardPeriod( | ||||
| 		true, | ||||
| 		pool, | ||||
| 		time.Time{}, // start time after accrual time
 | ||||
| 		distantFuture, | ||||
| 		cs(c("swap", 2000), c("ukava", 1000)), | ||||
| 	) | ||||
| 
 | ||||
| 	suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime) | ||||
| 
 | ||||
| 	suite.Panics(func() { | ||||
| 		suite.keeper.AccumulateRewards(suite.ctx, claimType, period) | ||||
| 	}) | ||||
| } | ||||
| @ -9,7 +9,6 @@ import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	earntypes "github.com/kava-labs/kava/x/earn/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/accumulators" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 
 | ||||
| 	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||||
| @ -33,6 +32,34 @@ func (k Keeper) AccumulateEarnRewards(ctx sdk.Context, rewardPeriod types.MultiR | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func GetProportionalRewardsPerSecond( | ||||
| 	rewardPeriod types.MultiRewardPeriod, | ||||
| 	totalBkavaSupply sdk.Int, | ||||
| 	singleBkavaSupply sdk.Int, | ||||
| ) sdk.DecCoins { | ||||
| 	// Rate per bkava-xxx = rewardsPerSecond * % of bkava-xxx
 | ||||
| 	//                    = rewardsPerSecond * (bkava-xxx / total bkava)
 | ||||
| 	//                    = (rewardsPerSecond * bkava-xxx) / total bkava
 | ||||
| 
 | ||||
| 	newRate := sdk.NewDecCoins() | ||||
| 
 | ||||
| 	// Prevent division by zero, if there are no total shares then there are no
 | ||||
| 	// rewards.
 | ||||
| 	if totalBkavaSupply.IsZero() { | ||||
| 		return newRate | ||||
| 	} | ||||
| 
 | ||||
| 	for _, rewardCoin := range rewardPeriod.RewardsPerSecond { | ||||
| 		scaledAmount := rewardCoin.Amount.ToDec(). | ||||
| 			Mul(singleBkavaSupply.ToDec()). | ||||
| 			Quo(totalBkavaSupply.ToDec()) | ||||
| 
 | ||||
| 		newRate = newRate.Add(sdk.NewDecCoinFromDec(rewardCoin.Denom, scaledAmount)) | ||||
| 	} | ||||
| 
 | ||||
| 	return newRate | ||||
| } | ||||
| 
 | ||||
| // accumulateEarnBkavaRewards does the same as AccumulateEarnRewards but for
 | ||||
| // *all* bkava vaults.
 | ||||
| func (k Keeper) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error { | ||||
| @ -85,7 +112,7 @@ func (k Keeper) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.M | ||||
| 			bkavaDenom, | ||||
| 			rewardPeriod.Start, | ||||
| 			rewardPeriod.End, | ||||
| 			accumulators.GetProportionalRewardsPerSecond( | ||||
| 			GetProportionalRewardsPerSecond( | ||||
| 				rewardPeriod, | ||||
| 				totalBkavaValue.Amount, | ||||
| 				derivativeValue.Amount, | ||||
|  | ||||
| @ -381,8 +381,7 @@ func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUnchangedWhenBlockT | ||||
| 
 | ||||
| 	// Must manually accumulate rewards as BeginBlockers only run when the block time increases
 | ||||
| 	// This does not run any x/mint or x/distribution BeginBlockers
 | ||||
| 	err = suite.keeper.AccumulateEarnRewards(suite.Ctx, period) | ||||
| 	suite.NoError(err) | ||||
| 	suite.keeper.AccumulateEarnRewards(suite.Ctx, period) | ||||
| 
 | ||||
| 	// check time and factors
 | ||||
| 
 | ||||
| @ -645,8 +644,7 @@ func (suite *AccumulateEarnRewardsIntegrationTests) TestNoPanicWhenStateDoesNotE | ||||
| 	suite.NotPanics(func() { | ||||
| 		// This does not update any state, as there are no bkava vaults
 | ||||
| 		// to iterate over, denoms are unknown
 | ||||
| 		err := suite.keeper.AccumulateEarnRewards(suite.Ctx, period) | ||||
| 		suite.NoError(err) | ||||
| 		suite.keeper.AccumulateEarnRewards(suite.Ctx, period) | ||||
| 	}) | ||||
| 
 | ||||
| 	// Times are not stored for vaults with no state
 | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| package accumulators_test | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper/accumulators" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
| @ -74,7 +74,7 @@ func TestGetProportionalRewardPeriod(t *testing.T) { | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			rewardsPerSecond := accumulators.GetProportionalRewardsPerSecond( | ||||
| 			rewardsPerSecond := keeper.GetProportionalRewardsPerSecond( | ||||
| 				tt.giveRewardPeriod, | ||||
| 				tt.giveTotalBkavaSupply, | ||||
| 				tt.giveSingleBkavaSupply, | ||||
| @ -1,197 +0,0 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // InitializeClaimTests runs unit tests for the keeper.InitializeClaim method
 | ||||
| //
 | ||||
| // inputs
 | ||||
| // - claim in store if it exists
 | ||||
| // - global indexes in store
 | ||||
| //
 | ||||
| // outputs
 | ||||
| // - sets or creates a claim
 | ||||
| type InitializeClaimTests struct { | ||||
| 	unitTester | ||||
| } | ||||
| 
 | ||||
| func TestInitializeRewardTests(t *testing.T) { | ||||
| 	suite.Run(t, new(InitializeClaimTests)) | ||||
| } | ||||
| 
 | ||||
| func (suite *InitializeClaimTests) TestClaimAddedWhenClaimDoesNotExistAndNoRewards() { | ||||
| 	// When a claim doesn't exist, and a user deposits to a non-rewarded pool;
 | ||||
| 	// then a claim is added with no rewards and no indexes
 | ||||
| 
 | ||||
| 	collateralType := "usdc" | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	owner := arbitraryAddress() | ||||
| 
 | ||||
| 	// no global indexes stored as this pool is not rewarded
 | ||||
| 
 | ||||
| 	suite.keeper.InitializeClaim(suite.ctx, claimType, collateralType, owner) | ||||
| 
 | ||||
| 	syncedClaim, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, owner) | ||||
| 	suite.True(found) | ||||
| 	// A new claim should have empty indexes. It doesn't strictly need the collateralType either.
 | ||||
| 	expectedIndexes := types.MultiRewardIndexes{{ | ||||
| 		CollateralType: collateralType, | ||||
| 		RewardIndexes:  nil, | ||||
| 	}} | ||||
| 	suite.Equal(expectedIndexes, syncedClaim.RewardIndexes) | ||||
| 	// a new claim should start with 0 rewards
 | ||||
| 	suite.Equal(sdk.Coins(nil), syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *InitializeClaimTests) TestClaimAddedWhenClaimDoesNotExistAndRewardsExist() { | ||||
| 	// When a claim doesn't exist, and a user deposits to a rewarded pool;
 | ||||
| 	// then a claim is added with no rewards and indexes matching the global indexes
 | ||||
| 
 | ||||
| 	collateralType := "usdc" | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 	owner := arbitraryAddress() | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom", | ||||
| 					RewardFactor:   d("1000.001"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	suite.keeper.InitializeClaim(suite.ctx, claimType, collateralType, owner) | ||||
| 
 | ||||
| 	syncedClaim, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, owner) | ||||
| 	suite.True(found) | ||||
| 	// a new claim should start with the current global indexes
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// a new claim should start with 0 rewards
 | ||||
| 	suite.Equal(sdk.Coins(nil), syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *InitializeClaimTests) TestClaimUpdatedWhenClaimExistsAndNoRewards() { | ||||
| 	// When a claim exists, and a user deposits to a new non-rewarded pool;
 | ||||
| 	// then the claim's rewards don't change
 | ||||
| 
 | ||||
| 	preexistingCollateralType := "preexisting" | ||||
| 
 | ||||
| 	preexistingIndexes := types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "rewarddenom", | ||||
| 			RewardFactor:   d("1000.001"), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	newCollateralType := "usdc" | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: arbitraryCoins(), | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: preexistingCollateralType, | ||||
| 				RewardIndexes:  preexistingIndexes, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	// no global indexes stored as the new pool is not rewarded
 | ||||
| 
 | ||||
| 	suite.keeper.InitializeClaim(suite.ctx, claimType, newCollateralType, claim.Owner) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// The preexisting indexes shouldn't be changed. It doesn't strictly need the new collateralType either.
 | ||||
| 	expectedIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: preexistingCollateralType, | ||||
| 			RewardIndexes:  preexistingIndexes, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: newCollateralType, | ||||
| 			RewardIndexes:  nil, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.Equal(expectedIndexes, syncedClaim.RewardIndexes) | ||||
| 	// init should never alter the rewards
 | ||||
| 	suite.Equal(claim.Reward, syncedClaim.Reward) | ||||
| } | ||||
| 
 | ||||
| func (suite *InitializeClaimTests) TestClaimUpdatedWhenClaimExistsAndRewardsExist() { | ||||
| 	// When a claim exists, and a user deposits to a new rewarded pool;
 | ||||
| 	// then the claim's rewards don't change and the indexes are updated to match the global indexes
 | ||||
| 
 | ||||
| 	preexistingCollateralType := "preexisting" | ||||
| 	preexistingIndexes := types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "rewarddenom", | ||||
| 			RewardFactor:   d("1000.001"), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	newCollateralType := "btcb:usdx" | ||||
| 	newIndexes := types.RewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "otherrewarddenom", | ||||
| 			RewardFactor:   d("1000.001"), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	claimType := types.CLAIM_TYPE_SWAP | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: arbitraryCoins(), | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: preexistingCollateralType, | ||||
| 				RewardIndexes:  preexistingIndexes, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: preexistingCollateralType, | ||||
| 			RewardIndexes:  increaseRewardFactors(preexistingIndexes), | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: newCollateralType, | ||||
| 			RewardIndexes:  newIndexes, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	suite.keeper.InitializeClaim(suite.ctx, claimType, newCollateralType, claim.Owner) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// only the indexes for the new pool should be updated
 | ||||
| 	expectedIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: preexistingCollateralType, | ||||
| 			RewardIndexes:  preexistingIndexes, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: newCollateralType, | ||||
| 			RewardIndexes:  newIndexes, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.Equal(expectedIndexes, syncedClaim.RewardIndexes) | ||||
| 	// init should never alter the rewards
 | ||||
| 	suite.Equal(claim.Reward, syncedClaim.Reward) | ||||
| } | ||||
| @ -1,472 +0,0 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // SynchronizeClaimTests runs unit tests for the keeper.SynchronizeClaim method
 | ||||
| //
 | ||||
| // inputs
 | ||||
| // - claim in store (only claim.RewardIndexes, claim.Reward)
 | ||||
| // - global indexes in store
 | ||||
| // - shares function arg
 | ||||
| //
 | ||||
| // outputs
 | ||||
| // - sets a claim
 | ||||
| type SynchronizeClaimTests struct { | ||||
| 	unitTester | ||||
| } | ||||
| 
 | ||||
| func TestSynchronizeClaim(t *testing.T) { | ||||
| 	suite.Run(t, new(SynchronizeClaimTests)) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesHaveIncreased() { | ||||
| 	// This is the normal case
 | ||||
| 	// Given some time has passed (meaning the global indexes have increased)
 | ||||
| 	// When the claim is synced
 | ||||
| 	// The user earns rewards for the time passed, and the claim indexes are updated
 | ||||
| 
 | ||||
| 	originalReward := arbitraryCoins() | ||||
| 	collateralType := "base:quote" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: originalReward, | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "rewarddenom", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes updated from global
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// new reward is (new index - old index) * user shares
 | ||||
| 	suite.Equal( | ||||
| 		cs(c("rewarddenom", 1_000_001_000_000)).Add(originalReward...), | ||||
| 		syncedClaim.Reward, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenGlobalIndexesUnchanged() { | ||||
| 	// It should be safe to call SynchronizeClaim multiple times
 | ||||
| 
 | ||||
| 	collateralType := "base:quote" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	unchangingIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom", | ||||
| 					RewardFactor:   d("1000.001"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:          claimType, | ||||
| 		Owner:         arbitraryAddress(), | ||||
| 		Reward:        arbitraryCoins(), | ||||
| 		RewardIndexes: unchangingIndexes, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	suite.storeGlobalIndexes(claimType, unchangingIndexes) | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// claim should have the same rewards and indexes as before
 | ||||
| 	suite.Equal(claim, syncedClaim) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardAdded() { | ||||
| 	// When a new reward is added (via gov) for a pool the user has already deposited to, and the claim is synced;
 | ||||
| 	// Then the user earns rewards for the time since the reward was added, and the indexes are added to the claim.
 | ||||
| 
 | ||||
| 	originalReward := arbitraryCoins() | ||||
| 	newlyRewardcollateralType := "newlyRewardedPool" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: originalReward, | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: "currentlyRewardedPool", | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "reward", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: "currentlyRewardedPool", | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "reward", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			CollateralType: newlyRewardcollateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "otherreward", | ||||
| 					// Indexes start at 0 when the reward is added by gov,
 | ||||
| 					// so this represents the syncing happening some time later.
 | ||||
| 					RewardFactor: d("1000.001"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, newlyRewardcollateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// the new indexes should be added to the claim, but the old ones should be unchanged
 | ||||
| 	newlyRewrdedIndexes, _ := globalIndexes.Get(newlyRewardcollateralType) | ||||
| 	expectedIndexes := claim.RewardIndexes.With(newlyRewardcollateralType, newlyRewrdedIndexes) | ||||
| 	suite.Equal(expectedIndexes, syncedClaim.RewardIndexes) | ||||
| 	// new reward is (new index - old index) * shares for the synced pool
 | ||||
| 	// The old index for `newlyrewarded` isn't in the claim, so it's added starting at 0 for calculating the reward.
 | ||||
| 	suite.Equal( | ||||
| 		cs(c("otherreward", 1_000_001_000_000)).Add(originalReward...), | ||||
| 		syncedClaim.Reward, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenNoReward() { | ||||
| 	// When a pool is not rewarded but the user has deposited to that pool, and the claim is synced;
 | ||||
| 	// Then the claim should be the same.
 | ||||
| 
 | ||||
| 	collateralType := "nonRewardPool" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:          claimType, | ||||
| 		Owner:         arbitraryAddress(), | ||||
| 		Reward:        arbitraryCoins(), | ||||
| 		RewardIndexes: nonEmptyMultiRewardIndexes, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	// No global indexes stored as this pool is not rewarded
 | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	suite.Equal(claim, syncedClaim) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardDenomAdded() { | ||||
| 	// When a new reward coin is added (via gov) to an already rewarded pool (that the user has already deposited to), and the claim is synced;
 | ||||
| 	// Then the user earns rewards for the time since the reward was added, and the new indexes are added.
 | ||||
| 
 | ||||
| 	originalReward := arbitraryCoins() | ||||
| 	collateralType := "base:quote" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: originalReward, | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "reward", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "reward", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					CollateralType: "otherreward", | ||||
| 					// Indexes start at 0 when the reward is added by gov,
 | ||||
| 					// so this represents the syncing happening some time later.
 | ||||
| 					RewardFactor: d("1000.001"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	userShares := i(1e9) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes should have the new reward denom added
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// new reward is (new index - old index) * shares
 | ||||
| 	// The old index for `otherreward` isn't in the claim, so it's added starting at 0 for calculating the reward.
 | ||||
| 	suite.Equal( | ||||
| 		cs(c("reward", 1_000_001_000_000), c("otherreward", 1_000_001_000_000)).Add(originalReward...), | ||||
| 		syncedClaim.Reward, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesIncreasedAndSourceIsZero() { | ||||
| 	// Given some time has passed (meaning the global indexes have increased)
 | ||||
| 	// When the claim is synced, but the user has no shares
 | ||||
| 	// The user earns no rewards for the time passed, but the claim indexes are updated
 | ||||
| 
 | ||||
| 	collateralType := "base:quote" | ||||
| 	claimType := types.CLAIM_TYPE_USDX_MINTING | ||||
| 
 | ||||
| 	claim := types.Claim{ | ||||
| 		Type:   claimType, | ||||
| 		Owner:  arbitraryAddress(), | ||||
| 		Reward: arbitraryCoins(), | ||||
| 		RewardIndexes: types.MultiRewardIndexes{ | ||||
| 			{ | ||||
| 				CollateralType: collateralType, | ||||
| 				RewardIndexes: types.RewardIndexes{ | ||||
| 					{ | ||||
| 						CollateralType: "rewarddenom", | ||||
| 						RewardFactor:   d("1000.001"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.keeper.Store.SetClaim(suite.ctx, claim) | ||||
| 
 | ||||
| 	globalIndexes := types.MultiRewardIndexes{ | ||||
| 		{ | ||||
| 			CollateralType: collateralType, | ||||
| 			RewardIndexes: types.RewardIndexes{ | ||||
| 				{ | ||||
| 					CollateralType: "rewarddenom", | ||||
| 					RewardFactor:   d("2000.002"), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.storeGlobalIndexes(claimType, globalIndexes) | ||||
| 
 | ||||
| 	userShares := i(0) | ||||
| 
 | ||||
| 	suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec()) | ||||
| 
 | ||||
| 	syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner) | ||||
| 	// indexes updated from global
 | ||||
| 	suite.Equal(globalIndexes, syncedClaim.RewardIndexes) | ||||
| 	// 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.Store.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.Store.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.Store.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) | ||||
| } | ||||
| @ -1,95 +0,0 @@ | ||||
| package store | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // GetRewardAccrualTime fetches the last time rewards were accrued for the
 | ||||
| // specified ClaimType and sourceID.
 | ||||
| func (k IncentiveStore) GetRewardAccrualTime( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| ) (time.Time, bool) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType)) | ||||
| 	b := store.Get(types.GetKeyFromSourceID(sourceID)) | ||||
| 	if b == nil { | ||||
| 		return time.Time{}, false | ||||
| 	} | ||||
| 	var accrualTime types.AccrualTime | ||||
| 	k.cdc.MustUnmarshal(b, &accrualTime) | ||||
| 
 | ||||
| 	return accrualTime.PreviousAccumulationTime, true | ||||
| } | ||||
| 
 | ||||
| // SetRewardAccrualTime stores the last time rewards were accrued for the
 | ||||
| // specified ClaimType and sourceID.
 | ||||
| func (k IncentiveStore) SetRewardAccrualTime( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	sourceID string, | ||||
| 	blockTime time.Time, | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType)) | ||||
| 
 | ||||
| 	at := types.NewAccrualTime(claimType, sourceID, blockTime) | ||||
| 	bz := k.cdc.MustMarshal(&at) | ||||
| 	store.Set(types.GetKeyFromSourceID(sourceID), bz) | ||||
| } | ||||
| 
 | ||||
| // IterateRewardAccrualTimesByClaimType iterates over all reward accrual times of a given
 | ||||
| // claimType and performs a callback function.
 | ||||
| func (k IncentiveStore) IterateRewardAccrualTimesByClaimType( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	cb func(string, time.Time) (stop bool), | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType)) | ||||
| 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var accrualTime types.AccrualTime | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &accrualTime) | ||||
| 
 | ||||
| 		if cb(accrualTime.CollateralType, accrualTime.PreviousAccumulationTime) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // IterateRewardAccrualTimes iterates over all reward accrual times of any
 | ||||
| // claimType and performs a callback function.
 | ||||
| func (k IncentiveStore) IterateRewardAccrualTimes( | ||||
| 	ctx sdk.Context, | ||||
| 	cb func(types.AccrualTime) (stop bool), | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousRewardAccrualTimeKeyPrefix) | ||||
| 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var accrualTime types.AccrualTime | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &accrualTime) | ||||
| 
 | ||||
| 		if cb(accrualTime) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetAllRewardAccrualTimes returns all reward accrual times of any claimType.
 | ||||
| func (k IncentiveStore) GetAllRewardAccrualTimes(ctx sdk.Context) types.AccrualTimes { | ||||
| 	var ats types.AccrualTimes | ||||
| 	k.IterateRewardAccrualTimes( | ||||
| 		ctx, | ||||
| 		func(accrualTime types.AccrualTime) bool { | ||||
| 			ats = append(ats, accrualTime) | ||||
| 			return false | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	return ats | ||||
| } | ||||
| @ -1,105 +0,0 @@ | ||||
| package store | ||||
| 
 | ||||
| import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // GetClaim returns the claim in the store corresponding the the owner and
 | ||||
| // claimType, and a boolean for if the claim was found
 | ||||
| func (k IncentiveStore) GetClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	addr sdk.AccAddress, | ||||
| ) (types.Claim, bool) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType)) | ||||
| 	bz := store.Get(addr) | ||||
| 	if bz == nil { | ||||
| 		return types.Claim{}, false | ||||
| 	} | ||||
| 	var c types.Claim | ||||
| 	k.cdc.MustUnmarshal(bz, &c) | ||||
| 	return c, true | ||||
| } | ||||
| 
 | ||||
| // SetClaim sets the claim in the store corresponding to the owner and claimType
 | ||||
| func (k IncentiveStore) SetClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	c types.Claim, | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(c.Type)) | ||||
| 	bz := k.cdc.MustMarshal(&c) | ||||
| 	store.Set(c.Owner, bz) | ||||
| } | ||||
| 
 | ||||
| // DeleteClaim deletes the claim in the store corresponding to the owner and claimType
 | ||||
| func (k IncentiveStore) DeleteClaim( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	owner sdk.AccAddress, | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType)) | ||||
| 	store.Delete(owner) | ||||
| } | ||||
| 
 | ||||
| // IterateClaimsByClaimType iterates over all claim objects in the store of a given
 | ||||
| // claimType and preforms a callback function
 | ||||
| func (k IncentiveStore) IterateClaimsByClaimType( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	cb func(c types.Claim) (stop bool), | ||||
| ) { | ||||
| 	iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType)) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var c types.Claim | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &c) | ||||
| 		if cb(c) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetClaims returns all Claim objects in the store of a given claimType
 | ||||
| func (k IncentiveStore) GetClaims( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| ) types.Claims { | ||||
| 	var cs types.Claims | ||||
| 	k.IterateClaimsByClaimType(ctx, claimType, func(c types.Claim) (stop bool) { | ||||
| 		cs = append(cs, c) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	return cs | ||||
| } | ||||
| 
 | ||||
| // IterateClaims iterates over all claim objects of any claimType in the
 | ||||
| // store and preforms a callback function
 | ||||
| func (k IncentiveStore) IterateClaims( | ||||
| 	ctx sdk.Context, | ||||
| 	cb func(c types.Claim) (stop bool), | ||||
| ) { | ||||
| 	iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.ClaimKeyPrefix) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var c types.Claim | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &c) | ||||
| 		if cb(c) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetAllClaims returns all Claim objects in the store of any claimType
 | ||||
| func (k IncentiveStore) GetAllClaims(ctx sdk.Context) types.Claims { | ||||
| 	var cs types.Claims | ||||
| 	k.IterateClaims(ctx, func(c types.Claim) (stop bool) { | ||||
| 		cs = append(cs, c) | ||||
| 		return false | ||||
| 	}) | ||||
| 
 | ||||
| 	return cs | ||||
| } | ||||
| @ -1,95 +0,0 @@ | ||||
| package store | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // SetRewardIndexes stores the global reward indexes that track total rewards of
 | ||||
| // a given claim type and collateralType.
 | ||||
| func (k IncentiveStore) SetRewardIndexes( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	collateralType string, | ||||
| 	indexes types.RewardIndexes, | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType)) | ||||
| 	bz := k.cdc.MustMarshal(&types.TypedRewardIndexes{ | ||||
| 		ClaimType:      claimType, | ||||
| 		CollateralType: collateralType, | ||||
| 		RewardIndexes:  indexes, | ||||
| 	}) | ||||
| 	store.Set(types.GetKeyFromSourceID(collateralType), bz) | ||||
| } | ||||
| 
 | ||||
| // GetRewardIndexesOfClaimType fetches the global reward indexes that track total rewards
 | ||||
| // of a given claimType and collateralType.
 | ||||
| func (k IncentiveStore) GetRewardIndexesOfClaimType( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	collateralType string, | ||||
| ) (types.RewardIndexes, bool) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType)) | ||||
| 	bz := store.Get(types.GetKeyFromSourceID(collateralType)) | ||||
| 	if bz == nil { | ||||
| 		return types.RewardIndexes{}, false | ||||
| 	} | ||||
| 
 | ||||
| 	var proto types.TypedRewardIndexes | ||||
| 	k.cdc.MustUnmarshal(bz, &proto) | ||||
| 	return proto.RewardIndexes, true | ||||
| } | ||||
| 
 | ||||
| // IterateRewardIndexesByClaimType iterates over all reward index objects in the store of a
 | ||||
| // given ClaimType and performs a callback function.
 | ||||
| func (k IncentiveStore) IterateRewardIndexesByClaimType( | ||||
| 	ctx sdk.Context, | ||||
| 	claimType types.ClaimType, | ||||
| 	cb func(types.TypedRewardIndexes) (stop bool), | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType)) | ||||
| 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var typedRewardIndexes types.TypedRewardIndexes | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &typedRewardIndexes) | ||||
| 
 | ||||
| 		if cb(typedRewardIndexes) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // IterateRewardIndexes iterates over all reward index objects in the store
 | ||||
| // of all ClaimTypes and performs a callback function.
 | ||||
| func (k IncentiveStore) IterateRewardIndexes( | ||||
| 	ctx sdk.Context, | ||||
| 	cb func(types.TypedRewardIndexes) (stop bool), | ||||
| ) { | ||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.RewardIndexesKeyPrefix) | ||||
| 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var typedRewardIndexes types.TypedRewardIndexes | ||||
| 		k.cdc.MustUnmarshal(iterator.Value(), &typedRewardIndexes) | ||||
| 
 | ||||
| 		if cb(typedRewardIndexes) { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetRewardIndexes returns all reward indexes of any claimType.
 | ||||
| func (k IncentiveStore) GetRewardIndexes(ctx sdk.Context) types.TypedRewardIndexesList { | ||||
| 	var tril types.TypedRewardIndexesList | ||||
| 	k.IterateRewardIndexes( | ||||
| 		ctx, | ||||
| 		func(typedRewardIndexes types.TypedRewardIndexes) bool { | ||||
| 			tril = append(tril, typedRewardIndexes) | ||||
| 			return false | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	return tril | ||||
| } | ||||
| @ -1,20 +0,0 @@ | ||||
| package store | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| ) | ||||
| 
 | ||||
| // IncentiveStore provides methods for interacting with the incentive store.
 | ||||
| type IncentiveStore struct { | ||||
| 	cdc codec.Codec | ||||
| 	key sdk.StoreKey | ||||
| } | ||||
| 
 | ||||
| // NewIncentiveStore creates a new IncentiveStore
 | ||||
| func NewIncentiveStore(cdc codec.Codec, key sdk.StoreKey) IncentiveStore { | ||||
| 	return IncentiveStore{ | ||||
| 		cdc: cdc, | ||||
| 		key: key, | ||||
| 	} | ||||
| } | ||||
| @ -118,12 +118,6 @@ func (suite *unitTester) storeGlobalEarnIndexes(indexes types.MultiRewardIndexes | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *unitTester) storeGlobalIndexes(claimType types.ClaimType, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		suite.keeper.Store.SetRewardIndexes(suite.ctx, claimType, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *unitTester) storeHardClaim(claim types.HardLiquidityProviderClaim) { | ||||
| 	suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim) | ||||
| } | ||||
|  | ||||
| @ -1,52 +0,0 @@ | ||||
| package v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // Legacy store key prefixes
 | ||||
| var ( | ||||
| 	EarnClaimKeyPrefix                     = []byte{0x18} // prefix for keys that store earn claims
 | ||||
| 	EarnRewardIndexesKeyPrefix             = []byte{0x19} // prefix for key that stores earn reward indexes
 | ||||
| 	PreviousEarnRewardAccrualTimeKeyPrefix = []byte{0x20} // prefix for key that stores the previous time earn rewards accrued
 | ||||
| ) | ||||
| 
 | ||||
| func LegacyAccrualTimeKeyFromClaimType(claimType types.ClaimType) []byte { | ||||
| 	switch claimType { | ||||
| 	case types.CLAIM_TYPE_HARD_BORROW: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_HARD_SUPPLY: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_EARN: | ||||
| 		return PreviousEarnRewardAccrualTimeKeyPrefix | ||||
| 	case types.CLAIM_TYPE_SAVINGS: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_SWAP: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_USDX_MINTING: | ||||
| 		panic("todo") | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unrecognized claim type: %s", claimType)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func LegacyRewardIndexesKeyFromClaimType(claimType types.ClaimType) []byte { | ||||
| 	switch claimType { | ||||
| 	case types.CLAIM_TYPE_HARD_BORROW: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_HARD_SUPPLY: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_EARN: | ||||
| 		return EarnRewardIndexesKeyPrefix | ||||
| 	case types.CLAIM_TYPE_SAVINGS: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_SWAP: | ||||
| 		panic("todo") | ||||
| 	case types.CLAIM_TYPE_USDX_MINTING: | ||||
| 		panic("todo") | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("unrecognized claim type: %s", claimType)) | ||||
| 	} | ||||
| } | ||||
| @ -1,142 +0,0 @@ | ||||
| package v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	"github.com/cosmos/cosmos-sdk/store/prefix" | ||||
| 	storetypes "github.com/cosmos/cosmos-sdk/store/types" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // MigrateStore performs in-place migrations from incentive ConsensusVersion 2 to 3.
 | ||||
| func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error { | ||||
| 	store := ctx.KVStore(storeKey) | ||||
| 
 | ||||
| 	if err := MigrateEarnClaims(store, cdc); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := MigrateAccrualTimes(store, cdc, types.CLAIM_TYPE_EARN); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := MigrateRewardIndexes(store, cdc, types.CLAIM_TYPE_EARN); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // MigrateEarnClaims migrates earn claims from v2 to v3
 | ||||
| func MigrateEarnClaims(store sdk.KVStore, cdc codec.BinaryCodec) error { | ||||
| 	newStore := prefix.NewStore(store, types.GetClaimKeyPrefix(types.CLAIM_TYPE_EARN)) | ||||
| 
 | ||||
| 	oldStore := prefix.NewStore(store, EarnClaimKeyPrefix) | ||||
| 	iterator := sdk.KVStorePrefixIterator(oldStore, []byte{}) | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var c types.EarnClaim | ||||
| 		cdc.MustUnmarshal(iterator.Value(), &c) | ||||
| 
 | ||||
| 		if err := c.Validate(); err != nil { | ||||
| 			return fmt.Errorf("invalid v2 EarnClaim: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// Convert to the new Claim type
 | ||||
| 		newClaim := types.NewClaim( | ||||
| 			types.CLAIM_TYPE_EARN, | ||||
| 			c.Owner, | ||||
| 			c.Reward, | ||||
| 			c.RewardIndexes, | ||||
| 		) | ||||
| 
 | ||||
| 		if err := newClaim.Validate(); err != nil { | ||||
| 			return fmt.Errorf("invalid v3 EarnClaim: %w", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// Set in the **newStore** for the new store prefix
 | ||||
| 		newStore.Set(c.Owner, cdc.MustMarshal(&newClaim)) | ||||
| 
 | ||||
| 		// Remove the old claim in the old store
 | ||||
| 		oldStore.Delete(iterator.Key()) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // MigrateAccrualTimes migrates accrual times from v2 to v3
 | ||||
| func MigrateAccrualTimes( | ||||
| 	store sdk.KVStore, | ||||
| 	cdc codec.BinaryCodec, | ||||
| 	claimType types.ClaimType, | ||||
| ) error { | ||||
| 	newStore := prefix.NewStore(store, types.GetPreviousRewardAccrualTimeKeyPrefix(claimType)) | ||||
| 
 | ||||
| 	// Need prefix.NewStore instead of using it directly in the iterator, as
 | ||||
| 	// there would be an extra space in the key
 | ||||
| 	legacyPrefix := LegacyAccrualTimeKeyFromClaimType(claimType) | ||||
| 	oldStore := prefix.NewStore(store, legacyPrefix) | ||||
| 	iterator := sdk.KVStorePrefixIterator(oldStore, []byte{}) | ||||
| 
 | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var blockTime time.Time | ||||
| 		if err := blockTime.UnmarshalBinary(iterator.Value()); err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 
 | ||||
| 		sourceID := string(iterator.Key()) | ||||
| 
 | ||||
| 		at := types.NewAccrualTime(claimType, sourceID, blockTime) | ||||
| 		if err := at.Validate(); err != nil { | ||||
| 			return fmt.Errorf("invalid v3 accrual time for claim type %s: %w", claimType, err) | ||||
| 		} | ||||
| 
 | ||||
| 		// Set in the **newStore** for the new store prefix
 | ||||
| 		bz := cdc.MustMarshal(&at) | ||||
| 		newStore.Set(types.GetKeyFromSourceID(sourceID), bz) | ||||
| 
 | ||||
| 		// Remove the old accrual time in the old store
 | ||||
| 		oldStore.Delete(iterator.Key()) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // MigrateRewardIndexes migrates reward indexes from v2 to v3
 | ||||
| func MigrateRewardIndexes( | ||||
| 	store sdk.KVStore, | ||||
| 	cdc codec.BinaryCodec, | ||||
| 	claimType types.ClaimType, | ||||
| ) error { | ||||
| 	newStore := prefix.NewStore(store, types.GetRewardIndexesKeyPrefix(claimType)) | ||||
| 
 | ||||
| 	legacyPrefix := LegacyRewardIndexesKeyFromClaimType(claimType) | ||||
| 	oldStore := prefix.NewStore(store, legacyPrefix) | ||||
| 	iterator := sdk.KVStorePrefixIterator(oldStore, []byte{}) | ||||
| 
 | ||||
| 	defer iterator.Close() | ||||
| 	for ; iterator.Valid(); iterator.Next() { | ||||
| 		var proto types.RewardIndexesProto | ||||
| 		cdc.MustUnmarshal(iterator.Value(), &proto) | ||||
| 
 | ||||
| 		sourceID := string(iterator.Key()) | ||||
| 
 | ||||
| 		rewardIndex := types.NewTypedRewardIndexes( | ||||
| 			claimType, | ||||
| 			sourceID, | ||||
| 			proto.RewardIndexes, | ||||
| 		) | ||||
| 
 | ||||
| 		bz := cdc.MustMarshal(&rewardIndex) | ||||
| 		newStore.Set(types.GetKeyFromSourceID(sourceID), bz) | ||||
| 
 | ||||
| 		// Remove the old reward indexes in the old store
 | ||||
| 		oldStore.Delete(iterator.Key()) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -1,159 +0,0 @@ | ||||
| package v3_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/incentive/testutil" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	v3 "github.com/kava-labs/kava/x/incentive/migrations/v3" | ||||
| ) | ||||
| 
 | ||||
| type StoreMigrateTestSuite struct { | ||||
| 	testutil.IntegrationTester | ||||
| 
 | ||||
| 	Addrs []sdk.AccAddress | ||||
| 
 | ||||
| 	keeper   testutil.TestKeeper | ||||
| 	storeKey sdk.StoreKey | ||||
| 	cdc      codec.Codec | ||||
| } | ||||
| 
 | ||||
| func TestStoreMigrateTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(StoreMigrateTestSuite)) | ||||
| } | ||||
| 
 | ||||
| func (suite *StoreMigrateTestSuite) SetupTest() { | ||||
| 	suite.IntegrationTester.SetupTest() | ||||
| 
 | ||||
| 	suite.keeper = testutil.TestKeeper{ | ||||
| 		Keeper: suite.App.GetIncentiveKeeper(), | ||||
| 	} | ||||
| 
 | ||||
| 	_, suite.Addrs = app.GeneratePrivKeyAddressPairs(5) | ||||
| 	suite.cdc = suite.App.AppCodec() | ||||
| 	suite.storeKey = suite.App.GetKeys()[types.StoreKey] | ||||
| 
 | ||||
| 	suite.StartChain() | ||||
| } | ||||
| 
 | ||||
| func (suite *StoreMigrateTestSuite) TestMigrateEarnClaims() { | ||||
| 	store := suite.Ctx.KVStore(suite.storeKey) | ||||
| 
 | ||||
| 	// Create v2 earn claims
 | ||||
| 	claim1 := types.NewEarnClaim( | ||||
| 		suite.Addrs[0], | ||||
| 		sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))), | ||||
| 		types.MultiRewardIndexes{ | ||||
| 			types.NewMultiRewardIndex("bnb-a", types.RewardIndexes{ | ||||
| 				types.NewRewardIndex("bnb", sdk.NewDec(1)), | ||||
| 			}), | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	claim2 := types.NewEarnClaim( | ||||
| 		suite.Addrs[1], | ||||
| 		sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(100))), | ||||
| 		types.MultiRewardIndexes{ | ||||
| 			types.NewMultiRewardIndex("ukava", types.RewardIndexes{ | ||||
| 				types.NewRewardIndex("ukava", sdk.NewDec(1)), | ||||
| 			}), | ||||
| 		}, | ||||
| 	) | ||||
| 
 | ||||
| 	suite.keeper.SetEarnClaim(suite.Ctx, claim1) | ||||
| 	suite.keeper.SetEarnClaim(suite.Ctx, claim2) | ||||
| 
 | ||||
| 	// Run earn claim migrations
 | ||||
| 	err := v3.MigrateEarnClaims(store, suite.cdc) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// Check that the claim was migrated correctly
 | ||||
| 	newClaim1, found := suite.keeper.Store.GetClaim(suite.Ctx, types.CLAIM_TYPE_EARN, claim1.Owner) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(claim1.Owner, newClaim1.Owner) | ||||
| 
 | ||||
| 	newClaim2, found := suite.keeper.Store.GetClaim(suite.Ctx, types.CLAIM_TYPE_EARN, claim2.Owner) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(claim2.Owner, newClaim2.Owner) | ||||
| 
 | ||||
| 	// Ensure removed from old store
 | ||||
| 	_, found = suite.keeper.GetEarnClaim(suite.Ctx, claim1.Owner) | ||||
| 	suite.Require().False(found) | ||||
| 
 | ||||
| 	_, found = suite.keeper.GetEarnClaim(suite.Ctx, claim2.Owner) | ||||
| 	suite.Require().False(found) | ||||
| } | ||||
| 
 | ||||
| func (suite *StoreMigrateTestSuite) TestMigrateAccrualTimes() { | ||||
| 	store := suite.Ctx.KVStore(suite.storeKey) | ||||
| 	vaultDenom1 := "ukava" | ||||
| 	vaultDenom2 := "usdc" | ||||
| 
 | ||||
| 	// Create v2 accrual times
 | ||||
| 	accrualTime1 := time.Now() | ||||
| 	accrualTime2 := time.Now().Add(time.Hour * 24) | ||||
| 	suite.keeper.SetEarnRewardAccrualTime(suite.Ctx, vaultDenom1, accrualTime1) | ||||
| 	suite.keeper.SetEarnRewardAccrualTime(suite.Ctx, vaultDenom2, accrualTime2) | ||||
| 
 | ||||
| 	// Run accrual time migrations
 | ||||
| 	err := v3.MigrateAccrualTimes(store, suite.cdc, types.CLAIM_TYPE_EARN) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	// Check that the accrual time was migrated correctly
 | ||||
| 	newAccrualTime1, found := suite.keeper.Store.GetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(accrualTime1.Unix(), newAccrualTime1.Unix()) | ||||
| 
 | ||||
| 	newAccrualTime2, found := suite.keeper.Store.GetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(accrualTime2.Unix(), newAccrualTime2.Unix()) | ||||
| 
 | ||||
| 	// Ensure removed from old store
 | ||||
| 	_, found = suite.keeper.GetEarnRewardAccrualTime(suite.Ctx, vaultDenom1) | ||||
| 	suite.Require().False(found) | ||||
| 	_, found = suite.keeper.GetEarnRewardAccrualTime(suite.Ctx, vaultDenom2) | ||||
| 	suite.Require().False(found) | ||||
| } | ||||
| 
 | ||||
| func (suite *StoreMigrateTestSuite) TestMigrateRewardIndexes() { | ||||
| 	store := suite.Ctx.KVStore(suite.storeKey) | ||||
| 	vaultDenom1 := "ukava" | ||||
| 	vaultDenom2 := "usdc" | ||||
| 
 | ||||
| 	rewardIndexes1 := types.RewardIndexes{ | ||||
| 		types.NewRewardIndex("ukava", sdk.NewDec(1)), | ||||
| 		types.NewRewardIndex("hard", sdk.NewDec(2)), | ||||
| 	} | ||||
| 	rewardIndexes2 := types.RewardIndexes{ | ||||
| 		types.NewRewardIndex("ukava", sdk.NewDec(4)), | ||||
| 		types.NewRewardIndex("swp", sdk.NewDec(10)), | ||||
| 	} | ||||
| 
 | ||||
| 	suite.keeper.SetEarnRewardIndexes(suite.Ctx, vaultDenom1, rewardIndexes1) | ||||
| 	suite.keeper.SetEarnRewardIndexes(suite.Ctx, vaultDenom2, rewardIndexes2) | ||||
| 
 | ||||
| 	err := v3.MigrateRewardIndexes(store, suite.cdc, types.CLAIM_TYPE_EARN) | ||||
| 	suite.Require().NoError(err) | ||||
| 
 | ||||
| 	newRewardIndexes1, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(rewardIndexes1, newRewardIndexes1) | ||||
| 
 | ||||
| 	newRewardIndexes2, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2) | ||||
| 	suite.Require().True(found) | ||||
| 	suite.Require().Equal(rewardIndexes2, newRewardIndexes2) | ||||
| 
 | ||||
| 	// Ensure removed from old store
 | ||||
| 	_, found = suite.keeper.GetEarnRewardIndexes(suite.Ctx, vaultDenom1) | ||||
| 	suite.Require().False(found) | ||||
| 
 | ||||
| 	_, found = suite.keeper.GetEarnRewardIndexes(suite.Ctx, vaultDenom2) | ||||
| 	suite.Require().False(found) | ||||
| } | ||||
| @ -21,9 +21,6 @@ import ( | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // ConsensusVersion defines the current module consensus version.
 | ||||
| const ConsensusVersion = 3 | ||||
| 
 | ||||
| var ( | ||||
| 	_ module.AppModule      = AppModule{} | ||||
| 	_ module.AppModuleBasic = AppModuleBasic{} | ||||
| @ -84,7 +81,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd | ||||
| 
 | ||||
| // ConsensusVersion implements AppModule/ConsensusVersion.
 | ||||
| func (AppModule) ConsensusVersion() uint64 { | ||||
| 	return ConsensusVersion | ||||
| 	return 1 | ||||
| } | ||||
| 
 | ||||
| // GetTxCmd returns the root tx command for the incentive module.
 | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| package testutil | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| @ -192,48 +191,6 @@ func (builder IncentiveGenesisBuilder) WithSimpleEarnRewardPeriod(ctype string, | ||||
| 	return builder.WithInitializedEarnRewardPeriod(builder.simpleRewardPeriod(ctype, rewardsPerSecond)) | ||||
| } | ||||
| 
 | ||||
| // WithInitializedRewardPeriod adds an initialized typed reward period.
 | ||||
| func (builder IncentiveGenesisBuilder) WithInitializedRewardPeriod( | ||||
| 	claimType types.ClaimType, | ||||
| 	periods types.MultiRewardPeriods, | ||||
| ) IncentiveGenesisBuilder { | ||||
| 	// Append to claim type if it exists -- claim types must be unique in RewardPeriods field
 | ||||
| 	for _, rewardPeriod := range builder.Params.RewardPeriods { | ||||
| 		if rewardPeriod.ClaimType == claimType { | ||||
| 			rewardPeriod.RewardPeriods = append(rewardPeriod.RewardPeriods, periods...) | ||||
| 			return builder | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Add new reward period for claim type
 | ||||
| 	builder.Params.RewardPeriods = append(builder.Params.RewardPeriods, types.NewTypedMultiRewardPeriod(claimType, periods)) | ||||
| 
 | ||||
| 	for _, period := range periods { | ||||
| 		accumulationTimeForPeriod := types.NewAccrualTime(claimType, period.CollateralType, builder.genesisTime) | ||||
| 		builder.AccrualTimes = append( | ||||
| 			builder.AccrualTimes, | ||||
| 			accumulationTimeForPeriod, | ||||
| 		) | ||||
| 
 | ||||
| 		if err := builder.AccrualTimes.Validate(); err != nil { | ||||
| 			panic(fmt.Errorf("invalid accrual times: %w", err)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return builder | ||||
| } | ||||
| 
 | ||||
| func (builder IncentiveGenesisBuilder) WithSimpleRewardPeriod( | ||||
| 	claimType types.ClaimType, | ||||
| 	collateralType string, | ||||
| 	rewardsPerSecond sdk.Coins, | ||||
| ) IncentiveGenesisBuilder { | ||||
| 	return builder.WithInitializedRewardPeriod( | ||||
| 		claimType, | ||||
| 		types.MultiRewardPeriods{builder.simpleRewardPeriod(collateralType, rewardsPerSecond)}, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (builder IncentiveGenesisBuilder) WithMultipliers(multipliers types.MultipliersPerDenoms) IncentiveGenesisBuilder { | ||||
| 	builder.Params.ClaimMultipliers = multipliers | ||||
| 
 | ||||
|  | ||||
| @ -442,8 +442,7 @@ func (suite *IntegrationTester) AddTestAddrsFromPubKeys(ctx sdk.Context, pubKeys | ||||
| 	initCoins := sdk.NewCoins(sdk.NewCoin(suite.App.GetStakingKeeper().BondDenom(ctx), accAmt)) | ||||
| 
 | ||||
| 	for _, pk := range pubKeys { | ||||
| 		err := suite.App.FundAccount(ctx, sdk.AccAddress(pk.Address()), initCoins) | ||||
| 		suite.Require().NoError(err) | ||||
| 		suite.App.FundAccount(ctx, sdk.AccAddress(pk.Address()), initCoins) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -469,28 +468,6 @@ func (suite *IntegrationTester) StoredEarnIndexesEqual(denom string, expected ty | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *IntegrationTester) StoredTimeEquals(claimType types.ClaimType, denom string, expected time.Time) { | ||||
| 	storedTime, found := suite.App.GetIncentiveKeeper().Store.GetRewardAccrualTime(suite.Ctx, claimType, denom) | ||||
| 	suite.Equal(found, expected != time.Time{}, "expected time is %v but time found = %v", expected, found) | ||||
| 	if found { | ||||
| 		suite.Equal(expected, storedTime) | ||||
| 	} else { | ||||
| 		suite.Empty(storedTime) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *IntegrationTester) StoredIndexesEqual(claimType types.ClaimType, denom string, expected types.RewardIndexes) { | ||||
| 	storedIndexes, found := suite.App.GetIncentiveKeeper().Store.GetRewardIndexesOfClaimType(suite.Ctx, claimType, denom) | ||||
| 	suite.Equal(found, expected != nil) | ||||
| 
 | ||||
| 	if found { | ||||
| 		suite.Equal(expected, storedIndexes) | ||||
| 	} else { | ||||
| 		// Can't compare Equal for types.RewardIndexes(nil) vs types.RewardIndexes{}
 | ||||
| 		suite.Empty(storedIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *IntegrationTester) AddIncentiveEarnMultiRewardPeriod(period types.MultiRewardPeriod) { | ||||
| 	ik := suite.App.GetIncentiveKeeper() | ||||
| 	params := ik.GetParams(suite.Ctx) | ||||
| @ -512,44 +489,6 @@ func (suite *IntegrationTester) AddIncentiveEarnMultiRewardPeriod(period types.M | ||||
| 	ik.SetParams(suite.Ctx, params) | ||||
| } | ||||
| 
 | ||||
| func (suite *IntegrationTester) AddIncentiveMultiRewardPeriod( | ||||
| 	claimType types.ClaimType, | ||||
| 	period types.MultiRewardPeriod, | ||||
| ) { | ||||
| 	ik := suite.App.GetIncentiveKeeper() | ||||
| 	params := ik.GetParams(suite.Ctx) | ||||
| 
 | ||||
| 	for i, rewardPeriod := range params.RewardPeriods { | ||||
| 		if claimType == rewardPeriod.ClaimType { | ||||
| 			for j, reward := range rewardPeriod.RewardPeriods { | ||||
| 				if reward.CollateralType == period.CollateralType { | ||||
| 					// Replace existing reward period if the collateralType exists.
 | ||||
| 					// Params are invalid if there are multiple reward periods for the
 | ||||
| 					// same collateral type.
 | ||||
| 					params.RewardPeriods[i].RewardPeriods[j] = period | ||||
| 					ik.SetParams(suite.Ctx, params) | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// Claim type period exists but not the specific collateral type
 | ||||
| 			params.RewardPeriods[i].RewardPeriods = append(params.RewardPeriods[i].RewardPeriods, period) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Claim type does not exist in params
 | ||||
| 	params.RewardPeriods = append(params.RewardPeriods, types.NewTypedMultiRewardPeriod( | ||||
| 		claimType, | ||||
| 		types.MultiRewardPeriods{ | ||||
| 			period, | ||||
| 		}, | ||||
| 	)) | ||||
| 
 | ||||
| 	suite.NoError(params.Validate()) | ||||
| 	ik.SetParams(suite.Ctx, params) | ||||
| } | ||||
| 
 | ||||
| // -----------------------------------------------------------------------------
 | ||||
| // x/router
 | ||||
| 
 | ||||
|  | ||||
| @ -1,54 +0,0 @@ | ||||
| package testutil | ||||
| 
 | ||||
| import ( | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/kava-labs/kava/x/incentive/keeper" | ||||
| 	"github.com/kava-labs/kava/x/incentive/types" | ||||
| ) | ||||
| 
 | ||||
| // TestKeeper is a test wrapper for the keeper which contains useful methods for testing
 | ||||
| type TestKeeper struct { | ||||
| 	keeper.Keeper | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalBorrowIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.SetHardBorrowRewardIndexes(ctx, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalSupplyIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.SetHardSupplyRewardIndexes(ctx, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalDelegatorIndexes(ctx sdk.Context, multiRewardIndexes types.MultiRewardIndexes) { | ||||
| 	// Hardcoded to use bond denom
 | ||||
| 	multiRewardIndex, _ := multiRewardIndexes.GetRewardIndex(types.BondDenom) | ||||
| 	keeper.SetDelegatorRewardIndexes(ctx, types.BondDenom, multiRewardIndex.RewardIndexes) | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalSwapIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.SetSwapRewardIndexes(ctx, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalSavingsIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.SetSavingsRewardIndexes(ctx, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalEarnIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.SetEarnRewardIndexes(ctx, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (keeper TestKeeper) StoreGlobalIndexes(ctx sdk.Context, claimType types.ClaimType, indexes types.MultiRewardIndexes) { | ||||
| 	for _, i := range indexes { | ||||
| 		keeper.Store.SetRewardIndexes(ctx, claimType, i.CollateralType, i.RewardIndexes) | ||||
| 	} | ||||
| } | ||||
| @ -1,18 +0,0 @@ | ||||
| package types | ||||
| 
 | ||||
| import sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| // SourceAdapter queries source shares from an external module.
 | ||||
| type SourceAdapter interface { | ||||
| 	// OwnerSharesBySource returns source shares owned by one address.
 | ||||
| 	//
 | ||||
| 	// For example, the shares a user owns in the kava:usdx and bnb:usdx swap pools.
 | ||||
| 	// It returns the shares for several sources at once, in a map of sourceIDs to shares. Specifying no sourceIDS will return no shares.
 | ||||
| 	// Note the returned map does not have a deterministic order.
 | ||||
| 	OwnerSharesBySource(ctx sdk.Context, owner sdk.AccAddress, sourceIDs []string) map[string]sdk.Dec | ||||
| 
 | ||||
| 	// TotalSharesBySource returns the sum of all shares for a source (across all users).
 | ||||
| 	//
 | ||||
| 	// For example, the total number of shares in the kava:usdx swap pool for all users.
 | ||||
| 	TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec | ||||
| } | ||||
| @ -57,58 +57,6 @@ func (c BaseMultiClaim) Validate() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Validate checks if a ClaimType is valid
 | ||||
| func (ct ClaimType) Validate() error { | ||||
| 	switch ct { | ||||
| 	case CLAIM_TYPE_HARD_BORROW, | ||||
| 		CLAIM_TYPE_HARD_SUPPLY, | ||||
| 		CLAIM_TYPE_DELEGATOR, | ||||
| 		CLAIM_TYPE_EARN, | ||||
| 		CLAIM_TYPE_SAVINGS, | ||||
| 		CLAIM_TYPE_SWAP, | ||||
| 		CLAIM_TYPE_USDX_MINTING: | ||||
| 		return nil | ||||
| 	default: | ||||
| 		return fmt.Errorf("invalid claim type: %v", ct) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // NewClaim returns a new Claim
 | ||||
| func NewClaim( | ||||
| 	claimType ClaimType, | ||||
| 	owner sdk.AccAddress, | ||||
| 	reward sdk.Coins, | ||||
| 	rewardIndexes MultiRewardIndexes, | ||||
| ) Claim { | ||||
| 	return Claim{ | ||||
| 		Type:          claimType, | ||||
| 		Owner:         owner, | ||||
| 		Reward:        reward, | ||||
| 		RewardIndexes: rewardIndexes, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Validate performs a basic check of a Claim
 | ||||
| func (c Claim) Validate() error { | ||||
| 	if err := c.Type.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if c.Owner.Empty() { | ||||
| 		return errors.New("claim owner cannot be empty") | ||||
| 	} | ||||
| 
 | ||||
| 	if err := c.Reward.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid reward amount %v: %w", c.Reward, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := c.RewardIndexes.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid reward indexes: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewUSDXMintingClaim returns a new USDXMintingClaim
 | ||||
| func NewUSDXMintingClaim(owner sdk.AccAddress, reward sdk.Coin, rewardIndexes RewardIndexes) USDXMintingClaim { | ||||
| 	return USDXMintingClaim{ | ||||
| @ -163,20 +111,6 @@ func (cs USDXMintingClaims) Validate() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Claims defines a slice of Claims
 | ||||
| type Claims []Claim | ||||
| 
 | ||||
| // Validate checks if all the claims are valid.
 | ||||
| func (cs Claims) Validate() error { | ||||
| 	for _, c := range cs { | ||||
| 		if err := c.Validate(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
 | ||||
| func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins, | ||||
| 	supplyRewardIndexes, borrowRewardIndexes MultiRewardIndexes, | ||||
| @ -700,51 +634,3 @@ func (mris MultiRewardIndexes) copy() MultiRewardIndexes { | ||||
| 	copy(newIndexes, mris) | ||||
| 	return newIndexes | ||||
| } | ||||
| 
 | ||||
| // NewTypedRewardIndexes returns a new TypedRewardIndexes
 | ||||
| func NewTypedRewardIndexes( | ||||
| 	claimType ClaimType, | ||||
| 	collateralType string, | ||||
| 	rewardIndexes RewardIndexes, | ||||
| ) TypedRewardIndexes { | ||||
| 	return TypedRewardIndexes{ | ||||
| 		ClaimType:      claimType, | ||||
| 		CollateralType: collateralType, | ||||
| 		RewardIndexes:  rewardIndexes, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Validate performs a basic check of a TypedRewardIndexes fields
 | ||||
| func (tril TypedRewardIndexes) Validate() error { | ||||
| 	if err := tril.ClaimType.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if tril.CollateralType == "" { | ||||
| 		return errors.New("collateral type cannot be empty") | ||||
| 	} | ||||
| 
 | ||||
| 	return tril.RewardIndexes.Validate() | ||||
| } | ||||
| 
 | ||||
| // TypedRewardIndexesList is a list of TypedRewardIndexes
 | ||||
| type TypedRewardIndexesList []TypedRewardIndexes | ||||
| 
 | ||||
| // Validate validates a slice of TypedRewardIndexesList
 | ||||
| func (tril TypedRewardIndexesList) Validate() error { | ||||
| 	seen := make(map[string]bool) | ||||
| 
 | ||||
| 	for _, tri := range tril { | ||||
| 		if err := tri.Validate(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		// Composite key of claim type and collateral type
 | ||||
| 		key := fmt.Sprintf("%s/%s", tri.ClaimType, tri.CollateralType) | ||||
| 		if seen[key] { | ||||
| 			return fmt.Errorf("duplicate TypedRewardIndexes found: %s", key) | ||||
| 		} | ||||
| 		seen[key] = true | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -26,58 +26,6 @@ var _ = math.Inf | ||||
| // proto package needs to be updated.
 | ||||
| const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 | ||||
| 
 | ||||
| // ClaimType is the type of claim
 | ||||
| type ClaimType int32 | ||||
| 
 | ||||
| const ( | ||||
| 	// indicates an invalid claim type
 | ||||
| 	CLAIM_TYPE_UNSPECIFIED ClaimType = 0 | ||||
| 	// claim type for hard borrow rewards
 | ||||
| 	CLAIM_TYPE_HARD_BORROW ClaimType = 1 | ||||
| 	// claim type for hard supply rewards
 | ||||
| 	CLAIM_TYPE_HARD_SUPPLY ClaimType = 2 | ||||
| 	// claim type for delegator rewards
 | ||||
| 	CLAIM_TYPE_DELEGATOR ClaimType = 3 | ||||
| 	// claim type for earn rewards
 | ||||
| 	CLAIM_TYPE_EARN ClaimType = 4 | ||||
| 	// claim type for savings rewards
 | ||||
| 	CLAIM_TYPE_SAVINGS ClaimType = 5 | ||||
| 	// claim type for swap rewards
 | ||||
| 	CLAIM_TYPE_SWAP ClaimType = 6 | ||||
| 	// claim type for usdx minting rewards
 | ||||
| 	CLAIM_TYPE_USDX_MINTING ClaimType = 7 | ||||
| ) | ||||
| 
 | ||||
| var ClaimType_name = map[int32]string{ | ||||
| 	0: "CLAIM_TYPE_UNSPECIFIED", | ||||
| 	1: "CLAIM_TYPE_HARD_BORROW", | ||||
| 	2: "CLAIM_TYPE_HARD_SUPPLY", | ||||
| 	3: "CLAIM_TYPE_DELEGATOR", | ||||
| 	4: "CLAIM_TYPE_EARN", | ||||
| 	5: "CLAIM_TYPE_SAVINGS", | ||||
| 	6: "CLAIM_TYPE_SWAP", | ||||
| 	7: "CLAIM_TYPE_USDX_MINTING", | ||||
| } | ||||
| 
 | ||||
| var ClaimType_value = map[string]int32{ | ||||
| 	"CLAIM_TYPE_UNSPECIFIED":  0, | ||||
| 	"CLAIM_TYPE_HARD_BORROW":  1, | ||||
| 	"CLAIM_TYPE_HARD_SUPPLY":  2, | ||||
| 	"CLAIM_TYPE_DELEGATOR":    3, | ||||
| 	"CLAIM_TYPE_EARN":         4, | ||||
| 	"CLAIM_TYPE_SAVINGS":      5, | ||||
| 	"CLAIM_TYPE_SWAP":         6, | ||||
| 	"CLAIM_TYPE_USDX_MINTING": 7, | ||||
| } | ||||
| 
 | ||||
| func (x ClaimType) String() string { | ||||
| 	return proto.EnumName(ClaimType_name, int32(x)) | ||||
| } | ||||
| 
 | ||||
| func (ClaimType) EnumDescriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{0} | ||||
| } | ||||
| 
 | ||||
| // BaseClaim is a claim with a single reward coin types
 | ||||
| type BaseClaim struct { | ||||
| 	Owner  github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=owner,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"owner,omitempty"` | ||||
| @ -233,47 +181,6 @@ func (m *RewardIndexesProto) XXX_DiscardUnknown() { | ||||
| 
 | ||||
| var xxx_messageInfo_RewardIndexesProto proto.InternalMessageInfo | ||||
| 
 | ||||
| // TypedRewardIndexes defines a RewardIndexes slice with its corresponding
 | ||||
| // claim and collateral type
 | ||||
| type TypedRewardIndexes struct { | ||||
| 	ClaimType      ClaimType     `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"` | ||||
| 	CollateralType string        `protobuf:"bytes,2,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"` | ||||
| 	RewardIndexes  RewardIndexes `protobuf:"bytes,3,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=RewardIndexes" json:"reward_indexes"` | ||||
| } | ||||
| 
 | ||||
| func (m *TypedRewardIndexes) Reset()         { *m = TypedRewardIndexes{} } | ||||
| func (m *TypedRewardIndexes) String() string { return proto.CompactTextString(m) } | ||||
| func (*TypedRewardIndexes) ProtoMessage()    {} | ||||
| func (*TypedRewardIndexes) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{4} | ||||
| } | ||||
| func (m *TypedRewardIndexes) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| } | ||||
| func (m *TypedRewardIndexes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	if deterministic { | ||||
| 		return xxx_messageInfo_TypedRewardIndexes.Marshal(b, m, deterministic) | ||||
| 	} else { | ||||
| 		b = b[:cap(b)] | ||||
| 		n, err := m.MarshalToSizedBuffer(b) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return b[:n], nil | ||||
| 	} | ||||
| } | ||||
| func (m *TypedRewardIndexes) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_TypedRewardIndexes.Merge(m, src) | ||||
| } | ||||
| func (m *TypedRewardIndexes) XXX_Size() int { | ||||
| 	return m.Size() | ||||
| } | ||||
| func (m *TypedRewardIndexes) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_TypedRewardIndexes.DiscardUnknown(m) | ||||
| } | ||||
| 
 | ||||
| var xxx_messageInfo_TypedRewardIndexes proto.InternalMessageInfo | ||||
| 
 | ||||
| // MultiRewardIndex stores reward accumulation information on multiple reward types
 | ||||
| type MultiRewardIndex struct { | ||||
| 	CollateralType string        `protobuf:"bytes,1,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"` | ||||
| @ -284,7 +191,7 @@ func (m *MultiRewardIndex) Reset()         { *m = MultiRewardIndex{} } | ||||
| func (m *MultiRewardIndex) String() string { return proto.CompactTextString(m) } | ||||
| func (*MultiRewardIndex) ProtoMessage()    {} | ||||
| func (*MultiRewardIndex) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{5} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{4} | ||||
| } | ||||
| func (m *MultiRewardIndex) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -322,7 +229,7 @@ func (m *MultiRewardIndexesProto) Reset()         { *m = MultiRewardIndexesProto | ||||
| func (m *MultiRewardIndexesProto) String() string { return proto.CompactTextString(m) } | ||||
| func (*MultiRewardIndexesProto) ProtoMessage()    {} | ||||
| func (*MultiRewardIndexesProto) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{6} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{5} | ||||
| } | ||||
| func (m *MultiRewardIndexesProto) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -361,7 +268,7 @@ func (m *USDXMintingClaim) Reset()         { *m = USDXMintingClaim{} } | ||||
| func (m *USDXMintingClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*USDXMintingClaim) ProtoMessage()    {} | ||||
| func (*USDXMintingClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{7} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{6} | ||||
| } | ||||
| func (m *USDXMintingClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -401,7 +308,7 @@ func (m *HardLiquidityProviderClaim) Reset()         { *m = HardLiquidityProvide | ||||
| func (m *HardLiquidityProviderClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*HardLiquidityProviderClaim) ProtoMessage()    {} | ||||
| func (*HardLiquidityProviderClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{8} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{7} | ||||
| } | ||||
| func (m *HardLiquidityProviderClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -440,7 +347,7 @@ func (m *DelegatorClaim) Reset()         { *m = DelegatorClaim{} } | ||||
| func (m *DelegatorClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*DelegatorClaim) ProtoMessage()    {} | ||||
| func (*DelegatorClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{9} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{8} | ||||
| } | ||||
| func (m *DelegatorClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -479,7 +386,7 @@ func (m *SwapClaim) Reset()         { *m = SwapClaim{} } | ||||
| func (m *SwapClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*SwapClaim) ProtoMessage()    {} | ||||
| func (*SwapClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{10} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{9} | ||||
| } | ||||
| func (m *SwapClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -518,7 +425,7 @@ func (m *SavingsClaim) Reset()         { *m = SavingsClaim{} } | ||||
| func (m *SavingsClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*SavingsClaim) ProtoMessage()    {} | ||||
| func (*SavingsClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{11} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{10} | ||||
| } | ||||
| func (m *SavingsClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -557,7 +464,7 @@ func (m *EarnClaim) Reset()         { *m = EarnClaim{} } | ||||
| func (m *EarnClaim) String() string { return proto.CompactTextString(m) } | ||||
| func (*EarnClaim) ProtoMessage()    {} | ||||
| func (*EarnClaim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{12} | ||||
| 	return fileDescriptor_5f7515029623a895, []int{11} | ||||
| } | ||||
| func (m *EarnClaim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -586,54 +493,11 @@ func (m *EarnClaim) XXX_DiscardUnknown() { | ||||
| 
 | ||||
| var xxx_messageInfo_EarnClaim proto.InternalMessageInfo | ||||
| 
 | ||||
| // Claim stores any generic rewards that can be claimed by owner
 | ||||
| type Claim struct { | ||||
| 	Type          ClaimType                                     `protobuf:"varint,1,opt,name=type,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"type,omitempty"` | ||||
| 	Owner         github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=owner,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"owner,omitempty"` | ||||
| 	Reward        github_com_cosmos_cosmos_sdk_types.Coins      `protobuf:"bytes,3,rep,name=reward,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"reward"` | ||||
| 	RewardIndexes MultiRewardIndexes                            `protobuf:"bytes,4,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=MultiRewardIndexes" json:"reward_indexes"` | ||||
| } | ||||
| 
 | ||||
| func (m *Claim) Reset()         { *m = Claim{} } | ||||
| func (m *Claim) String() string { return proto.CompactTextString(m) } | ||||
| func (*Claim) ProtoMessage()    {} | ||||
| func (*Claim) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_5f7515029623a895, []int{13} | ||||
| } | ||||
| func (m *Claim) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| } | ||||
| func (m *Claim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	if deterministic { | ||||
| 		return xxx_messageInfo_Claim.Marshal(b, m, deterministic) | ||||
| 	} else { | ||||
| 		b = b[:cap(b)] | ||||
| 		n, err := m.MarshalToSizedBuffer(b) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return b[:n], nil | ||||
| 	} | ||||
| } | ||||
| func (m *Claim) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_Claim.Merge(m, src) | ||||
| } | ||||
| func (m *Claim) XXX_Size() int { | ||||
| 	return m.Size() | ||||
| } | ||||
| func (m *Claim) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_Claim.DiscardUnknown(m) | ||||
| } | ||||
| 
 | ||||
| var xxx_messageInfo_Claim proto.InternalMessageInfo | ||||
| 
 | ||||
| func init() { | ||||
| 	proto.RegisterEnum("kava.incentive.v1beta1.ClaimType", ClaimType_name, ClaimType_value) | ||||
| 	proto.RegisterType((*BaseClaim)(nil), "kava.incentive.v1beta1.BaseClaim") | ||||
| 	proto.RegisterType((*BaseMultiClaim)(nil), "kava.incentive.v1beta1.BaseMultiClaim") | ||||
| 	proto.RegisterType((*RewardIndex)(nil), "kava.incentive.v1beta1.RewardIndex") | ||||
| 	proto.RegisterType((*RewardIndexesProto)(nil), "kava.incentive.v1beta1.RewardIndexesProto") | ||||
| 	proto.RegisterType((*TypedRewardIndexes)(nil), "kava.incentive.v1beta1.TypedRewardIndexes") | ||||
| 	proto.RegisterType((*MultiRewardIndex)(nil), "kava.incentive.v1beta1.MultiRewardIndex") | ||||
| 	proto.RegisterType((*MultiRewardIndexesProto)(nil), "kava.incentive.v1beta1.MultiRewardIndexesProto") | ||||
| 	proto.RegisterType((*USDXMintingClaim)(nil), "kava.incentive.v1beta1.USDXMintingClaim") | ||||
| @ -642,7 +506,6 @@ func init() { | ||||
| 	proto.RegisterType((*SwapClaim)(nil), "kava.incentive.v1beta1.SwapClaim") | ||||
| 	proto.RegisterType((*SavingsClaim)(nil), "kava.incentive.v1beta1.SavingsClaim") | ||||
| 	proto.RegisterType((*EarnClaim)(nil), "kava.incentive.v1beta1.EarnClaim") | ||||
| 	proto.RegisterType((*Claim)(nil), "kava.incentive.v1beta1.Claim") | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| @ -650,63 +513,51 @@ func init() { | ||||
| } | ||||
| 
 | ||||
| var fileDescriptor_5f7515029623a895 = []byte{ | ||||
| 	// 887 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0x4f, 0x6f, 0xe3, 0x44, | ||||
| 	0x14, 0xcf, 0xa4, 0x69, 0x21, 0xaf, 0xdd, 0xac, 0x35, 0xfd, 0xb3, 0xdd, 0x20, 0x39, 0x4b, 0x56, | ||||
| 	0x5a, 0x2a, 0x50, 0x1d, 0x76, 0x11, 0xe2, 0x8a, 0xdd, 0x64, 0x5b, 0xa3, 0x36, 0x8d, 0xec, 0x96, | ||||
| 	0xdd, 0xe5, 0x80, 0x35, 0xb1, 0x87, 0x60, 0xd5, 0xf1, 0x04, 0xdb, 0x4d, 0x9a, 0x6f, 0x80, 0xc4, | ||||
| 	0x05, 0xbe, 0x00, 0x17, 0x38, 0x71, 0xe6, 0x0b, 0x70, 0x2b, 0x12, 0x42, 0x15, 0x12, 0x12, 0xe2, | ||||
| 	0x10, 0xd8, 0xf6, 0x0b, 0x70, 0xe6, 0x84, 0x3c, 0x76, 0x53, 0x37, 0x75, 0x56, 0xcb, 0x2a, 0xe9, | ||||
| 	0xa1, 0xa7, 0x8c, 0xdf, 0x7b, 0xf3, 0xde, 0xef, 0xf7, 0x7b, 0x6f, 0x9c, 0x31, 0xdc, 0x3f, 0x20, | ||||
| 	0x5d, 0x52, 0xb1, 0x5d, 0x93, 0xba, 0x81, 0xdd, 0xa5, 0x95, 0xee, 0xc3, 0x26, 0x0d, 0xc8, 0xc3, | ||||
| 	0x8a, 0xe9, 0x10, 0xbb, 0xed, 0x4b, 0x1d, 0x8f, 0x05, 0x0c, 0xaf, 0x84, 0x41, 0xd2, 0x30, 0x48, | ||||
| 	0x8a, 0x83, 0x8a, 0xa2, 0xc9, 0xfc, 0x36, 0xf3, 0x2b, 0x4d, 0xe2, 0x27, 0x76, 0x32, 0xdb, 0x8d, | ||||
| 	0xf6, 0x15, 0xef, 0x46, 0x7e, 0x83, 0x3f, 0x55, 0xa2, 0x87, 0xd8, 0xb5, 0xd4, 0x62, 0x2d, 0x16, | ||||
| 	0xd9, 0xc3, 0x55, 0x64, 0x2d, 0x7f, 0x8f, 0x20, 0xaf, 0x10, 0x9f, 0x6e, 0x84, 0xd5, 0xf1, 0xa7, | ||||
| 	0x30, 0xcb, 0x7a, 0x2e, 0xf5, 0x56, 0xd1, 0x3d, 0xb4, 0xb6, 0xa0, 0x6c, 0xfd, 0x3b, 0x28, 0xad, | ||||
| 	0xb7, 0xec, 0xe0, 0xf3, 0xc3, 0xa6, 0x64, 0xb2, 0x76, 0x9c, 0x2f, 0xfe, 0x59, 0xf7, 0xad, 0x83, | ||||
| 	0x4a, 0xd0, 0xef, 0x50, 0x5f, 0x92, 0x4d, 0x53, 0xb6, 0x2c, 0x8f, 0xfa, 0xfe, 0x6f, 0x3f, 0xae, | ||||
| 	0x2f, 0xc6, 0x55, 0x63, 0x8b, 0xd2, 0x0f, 0xa8, 0xaf, 0x45, 0x69, 0xf1, 0x07, 0x30, 0xe7, 0xd1, | ||||
| 	0x1e, 0xf1, 0xac, 0xd5, 0xec, 0x3d, 0xb4, 0x36, 0xff, 0xe8, 0xae, 0x14, 0x07, 0x87, 0x7c, 0xce, | ||||
| 	0x49, 0x4a, 0x1b, 0xcc, 0x76, 0x95, 0xdc, 0xf1, 0xa0, 0x94, 0xd1, 0xe2, 0xf0, 0xf2, 0xef, 0x08, | ||||
| 	0x0a, 0x21, 0xcc, 0x9d, 0x43, 0x27, 0xb0, 0xaf, 0x07, 0xab, 0x99, 0xc0, 0x3a, 0xf3, 0x62, 0xac, | ||||
| 	0xef, 0x86, 0x58, 0x7f, 0xf8, 0xab, 0xb4, 0xf6, 0x12, 0xf5, 0xc3, 0x0d, 0xfe, 0x90, 0xd7, 0x57, | ||||
| 	0x08, 0xe6, 0x35, 0xbe, 0x54, 0x5d, 0x8b, 0x1e, 0xe1, 0xb7, 0xe0, 0xb6, 0xc9, 0x1c, 0x87, 0x04, | ||||
| 	0xd4, 0x23, 0x8e, 0x11, 0xee, 0xe0, 0xf4, 0xf2, 0x5a, 0xe1, 0xc2, 0xbc, 0xd7, 0xef, 0x50, 0xac, | ||||
| 	0xc3, 0xad, 0x28, 0x85, 0xf1, 0x19, 0x31, 0x03, 0xe6, 0x71, 0x41, 0x17, 0x14, 0x29, 0x44, 0xf2, | ||||
| 	0xe7, 0xa0, 0xf4, 0xe0, 0x25, 0x90, 0x54, 0xa9, 0xa9, 0x2d, 0x44, 0x49, 0x1e, 0xf3, 0x1c, 0xe5, | ||||
| 	0x1e, 0xe0, 0x04, 0x18, 0xea, 0x37, 0xf8, 0x2c, 0x12, 0x28, 0xc4, 0xa5, 0xec, 0xc8, 0xbc, 0x8a, | ||||
| 	0xb8, 0x20, 0xf7, 0xa5, 0xf4, 0x21, 0x95, 0x12, 0x39, 0x94, 0xe5, 0x58, 0x9a, 0x5b, 0x97, 0x12, | ||||
| 	0x6b, 0x31, 0xf8, 0xf8, 0xb1, 0x7c, 0x8a, 0x00, 0x87, 0xb4, 0xac, 0x4b, 0x51, 0xf8, 0x43, 0x00, | ||||
| 	0x7e, 0x2a, 0x2e, 0x84, 0x28, 0x3c, 0x7a, 0x73, 0x5c, 0x55, 0x3e, 0x15, 0x61, 0x12, 0x2d, 0x6f, | ||||
| 	0x9e, 0x2f, 0xd3, 0xf4, 0xcc, 0xa6, 0xea, 0x79, 0x95, 0xe4, 0xcc, 0xa4, 0x49, 0x7e, 0x8b, 0x40, | ||||
| 	0xe0, 0xf3, 0xfb, 0x4a, 0x0d, 0xbf, 0x0a, 0x30, 0x3b, 0x69, 0x80, 0xdf, 0x20, 0xb8, 0x33, 0x0a, | ||||
| 	0xf0, 0x7c, 0x08, 0xba, 0xb0, 0xd4, 0x0e, 0x5d, 0x46, 0xea, 0x28, 0xac, 0x8d, 0x03, 0x31, 0x9a, | ||||
| 	0x4e, 0x29, 0xc6, 0x48, 0xf0, 0xd5, 0x42, 0x1a, 0x6e, 0x5f, 0xb1, 0x95, 0x7f, 0x42, 0x20, 0xec, | ||||
| 	0xeb, 0xd5, 0xa7, 0x3b, 0xb6, 0x1b, 0xd8, 0x6e, 0x2b, 0x3a, 0xfa, 0x1f, 0x01, 0x84, 0x87, 0xd0, | ||||
| 	0xe0, 0x7d, 0xe6, 0x7a, 0xcd, 0x8f, 0x9f, 0x8b, 0xe1, 0xdb, 0x4d, 0x79, 0x3d, 0xac, 0x7d, 0x32, | ||||
| 	0x28, 0x21, 0x2d, 0xdf, 0x1c, 0xbe, 0xf2, 0xae, 0x41, 0xd7, 0xe7, 0x59, 0x28, 0x6e, 0x11, 0xcf, | ||||
| 	0xda, 0xb6, 0xbf, 0x38, 0xb4, 0x2d, 0x3b, 0xe8, 0x37, 0x3c, 0xd6, 0xb5, 0x2d, 0xea, 0x45, 0x08, | ||||
| 	0x76, 0x53, 0xd8, 0x3c, 0x78, 0x11, 0x9b, 0x8b, 0x97, 0x60, 0x3a, 0xa5, 0x23, 0x58, 0xf6, 0x0f, | ||||
| 	0x3b, 0x1d, 0xa7, 0x6f, 0xa4, 0x32, 0x9b, 0x4c, 0xb3, 0x16, 0xa3, 0x12, 0x97, 0x0f, 0xec, 0x11, | ||||
| 	0x2c, 0x37, 0x99, 0xe7, 0xb1, 0x9e, 0x91, 0x7a, 0x98, 0x26, 0x54, 0x39, 0x2a, 0x71, 0x79, 0x4e, | ||||
| 	0x7e, 0x45, 0x50, 0xa8, 0x52, 0x87, 0xb6, 0x48, 0xc0, 0xa6, 0xa5, 0xeb, 0xc1, 0x98, 0x51, 0x99, | ||||
| 	0x0c, 0xad, 0x91, 0xa1, 0xf9, 0x19, 0x41, 0x5e, 0xef, 0x91, 0xce, 0x4d, 0xe0, 0xf2, 0x0b, 0x82, | ||||
| 	0x05, 0x9d, 0x74, 0x6d, 0xb7, 0xe5, 0xdf, 0x94, 0xd6, 0xd4, 0x88, 0xe7, 0xde, 0x04, 0x2e, 0xff, | ||||
| 	0x64, 0x61, 0x36, 0x2a, 0xfb, 0x3e, 0xe4, 0xfe, 0xdf, 0xdf, 0x2c, 0x0f, 0xbf, 0xb8, 0x86, 0x65, | ||||
| 	0xa7, 0x7d, 0x0d, 0x9b, 0x99, 0xda, 0x35, 0x2c, 0x45, 0xf2, 0xdc, 0xd4, 0x24, 0x7f, 0x7b, 0x80, | ||||
| 	0x20, 0x3f, 0x54, 0x11, 0x17, 0x61, 0x65, 0x63, 0x5b, 0x56, 0x77, 0x8c, 0xbd, 0x67, 0x8d, 0x9a, | ||||
| 	0xb1, 0x5f, 0xd7, 0x1b, 0xb5, 0x0d, 0xf5, 0xb1, 0x5a, 0xab, 0x0a, 0x99, 0x11, 0xdf, 0x96, 0xac, | ||||
| 	0x55, 0x0d, 0x65, 0x57, 0xd3, 0x76, 0x9f, 0x08, 0x28, 0xcd, 0xa7, 0xef, 0x37, 0x1a, 0xdb, 0xcf, | ||||
| 	0x84, 0x2c, 0x5e, 0x85, 0xa5, 0x84, 0xaf, 0x5a, 0xdb, 0xae, 0x6d, 0xca, 0x7b, 0xbb, 0x9a, 0x30, | ||||
| 	0x83, 0x17, 0xe1, 0x76, 0xc2, 0x53, 0x93, 0xb5, 0xba, 0x90, 0xc3, 0x2b, 0x80, 0x13, 0x46, 0x5d, | ||||
| 	0xfe, 0x58, 0xad, 0x6f, 0xea, 0xc2, 0xec, 0x48, 0xb0, 0xfe, 0x44, 0x6e, 0x08, 0x73, 0xf8, 0x0d, | ||||
| 	0xb8, 0x93, 0xc4, 0xab, 0x57, 0x9f, 0x1a, 0x3b, 0x6a, 0x7d, 0x4f, 0xad, 0x6f, 0x0a, 0xaf, 0x15, | ||||
| 	0x73, 0x5f, 0x7e, 0x27, 0x66, 0x14, 0xf5, 0xf8, 0xb9, 0x98, 0x39, 0x3e, 0x15, 0xd1, 0xc9, 0xa9, | ||||
| 	0x88, 0xfe, 0x3e, 0x15, 0xd1, 0xd7, 0x67, 0x62, 0xe6, 0xe4, 0x4c, 0xcc, 0xfc, 0x71, 0x26, 0x66, | ||||
| 	0x3e, 0x79, 0x27, 0xd1, 0x9d, 0x50, 0xdd, 0x75, 0x87, 0x34, 0x7d, 0xbe, 0xaa, 0x1c, 0x25, 0x3e, | ||||
| 	0x8b, 0x78, 0x9b, 0x9a, 0x73, 0xfc, 0x2b, 0xe5, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcf, | ||||
| 	0x23, 0x97, 0x53, 0x35, 0x0d, 0x00, 0x00, | ||||
| 	// 691 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x4f, 0x4f, 0x13, 0x4d, | ||||
| 	0x18, 0xef, 0xc0, 0x0b, 0x79, 0x3b, 0x94, 0xbe, 0x64, 0x81, 0x57, 0xe8, 0x61, 0x8b, 0x25, 0xc1, | ||||
| 	0x26, 0xa6, 0xbb, 0x82, 0x07, 0x13, 0x6f, 0x2c, 0x68, 0xc0, 0x48, 0x24, 0x5b, 0x4d, 0x8c, 0x07, | ||||
| 	0x9b, 0xd9, 0xdd, 0xb1, 0x4e, 0xd8, 0xee, 0xd4, 0x99, 0x6d, 0x4b, 0x3f, 0x83, 0x17, 0xfd, 0x02, | ||||
| 	0x7e, 0x00, 0x2f, 0x5e, 0xf8, 0x10, 0xc4, 0x78, 0x20, 0xc6, 0xc4, 0x3f, 0x87, 0x8a, 0x70, 0xf5, | ||||
| 	0x13, 0x78, 0x32, 0xf3, 0x07, 0x58, 0xa0, 0x25, 0xc4, 0x14, 0x0f, 0x9c, 0x76, 0xe7, 0x99, 0x67, | ||||
| 	0x9e, 0xdf, 0x9f, 0x79, 0x76, 0x76, 0xe0, 0xec, 0x06, 0x6a, 0x22, 0x9b, 0x44, 0x3e, 0x8e, 0x62, | ||||
| 	0xd2, 0xc4, 0x76, 0x73, 0xde, 0xc3, 0x31, 0x9a, 0xb7, 0xfd, 0x10, 0x91, 0x1a, 0xb7, 0xea, 0x8c, | ||||
| 	0xc6, 0xd4, 0xf8, 0x5f, 0x24, 0x59, 0x87, 0x49, 0x96, 0x4e, 0xca, 0x99, 0x3e, 0xe5, 0x35, 0xca, | ||||
| 	0x6d, 0x0f, 0xf1, 0xc4, 0x4a, 0x4a, 0x22, 0xb5, 0x2e, 0x37, 0xad, 0xe6, 0x2b, 0x72, 0x64, 0xab, | ||||
| 	0x81, 0x9e, 0x9a, 0xa8, 0xd2, 0x2a, 0x55, 0x71, 0xf1, 0xa6, 0xa2, 0x85, 0x77, 0x00, 0xa6, 0x1d, | ||||
| 	0xc4, 0xf1, 0x92, 0x40, 0x37, 0x9e, 0xc2, 0x21, 0xda, 0x8a, 0x30, 0x9b, 0x02, 0x33, 0xa0, 0x98, | ||||
| 	0x71, 0x56, 0x7e, 0x75, 0xf2, 0xa5, 0x2a, 0x89, 0x9f, 0x37, 0x3c, 0xcb, 0xa7, 0x35, 0x5d, 0x4f, | ||||
| 	0x3f, 0x4a, 0x3c, 0xd8, 0xb0, 0xe3, 0x76, 0x1d, 0x73, 0x6b, 0xd1, 0xf7, 0x17, 0x83, 0x80, 0x61, | ||||
| 	0xce, 0x3f, 0x6e, 0x95, 0xc6, 0x35, 0xaa, 0x8e, 0x38, 0xed, 0x18, 0x73, 0x57, 0x95, 0x35, 0x6e, | ||||
| 	0xc1, 0x61, 0x86, 0x5b, 0x88, 0x05, 0x53, 0x03, 0x33, 0xa0, 0x38, 0xb2, 0x30, 0x6d, 0xe9, 0x64, | ||||
| 	0xa1, 0xe7, 0x40, 0xa4, 0xb5, 0x44, 0x49, 0xe4, 0xfc, 0xb3, 0xdd, 0xc9, 0xa7, 0x5c, 0x9d, 0x7e, | ||||
| 	0x3b, 0xfd, 0x7e, 0xab, 0x34, 0x24, 0x39, 0x16, 0x76, 0x01, 0xcc, 0x0a, 0xc6, 0x6b, 0x8d, 0x30, | ||||
| 	0x26, 0x7f, 0x87, 0xb6, 0x9f, 0xa0, 0x3d, 0x78, 0x36, 0xed, 0x1b, 0x82, 0xf6, 0xdb, 0xef, 0xf9, | ||||
| 	0xe2, 0x39, 0xf0, 0xc5, 0x02, 0xde, 0x4d, 0xe2, 0x4b, 0x00, 0x47, 0x5c, 0x19, 0x5d, 0x8d, 0x02, | ||||
| 	0xbc, 0x69, 0x5c, 0x83, 0xff, 0xf9, 0x34, 0x0c, 0x51, 0x8c, 0x19, 0x0a, 0x2b, 0x62, 0xb1, 0x54, | ||||
| 	0x9a, 0x76, 0xb3, 0x47, 0xe1, 0x87, 0xed, 0x3a, 0x36, 0xca, 0x70, 0x54, 0x55, 0xab, 0x3c, 0x43, | ||||
| 	0x7e, 0x4c, 0x99, 0xb4, 0x39, 0xe3, 0x58, 0x82, 0xd4, 0xb7, 0x4e, 0x7e, 0xee, 0x1c, 0xa4, 0x96, | ||||
| 	0xb1, 0xef, 0x66, 0x54, 0x91, 0xbb, 0xb2, 0x46, 0xa1, 0x05, 0x8d, 0x04, 0x19, 0xcc, 0xd7, 0x65, | ||||
| 	0x87, 0x22, 0x98, 0xd5, 0x50, 0x44, 0x85, 0xa7, 0x80, 0xf4, 0x66, 0xd6, 0xea, 0xde, 0xba, 0x56, | ||||
| 	0xa2, 0x86, 0x33, 0xa9, 0x5d, 0x1a, 0x3d, 0x56, 0xd8, 0xd5, 0xe4, 0xf5, 0xb0, 0xf0, 0x06, 0xc0, | ||||
| 	0x31, 0xb9, 0xcb, 0x7f, 0xe4, 0xc5, 0x69, 0x82, 0x03, 0xfd, 0x26, 0xf8, 0x1a, 0xc0, 0x2b, 0x27, | ||||
| 	0x09, 0x1e, 0xf8, 0xd3, 0x84, 0x13, 0x35, 0x31, 0x55, 0xe9, 0xea, 0x52, 0xb1, 0x17, 0x89, 0x93, | ||||
| 	0xe5, 0x9c, 0x9c, 0x66, 0x62, 0x9c, 0x06, 0x72, 0x8d, 0xda, 0xa9, 0x58, 0xe1, 0x03, 0x80, 0x63, | ||||
| 	0x8f, 0xca, 0xcb, 0x8f, 0xd7, 0x48, 0x14, 0x93, 0xa8, 0xaa, 0x3e, 0x90, 0x7b, 0x10, 0x8a, 0x56, | ||||
| 	0xad, 0xc8, 0x33, 0x46, 0xfa, 0x35, 0xb2, 0x70, 0xb5, 0x17, 0x85, 0xc3, 0xe3, 0xc0, 0xf9, 0x57, | ||||
| 	0x60, 0xef, 0x74, 0xf2, 0xc0, 0x4d, 0x7b, 0x87, 0x67, 0xc4, 0xc5, 0xfb, 0x9a, 0xfc, 0x14, 0x7e, | ||||
| 	0x0e, 0xc0, 0xdc, 0x0a, 0x62, 0xc1, 0x7d, 0xf2, 0xa2, 0x41, 0x02, 0x12, 0xb7, 0xd7, 0x19, 0x6d, | ||||
| 	0x92, 0x00, 0x33, 0x45, 0xe6, 0x41, 0x17, 0x61, 0x73, 0x67, 0x09, 0x3b, 0x3a, 0x35, 0xba, 0xab, | ||||
| 	0xdb, 0x84, 0x93, 0xbc, 0x51, 0xaf, 0x87, 0xed, 0x4a, 0x57, 0x91, 0xfd, 0xd9, 0xb7, 0x71, 0x05, | ||||
| 	0x71, 0x2c, 0x28, 0x90, 0x3d, 0xca, 0x18, 0x6d, 0x9d, 0x44, 0x1e, 0xec, 0x27, 0xb2, 0x82, 0x70, | ||||
| 	0x7b, 0xd9, 0xfd, 0x15, 0xc0, 0xec, 0x32, 0x0e, 0x71, 0x15, 0xc5, 0xf4, 0xa2, 0x2c, 0xde, 0xe8, | ||||
| 	0xd1, 0x40, 0xfd, 0x51, 0xd8, 0xbb, 0x95, 0x3e, 0x01, 0x98, 0x2e, 0xb7, 0x50, 0xfd, 0x92, 0xc9, | ||||
| 	0xfa, 0x0c, 0x60, 0xa6, 0x8c, 0x9a, 0x24, 0xaa, 0xf2, 0x4b, 0xb8, 0x61, 0x77, 0x10, 0x8b, 0x2e, | ||||
| 	0x97, 0x2c, 0x67, 0x75, 0xfb, 0x87, 0x99, 0xda, 0xde, 0x33, 0xc1, 0xce, 0x9e, 0x09, 0x76, 0xf7, | ||||
| 	0x4c, 0xf0, 0x6a, 0xdf, 0x4c, 0xed, 0xec, 0x9b, 0xa9, 0x2f, 0xfb, 0x66, 0xea, 0xc9, 0xf5, 0xc4, | ||||
| 	0x3f, 0x5a, 0xf0, 0x28, 0x85, 0xc8, 0xe3, 0xf2, 0xcd, 0xde, 0x4c, 0xdc, 0x1a, 0xe5, 0xcf, 0xda, | ||||
| 	0x1b, 0x96, 0x97, 0xb8, 0x9b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x88, 0xd7, 0x8a, 0x4f, 0x54, | ||||
| 	0x0a, 0x00, 0x00, | ||||
| } | ||||
| 
 | ||||
| func (m *BaseClaim) Marshal() (dAtA []byte, err error) { | ||||
| @ -870,55 +721,6 @@ func (m *RewardIndexesProto) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *TypedRewardIndexes) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
| 
 | ||||
| func (m *TypedRewardIndexes) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	size := m.Size() | ||||
| 	return m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| } | ||||
| 
 | ||||
| func (m *TypedRewardIndexes) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	i := len(dAtA) | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintClaims(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x1a | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.CollateralType) > 0 { | ||||
| 		i -= len(m.CollateralType) | ||||
| 		copy(dAtA[i:], m.CollateralType) | ||||
| 		i = encodeVarintClaims(dAtA, i, uint64(len(m.CollateralType))) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x12 | ||||
| 	} | ||||
| 	if m.ClaimType != 0 { | ||||
| 		i = encodeVarintClaims(dAtA, i, uint64(m.ClaimType)) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x8 | ||||
| 	} | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *MultiRewardIndex) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| @ -1296,69 +1098,6 @@ func (m *EarnClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *Claim) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
| 
 | ||||
| func (m *Claim) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	size := m.Size() | ||||
| 	return m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| } | ||||
| 
 | ||||
| func (m *Claim) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	i := len(dAtA) | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintClaims(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x22 | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.Reward) > 0 { | ||||
| 		for iNdEx := len(m.Reward) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.Reward[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintClaims(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x1a | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.Owner) > 0 { | ||||
| 		i -= len(m.Owner) | ||||
| 		copy(dAtA[i:], m.Owner) | ||||
| 		i = encodeVarintClaims(dAtA, i, uint64(len(m.Owner))) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x12 | ||||
| 	} | ||||
| 	if m.Type != 0 { | ||||
| 		i = encodeVarintClaims(dAtA, i, uint64(m.Type)) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x8 | ||||
| 	} | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func encodeVarintClaims(dAtA []byte, offset int, v uint64) int { | ||||
| 	offset -= sovClaims(v) | ||||
| 	base := offset | ||||
| @ -1434,28 +1173,6 @@ func (m *RewardIndexesProto) Size() (n int) { | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *TypedRewardIndexes) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.ClaimType != 0 { | ||||
| 		n += 1 + sovClaims(uint64(m.ClaimType)) | ||||
| 	} | ||||
| 	l = len(m.CollateralType) | ||||
| 	if l > 0 { | ||||
| 		n += 1 + l + sovClaims(uint64(l)) | ||||
| 	} | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for _, e := range m.RewardIndexes { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovClaims(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *MultiRewardIndex) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| @ -1598,34 +1315,6 @@ func (m *EarnClaim) Size() (n int) { | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *Claim) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.Type != 0 { | ||||
| 		n += 1 + sovClaims(uint64(m.Type)) | ||||
| 	} | ||||
| 	l = len(m.Owner) | ||||
| 	if l > 0 { | ||||
| 		n += 1 + l + sovClaims(uint64(l)) | ||||
| 	} | ||||
| 	if len(m.Reward) > 0 { | ||||
| 		for _, e := range m.Reward { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovClaims(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for _, e := range m.RewardIndexes { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovClaims(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func sovClaims(x uint64) (n int) { | ||||
| 	return (math_bits.Len64(x|1) + 6) / 7 | ||||
| } | ||||
| @ -2066,141 +1755,6 @@ func (m *RewardIndexesProto) Unmarshal(dAtA []byte) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *TypedRewardIndexes) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowClaims | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= uint64(b&0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: TypedRewardIndexes: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: TypedRewardIndexes: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 0 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType) | ||||
| 			} | ||||
| 			m.ClaimType = 0 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				m.ClaimType |= ClaimType(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field CollateralType", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= uint64(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.CollateralType = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		case 3: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.RewardIndexes = append(m.RewardIndexes, RewardIndex{}) | ||||
| 			if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipClaims(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if (skippy < 0) || (iNdEx+skippy) < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *MultiRewardIndex) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| @ -3137,177 +2691,6 @@ func (m *EarnClaim) Unmarshal(dAtA []byte) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *Claim) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowClaims | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= uint64(b&0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: Claim: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: Claim: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 0 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) | ||||
| 			} | ||||
| 			m.Type = 0 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				m.Type |= ClaimType(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) | ||||
| 			} | ||||
| 			var byteLen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				byteLen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if byteLen < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			postIndex := iNdEx + byteLen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Owner = append(m.Owner[:0], dAtA[iNdEx:postIndex]...) | ||||
| 			if m.Owner == nil { | ||||
| 				m.Owner = []byte{} | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 3: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Reward", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Reward = append(m.Reward, types.Coin{}) | ||||
| 			if err := m.Reward[len(m.Reward)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 4: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowClaims | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.RewardIndexes = append(m.RewardIndexes, MultiRewardIndex{}) | ||||
| 			if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipClaims(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if (skippy < 0) || (iNdEx+skippy) < 0 { | ||||
| 				return ErrInvalidLengthClaims | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func skipClaims(dAtA []byte) (n int, err error) { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
|  | ||||
| @ -21,59 +21,6 @@ func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) } | ||||
| func TestClaims_Validate(t *testing.T) { | ||||
| 	owner := sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))) | ||||
| 
 | ||||
| 	t.Run("Claims", func(t *testing.T) { | ||||
| 		validRewardIndexes := RewardIndexes{}.With("ukava", d("0.002")) | ||||
| 		validMultiRewardIndexes := MultiRewardIndexes{}.With("ukava", validRewardIndexes) | ||||
| 		invalidRewardIndexes := RewardIndexes{}.With("ukava", d("-0.002")) | ||||
| 		invalidMultiRewardIndexes := MultiRewardIndexes{}.With("ukava", invalidRewardIndexes) | ||||
| 
 | ||||
| 		testCases := []struct { | ||||
| 			name    string | ||||
| 			claims  Claims | ||||
| 			expPass bool | ||||
| 		}{ | ||||
| 			{ | ||||
| 				name: "valid", | ||||
| 				claims: Claims{ | ||||
| 					NewClaim(CLAIM_TYPE_USDX_MINTING, owner, cs(c("bnb", 1)), validMultiRewardIndexes), | ||||
| 				}, | ||||
| 				expPass: true, | ||||
| 			}, | ||||
| 			{ | ||||
| 				name: "invalid owner", | ||||
| 				claims: Claims{ | ||||
| 					NewClaim(CLAIM_TYPE_USDX_MINTING, nil, cs(c("bnb", 1)), validMultiRewardIndexes), | ||||
| 				}, | ||||
| 				expPass: false, | ||||
| 			}, | ||||
| 			{ | ||||
| 				name: "invalid reward", | ||||
| 				claims: Claims{ | ||||
| 					NewClaim(CLAIM_TYPE_USDX_MINTING, owner, sdk.Coins{sdk.Coin{Denom: "invalid😫"}}, validMultiRewardIndexes), | ||||
| 				}, | ||||
| 				expPass: false, | ||||
| 			}, | ||||
| 			{ | ||||
| 				name: "invalid indexes", | ||||
| 				claims: Claims{ | ||||
| 					NewClaim(CLAIM_TYPE_USDX_MINTING, nil, cs(c("bnb", 1)), invalidMultiRewardIndexes), | ||||
| 				}, | ||||
| 				expPass: false, | ||||
| 			}, | ||||
| 		} | ||||
| 
 | ||||
| 		for _, tc := range testCases { | ||||
| 			t.Run(tc.name, func(t *testing.T) { | ||||
| 				err := tc.claims.Validate() | ||||
| 				if tc.expPass { | ||||
| 					require.NoError(t, err) | ||||
| 				} else { | ||||
| 					require.Error(t, err) | ||||
| 				} | ||||
| 			}) | ||||
| 		} | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("USDXMintingClaims", func(t *testing.T) { | ||||
| 		testCases := []struct { | ||||
| 			name    string | ||||
|  | ||||
| @ -16,22 +16,14 @@ var ( | ||||
| 		MultiRewardIndexes{}, | ||||
| 	) | ||||
| 	DefaultEarnClaims = EarnClaims{} | ||||
| 
 | ||||
| 	// New fields
 | ||||
| 	DefaultClaims                 = Claims{} | ||||
| 	DefaultAccrualTimes           = AccrualTimes{} | ||||
| 	DefaultTypedRewardIndexesList = TypedRewardIndexesList{} | ||||
| ) | ||||
| 
 | ||||
| // NewGenesisState returns a new genesis state
 | ||||
| func NewGenesisState( | ||||
| 	params Params, | ||||
| 	usdxState, hardSupplyState, hardBorrowState, delegatorState, swapState, savingsState, earnState GenesisRewardState, | ||||
| 	c Claims, | ||||
| 	uc USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims, | ||||
| 	c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims, | ||||
| 	earnc EarnClaims, | ||||
| 	accrualTimes AccrualTimes, | ||||
| 	rewardIndexes TypedRewardIndexesList, | ||||
| ) GenesisState { | ||||
| 	return GenesisState{ | ||||
| 		Params: params, | ||||
| @ -44,18 +36,12 @@ func NewGenesisState( | ||||
| 		SavingsRewardState:    savingsState, | ||||
| 		EarnRewardState:       earnState, | ||||
| 
 | ||||
| 		USDXMintingClaims:           uc, | ||||
| 		USDXMintingClaims:           c, | ||||
| 		HardLiquidityProviderClaims: hc, | ||||
| 		DelegatorClaims:             dc, | ||||
| 		SwapClaims:                  sc, | ||||
| 		SavingsClaims:               savingsc, | ||||
| 		EarnClaims:                  earnc, | ||||
| 
 | ||||
| 		// New fields
 | ||||
| 		// Claims of all types
 | ||||
| 		Claims:        c, | ||||
| 		AccrualTimes:  accrualTimes, | ||||
| 		RewardIndexes: rewardIndexes, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -70,15 +56,12 @@ func DefaultGenesisState() GenesisState { | ||||
| 		SwapRewardState:             DefaultGenesisRewardState, | ||||
| 		SavingsRewardState:          DefaultGenesisRewardState, | ||||
| 		EarnRewardState:             DefaultGenesisRewardState, | ||||
| 		Claims:                      DefaultClaims, | ||||
| 		USDXMintingClaims:           DefaultUSDXClaims, | ||||
| 		HardLiquidityProviderClaims: DefaultHardClaims, | ||||
| 		DelegatorClaims:             DefaultDelegatorClaims, | ||||
| 		SwapClaims:                  DefaultSwapClaims, | ||||
| 		SavingsClaims:               DefaultSavingsClaims, | ||||
| 		EarnClaims:                  DefaultEarnClaims, | ||||
| 		AccrualTimes:                DefaultAccrualTimes, | ||||
| 		RewardIndexes:               DefaultTypedRewardIndexesList, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -128,20 +111,7 @@ func (gs GenesisState) Validate() error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := gs.EarnClaims.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Refactored methods -- these will eventually replace the claim and state methods above
 | ||||
| 	if err := gs.Claims.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := gs.AccrualTimes.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return gs.RewardIndexes.Validate() | ||||
| 	return gs.EarnClaims.Validate() | ||||
| } | ||||
| 
 | ||||
| // NewGenesisRewardState returns a new GenesisRewardState
 | ||||
| @ -188,50 +158,3 @@ func (gats AccumulationTimes) Validate() error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewAccrualTime returns a new AccrualTime
 | ||||
| func NewAccrualTime(claimType ClaimType, collateralType string, prevTime time.Time) AccrualTime { | ||||
| 	return AccrualTime{ | ||||
| 		ClaimType:                claimType, | ||||
| 		CollateralType:           collateralType, | ||||
| 		PreviousAccumulationTime: prevTime, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Validate performs validation of AccrualTime
 | ||||
| func (at AccrualTime) Validate() error { | ||||
| 	if at.PreviousAccumulationTime.IsZero() { | ||||
| 		return fmt.Errorf("previous accumulation time cannot be zero") | ||||
| 	} | ||||
| 
 | ||||
| 	if err := at.ClaimType.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(at.CollateralType) == 0 { | ||||
| 		return fmt.Errorf("collateral type cannot be empty") | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // AccrualTimes slice of AccrualTime
 | ||||
| type AccrualTimes []AccrualTime | ||||
| 
 | ||||
| // Validate performs validation of AccrualTimes
 | ||||
| func (gats AccrualTimes) Validate() error { | ||||
| 	seenAccrualTimes := make(map[string]bool) | ||||
| 
 | ||||
| 	for _, gat := range gats { | ||||
| 		if err := gat.Validate(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		key := fmt.Sprintf("%s-%s", gat.ClaimType, gat.CollateralType) | ||||
| 		if seenAccrualTimes[key] { | ||||
| 			return fmt.Errorf("duplicate accrual time found for %s", key) | ||||
| 		} | ||||
| 		seenAccrualTimes[key] = true | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -28,8 +28,6 @@ var _ = time.Kitchen | ||||
| const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 | ||||
| 
 | ||||
| // AccumulationTime stores the previous reward distribution time and its corresponding collateral type
 | ||||
| //
 | ||||
| // Deprecated: Do not use.
 | ||||
| type AccumulationTime struct { | ||||
| 	CollateralType           string    `protobuf:"bytes,1,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"` | ||||
| 	PreviousAccumulationTime time.Time `protobuf:"bytes,2,opt,name=previous_accumulation_time,json=previousAccumulationTime,proto3,stdtime" json:"previous_accumulation_time"` | ||||
| @ -68,48 +66,6 @@ func (m *AccumulationTime) XXX_DiscardUnknown() { | ||||
| 
 | ||||
| var xxx_messageInfo_AccumulationTime proto.InternalMessageInfo | ||||
| 
 | ||||
| // AccrualTime stores the previous reward distribution time and its
 | ||||
| // corresponding collateral type and claim type. This is the new version of
 | ||||
| // AccumulationTime that is used for the new claim types.
 | ||||
| type AccrualTime struct { | ||||
| 	ClaimType                ClaimType `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"` | ||||
| 	CollateralType           string    `protobuf:"bytes,2,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"` | ||||
| 	PreviousAccumulationTime time.Time `protobuf:"bytes,3,opt,name=previous_accumulation_time,json=previousAccumulationTime,proto3,stdtime" json:"previous_accumulation_time"` | ||||
| } | ||||
| 
 | ||||
| func (m *AccrualTime) Reset()         { *m = AccrualTime{} } | ||||
| func (m *AccrualTime) String() string { return proto.CompactTextString(m) } | ||||
| func (*AccrualTime) ProtoMessage()    {} | ||||
| func (*AccrualTime) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8b76737885d05afd, []int{1} | ||||
| } | ||||
| func (m *AccrualTime) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| } | ||||
| func (m *AccrualTime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	if deterministic { | ||||
| 		return xxx_messageInfo_AccrualTime.Marshal(b, m, deterministic) | ||||
| 	} else { | ||||
| 		b = b[:cap(b)] | ||||
| 		n, err := m.MarshalToSizedBuffer(b) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return b[:n], nil | ||||
| 	} | ||||
| } | ||||
| func (m *AccrualTime) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_AccrualTime.Merge(m, src) | ||||
| } | ||||
| func (m *AccrualTime) XXX_Size() int { | ||||
| 	return m.Size() | ||||
| } | ||||
| func (m *AccrualTime) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_AccrualTime.DiscardUnknown(m) | ||||
| } | ||||
| 
 | ||||
| var xxx_messageInfo_AccrualTime proto.InternalMessageInfo | ||||
| 
 | ||||
| // GenesisRewardState groups together the global state for a particular reward so it can be exported in genesis.
 | ||||
| type GenesisRewardState struct { | ||||
| 	AccumulationTimes  AccumulationTimes  `protobuf:"bytes,1,rep,name=accumulation_times,json=accumulationTimes,proto3,castrepeated=AccumulationTimes" json:"accumulation_times"` | ||||
| @ -120,7 +76,7 @@ func (m *GenesisRewardState) Reset()         { *m = GenesisRewardState{} } | ||||
| func (m *GenesisRewardState) String() string { return proto.CompactTextString(m) } | ||||
| func (*GenesisRewardState) ProtoMessage()    {} | ||||
| func (*GenesisRewardState) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8b76737885d05afd, []int{2} | ||||
| 	return fileDescriptor_8b76737885d05afd, []int{1} | ||||
| } | ||||
| func (m *GenesisRewardState) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -165,16 +121,13 @@ type GenesisState struct { | ||||
| 	SavingsClaims               SavingsClaims               `protobuf:"bytes,12,rep,name=savings_claims,json=savingsClaims,proto3,castrepeated=SavingsClaims" json:"savings_claims"` | ||||
| 	EarnRewardState             GenesisRewardState          `protobuf:"bytes,13,opt,name=earn_reward_state,json=earnRewardState,proto3" json:"earn_reward_state"` | ||||
| 	EarnClaims                  EarnClaims                  `protobuf:"bytes,14,rep,name=earn_claims,json=earnClaims,proto3,castrepeated=EarnClaims" json:"earn_claims"` | ||||
| 	Claims                      Claims                      `protobuf:"bytes,15,rep,name=claims,proto3,castrepeated=Claims" json:"claims"` | ||||
| 	AccrualTimes                AccrualTimes                `protobuf:"bytes,16,rep,name=accrual_times,json=accrualTimes,proto3,castrepeated=AccrualTimes" json:"accrual_times"` | ||||
| 	RewardIndexes               TypedRewardIndexesList      `protobuf:"bytes,17,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=TypedRewardIndexesList" json:"reward_indexes"` | ||||
| } | ||||
| 
 | ||||
| func (m *GenesisState) Reset()         { *m = GenesisState{} } | ||||
| func (m *GenesisState) String() string { return proto.CompactTextString(m) } | ||||
| func (*GenesisState) ProtoMessage()    {} | ||||
| func (*GenesisState) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_8b76737885d05afd, []int{3} | ||||
| 	return fileDescriptor_8b76737885d05afd, []int{2} | ||||
| } | ||||
| func (m *GenesisState) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -205,7 +158,6 @@ var xxx_messageInfo_GenesisState proto.InternalMessageInfo | ||||
| 
 | ||||
| func init() { | ||||
| 	proto.RegisterType((*AccumulationTime)(nil), "kava.incentive.v1beta1.AccumulationTime") | ||||
| 	proto.RegisterType((*AccrualTime)(nil), "kava.incentive.v1beta1.AccrualTime") | ||||
| 	proto.RegisterType((*GenesisRewardState)(nil), "kava.incentive.v1beta1.GenesisRewardState") | ||||
| 	proto.RegisterType((*GenesisState)(nil), "kava.incentive.v1beta1.GenesisState") | ||||
| } | ||||
| @ -215,64 +167,57 @@ func init() { | ||||
| } | ||||
| 
 | ||||
| var fileDescriptor_8b76737885d05afd = []byte{ | ||||
| 	// 911 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x1b, 0x45, | ||||
| 	0x14, 0xf7, 0x3a, 0xc5, 0x34, 0xe3, 0xd8, 0x8e, 0x07, 0x37, 0x35, 0xae, 0x58, 0x87, 0xa4, 0x82, | ||||
| 	0x08, 0xc4, 0x5a, 0x35, 0x37, 0xc4, 0x81, 0x2e, 0xad, 0xa0, 0x52, 0x2b, 0x55, 0x93, 0x50, 0x21, | ||||
| 	0x84, 0xb0, 0x66, 0x77, 0xa7, 0x9b, 0x81, 0xfd, 0xd7, 0x99, 0x59, 0x27, 0xb9, 0x71, 0xe4, 0xd8, | ||||
| 	0x0f, 0xc0, 0x8d, 0x1b, 0x9f, 0x24, 0xc7, 0x1e, 0x39, 0xa0, 0x06, 0x9c, 0x2f, 0x82, 0x66, 0x76, | ||||
| 	0xd6, 0xd9, 0xb5, 0xb3, 0x46, 0x98, 0xde, 0x66, 0xdf, 0xbc, 0xf9, 0xfd, 0x99, 0xf7, 0x66, 0x67, | ||||
| 	0xc0, 0xdd, 0x9f, 0xf0, 0x14, 0x8f, 0x68, 0xe4, 0x92, 0x48, 0xd0, 0x29, 0x19, 0x4d, 0xef, 0x39, | ||||
| 	0x44, 0xe0, 0x7b, 0x23, 0x9f, 0x44, 0x84, 0x53, 0x6e, 0x25, 0x2c, 0x16, 0x31, 0xdc, 0x91, 0x59, | ||||
| 	0xd6, 0x3c, 0xcb, 0xd2, 0x59, 0x83, 0x9e, 0x1f, 0xfb, 0xb1, 0x4a, 0x19, 0xc9, 0x51, 0x96, 0x3d, | ||||
| 	0x18, 0xfa, 0x71, 0xec, 0x07, 0x64, 0xa4, 0xbe, 0x9c, 0xf4, 0xf9, 0x48, 0xd0, 0x90, 0x70, 0x81, | ||||
| 	0xc3, 0x44, 0x27, 0xec, 0x57, 0x90, 0xba, 0x01, 0xa6, 0x21, 0xff, 0x97, 0xa4, 0x04, 0x33, 0x9c, | ||||
| 	0x27, 0xed, 0xfd, 0x66, 0x80, 0xed, 0xfb, 0xae, 0x9b, 0x86, 0x69, 0x80, 0x05, 0x8d, 0xa3, 0x23, | ||||
| 	0x1a, 0x12, 0xf8, 0x21, 0xe8, 0xb8, 0x71, 0x10, 0x60, 0x41, 0x18, 0x0e, 0x26, 0xe2, 0x2c, 0x21, | ||||
| 	0x7d, 0x63, 0xd7, 0x38, 0xd8, 0x44, 0xed, 0xab, 0xf0, 0xd1, 0x59, 0x42, 0xa0, 0x03, 0x06, 0x09, | ||||
| 	0x23, 0x53, 0x1a, 0xa7, 0x7c, 0x82, 0x0b, 0x28, 0x13, 0x29, 0xb8, 0x5f, 0xdf, 0x35, 0x0e, 0x9a, | ||||
| 	0xe3, 0x81, 0x95, 0xb9, 0xb1, 0x72, 0x37, 0xd6, 0x51, 0xee, 0xc6, 0xbe, 0x79, 0xfe, 0x7a, 0x58, | ||||
| 	0x7b, 0x79, 0x31, 0x34, 0x50, 0x3f, 0xc7, 0x59, 0x14, 0xf3, 0x59, 0xbd, 0x6f, 0xec, 0xfd, 0x69, | ||||
| 	0x80, 0xe6, 0x7d, 0xd7, 0x65, 0x29, 0x0e, 0x94, 0xc0, 0x2f, 0x00, 0x50, 0x56, 0xaf, 0xb4, 0xb5, | ||||
| 	0xc7, 0xef, 0x5b, 0xd7, 0xef, 0xb1, 0xf5, 0xa5, 0xcc, 0x94, 0x72, 0xd1, 0xa6, 0x9b, 0x0f, 0xaf, | ||||
| 	0xb3, 0x58, 0x5f, 0xc3, 0xe2, 0xc6, 0x9b, 0xb0, 0xb8, 0xf7, 0x73, 0x1d, 0xc0, 0xaf, 0xb2, 0x7e, | ||||
| 	0x41, 0xe4, 0x04, 0x33, 0xef, 0x50, 0x60, 0x41, 0x20, 0x03, 0x70, 0x89, 0x91, 0xf7, 0x8d, 0xdd, | ||||
| 	0x8d, 0x83, 0xe6, 0xf8, 0xa0, 0xca, 0xed, 0x22, 0xb8, 0xfd, 0xae, 0x14, 0xf0, 0xfb, 0xc5, 0xb0, | ||||
| 	0xbb, 0x38, 0xc3, 0x51, 0x17, 0x2f, 0x86, 0xe0, 0x14, 0xf4, 0xc2, 0x34, 0x10, 0x74, 0xc2, 0x94, | ||||
| 	0x90, 0x09, 0x8d, 0x3c, 0x72, 0x4a, 0x78, 0xbf, 0xbe, 0x9a, 0xf5, 0x89, 0x5c, 0x93, 0x69, 0x7f, | ||||
| 	0x24, 0x57, 0xd8, 0x03, 0xcd, 0x0a, 0x17, 0x67, 0x08, 0x47, 0x30, 0x5c, 0x8a, 0xed, 0x5d, 0xb4, | ||||
| 	0xc0, 0x96, 0xde, 0x82, 0xcc, 0xfc, 0xe7, 0xa0, 0x91, 0x35, 0xaa, 0x2a, 0x6f, 0x73, 0x6c, 0x56, | ||||
| 	0x51, 0x3f, 0x55, 0x59, 0xf6, 0x0d, 0x49, 0x88, 0xf4, 0x1a, 0x18, 0x83, 0x6e, 0xca, 0xbd, 0xd3, | ||||
| 	0xdc, 0x05, 0x97, 0x90, 0xba, 0x1f, 0x3f, 0xaa, 0x02, 0x5a, 0xae, 0x80, 0x7d, 0x5b, 0x82, 0xce, | ||||
| 	0x5e, 0x0f, 0x3b, 0xdf, 0x1c, 0x3e, 0xf8, 0xb6, 0x30, 0x81, 0x3a, 0x12, 0xbd, 0x58, 0x2b, 0x0a, | ||||
| 	0xfa, 0xc7, 0x8a, 0x29, 0x4d, 0x92, 0xe0, 0xac, 0xcc, 0xbb, 0xf1, 0x9f, 0x79, 0x33, 0x33, 0xb7, | ||||
| 	0x24, 0xe2, 0xa1, 0x02, 0xbc, 0x8e, 0xca, 0x89, 0x19, 0x8b, 0x4f, 0xca, 0x54, 0x37, 0xfe, 0x0f, | ||||
| 	0x95, 0xad, 0x00, 0x8b, 0x54, 0xcf, 0xc1, 0x8e, 0x47, 0x02, 0xe2, 0x63, 0x11, 0xb3, 0x32, 0xd1, | ||||
| 	0x5b, 0x6b, 0x12, 0xf5, 0xe6, 0x78, 0x45, 0x9e, 0xef, 0x41, 0x97, 0x9f, 0xe0, 0xa4, 0x4c, 0xd1, | ||||
| 	0x58, 0x93, 0xa2, 0x23, 0xa1, 0x8a, 0xe8, 0xbf, 0x18, 0xe0, 0x1d, 0xd5, 0x0d, 0x21, 0x8d, 0x04, | ||||
| 	0x8d, 0xfc, 0x49, 0xf6, 0x9b, 0xec, 0xbf, 0xbd, 0xba, 0xa7, 0x65, 0xcd, 0x9f, 0x64, 0x2b, 0xd4, | ||||
| 	0x2f, 0xc4, 0xb6, 0x74, 0x37, 0x74, 0x17, 0x67, 0xb8, 0x3c, 0x5e, 0x4b, 0x41, 0xa4, 0x5a, 0xb0, | ||||
| 	0x14, 0x82, 0xbf, 0x1a, 0xc0, 0x54, 0xc5, 0x0b, 0xe8, 0x8b, 0x94, 0x7a, 0x54, 0x9c, 0x4d, 0x12, | ||||
| 	0x16, 0x4f, 0xa9, 0x47, 0x58, 0xae, 0xea, 0xa6, 0x52, 0x35, 0xae, 0x52, 0xf5, 0x35, 0x66, 0xde, | ||||
| 	0xe3, 0x7c, 0xf1, 0x53, 0xbd, 0x36, 0xd3, 0xb7, 0xaf, 0xcf, 0xdc, 0x9d, 0xea, 0x1c, 0x8e, 0xee, | ||||
| 	0x1c, 0x57, 0x4f, 0xc2, 0x1f, 0xc1, 0xf6, 0x55, 0xbd, 0xb5, 0x9e, 0x4d, 0xa5, 0xe7, 0x83, 0x2a, | ||||
| 	0x3d, 0x0f, 0xf2, 0xfc, 0x4c, 0xc3, 0x6d, 0xad, 0xa1, 0x53, 0x8e, 0x73, 0xd4, 0xf1, 0xca, 0x01, | ||||
| 	0xf8, 0x0c, 0x34, 0x55, 0xcd, 0x35, 0x0d, 0x50, 0x34, 0x95, 0x3f, 0xf1, 0xc3, 0x13, 0x9c, 0x64, | ||||
| 	0x0c, 0x50, 0x33, 0x80, 0x79, 0x88, 0x23, 0xc0, 0xe7, 0x63, 0xe8, 0x80, 0x1e, 0xc7, 0x53, 0x1a, | ||||
| 	0xf9, 0xbc, 0xdc, 0x4e, 0xcd, 0x35, 0xdb, 0x09, 0x6a, 0xb4, 0x62, 0x47, 0x39, 0xa0, 0x9d, 0x73, | ||||
| 	0x68, 0xf9, 0x5b, 0x4a, 0xfe, 0xdd, 0x4a, 0xf9, 0x59, 0x76, 0xe6, 0xe0, 0x96, 0x76, 0xd0, 0x2a, | ||||
| 	0x46, 0x39, 0x6a, 0xf1, 0xe2, 0xa7, 0x3c, 0x13, 0x04, 0xb3, 0xa8, 0x6c, 0xa2, 0xb5, 0xee, 0x99, | ||||
| 	0x90, 0x50, 0x45, 0x07, 0xcf, 0x40, 0x53, 0xa1, 0x6b, 0xf9, 0xed, 0xd5, 0xbb, 0xff, 0x10, 0xb3, | ||||
| 	0x68, 0x61, 0xf7, 0xe7, 0x21, 0x8e, 0x00, 0x99, 0x8f, 0xe1, 0x43, 0xd0, 0xd0, 0x90, 0x1d, 0x05, | ||||
| 	0xf9, 0xde, 0xca, 0x5b, 0xd9, 0x6e, 0x6b, 0xb8, 0x86, 0x86, 0xd2, 0x8b, 0xe1, 0x0f, 0xa0, 0x85, | ||||
| 	0xb3, 0xfb, 0x5e, 0xdf, 0x7a, 0xdb, 0x0a, 0x6d, 0x7f, 0xc5, 0xad, 0x97, 0x3f, 0x0e, 0xec, 0x9e, | ||||
| 	0xc6, 0xdc, 0x2a, 0x04, 0x39, 0xda, 0xc2, 0x85, 0x2f, 0xf8, 0x02, 0xb4, 0x17, 0x2e, 0xb8, 0xae, | ||||
| 	0x22, 0xa8, 0xdc, 0x59, 0xf9, 0x16, 0xf0, 0x4a, 0x57, 0x96, 0x6d, 0x6a, 0x9e, 0x9d, 0xe5, 0xb9, | ||||
| 	0xc7, 0x94, 0x0b, 0xd4, 0x62, 0xa5, 0xf4, 0x47, 0xe7, 0x7f, 0x9b, 0xb5, 0xf3, 0x99, 0x69, 0xbc, | ||||
| 	0x9a, 0x99, 0xc6, 0x5f, 0x33, 0xd3, 0x78, 0x79, 0x69, 0xd6, 0x5e, 0x5d, 0x9a, 0xb5, 0x3f, 0x2e, | ||||
| 	0xcd, 0xda, 0x77, 0x1f, 0xfb, 0x54, 0x1c, 0xa7, 0x8e, 0xe5, 0xc6, 0xe1, 0x48, 0x4a, 0xf8, 0x24, | ||||
| 	0xc0, 0x0e, 0x57, 0xa3, 0xd1, 0x69, 0xe1, 0x0d, 0x27, 0x1f, 0x2a, 0xdc, 0x69, 0xa8, 0x77, 0xc6, | ||||
| 	0xa7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x85, 0x46, 0xc8, 0xc0, 0x7c, 0x0a, 0x00, 0x00, | ||||
| 	// 785 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x4f, 0xdb, 0x48, | ||||
| 	0x14, 0xc7, 0x63, 0x60, 0x59, 0x98, 0x00, 0x21, 0xb3, 0x01, 0xb2, 0x41, 0x72, 0x58, 0x40, 0xbb, | ||||
| 	0xd1, 0x56, 0xb5, 0x45, 0x7a, 0xed, 0xa5, 0x2e, 0x55, 0x8b, 0x54, 0x24, 0xe4, 0x50, 0x54, 0x55, | ||||
| 	0x95, 0xa2, 0x71, 0x3c, 0x98, 0x69, 0xfd, 0xab, 0x1e, 0x3b, 0x21, 0xb7, 0x1e, 0x7b, 0xe4, 0x0f, | ||||
| 	0xa8, 0xd4, 0x7b, 0xff, 0x8f, 0x4a, 0x1c, 0x39, 0xf6, 0x04, 0x6d, 0xf8, 0x47, 0xaa, 0x19, 0x8f, | ||||
| 	0x83, 0x9d, 0x60, 0xaa, 0xa6, 0xb7, 0xc9, 0x9b, 0x37, 0xdf, 0xcf, 0xf7, 0xcd, 0x7b, 0x13, 0x83, | ||||
| 	0xed, 0xb7, 0xa8, 0x8b, 0x54, 0xe2, 0x76, 0xb0, 0x1b, 0x92, 0x2e, 0x56, 0xbb, 0x3b, 0x06, 0x0e, | ||||
| 	0xd1, 0x8e, 0x6a, 0x61, 0x17, 0x53, 0x42, 0x15, 0x3f, 0xf0, 0x42, 0x0f, 0xae, 0xb2, 0x2c, 0x65, | ||||
| 	0x98, 0xa5, 0x88, 0xac, 0x5a, 0xc5, 0xf2, 0x2c, 0x8f, 0xa7, 0xa8, 0x6c, 0x15, 0x67, 0xd7, 0xea, | ||||
| 	0x96, 0xe7, 0x59, 0x36, 0x56, 0xf9, 0x2f, 0x23, 0x3a, 0x56, 0x43, 0xe2, 0x60, 0x1a, 0x22, 0xc7, | ||||
| 	0x17, 0x09, 0x5b, 0x39, 0xd0, 0x8e, 0x8d, 0x88, 0x43, 0x7f, 0x92, 0xe4, 0xa3, 0x00, 0x25, 0x49, | ||||
| 	0x9b, 0x9f, 0x24, 0xb0, 0xfc, 0xa8, 0xd3, 0x89, 0x9c, 0xc8, 0x46, 0x21, 0xf1, 0xdc, 0x43, 0xe2, | ||||
| 	0x60, 0xf8, 0x1f, 0x28, 0x75, 0x3c, 0xdb, 0x46, 0x21, 0x0e, 0x90, 0xdd, 0x0e, 0xfb, 0x3e, 0xae, | ||||
| 	0x4a, 0x1b, 0x52, 0x63, 0x5e, 0x5f, 0xba, 0x09, 0x1f, 0xf6, 0x7d, 0x0c, 0x0d, 0x50, 0xf3, 0x03, | ||||
| 	0xdc, 0x25, 0x5e, 0x44, 0xdb, 0x28, 0xa5, 0xd2, 0x66, 0x86, 0xab, 0x53, 0x1b, 0x52, 0xa3, 0xd8, | ||||
| 	0xac, 0x29, 0x71, 0x35, 0x4a, 0x52, 0x8d, 0x72, 0x98, 0x54, 0xa3, 0xcd, 0x9d, 0x5f, 0xd6, 0x0b, | ||||
| 	0x67, 0x57, 0x75, 0x49, 0xaf, 0x26, 0x3a, 0xa3, 0x66, 0x36, 0xdf, 0x4f, 0x01, 0xf8, 0x34, 0xbe, | ||||
| 	0x4c, 0x1d, 0xf7, 0x50, 0x60, 0xb6, 0x42, 0x14, 0x62, 0x18, 0x00, 0x38, 0x46, 0xa4, 0x55, 0x69, | ||||
| 	0x63, 0xba, 0x51, 0x6c, 0x36, 0x94, 0xdb, 0xaf, 0x5b, 0x19, 0x15, 0xd7, 0xfe, 0x66, 0x06, 0x3e, | ||||
| 	0x5f, 0xd5, 0xcb, 0xa3, 0x3b, 0x54, 0x2f, 0xa3, 0xd1, 0x10, 0xec, 0x82, 0x8a, 0x13, 0xd9, 0x21, | ||||
| 	0x69, 0x07, 0xdc, 0x48, 0x9b, 0xb8, 0x26, 0x3e, 0xc5, 0xb4, 0x3a, 0x75, 0x37, 0x75, 0x9f, 0x9d, | ||||
| 	0x89, 0xbd, 0xef, 0xb1, 0x13, 0x5a, 0x4d, 0x50, 0xe1, 0xe8, 0x0e, 0xa6, 0x3a, 0x74, 0xc6, 0x62, | ||||
| 	0x9b, 0x5f, 0x8a, 0x60, 0x41, 0x5c, 0x41, 0x5c, 0xfc, 0x43, 0x30, 0x1b, 0x77, 0x91, 0xf7, 0xa5, | ||||
| 	0xd8, 0x94, 0xf3, 0xd0, 0x07, 0x3c, 0x4b, 0x9b, 0x61, 0x40, 0x5d, 0x9c, 0x81, 0x1e, 0x28, 0x47, | ||||
| 	0xd4, 0x3c, 0x4d, 0xaa, 0xa0, 0x4c, 0x52, 0x34, 0xeb, 0xff, 0x3c, 0xa1, 0xf1, 0x0e, 0x68, 0x6b, | ||||
| 	0x4c, 0x74, 0x70, 0x59, 0x2f, 0xbd, 0x68, 0xed, 0xbe, 0x4c, 0x6d, 0xe8, 0x25, 0xa6, 0x9e, 0xee, | ||||
| 	0x15, 0x01, 0xd5, 0x13, 0x4e, 0x8a, 0x7c, 0xdf, 0xee, 0x67, 0xb9, 0xd3, 0xbf, 0xcc, 0x8d, 0x8b, | ||||
| 	0x59, 0x61, 0x8a, 0x2d, 0x2e, 0x78, 0x1b, 0xca, 0xf0, 0x82, 0xc0, 0xeb, 0x65, 0x51, 0x33, 0xbf, | ||||
| 	0x83, 0xd2, 0xb8, 0x60, 0x1a, 0x75, 0x0c, 0x56, 0x4d, 0x6c, 0x63, 0x0b, 0x85, 0x5e, 0x90, 0x05, | ||||
| 	0xfd, 0x31, 0x21, 0xa8, 0x32, 0xd4, 0x4b, 0x73, 0x5e, 0x83, 0x32, 0xed, 0x21, 0x3f, 0x8b, 0x98, | ||||
| 	0x9d, 0x10, 0x51, 0x62, 0x52, 0x69, 0xf5, 0x0f, 0x12, 0xf8, 0x8b, 0x4f, 0x83, 0x43, 0xdc, 0x90, | ||||
| 	0xb8, 0x56, 0x3b, 0xfe, 0x0f, 0xa9, 0xfe, 0x79, 0xf7, 0x4c, 0xb3, 0x9e, 0xef, 0xc7, 0x27, 0x1e, | ||||
| 	0xb3, 0x03, 0x9a, 0x22, 0xa6, 0xa1, 0x3c, 0xba, 0x43, 0xd9, 0xf3, 0x1a, 0x0b, 0xea, 0x7c, 0x04, | ||||
| 	0x33, 0x21, 0xf8, 0x51, 0x02, 0x32, 0x6f, 0x9e, 0x4d, 0xde, 0x45, 0xc4, 0x24, 0x61, 0xbf, 0xed, | ||||
| 	0x07, 0x5e, 0x97, 0x98, 0x38, 0x48, 0x5c, 0xcd, 0x71, 0x57, 0xcd, 0x3c, 0x57, 0xcf, 0x50, 0x60, | ||||
| 	0x3e, 0x4f, 0x0e, 0x1f, 0x88, 0xb3, 0xb1, 0xbf, 0x2d, 0xf1, 0xe6, 0xd6, 0xf3, 0x73, 0xa8, 0xbe, | ||||
| 	0x7e, 0x92, 0xbf, 0x09, 0xdf, 0x80, 0xe5, 0x9b, 0x7e, 0x0b, 0x3f, 0xf3, 0xdc, 0xcf, 0xbf, 0x79, | ||||
| 	0x7e, 0x76, 0x93, 0xfc, 0xd8, 0xc3, 0x9a, 0xf0, 0x50, 0xca, 0xc6, 0xa9, 0x5e, 0x32, 0xb3, 0x01, | ||||
| 	0x78, 0x04, 0x8a, 0xbc, 0xe7, 0x02, 0x03, 0x38, 0xe6, 0x9f, 0x3c, 0x4c, 0xab, 0x87, 0xfc, 0x98, | ||||
| 	0x00, 0x05, 0x01, 0x0c, 0x43, 0x54, 0x07, 0x74, 0xb8, 0x86, 0x06, 0xa8, 0x50, 0xd4, 0x25, 0xae, | ||||
| 	0x45, 0xb3, 0xe3, 0x54, 0x9c, 0x70, 0x9c, 0xa0, 0x50, 0x4b, 0x4f, 0x94, 0x01, 0x96, 0x12, 0x86, | ||||
| 	0xb0, 0xbf, 0xc0, 0xed, 0x6f, 0xe7, 0xda, 0x8f, 0xb3, 0xe3, 0x0a, 0x56, 0x44, 0x05, 0x8b, 0xe9, | ||||
| 	0x28, 0xd5, 0x17, 0x69, 0xfa, 0x27, 0x7b, 0x13, 0x18, 0x05, 0x6e, 0xb6, 0x88, 0xc5, 0x49, 0xdf, | ||||
| 	0x04, 0x93, 0x4a, 0x57, 0x70, 0x04, 0x8a, 0x5c, 0x5d, 0xd8, 0x5f, 0xba, 0xfb, 0xf6, 0x9f, 0xa0, | ||||
| 	0xc0, 0x1d, 0xb9, 0xfd, 0x61, 0x88, 0xea, 0x00, 0x0f, 0xd7, 0xda, 0xde, 0xf9, 0x77, 0xb9, 0x70, | ||||
| 	0x3e, 0x90, 0xa5, 0x8b, 0x81, 0x2c, 0x7d, 0x1b, 0xc8, 0xd2, 0xd9, 0xb5, 0x5c, 0xb8, 0xb8, 0x96, | ||||
| 	0x0b, 0x5f, 0xaf, 0xe5, 0xc2, 0xab, 0x7b, 0x16, 0x09, 0x4f, 0x22, 0x43, 0xe9, 0x78, 0x8e, 0xca, | ||||
| 	0x50, 0xf7, 0x6d, 0x64, 0x50, 0xbe, 0x52, 0x4f, 0x53, 0x9f, 0x71, 0xf6, 0x39, 0xa6, 0xc6, 0x2c, | ||||
| 	0xff, 0x9a, 0x3e, 0xf8, 0x11, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xa8, 0x1c, 0xb0, 0x7f, 0x08, 0x00, | ||||
| 	0x00, | ||||
| } | ||||
| 
 | ||||
| func (m *AccumulationTime) Marshal() (dAtA []byte, err error) { | ||||
| @ -313,49 +258,6 @@ func (m *AccumulationTime) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *AccrualTime) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
| 
 | ||||
| func (m *AccrualTime) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	size := m.Size() | ||||
| 	return m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| } | ||||
| 
 | ||||
| func (m *AccrualTime) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	i := len(dAtA) | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousAccumulationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousAccumulationTime):]) | ||||
| 	if err2 != nil { | ||||
| 		return 0, err2 | ||||
| 	} | ||||
| 	i -= n2 | ||||
| 	i = encodeVarintGenesis(dAtA, i, uint64(n2)) | ||||
| 	i-- | ||||
| 	dAtA[i] = 0x1a | ||||
| 	if len(m.CollateralType) > 0 { | ||||
| 		i -= len(m.CollateralType) | ||||
| 		copy(dAtA[i:], m.CollateralType) | ||||
| 		i = encodeVarintGenesis(dAtA, i, uint64(len(m.CollateralType))) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x12 | ||||
| 	} | ||||
| 	if m.ClaimType != 0 { | ||||
| 		i = encodeVarintGenesis(dAtA, i, uint64(m.ClaimType)) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x8 | ||||
| 	} | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *GenesisRewardState) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| @ -427,52 +329,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintGenesis(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x1 | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x8a | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.AccrualTimes) > 0 { | ||||
| 		for iNdEx := len(m.AccrualTimes) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.AccrualTimes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintGenesis(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x1 | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x82 | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.Claims) > 0 { | ||||
| 		for iNdEx := len(m.Claims) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.Claims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintGenesis(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x7a | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.EarnClaims) > 0 { | ||||
| 		for iNdEx := len(m.EarnClaims) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| @ -666,24 +522,6 @@ func (m *AccumulationTime) Size() (n int) { | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *AccrualTime) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.ClaimType != 0 { | ||||
| 		n += 1 + sovGenesis(uint64(m.ClaimType)) | ||||
| 	} | ||||
| 	l = len(m.CollateralType) | ||||
| 	if l > 0 { | ||||
| 		n += 1 + l + sovGenesis(uint64(l)) | ||||
| 	} | ||||
| 	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousAccumulationTime) | ||||
| 	n += 1 + l + sovGenesis(uint64(l)) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *GenesisRewardState) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| @ -763,24 +601,6 @@ func (m *GenesisState) Size() (n int) { | ||||
| 			n += 1 + l + sovGenesis(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.Claims) > 0 { | ||||
| 		for _, e := range m.Claims { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovGenesis(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.AccrualTimes) > 0 { | ||||
| 		for _, e := range m.AccrualTimes { | ||||
| 			l = e.Size() | ||||
| 			n += 2 + l + sovGenesis(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.RewardIndexes) > 0 { | ||||
| 		for _, e := range m.RewardIndexes { | ||||
| 			l = e.Size() | ||||
| 			n += 2 + l + sovGenesis(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| @ -905,140 +725,6 @@ func (m *AccumulationTime) Unmarshal(dAtA []byte) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *AccrualTime) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowGenesis | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= uint64(b&0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: AccrualTime: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: AccrualTime: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 0 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType) | ||||
| 			} | ||||
| 			m.ClaimType = 0 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				m.ClaimType |= ClaimType(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field CollateralType", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= uint64(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.CollateralType = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		case 3: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field PreviousAccumulationTime", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.PreviousAccumulationTime, dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenesis(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if (skippy < 0) || (iNdEx+skippy) < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *GenesisRewardState) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| @ -1654,108 +1340,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 15: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Claims", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Claims = append(m.Claims, Claim{}) | ||||
| 			if err := m.Claims[len(m.Claims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 16: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field AccrualTimes", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.AccrualTimes = append(m.AccrualTimes, AccrualTime{}) | ||||
| 			if err := m.AccrualTimes[len(m.AccrualTimes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 17: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenesis | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthGenesis | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.RewardIndexes = append(m.RewardIndexes, TypedRewardIndexes{}) | ||||
| 			if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenesis(dAtA[iNdEx:]) | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package types | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| @ -56,7 +57,6 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 						}, | ||||
| 					}, | ||||
| 					time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC), | ||||
| 					DefaultTypedMultiRewardPeriods, | ||||
| 				), | ||||
| 				USDXRewardState: GenesisRewardState{ | ||||
| 					AccumulationTimes: AccumulationTimes{{ | ||||
| @ -68,17 +68,16 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 						RewardIndexes:  normalRewardIndexes, | ||||
| 					}}, | ||||
| 				}, | ||||
| 				Claims: Claims{ | ||||
| 				USDXMintingClaims: USDXMintingClaims{ | ||||
| 					{ | ||||
| 						Type:   CLAIM_TYPE_USDX_MINTING, | ||||
| 						BaseClaim: BaseClaim{ | ||||
| 							Owner:  sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))), | ||||
| 						Reward: cs(c("ukava", 100000000)), | ||||
| 						RewardIndexes: []MultiRewardIndex{ | ||||
| 							Reward: sdk.NewCoin("ukava", sdk.NewInt(100000000)), | ||||
| 						}, | ||||
| 						RewardIndexes: []RewardIndex{ | ||||
| 							{ | ||||
| 								CollateralType: "bnb-a", | ||||
| 								RewardIndexes: RewardIndexes{ | ||||
| 									NewRewardIndex(USDXMintingRewardDenom, sdk.ZeroDec()), | ||||
| 								}, | ||||
| 								RewardFactor:   sdk.ZeroDec(), | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| @ -102,7 +101,7 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 						RewardIndexes:  normalRewardIndexes, | ||||
| 					}}, | ||||
| 				}, | ||||
| 				Claims: DefaultClaims, | ||||
| 				USDXMintingClaims: DefaultUSDXClaims, | ||||
| 			}, | ||||
| 			errArgs: errArgs{ | ||||
| 				expectPass: false, | ||||
| @ -114,17 +113,16 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 			genesis: GenesisState{ | ||||
| 				Params:          DefaultParams(), | ||||
| 				USDXRewardState: DefaultGenesisRewardState, | ||||
| 				Claims: Claims{ | ||||
| 				USDXMintingClaims: USDXMintingClaims{ | ||||
| 					{ | ||||
| 						Type:   CLAIM_TYPE_USDX_MINTING, | ||||
| 						BaseClaim: BaseClaim{ | ||||
| 							Owner:  nil, // invalid address
 | ||||
| 						Reward: cs(c("ukava", 100000000)), | ||||
| 						RewardIndexes: []MultiRewardIndex{ | ||||
| 							Reward: sdk.NewCoin("ukava", sdk.NewInt(100000000)), | ||||
| 						}, | ||||
| 						RewardIndexes: []RewardIndex{ | ||||
| 							{ | ||||
| 								CollateralType: "bnb-a", | ||||
| 								RewardIndexes: RewardIndexes{ | ||||
| 									NewRewardIndex(USDXMintingRewardDenom, sdk.ZeroDec()), | ||||
| 								}, | ||||
| 								RewardFactor:   sdk.ZeroDec(), | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| @ -135,20 +133,6 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 				contains:   "claim owner cannot be empty", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid accrual time", | ||||
| 			genesis: GenesisState{ | ||||
| 				Params: DefaultParams(), | ||||
| 				Claims: DefaultClaims, | ||||
| 				AccrualTimes: AccrualTimes{ | ||||
| 					NewAccrualTime(CLAIM_TYPE_USDX_MINTING, "", time.Date(2020, 10, 15, 14, 0, 0, 0, time.UTC)), | ||||
| 				}, | ||||
| 			}, | ||||
| 			errArgs: errArgs{ | ||||
| 				expectPass: false, | ||||
| 				contains:   "collateral type cannot be empty", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tc := range testCases { | ||||
| @ -158,7 +142,7 @@ func TestGenesisState_Validate(t *testing.T) { | ||||
| 				require.NoError(t, err, tc.name) | ||||
| 			} else { | ||||
| 				require.Error(t, err, tc.name) | ||||
| 				require.Contains(t, err.Error(), tc.errArgs.contains) | ||||
| 				require.True(t, strings.Contains(err.Error(), tc.errArgs.contains)) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| @ -203,76 +187,4 @@ func TestGenesisAccumulationTimes_Validate(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestAccrualTimes_Validate(t *testing.T) { | ||||
| 	testCases := []struct { | ||||
| 		name    string | ||||
| 		gats    AccrualTimes | ||||
| 		wantErr bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "normal", | ||||
| 			gats: AccrualTimes{ | ||||
| 				{ | ||||
| 					ClaimType:                CLAIM_TYPE_USDX_MINTING, | ||||
| 					CollateralType:           "btcb", | ||||
| 					PreviousAccumulationTime: normalAccumulationtime, | ||||
| 				}, | ||||
| 				{ | ||||
| 					ClaimType:                CLAIM_TYPE_USDX_MINTING, | ||||
| 					CollateralType:           "bnb", | ||||
| 					PreviousAccumulationTime: normalAccumulationtime, | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantErr: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:    "empty", | ||||
| 			gats:    nil, | ||||
| 			wantErr: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "empty collateral type", | ||||
| 			gats: AccrualTimes{ | ||||
| 				{ | ||||
| 					ClaimType:                CLAIM_TYPE_USDX_MINTING, | ||||
| 					PreviousAccumulationTime: normalAccumulationtime, | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantErr: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid claim type", | ||||
| 			gats: AccrualTimes{ | ||||
| 				{ | ||||
| 					ClaimType:                10000000, | ||||
| 					CollateralType:           "btcb", | ||||
| 					PreviousAccumulationTime: normalAccumulationtime, | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantErr: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "unspecified claim type", | ||||
| 			gats: AccrualTimes{ | ||||
| 				{ | ||||
| 					ClaimType:                CLAIM_TYPE_UNSPECIFIED, | ||||
| 					CollateralType:           "btcb", | ||||
| 					PreviousAccumulationTime: normalAccumulationtime, | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantErr: true, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tc := range testCases { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			err := tc.gats.Validate() | ||||
| 			if tc.wantErr { | ||||
| 				require.NotNil(t, err) | ||||
| 			} else { | ||||
| 				require.Nil(t, err) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var normalAccumulationtime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
|  | ||||
| @ -1,9 +1,5 @@ | ||||
| package types | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// ModuleName The name that will be used throughout the module
 | ||||
| 	ModuleName = "incentive" | ||||
| @ -44,47 +40,3 @@ var ( | ||||
| 	EarnRewardIndexesKeyPrefix                    = []byte{0x19} // prefix for key that stores earn reward indexes
 | ||||
| 	PreviousEarnRewardAccrualTimeKeyPrefix        = []byte{0x20} // prefix for key that stores the previous time earn rewards accrued
 | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	ClaimKeyPrefix                     = []byte{0x21} | ||||
| 	RewardIndexesKeyPrefix             = []byte{0x22} | ||||
| 	PreviousRewardAccrualTimeKeyPrefix = []byte{0x23} | ||||
| ) | ||||
| 
 | ||||
| var sep = []byte("|") | ||||
| 
 | ||||
| func createKey(bytes ...[]byte) (r []byte) { | ||||
| 	for _, b := range bytes { | ||||
| 		r = append(r, b...) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getKeyPrefix(dataTypePrefix []byte, claimType ClaimType) []byte { | ||||
| 	b := make([]byte, 4) | ||||
| 	binary.BigEndian.PutUint32(b, uint32(claimType)) | ||||
| 
 | ||||
| 	return createKey(dataTypePrefix, sep, b) | ||||
| } | ||||
| 
 | ||||
| // GetClaimKeyPrefix returns the claim store key prefix for the given ClaimType.
 | ||||
| func GetClaimKeyPrefix(claimType ClaimType) []byte { | ||||
| 	return getKeyPrefix(ClaimKeyPrefix, claimType) | ||||
| } | ||||
| 
 | ||||
| // GetRewardIndexesKeyPrefix returns the reward indexes key prefix for the given
 | ||||
| // ClaimType.
 | ||||
| func GetRewardIndexesKeyPrefix(claimType ClaimType) []byte { | ||||
| 	return getKeyPrefix(RewardIndexesKeyPrefix, claimType) | ||||
| } | ||||
| 
 | ||||
| // GetPreviousRewardAccrualTimeKeyPrefix returns the previous reward accrual time
 | ||||
| // key prefix for the given ClaimType.
 | ||||
| func GetPreviousRewardAccrualTimeKeyPrefix(claimType ClaimType) []byte { | ||||
| 	return getKeyPrefix(PreviousRewardAccrualTimeKeyPrefix, claimType) | ||||
| } | ||||
| 
 | ||||
| // GetKeyFromSourceID returns the store key for the given source ID.
 | ||||
| func GetKeyFromSourceID(sourceID string) []byte { | ||||
| 	return []byte(sourceID) | ||||
| } | ||||
|  | ||||
| @ -24,13 +24,11 @@ var ( | ||||
| 	KeyEarnRewardPeriods        = []byte("EarnRewardPeriods") | ||||
| 	KeyClaimEnd                 = []byte("ClaimEnd") | ||||
| 	KeyMultipliers              = []byte("ClaimMultipliers") | ||||
| 	KeyTypedMultiRewardPeriods  = []byte("TypedMultiRewardPeriods") | ||||
| 
 | ||||
| 	DefaultActive             = false | ||||
| 	DefaultRewardPeriods      = RewardPeriods{} | ||||
| 	DefaultMultiRewardPeriods = MultiRewardPeriods{} | ||||
| 	DefaultMultipliers        = MultipliersPerDenoms{} | ||||
| 	DefaultTypedMultiRewardPeriods = TypedMultiRewardPeriods{} | ||||
| 	DefaultClaimEnd           = tmtime.Canonical(time.Unix(1, 0)) | ||||
| 
 | ||||
| 	BondDenom              = "ukava" | ||||
| @ -46,7 +44,6 @@ func NewParams( | ||||
| 	hardSupply, hardBorrow, delegator, swap, savings, earn MultiRewardPeriods, | ||||
| 	multipliers MultipliersPerDenoms, | ||||
| 	claimEnd time.Time, | ||||
| 	rewardPeriods TypedMultiRewardPeriods, | ||||
| ) Params { | ||||
| 	return Params{ | ||||
| 		USDXMintingRewardPeriods: usdxMinting, | ||||
| @ -55,10 +52,8 @@ func NewParams( | ||||
| 		DelegatorRewardPeriods:   delegator, | ||||
| 		SwapRewardPeriods:        swap, | ||||
| 		SavingsRewardPeriods:     savings, | ||||
| 		EarnRewardPeriods:        earn, | ||||
| 		ClaimMultipliers:         multipliers, | ||||
| 		ClaimEnd:                 claimEnd, | ||||
| 		RewardPeriods:            rewardPeriods, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -74,7 +69,6 @@ func DefaultParams() Params { | ||||
| 		DefaultMultiRewardPeriods, | ||||
| 		DefaultMultipliers, | ||||
| 		DefaultClaimEnd, | ||||
| 		DefaultTypedMultiRewardPeriods, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| @ -95,7 +89,6 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { | ||||
| 		paramtypes.NewParamSetPair(KeyEarnRewardPeriods, &p.EarnRewardPeriods, validateMultiRewardPeriodsParam), | ||||
| 		paramtypes.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersPerDenomParam), | ||||
| 		paramtypes.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam), | ||||
| 		paramtypes.NewParamSetPair(KeyTypedMultiRewardPeriods, &p.RewardPeriods, validatedRewardPeriodsParam), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -133,10 +126,6 @@ func (p Params) Validate() error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if err := validatedRewardPeriodsParam(p.RewardPeriods); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -177,15 +166,6 @@ func validateClaimEndParam(i interface{}) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func validatedRewardPeriodsParam(i interface{}) error { | ||||
| 	periods, ok := i.(TypedMultiRewardPeriods) | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("invalid parameter type: %T", i) | ||||
| 	} | ||||
| 
 | ||||
| 	return periods.Validate() | ||||
| } | ||||
| 
 | ||||
| // NewRewardPeriod returns a new RewardPeriod
 | ||||
| func NewRewardPeriod(active bool, collateralType string, start time.Time, end time.Time, reward sdk.Coin) RewardPeriod { | ||||
| 	return RewardPeriod{ | ||||
| @ -326,45 +306,3 @@ func (mrps MultiRewardPeriods) Validate() error { | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // NewTypedMultiRewardPeriod returns a new TypedMultiRewardPeriod
 | ||||
| func NewTypedMultiRewardPeriod(claimType ClaimType, rewardPeriods MultiRewardPeriods) TypedMultiRewardPeriod { | ||||
| 	return TypedMultiRewardPeriod{ | ||||
| 		ClaimType:     claimType, | ||||
| 		RewardPeriods: rewardPeriods, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Validate performs a basic check of a TypedMultiRewardPeriod fields.
 | ||||
| func (mrp TypedMultiRewardPeriod) Validate() error { | ||||
| 	if err := mrp.ClaimType.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid claim type: %w", err) | ||||
| 	} | ||||
| 	if err := mrp.RewardPeriods.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid reward periods: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // TypedMultiRewardPeriods array of TypedMultiRewardPeriod
 | ||||
| type TypedMultiRewardPeriods []TypedMultiRewardPeriod | ||||
| 
 | ||||
| // Validate checks if all the TypedMultiRewardPeriods are valid and there
 | ||||
| // are no duplicated entries.
 | ||||
| func (mrps TypedMultiRewardPeriods) Validate() error { | ||||
| 	seenClaimTypes := make(map[ClaimType]bool) | ||||
| 	for _, mrp := range mrps { | ||||
| 		if seenClaimTypes[mrp.ClaimType] { | ||||
| 			return fmt.Errorf("duplicated reward period with claim type %s", mrp.ClaimType) | ||||
| 		} | ||||
| 
 | ||||
| 		if err := mrp.Validate(); err != nil { | ||||
| 			return fmt.Errorf("invalid reward period for claimType %s: %w", mrp.ClaimType, err) | ||||
| 		} | ||||
| 
 | ||||
| 		seenClaimTypes[mrp.ClaimType] = true | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -113,47 +113,7 @@ func (m *MultiRewardPeriod) XXX_DiscardUnknown() { | ||||
| 
 | ||||
| var xxx_messageInfo_MultiRewardPeriod proto.InternalMessageInfo | ||||
| 
 | ||||
| // TypedMultiRewardPeriod stores mutiple reward types of a claim type
 | ||||
| type TypedMultiRewardPeriod struct { | ||||
| 	ClaimType     ClaimType          `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"` | ||||
| 	RewardPeriods MultiRewardPeriods `protobuf:"bytes,2,rep,name=reward_periods,json=rewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"reward_periods"` | ||||
| } | ||||
| 
 | ||||
| func (m *TypedMultiRewardPeriod) Reset()         { *m = TypedMultiRewardPeriod{} } | ||||
| func (m *TypedMultiRewardPeriod) String() string { return proto.CompactTextString(m) } | ||||
| func (*TypedMultiRewardPeriod) ProtoMessage()    {} | ||||
| func (*TypedMultiRewardPeriod) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{2} | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { | ||||
| 	if deterministic { | ||||
| 		return xxx_messageInfo_TypedMultiRewardPeriod.Marshal(b, m, deterministic) | ||||
| 	} else { | ||||
| 		b = b[:cap(b)] | ||||
| 		n, err := m.MarshalToSizedBuffer(b) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return b[:n], nil | ||||
| 	} | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) XXX_Merge(src proto.Message) { | ||||
| 	xxx_messageInfo_TypedMultiRewardPeriod.Merge(m, src) | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) XXX_Size() int { | ||||
| 	return m.Size() | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) XXX_DiscardUnknown() { | ||||
| 	xxx_messageInfo_TypedMultiRewardPeriod.DiscardUnknown(m) | ||||
| } | ||||
| 
 | ||||
| var xxx_messageInfo_TypedMultiRewardPeriod proto.InternalMessageInfo | ||||
| 
 | ||||
| // Multiplier amount the claim rewards get increased by, along with how long the
 | ||||
| // claim rewards are locked
 | ||||
| // Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
 | ||||
| type Multiplier struct { | ||||
| 	Name         string                                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` | ||||
| 	MonthsLockup int64                                  `protobuf:"varint,2,opt,name=months_lockup,json=monthsLockup,proto3" json:"months_lockup,omitempty"` | ||||
| @ -164,7 +124,7 @@ func (m *Multiplier) Reset()         { *m = Multiplier{} } | ||||
| func (m *Multiplier) String() string { return proto.CompactTextString(m) } | ||||
| func (*Multiplier) ProtoMessage()    {} | ||||
| func (*Multiplier) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{3} | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{2} | ||||
| } | ||||
| func (m *Multiplier) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -203,7 +163,7 @@ func (m *MultipliersPerDenom) Reset()         { *m = MultipliersPerDenom{} } | ||||
| func (m *MultipliersPerDenom) String() string { return proto.CompactTextString(m) } | ||||
| func (*MultipliersPerDenom) ProtoMessage()    {} | ||||
| func (*MultipliersPerDenom) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{4} | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{3} | ||||
| } | ||||
| func (m *MultipliersPerDenom) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -243,14 +203,13 @@ type Params struct { | ||||
| 	ClaimEnd                 time.Time            `protobuf:"bytes,7,opt,name=claim_end,json=claimEnd,proto3,stdtime" json:"claim_end"` | ||||
| 	SavingsRewardPeriods     MultiRewardPeriods   `protobuf:"bytes,8,rep,name=savings_reward_periods,json=savingsRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"savings_reward_periods"` | ||||
| 	EarnRewardPeriods        MultiRewardPeriods   `protobuf:"bytes,9,rep,name=earn_reward_periods,json=earnRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"earn_reward_periods"` | ||||
| 	RewardPeriods            TypedMultiRewardPeriods `protobuf:"bytes,10,rep,name=reward_periods,json=rewardPeriods,proto3,castrepeated=TypedMultiRewardPeriods" json:"reward_periods"` | ||||
| } | ||||
| 
 | ||||
| func (m *Params) Reset()         { *m = Params{} } | ||||
| func (m *Params) String() string { return proto.CompactTextString(m) } | ||||
| func (*Params) ProtoMessage()    {} | ||||
| func (*Params) Descriptor() ([]byte, []int) { | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{5} | ||||
| 	return fileDescriptor_bb8833f5d745eac9, []int{4} | ||||
| } | ||||
| func (m *Params) XXX_Unmarshal(b []byte) error { | ||||
| 	return m.Unmarshal(b) | ||||
| @ -282,7 +241,6 @@ var xxx_messageInfo_Params proto.InternalMessageInfo | ||||
| func init() { | ||||
| 	proto.RegisterType((*RewardPeriod)(nil), "kava.incentive.v1beta1.RewardPeriod") | ||||
| 	proto.RegisterType((*MultiRewardPeriod)(nil), "kava.incentive.v1beta1.MultiRewardPeriod") | ||||
| 	proto.RegisterType((*TypedMultiRewardPeriod)(nil), "kava.incentive.v1beta1.TypedMultiRewardPeriod") | ||||
| 	proto.RegisterType((*Multiplier)(nil), "kava.incentive.v1beta1.Multiplier") | ||||
| 	proto.RegisterType((*MultipliersPerDenom)(nil), "kava.incentive.v1beta1.MultipliersPerDenom") | ||||
| 	proto.RegisterType((*Params)(nil), "kava.incentive.v1beta1.Params") | ||||
| @ -293,60 +251,56 @@ func init() { | ||||
| } | ||||
| 
 | ||||
| var fileDescriptor_bb8833f5d745eac9 = []byte{ | ||||
| 	// 844 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0xeb, 0x44, | ||||
| 	0x14, 0x8e, 0xf3, 0x47, 0x32, 0xfd, 0xa1, 0x9d, 0x46, 0xa9, 0x09, 0xc8, 0x2e, 0x29, 0x82, 0xa0, | ||||
| 	0xaa, 0x36, 0x2d, 0x12, 0x0b, 0x56, 0xe0, 0x16, 0x24, 0x24, 0x2a, 0x55, 0x6e, 0x91, 0x80, 0x8d, | ||||
| 	0x35, 0xb1, 0xa7, 0xae, 0x55, 0xdb, 0x63, 0xcd, 0x38, 0x69, 0x23, 0x16, 0x48, 0x2c, 0xd8, 0x21, | ||||
| 	0x55, 0x2c, 0x78, 0x88, 0xbe, 0x06, 0x9b, 0x88, 0x55, 0x97, 0x88, 0x45, 0xcb, 0x4d, 0x5f, 0xe4, | ||||
| 	0x6a, 0xc6, 0x4e, 0x93, 0x38, 0x49, 0xef, 0xad, 0x94, 0xbb, 0xb8, 0xab, 0x9c, 0x99, 0x39, 0xe7, | ||||
| 	0x7c, 0xdf, 0xf9, 0xce, 0xcc, 0x89, 0xc1, 0xf6, 0x05, 0xea, 0x22, 0xdd, 0x0b, 0x6d, 0x1c, 0xc6, | ||||
| 	0x5e, 0x17, 0xeb, 0xdd, 0xbd, 0x36, 0x8e, 0xd1, 0x9e, 0x1e, 0x21, 0x8a, 0x02, 0xa6, 0x45, 0x94, | ||||
| 	0xc4, 0x04, 0xd6, 0xb9, 0x93, 0xf6, 0xe8, 0xa4, 0xa5, 0x4e, 0x0d, 0xc5, 0x26, 0x2c, 0x20, 0x4c, | ||||
| 	0x6f, 0x23, 0x36, 0x8a, 0xb4, 0x89, 0x17, 0x26, 0x71, 0x8d, 0x9a, 0x4b, 0x5c, 0x22, 0x4c, 0x9d, | ||||
| 	0x5b, 0xe9, 0xae, 0xea, 0x12, 0xe2, 0xfa, 0x58, 0x17, 0xab, 0x76, 0xe7, 0x4c, 0x8f, 0xbd, 0x00, | ||||
| 	0xb3, 0x18, 0x05, 0x51, 0xea, 0x30, 0x8f, 0x93, 0xed, 0x23, 0x6f, 0xc8, 0xa9, 0xf9, 0x67, 0x1e, | ||||
| 	0x2c, 0x9b, 0xf8, 0x12, 0x51, 0xe7, 0x18, 0x53, 0x8f, 0x38, 0xb0, 0x0e, 0xca, 0xc8, 0xe6, 0xfe, | ||||
| 	0xb2, 0xb4, 0x25, 0xb5, 0x2a, 0x66, 0xba, 0x82, 0x9f, 0x80, 0x77, 0x6d, 0xe2, 0xfb, 0x28, 0xc6, | ||||
| 	0x14, 0xf9, 0x56, 0xdc, 0x8b, 0xb0, 0x9c, 0xdf, 0x92, 0x5a, 0x55, 0x73, 0x75, 0xb4, 0x7d, 0xda, | ||||
| 	0x8b, 0x30, 0xfc, 0x12, 0x94, 0x58, 0x8c, 0x68, 0x2c, 0x17, 0xb6, 0xa4, 0xd6, 0xd2, 0x7e, 0x43, | ||||
| 	0x4b, 0x78, 0x6a, 0x43, 0x9e, 0xda, 0xe9, 0x90, 0xa7, 0x51, 0xe9, 0xdf, 0xa9, 0xb9, 0xeb, 0x7b, | ||||
| 	0x55, 0x32, 0x93, 0x10, 0xf8, 0x05, 0x28, 0xe0, 0xd0, 0x91, 0x8b, 0xcf, 0x88, 0xe4, 0x01, 0xf0, | ||||
| 	0x08, 0x40, 0x2a, 0x8a, 0x60, 0x56, 0x84, 0xa9, 0xc5, 0xb0, 0x4d, 0x42, 0x47, 0x2e, 0x89, 0x34, | ||||
| 	0xef, 0x69, 0x89, 0xbc, 0x1a, 0x97, 0x77, 0xa8, 0xb9, 0x76, 0x40, 0xbc, 0xd0, 0x28, 0xf2, 0x2c, | ||||
| 	0xe6, 0x5a, 0x1a, 0x7a, 0x8c, 0xe9, 0x89, 0x08, 0x6c, 0xfe, 0x9d, 0x07, 0xeb, 0x47, 0x1d, 0x3f, | ||||
| 	0xf6, 0xde, 0x7e, 0x65, 0x7a, 0x73, 0x94, 0x29, 0x3c, 0xad, 0xcc, 0x67, 0x3c, 0xcb, 0xcd, 0xbd, | ||||
| 	0xda, 0x72, 0xbd, 0xf8, 0xbc, 0xd3, 0xd6, 0x6c, 0x12, 0xe8, 0xe9, 0x2d, 0x4d, 0x7e, 0x76, 0x99, | ||||
| 	0x73, 0xa1, 0xf3, 0x5a, 0x99, 0x08, 0x60, 0x33, 0x54, 0xec, 0x4b, 0xa0, 0xce, 0xeb, 0x76, 0xa6, | ||||
| 	0xa5, 0xfc, 0x0a, 0x00, 0x71, 0x0b, 0x13, 0xb5, 0xb8, 0x9c, 0xab, 0xfb, 0x1f, 0x6a, 0xb3, 0x9f, | ||||
| 	0x87, 0x76, 0xc0, 0x3d, 0x79, 0x22, 0xb3, 0x6a, 0x0f, 0x4d, 0xe8, 0x83, 0xd5, 0x04, 0x90, 0x97, | ||||
| 	0xe5, 0x11, 0x87, 0xc9, 0x79, 0x51, 0xd3, 0xa7, 0xf3, 0xb2, 0x4c, 0x91, 0x30, 0x1a, 0x69, 0x8d, | ||||
| 	0x70, 0xea, 0x88, 0x99, 0x2b, 0x74, 0x7c, 0xd9, 0xfc, 0x43, 0x02, 0x40, 0x78, 0x45, 0xbe, 0x87, | ||||
| 	0x29, 0x84, 0xa0, 0x18, 0xa2, 0x20, 0x21, 0x5e, 0x35, 0x85, 0x0d, 0xb7, 0xc1, 0x4a, 0x40, 0xc2, | ||||
| 	0xf8, 0x9c, 0x59, 0x3e, 0xb1, 0x2f, 0x3a, 0x91, 0xb8, 0x03, 0x05, 0x73, 0x39, 0xd9, 0xfc, 0x5e, | ||||
| 	0xec, 0xc1, 0x6f, 0x41, 0xf9, 0x0c, 0xd9, 0x31, 0xa1, 0xe2, 0x0a, 0x2c, 0x1b, 0x1a, 0xa7, 0xf0, | ||||
| 	0xdf, 0x9d, 0xfa, 0xf1, 0x6b, 0xc8, 0x7c, 0x88, 0x6d, 0x33, 0x8d, 0x6e, 0xfe, 0x2e, 0x81, 0x8d, | ||||
| 	0x11, 0x1f, 0xae, 0xf9, 0x21, 0x0e, 0x49, 0x00, 0x6b, 0xa0, 0xe4, 0x70, 0x23, 0x65, 0x96, 0x2c, | ||||
| 	0xe0, 0x4f, 0x60, 0x29, 0x18, 0x39, 0xa7, 0x42, 0x35, 0x9f, 0x14, 0x4a, 0xb8, 0x1a, 0x1b, 0xa9, | ||||
| 	0x42, 0x4b, 0x63, 0x58, 0xe6, 0x78, 0xae, 0xe6, 0x3f, 0x55, 0x50, 0x3e, 0x16, 0x33, 0x0e, 0xfe, | ||||
| 	0x25, 0x81, 0xf7, 0x3b, 0xcc, 0xb9, 0xb2, 0x02, 0x2f, 0x8c, 0xbd, 0xd0, 0xb5, 0x32, 0xfd, 0x91, | ||||
| 	0x04, 0xec, 0x47, 0xf3, 0x60, 0x27, 0x5a, 0xb3, 0xc7, 0x81, 0x07, 0x77, 0xaa, 0xfc, 0xc3, 0xc9, | ||||
| 	0xe1, 0x8f, 0x47, 0x49, 0xbe, 0x89, 0x06, 0xdd, 0xdc, 0xab, 0x2b, 0x93, 0x1d, 0x93, 0x39, 0xf6, | ||||
| 	0x2c, 0x57, 0xf8, 0x9b, 0x04, 0x1a, 0xe7, 0x9c, 0x09, 0xeb, 0x44, 0x91, 0xdf, 0xb3, 0xde, 0xe4, | ||||
| 	0xbd, 0xd9, 0xe4, 0x40, 0x27, 0x02, 0x67, 0x0e, 0x89, 0x36, 0xa1, 0x94, 0x5c, 0x66, 0x49, 0x14, | ||||
| 	0x16, 0x4e, 0xc2, 0x10, 0x38, 0x93, 0x24, 0x7e, 0x05, 0xb2, 0x83, 0x7d, 0xec, 0xa2, 0x98, 0xd0, | ||||
| 	0x2c, 0x83, 0xe2, 0x22, 0x19, 0xd4, 0x1f, 0x61, 0x26, 0x09, 0x74, 0xc0, 0x06, 0xbb, 0x44, 0x51, | ||||
| 	0x16, 0xbb, 0xb4, 0x48, 0xec, 0x75, 0x8e, 0x30, 0x09, 0xdb, 0x05, 0xeb, 0xc9, 0xb8, 0x19, 0x7f, | ||||
| 	0x06, 0x65, 0x01, 0xba, 0xf3, 0xea, 0x67, 0xf0, 0xf8, 0xbc, 0x8c, 0x0f, 0x52, 0xd8, 0xda, 0x8c, | ||||
| 	0x43, 0x66, 0xae, 0x09, 0x8c, 0xb1, 0x23, 0xf8, 0x35, 0x48, 0x26, 0x96, 0xc5, 0x47, 0xf7, 0x3b, | ||||
| 	0xcf, 0x18, 0xdd, 0x15, 0x11, 0xf6, 0x4d, 0xe8, 0xc0, 0x5f, 0x40, 0x9d, 0xa1, 0xae, 0x17, 0xba, | ||||
| 	0x2c, 0x2b, 0x5a, 0x65, 0x91, 0xa2, 0xd5, 0x52, 0x90, 0xa9, 0x76, 0x61, 0x44, 0xc3, 0x2c, 0x72, | ||||
| 	0x75, 0xa1, 0xed, 0xe2, 0x08, 0xd9, 0x76, 0x65, 0x67, 0x3b, 0x10, 0x88, 0xda, 0x3c, 0xc4, 0xd9, | ||||
| 	0xff, 0x32, 0x86, 0x9a, 0xc2, 0x6e, 0xce, 0x3e, 0xcf, 0x4e, 0x79, 0xe3, 0xbb, 0xfe, 0x0b, 0x25, | ||||
| 	0xd7, 0x1f, 0x28, 0xd2, 0xed, 0x40, 0x91, 0xfe, 0x1f, 0x28, 0xd2, 0xf5, 0x83, 0x92, 0xbb, 0x7d, | ||||
| 	0x50, 0x72, 0xff, 0x3e, 0x28, 0xb9, 0x9f, 0x77, 0xc6, 0x66, 0x34, 0xe7, 0xb1, 0xeb, 0xa3, 0x36, | ||||
| 	0x13, 0x96, 0x7e, 0x35, 0xf6, 0x95, 0x25, 0x86, 0x75, 0xbb, 0x2c, 0xda, 0xfb, 0xf9, 0xcb, 0x00, | ||||
| 	0x00, 0x00, 0xff, 0xff, 0x4c, 0xba, 0x2a, 0x08, 0x18, 0x0a, 0x00, 0x00, | ||||
| 	// 774 bytes of a gzipped FileDescriptorProto
 | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x96, 0xcf, 0x6e, 0xd3, 0x4a, | ||||
| 	0x14, 0xc6, 0xe3, 0xfc, 0xbb, 0xc9, 0xb4, 0xbd, 0xb7, 0x9d, 0x46, 0xb9, 0xbe, 0xb9, 0xc8, 0xa9, | ||||
| 	0x52, 0x04, 0x41, 0x55, 0x6d, 0x0a, 0x12, 0x0b, 0x76, 0x98, 0x82, 0x84, 0x44, 0xa5, 0xca, 0x2d, | ||||
| 	0x12, 0xb0, 0x89, 0x26, 0xf6, 0xd4, 0xb5, 0x6a, 0x7b, 0xac, 0x99, 0x49, 0xda, 0x88, 0x05, 0x12, | ||||
| 	0x0b, 0x76, 0x48, 0x15, 0x0b, 0x1e, 0xa2, 0xaf, 0xc1, 0xa6, 0xcb, 0x8a, 0x15, 0x62, 0xd1, 0x42, | ||||
| 	0xfa, 0x22, 0x68, 0xc6, 0x6e, 0xe3, 0xa4, 0x69, 0xa1, 0x52, 0x36, 0xac, 0x32, 0x3e, 0x73, 0xce, | ||||
| 	0xf9, 0x7d, 0xfe, 0xc6, 0x67, 0x14, 0xb0, 0xb8, 0x83, 0xba, 0xc8, 0xf0, 0x42, 0x1b, 0x87, 0xdc, | ||||
| 	0xeb, 0x62, 0xa3, 0xbb, 0xd2, 0xc6, 0x1c, 0xad, 0x18, 0x11, 0xa2, 0x28, 0x60, 0x7a, 0x44, 0x09, | ||||
| 	0x27, 0xb0, 0x2a, 0x92, 0xf4, 0xf3, 0x24, 0x3d, 0x49, 0xaa, 0x69, 0x36, 0x61, 0x01, 0x61, 0x46, | ||||
| 	0x1b, 0xb1, 0x41, 0xa5, 0x4d, 0xbc, 0x30, 0xae, 0xab, 0x55, 0x5c, 0xe2, 0x12, 0xb9, 0x34, 0xc4, | ||||
| 	0x2a, 0x89, 0xd6, 0x5d, 0x42, 0x5c, 0x1f, 0x1b, 0xf2, 0xa9, 0xdd, 0xd9, 0x32, 0xb8, 0x17, 0x60, | ||||
| 	0xc6, 0x51, 0x10, 0xc5, 0x09, 0x8d, 0x8f, 0x59, 0x30, 0x6d, 0xe1, 0x5d, 0x44, 0x9d, 0x75, 0x4c, | ||||
| 	0x3d, 0xe2, 0xc0, 0x2a, 0x28, 0x22, 0x5b, 0x90, 0x55, 0x65, 0x41, 0x69, 0x96, 0xac, 0xe4, 0x09, | ||||
| 	0xde, 0x06, 0xff, 0xd8, 0xc4, 0xf7, 0x11, 0xc7, 0x14, 0xf9, 0x2d, 0xde, 0x8b, 0xb0, 0x9a, 0x5d, | ||||
| 	0x50, 0x9a, 0x65, 0xeb, 0xef, 0x41, 0x78, 0xb3, 0x17, 0x61, 0xf8, 0x10, 0x14, 0x18, 0x47, 0x94, | ||||
| 	0xab, 0xb9, 0x05, 0xa5, 0x39, 0x75, 0xaf, 0xa6, 0xc7, 0x12, 0xf4, 0x33, 0x09, 0xfa, 0xe6, 0x99, | ||||
| 	0x04, 0xb3, 0x74, 0x78, 0x5c, 0xcf, 0xec, 0x9f, 0xd4, 0x15, 0x2b, 0x2e, 0x81, 0x0f, 0x40, 0x0e, | ||||
| 	0x87, 0x8e, 0x9a, 0xbf, 0x46, 0xa5, 0x28, 0x80, 0x6b, 0x00, 0x52, 0xf9, 0x12, 0xac, 0x15, 0x61, | ||||
| 	0xda, 0x62, 0xd8, 0x26, 0xa1, 0xa3, 0x16, 0x64, 0x9b, 0xff, 0xf4, 0xd8, 0x39, 0x5d, 0x38, 0x77, | ||||
| 	0x66, 0xa7, 0xfe, 0x98, 0x78, 0xa1, 0x99, 0x17, 0x5d, 0xac, 0xd9, 0xa4, 0x74, 0x1d, 0xd3, 0x0d, | ||||
| 	0x59, 0xd8, 0xf8, 0x9c, 0x05, 0x73, 0x6b, 0x1d, 0x9f, 0x7b, 0x7f, 0xbe, 0x33, 0xbd, 0x4b, 0x9c, | ||||
| 	0xc9, 0x5d, 0xed, 0xcc, 0x5d, 0xd1, 0xe5, 0xe0, 0xa4, 0xde, 0x74, 0x3d, 0xbe, 0xdd, 0x69, 0xeb, | ||||
| 	0x36, 0x09, 0x8c, 0xe4, 0x03, 0x8c, 0x7f, 0x96, 0x99, 0xb3, 0x63, 0x88, 0x77, 0x65, 0xb2, 0x80, | ||||
| 	0x8d, 0x71, 0xf1, 0x83, 0x02, 0x80, 0x74, 0x31, 0xf2, 0x3d, 0x4c, 0x21, 0x04, 0xf9, 0x10, 0x05, | ||||
| 	0xb1, 0x79, 0x65, 0x4b, 0xae, 0xe1, 0x22, 0x98, 0x09, 0x48, 0xc8, 0xb7, 0x59, 0xcb, 0x27, 0xf6, | ||||
| 	0x4e, 0x27, 0x92, 0xc6, 0xe5, 0xac, 0xe9, 0x38, 0xf8, 0x5c, 0xc6, 0xe0, 0x53, 0x50, 0xdc, 0x42, | ||||
| 	0x36, 0x27, 0x54, 0xfa, 0x36, 0x6d, 0xea, 0x42, 0xdb, 0xb7, 0xe3, 0xfa, 0xad, 0xdf, 0xd0, 0xb6, | ||||
| 	0x8a, 0x6d, 0x2b, 0xa9, 0x6e, 0xbc, 0x57, 0xc0, 0xfc, 0x40, 0x8f, 0x10, 0xba, 0x8a, 0x43, 0x12, | ||||
| 	0xc0, 0x0a, 0x28, 0x38, 0x62, 0x91, 0x28, 0x8b, 0x1f, 0xe0, 0x2b, 0x30, 0x15, 0x0c, 0x92, 0xd5, | ||||
| 	0xac, 0x74, 0xac, 0xa1, 0x8f, 0x9f, 0x4e, 0x7d, 0xd0, 0xd7, 0x9c, 0x4f, 0xac, 0x9b, 0x4a, 0xb1, | ||||
| 	0xac, 0x74, 0xaf, 0xc6, 0x97, 0x12, 0x28, 0xae, 0xcb, 0x99, 0x87, 0x9f, 0x14, 0xf0, 0x7f, 0x87, | ||||
| 	0x39, 0x7b, 0xad, 0xc0, 0x0b, 0xb9, 0x17, 0xba, 0xad, 0xd8, 0x45, 0x71, 0x56, 0x1e, 0x71, 0x98, | ||||
| 	0xaa, 0x48, 0xec, 0xcd, 0xcb, 0xb0, 0xe9, 0xef, 0xd3, 0x5c, 0x11, 0xe0, 0xfe, 0x71, 0x5d, 0x7d, | ||||
| 	0xb1, 0xb1, 0xfa, 0x72, 0x2d, 0xee, 0x97, 0x4e, 0x60, 0x07, 0x27, 0xf5, 0x99, 0xa1, 0x80, 0xa5, | ||||
| 	0x0a, 0xf6, 0xb8, 0x54, 0xf8, 0x4e, 0x01, 0xb5, 0x6d, 0xa1, 0x84, 0x75, 0xa2, 0xc8, 0xef, 0x8d, | ||||
| 	0xea, 0x8a, 0xed, 0xb8, 0x73, 0xa5, 0x1d, 0x43, 0xe2, 0x6a, 0x89, 0x2b, 0xf0, 0xc2, 0x16, 0xb3, | ||||
| 	0xfe, 0x15, 0xa0, 0x0d, 0xc9, 0xb9, 0x44, 0x44, 0x9b, 0x50, 0x4a, 0x76, 0x47, 0x45, 0xe4, 0x26, | ||||
| 	0x2e, 0xc2, 0x94, 0x9c, 0x61, 0x11, 0x6f, 0x81, 0xea, 0x60, 0x1f, 0xbb, 0x88, 0x13, 0x3a, 0xaa, | ||||
| 	0x20, 0x3f, 0x49, 0x05, 0xd5, 0x73, 0xcc, 0xb0, 0x80, 0x0e, 0x98, 0x67, 0xbb, 0x28, 0x1a, 0x65, | ||||
| 	0x17, 0x26, 0xc9, 0x9e, 0x13, 0x84, 0x61, 0x6c, 0x17, 0xcc, 0xd9, 0x3e, 0xf2, 0x82, 0x56, 0x7a, | ||||
| 	0x0c, 0x8a, 0x12, 0xba, 0xf4, 0xeb, 0x31, 0x38, 0x1f, 0x2f, 0xf3, 0x46, 0x82, 0xad, 0x8c, 0xd9, | ||||
| 	0x64, 0xd6, 0xac, 0x64, 0xa4, 0xb6, 0xe0, 0x23, 0x50, 0x8e, 0xb9, 0xe2, 0xbe, 0xfb, 0xeb, 0x1a, | ||||
| 	0xf7, 0x5d, 0x49, 0x96, 0x3d, 0x09, 0x1d, 0xf8, 0x06, 0x54, 0x19, 0xea, 0x7a, 0xa1, 0xcb, 0x46, | ||||
| 	0x4d, 0x2b, 0x4d, 0xd2, 0xb4, 0x4a, 0x02, 0xb9, 0x70, 0x5c, 0x18, 0xd1, 0x70, 0x94, 0x5c, 0x9e, | ||||
| 	0xe8, 0x71, 0x09, 0xc2, 0x50, 0xc8, 0x7c, 0x76, 0xf8, 0x43, 0xcb, 0x1c, 0xf6, 0x35, 0xe5, 0xa8, | ||||
| 	0xaf, 0x29, 0xdf, 0xfb, 0x9a, 0xb2, 0x7f, 0xaa, 0x65, 0x8e, 0x4e, 0xb5, 0xcc, 0xd7, 0x53, 0x2d, | ||||
| 	0xf3, 0x7a, 0x29, 0x75, 0x57, 0x0a, 0x05, 0xcb, 0x3e, 0x6a, 0x33, 0xb9, 0x32, 0xf6, 0x52, 0xff, | ||||
| 	0x48, 0xe4, 0xa5, 0xd9, 0x2e, 0x4a, 0x9b, 0xef, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xca, 0x77, | ||||
| 	0xf8, 0x09, 0xb0, 0x08, 0x00, 0x00, | ||||
| } | ||||
| 
 | ||||
| func (m *RewardPeriod) Marshal() (dAtA []byte, err error) { | ||||
| @ -485,48 +439,6 @@ func (m *MultiRewardPeriod) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *TypedMultiRewardPeriod) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
| 
 | ||||
| func (m *TypedMultiRewardPeriod) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	size := m.Size() | ||||
| 	return m.MarshalToSizedBuffer(dAtA[:size]) | ||||
| } | ||||
| 
 | ||||
| func (m *TypedMultiRewardPeriod) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	i := len(dAtA) | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if len(m.RewardPeriods) > 0 { | ||||
| 		for iNdEx := len(m.RewardPeriods) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.RewardPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintParams(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x12 | ||||
| 		} | ||||
| 	} | ||||
| 	if m.ClaimType != 0 { | ||||
| 		i = encodeVarintParams(dAtA, i, uint64(m.ClaimType)) | ||||
| 		i-- | ||||
| 		dAtA[i] = 0x8 | ||||
| 	} | ||||
| 	return len(dAtA) - i, nil | ||||
| } | ||||
| 
 | ||||
| func (m *Multiplier) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| @ -636,20 +548,6 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if len(m.RewardPeriods) > 0 { | ||||
| 		for iNdEx := len(m.RewardPeriods) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| 				size, err := m.RewardPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				i -= size | ||||
| 				i = encodeVarintParams(dAtA, i, uint64(size)) | ||||
| 			} | ||||
| 			i-- | ||||
| 			dAtA[i] = 0x52 | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.EarnRewardPeriods) > 0 { | ||||
| 		for iNdEx := len(m.EarnRewardPeriods) - 1; iNdEx >= 0; iNdEx-- { | ||||
| 			{ | ||||
| @ -832,24 +730,6 @@ func (m *MultiRewardPeriod) Size() (n int) { | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *TypedMultiRewardPeriod) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.ClaimType != 0 { | ||||
| 		n += 1 + sovParams(uint64(m.ClaimType)) | ||||
| 	} | ||||
| 	if len(m.RewardPeriods) > 0 { | ||||
| 		for _, e := range m.RewardPeriods { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovParams(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (m *Multiplier) Size() (n int) { | ||||
| 	if m == nil { | ||||
| 		return 0 | ||||
| @ -943,12 +823,6 @@ func (m *Params) Size() (n int) { | ||||
| 			n += 1 + l + sovParams(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(m.RewardPeriods) > 0 { | ||||
| 		for _, e := range m.RewardPeriods { | ||||
| 			l = e.Size() | ||||
| 			n += 1 + l + sovParams(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| @ -1361,109 +1235,6 @@ func (m *MultiRewardPeriod) Unmarshal(dAtA []byte) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *TypedMultiRewardPeriod) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowParams | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= uint64(b&0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: TypedMultiRewardPeriod: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: TypedMultiRewardPeriod: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 0 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType) | ||||
| 			} | ||||
| 			m.ClaimType = 0 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowParams | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				m.ClaimType |= ClaimType(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field RewardPeriods", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowParams | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthParams | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthParams | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.RewardPeriods = append(m.RewardPeriods, MultiRewardPeriod{}) | ||||
| 			if err := m.RewardPeriods[len(m.RewardPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipParams(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if (skippy < 0) || (iNdEx+skippy) < 0 { | ||||
| 				return ErrInvalidLengthParams | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *Multiplier) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| @ -2048,40 +1819,6 @@ func (m *Params) Unmarshal(dAtA []byte) error { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 10: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field RewardPeriods", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowParams | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= int(b&0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthParams | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex < 0 { | ||||
| 				return ErrInvalidLengthParams | ||||
| 			} | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.RewardPeriods = append(m.RewardPeriods, TypedMultiRewardPeriod{}) | ||||
| 			if err := m.RewardPeriods[len(m.RewardPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipParams(dAtA[iNdEx:]) | ||||
|  | ||||
| @ -1,11 +0,0 @@ | ||||
| package types | ||||
| 
 | ||||
| import sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| type RewardAccumulator interface { | ||||
| 	AccumulateRewards( | ||||
| 		ctx sdk.Context, | ||||
| 		claimType ClaimType, | ||||
| 		rewardPeriod MultiRewardPeriod, | ||||
| 	) error | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ruaridh
						Ruaridh