diff --git a/app/app.go b/app/app.go
index 310b7bbc..3843469b 100644
--- a/app/app.go
+++ b/app/app.go
@@ -597,6 +597,17 @@ func NewApp(
app.bankKeeper,
&app.stakingKeeper,
)
+ earnKeeper := earnkeeper.NewKeeper(
+ appCodec,
+ keys[earntypes.StoreKey],
+ earnSubspace,
+ app.accountKeeper,
+ app.bankKeeper,
+ &app.liquidKeeper,
+ &hardKeeper,
+ &savingsKeeper,
+ )
+
app.incentiveKeeper = incentivekeeper.NewKeeper(
appCodec,
keys[incentivetypes.StoreKey],
@@ -608,16 +619,7 @@ func NewApp(
app.stakingKeeper,
&swapKeeper,
&savingsKeeper,
- )
- app.earnKeeper = earnkeeper.NewKeeper(
- appCodec,
- keys[earntypes.StoreKey],
- earnSubspace,
- app.accountKeeper,
- app.bankKeeper,
- app.liquidKeeper,
- &hardKeeper,
- &savingsKeeper,
+ &earnKeeper,
)
// create committee keeper with router
@@ -667,6 +669,7 @@ func NewApp(
app.cdpKeeper = *cdpKeeper.SetHooks(cdptypes.NewMultiCDPHooks(app.incentiveKeeper.Hooks()))
app.hardKeeper = *hardKeeper.SetHooks(hardtypes.NewMultiHARDHooks(app.incentiveKeeper.Hooks()))
app.savingsKeeper = *savingsKeeper.SetHooks(savingstypes.NewMultiSavingsHooks(app.incentiveKeeper.Hooks()))
+ app.earnKeeper = *earnKeeper.SetHooks(app.incentiveKeeper.Hooks())
// create the module manager (Note: Any module instantiated in the module manager that is later modified
// must be passed by reference here.)
diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md
index 5ccc403c..3e8d03ad 100644
--- a/docs/core/proto-docs.md
+++ b/docs/core/proto-docs.md
@@ -302,6 +302,7 @@
- [BaseClaim](#kava.incentive.v1beta1.BaseClaim)
- [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim)
- [DelegatorClaim](#kava.incentive.v1beta1.DelegatorClaim)
+ - [EarnClaim](#kava.incentive.v1beta1.EarnClaim)
- [HardLiquidityProviderClaim](#kava.incentive.v1beta1.HardLiquidityProviderClaim)
- [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex)
- [MultiRewardIndexesProto](#kava.incentive.v1beta1.MultiRewardIndexesProto)
@@ -326,6 +327,8 @@
- [kava/incentive/v1beta1/tx.proto](#kava/incentive/v1beta1/tx.proto)
- [MsgClaimDelegatorReward](#kava.incentive.v1beta1.MsgClaimDelegatorReward)
- [MsgClaimDelegatorRewardResponse](#kava.incentive.v1beta1.MsgClaimDelegatorRewardResponse)
+ - [MsgClaimEarnReward](#kava.incentive.v1beta1.MsgClaimEarnReward)
+ - [MsgClaimEarnRewardResponse](#kava.incentive.v1beta1.MsgClaimEarnRewardResponse)
- [MsgClaimHardReward](#kava.incentive.v1beta1.MsgClaimHardReward)
- [MsgClaimHardRewardResponse](#kava.incentive.v1beta1.MsgClaimHardRewardResponse)
- [MsgClaimSavingsReward](#kava.incentive.v1beta1.MsgClaimSavingsReward)
@@ -4353,6 +4356,22 @@ DelegatorClaim stores delegation rewards that can be claimed by owner
+
+
+### EarnClaim
+EarnClaim stores the earn rewards that can be claimed by owner
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `base_claim` | [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim) | | |
+| `reward_indexes` | [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex) | repeated | |
+
+
+
+
+
+
### HardLiquidityProviderClaim
@@ -4564,6 +4583,7 @@ Params
| `claim_multipliers` | [MultipliersPerDenom](#kava.incentive.v1beta1.MultipliersPerDenom) | repeated | |
| `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 | |
@@ -4657,6 +4677,8 @@ GenesisState is the state that must be provided at genesis.
| `swap_claims` | [SwapClaim](#kava.incentive.v1beta1.SwapClaim) | repeated | |
| `savings_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | | |
| `savings_claims` | [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim) | repeated | |
+| `earn_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | | |
+| `earn_claims` | [EarnClaim](#kava.incentive.v1beta1.EarnClaim) | repeated | |
@@ -4705,6 +4727,32 @@ MsgClaimDelegatorRewardResponse defines the Msg/ClaimDelegatorReward response ty
+
+
+### MsgClaimEarnReward
+MsgClaimEarnReward message type used to claim earn rewards
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `sender` | [string](#string) | | |
+| `denoms_to_claim` | [Selection](#kava.incentive.v1beta1.Selection) | repeated | |
+
+
+
+
+
+
+
+
+### MsgClaimEarnRewardResponse
+MsgClaimEarnRewardResponse defines the Msg/ClaimEarnReward response type.
+
+
+
+
+
+
### MsgClaimHardReward
@@ -4842,8 +4890,9 @@ Msg defines the incentive Msg service.
| `ClaimUSDXMintingReward` | [MsgClaimUSDXMintingReward](#kava.incentive.v1beta1.MsgClaimUSDXMintingReward) | [MsgClaimUSDXMintingRewardResponse](#kava.incentive.v1beta1.MsgClaimUSDXMintingRewardResponse) | ClaimUSDXMintingReward is a message type used to claim USDX minting rewards | |
| `ClaimHardReward` | [MsgClaimHardReward](#kava.incentive.v1beta1.MsgClaimHardReward) | [MsgClaimHardRewardResponse](#kava.incentive.v1beta1.MsgClaimHardRewardResponse) | ClaimHardReward is a message type used to claim Hard liquidity provider rewards | |
| `ClaimDelegatorReward` | [MsgClaimDelegatorReward](#kava.incentive.v1beta1.MsgClaimDelegatorReward) | [MsgClaimDelegatorRewardResponse](#kava.incentive.v1beta1.MsgClaimDelegatorRewardResponse) | ClaimDelegatorReward is a message type used to claim delegator rewards | |
-| `ClaimSwapReward` | [MsgClaimSwapReward](#kava.incentive.v1beta1.MsgClaimSwapReward) | [MsgClaimSwapRewardResponse](#kava.incentive.v1beta1.MsgClaimSwapRewardResponse) | ClaimSwapReward is a message type used to claim delegator rewards | |
+| `ClaimSwapReward` | [MsgClaimSwapReward](#kava.incentive.v1beta1.MsgClaimSwapReward) | [MsgClaimSwapRewardResponse](#kava.incentive.v1beta1.MsgClaimSwapRewardResponse) | ClaimSwapReward is a message type used to claim swap rewards | |
| `ClaimSavingsReward` | [MsgClaimSavingsReward](#kava.incentive.v1beta1.MsgClaimSavingsReward) | [MsgClaimSavingsRewardResponse](#kava.incentive.v1beta1.MsgClaimSavingsRewardResponse) | ClaimSavingsReward is a message type used to claim savings rewards | |
+| `ClaimEarnReward` | [MsgClaimEarnReward](#kava.incentive.v1beta1.MsgClaimEarnReward) | [MsgClaimEarnRewardResponse](#kava.incentive.v1beta1.MsgClaimEarnRewardResponse) | ClaimEarnReward is a message type used to claim earn rewards | |
diff --git a/proto/kava/incentive/v1beta1/claims.proto b/proto/kava/incentive/v1beta1/claims.proto
index 31c956c8..df28d2cc 100644
--- a/proto/kava/incentive/v1beta1/claims.proto
+++ b/proto/kava/incentive/v1beta1/claims.proto
@@ -115,3 +115,13 @@ message SavingsClaim {
repeated MultiRewardIndex reward_indexes = 2
[(gogoproto.castrepeated) = "MultiRewardIndexes", (gogoproto.nullable) = false];
}
+
+// 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];
+
+ repeated MultiRewardIndex reward_indexes = 2
+ [(gogoproto.castrepeated) = "MultiRewardIndexes", (gogoproto.nullable) = false];
+}
diff --git a/proto/kava/incentive/v1beta1/genesis.proto b/proto/kava/incentive/v1beta1/genesis.proto
index d2119f64..451bc226 100644
--- a/proto/kava/incentive/v1beta1/genesis.proto
+++ b/proto/kava/incentive/v1beta1/genesis.proto
@@ -60,4 +60,8 @@ message GenesisState {
GenesisRewardState savings_reward_state = 11 [(gogoproto.nullable) = false];
repeated SavingsClaim savings_claims = 12 [(gogoproto.castrepeated) = "SavingsClaims", (gogoproto.nullable) = false];
+
+ GenesisRewardState earn_reward_state = 13 [(gogoproto.nullable) = false];
+
+ repeated EarnClaim earn_claims = 14 [(gogoproto.castrepeated) = "EarnClaims", (gogoproto.nullable) = false];
}
diff --git a/proto/kava/incentive/v1beta1/params.proto b/proto/kava/incentive/v1beta1/params.proto
index 5a010fcb..e35d0bc5 100644
--- a/proto/kava/incentive/v1beta1/params.proto
+++ b/proto/kava/incentive/v1beta1/params.proto
@@ -79,4 +79,7 @@ message Params {
repeated MultiRewardPeriod savings_reward_periods = 8
[(gogoproto.castrepeated) = "MultiRewardPeriods", (gogoproto.nullable) = false];
+
+ repeated MultiRewardPeriod earn_reward_periods = 9
+ [(gogoproto.castrepeated) = "MultiRewardPeriods", (gogoproto.nullable) = false];
}
diff --git a/proto/kava/incentive/v1beta1/tx.proto b/proto/kava/incentive/v1beta1/tx.proto
index 0eef7bad..5d83e898 100644
--- a/proto/kava/incentive/v1beta1/tx.proto
+++ b/proto/kava/incentive/v1beta1/tx.proto
@@ -16,11 +16,14 @@ service Msg {
// ClaimDelegatorReward is a message type used to claim delegator rewards
rpc ClaimDelegatorReward(MsgClaimDelegatorReward) returns (MsgClaimDelegatorRewardResponse);
- // ClaimSwapReward is a message type used to claim delegator rewards
+ // ClaimSwapReward is a message type used to claim swap rewards
rpc ClaimSwapReward(MsgClaimSwapReward) returns (MsgClaimSwapRewardResponse);
// ClaimSavingsReward is a message type used to claim savings rewards
rpc ClaimSavingsReward(MsgClaimSavingsReward) returns (MsgClaimSavingsRewardResponse);
+
+ // ClaimEarnReward is a message type used to claim earn rewards
+ rpc ClaimEarnReward(MsgClaimEarnReward) returns (MsgClaimEarnRewardResponse);
}
// Selection is a pair of denom and multiplier name. It holds the choice of multiplier a user makes when they claim a
@@ -92,3 +95,15 @@ message MsgClaimSavingsReward {
// MsgClaimSavingsRewardResponse defines the Msg/ClaimSavingsReward response type.
message MsgClaimSavingsRewardResponse {}
+
+// MsgClaimEarnReward message type used to claim earn rewards
+message MsgClaimEarnReward {
+ option (gogoproto.equal) = false;
+ option (gogoproto.goproto_getters) = false;
+
+ string sender = 1;
+ repeated Selection denoms_to_claim = 2 [(gogoproto.castrepeated) = "Selections", (gogoproto.nullable) = false];
+}
+
+// MsgClaimEarnRewardResponse defines the Msg/ClaimEarnReward response type.
+message MsgClaimEarnRewardResponse {}
diff --git a/x/earn/types/expected_keepers.go b/x/earn/types/expected_keepers.go
index 8193cb51..df654e60 100644
--- a/x/earn/types/expected_keepers.go
+++ b/x/earn/types/expected_keepers.go
@@ -48,6 +48,6 @@ type SavingsKeeper interface {
// EarnHooks are event hooks called when a user's deposit to a earn vault changes.
type EarnHooks interface {
- AfterVaultDepositCreated(ctx sdk.Context, vaultDenom string, depositor sdk.AccAddress, sharedOwned sdk.Dec)
- BeforeVaultDepositModified(ctx sdk.Context, vaultDenom string, depositor sdk.AccAddress, sharedOwned sdk.Dec)
+ AfterVaultDepositCreated(ctx sdk.Context, vaultDenom string, depositor sdk.AccAddress, sharesOwned sdk.Dec)
+ BeforeVaultDepositModified(ctx sdk.Context, vaultDenom string, depositor sdk.AccAddress, sharesOwned sdk.Dec)
}
diff --git a/x/earn/types/mocks/EarnHooks.go b/x/earn/types/mocks/EarnHooks.go
index 35df4a26..97df2f16 100644
--- a/x/earn/types/mocks/EarnHooks.go
+++ b/x/earn/types/mocks/EarnHooks.go
@@ -12,14 +12,14 @@ type EarnHooks struct {
mock.Mock
}
-// AfterVaultDepositCreated provides a mock function with given fields: ctx, vaultDenom, depositor, sharedOwned
-func (_m *EarnHooks) AfterVaultDepositCreated(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharedOwned types.Dec) {
- _m.Called(ctx, vaultDenom, depositor, sharedOwned)
+// AfterVaultDepositCreated provides a mock function with given fields: ctx, vaultDenom, depositor, sharesOwned
+func (_m *EarnHooks) AfterVaultDepositCreated(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharesOwned types.Dec) {
+ _m.Called(ctx, vaultDenom, depositor, sharesOwned)
}
-// BeforeVaultDepositModified provides a mock function with given fields: ctx, vaultDenom, depositor, sharedOwned
-func (_m *EarnHooks) BeforeVaultDepositModified(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharedOwned types.Dec) {
- _m.Called(ctx, vaultDenom, depositor, sharedOwned)
+// BeforeVaultDepositModified provides a mock function with given fields: ctx, vaultDenom, depositor, sharesOwned
+func (_m *EarnHooks) BeforeVaultDepositModified(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharesOwned types.Dec) {
+ _m.Called(ctx, vaultDenom, depositor, sharesOwned)
}
type mockConstructorTestingTNewEarnHooks interface {
diff --git a/x/incentive/abci.go b/x/incentive/abci.go
index 92306e6b..7e8b6407 100644
--- a/x/incentive/abci.go
+++ b/x/incentive/abci.go
@@ -28,4 +28,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
for _, rp := range params.SavingsRewardPeriods {
k.AccumulateSavingsRewards(ctx, rp)
}
+ for _, rp := range params.EarnRewardPeriods {
+ k.AccumulateEarnRewards(ctx, rp)
+ }
}
diff --git a/x/incentive/client/cli/query.go b/x/incentive/client/cli/query.go
index 367ec686..248d27b5 100644
--- a/x/incentive/client/cli/query.go
+++ b/x/incentive/client/cli/query.go
@@ -25,9 +25,10 @@ const (
typeUSDXMinting = "usdx-minting"
typeSwap = "swap"
typeSavings = "savings"
+ typeEarn = "earn"
)
-var rewardTypes = []string{typeDelegator, typeHard, typeUSDXMinting, typeSwap}
+var rewardTypes = []string{typeDelegator, typeHard, typeUSDXMinting, typeSwap, typeEarn}
// GetQueryCmd returns the cli query commands for the incentive module
func GetQueryCmd() *cobra.Command {
@@ -59,20 +60,17 @@ func queryRewardsCmd() *cobra.Command {
fmt.Sprintf(`Query rewards with optional flags for owner and type
Example:
- $ %s query %s rewards
- $ %s query %s rewards --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
- $ %s query %s rewards --type hard
- $ %s query %s rewards --type usdx-minting
- $ %s query %s rewards --type delegator
- $ %s query %s rewards --type swap
- $ %s query %s rewards --type savings
- $ %s query %s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
- $ %s query %s rewards --type hard --unsynced
+ $ %[1]s query %[2]s rewards
+ $ %[1]s query %[2]s rewards --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
+ $ %[1]s query %[2]s rewards --type hard
+ $ %[1]s query %[2]s rewards --type usdx-minting
+ $ %[1]s query %[2]s rewards --type delegator
+ $ %[1]s query %[2]s rewards --type swap
+ $ %[1]s query %[2]s rewards --type savings
+ $ %[1]s query %[2]s rewards --type earn
+ $ %[1]s query %[2]s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
+ $ %[1]s query %[2]s rewards --type hard --unsynced
`,
- version.AppName, types.ModuleName, version.AppName, types.ModuleName,
- version.AppName, types.ModuleName, version.AppName, types.ModuleName,
- version.AppName, types.ModuleName, version.AppName, types.ModuleName,
- version.AppName, types.ModuleName, version.AppName, types.ModuleName,
version.AppName, types.ModuleName)),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
@@ -131,6 +129,13 @@ func queryRewardsCmd() *cobra.Command {
return err
}
return cliCtx.PrintObjectLegacy(claims)
+ case typeEarn:
+ params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
+ claims, err := executeEarnRewardsQuery(cliCtx, params)
+ if err != nil {
+ return err
+ }
+ return cliCtx.PrintObjectLegacy(claims)
default:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
@@ -362,3 +367,25 @@ func executeSavingsRewardsQuery(cliCtx client.Context, params types.QueryRewards
return claims, nil
}
+
+func executeEarnRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.EarnClaims, error) {
+ bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
+ if err != nil {
+ return types.EarnClaims{}, err
+ }
+
+ route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetEarnRewards)
+ res, height, err := cliCtx.QueryWithData(route, bz)
+ if err != nil {
+ return types.EarnClaims{}, err
+ }
+
+ cliCtx = cliCtx.WithHeight(height)
+
+ var claims types.EarnClaims
+ if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
+ return types.EarnClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
+ }
+
+ return claims, nil
+}
diff --git a/x/incentive/client/rest/query.go b/x/incentive/client/rest/query.go
index fa086bbb..437b79ec 100644
--- a/x/incentive/client/rest/query.go
+++ b/x/incentive/client/rest/query.go
@@ -68,6 +68,8 @@ func queryRewardsHandlerFn(cliCtx client.Context) http.HandlerFunc {
executeDelegatorRewardsQuery(w, cliCtx, params)
case "swap":
executeSwapRewardsQuery(w, cliCtx, params)
+ case "earn":
+ executeEarnRewardsQuery(w, cliCtx, params)
default:
executeAllRewardQueries(w, cliCtx, params)
}
@@ -182,6 +184,23 @@ func executeSwapRewardsQuery(w http.ResponseWriter, cliCtx client.Context, param
rest.PostProcessResponse(w, cliCtx, res)
}
+func executeEarnRewardsQuery(w http.ResponseWriter, cliCtx client.Context, params types.QueryRewardsParams) {
+ bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
+ if err != nil {
+ rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
+ return
+ }
+
+ res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetEarnRewards), bz)
+ if err != nil {
+ rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
+ return
+ }
+
+ cliCtx = cliCtx.WithHeight(height)
+ rest.PostProcessResponse(w, cliCtx, res)
+}
+
func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, params types.QueryRewardsParams) {
paramsBz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
@@ -212,7 +231,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
var delegatorClaims types.DelegatorClaims
cliCtx.LegacyAmino.MustUnmarshalJSON(delegatorRes, &delegatorClaims)
- swapRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetSwapRewards), paramsBz)
+ swapRes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetSwapRewards), paramsBz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
@@ -220,6 +239,14 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
var swapClaims types.SwapClaims
cliCtx.LegacyAmino.MustUnmarshalJSON(swapRes, &swapClaims)
+ earnRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetEarnRewards), paramsBz)
+ if err != nil {
+ rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
+ return
+ }
+ var earnClaims types.EarnClaims
+ cliCtx.LegacyAmino.MustUnmarshalJSON(earnRes, &earnClaims)
+
cliCtx = cliCtx.WithHeight(height)
type rewardResult struct {
@@ -227,6 +254,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
UsdxMintingClaims types.USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
DelegatorClaims types.DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"`
SwapClaims types.SwapClaims `json:"swap_claims" yaml:"swap_claims"`
+ EarnClaims types.EarnClaims `json:"earn_claims" yaml:"earn_claims"`
}
res := rewardResult{
@@ -234,6 +262,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
UsdxMintingClaims: usdxMintingClaims,
DelegatorClaims: delegatorClaims,
SwapClaims: swapClaims,
+ EarnClaims: earnClaims,
}
resBz, err := cliCtx.LegacyAmino.MarshalJSON(res)
diff --git a/x/incentive/client/rest/tx.go b/x/incentive/client/rest/tx.go
index dd7fe70a..61b2da78 100644
--- a/x/incentive/client/rest/tx.go
+++ b/x/incentive/client/rest/tx.go
@@ -20,6 +20,7 @@ func registerTxRoutes(cliCtx client.Context, r *mux.Router) {
r.HandleFunc("/incentive/claim-hard", postClaimHandlerFn(cliCtx, hardGenerator)).Methods("POST")
r.HandleFunc("/incentive/claim-delegator", postClaimHandlerFn(cliCtx, delegatorGenerator)).Methods("POST")
r.HandleFunc("/incentive/claim-swap", postClaimHandlerFn(cliCtx, swapGenerator)).Methods("POST")
+ r.HandleFunc("/incentive/claim-earn", postClaimHandlerFn(cliCtx, earnGenerator)).Methods("POST")
}
func usdxMintingGenerator(req PostClaimReq) (sdk.Msg, error) {
@@ -45,6 +46,11 @@ func swapGenerator(req PostClaimReq) (sdk.Msg, error) {
return &msg, nil
}
+func earnGenerator(req PostClaimReq) (sdk.Msg, error) {
+ msg := types.NewMsgClaimEarnReward(req.Sender.String(), req.DenomsToClaim)
+ return &msg, nil
+}
+
func postClaimHandlerFn(cliCtx client.Context, msgGenerator func(req PostClaimReq) (sdk.Msg, error)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var requestBody PostClaimReq
diff --git a/x/incentive/genesis.go b/x/incentive/genesis.go
index 2fd89939..6f2580ff 100644
--- a/x/incentive/genesis.go
+++ b/x/incentive/genesis.go
@@ -126,6 +126,20 @@ func InitGenesis(
for _, mri := range gs.SavingsRewardState.MultiRewardIndexes {
k.SetSavingsRewardIndexes(ctx, mri.CollateralType, mri.RewardIndexes)
}
+
+ // Earn
+ for _, claim := range gs.EarnClaims {
+ k.SetEarnClaim(ctx, claim)
+ }
+ for _, gat := range gs.EarnRewardState.AccumulationTimes {
+ if err := ValidateAccumulationTime(gat.PreviousAccumulationTime, ctx.BlockTime()); err != nil {
+ panic(err.Error())
+ }
+ k.SetEarnRewardAccrualTime(ctx, gat.CollateralType, gat.PreviousAccumulationTime)
+ }
+ for _, mri := range gs.EarnRewardState.MultiRewardIndexes {
+ k.SetEarnRewardIndexes(ctx, mri.CollateralType, mri.RewardIndexes)
+ }
}
// ExportGenesis export genesis state for incentive module
@@ -148,10 +162,15 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
savingsClaims := k.GetAllSavingsClaims(ctx)
savingsRewardState := getSavingsGenesisRewardState(ctx, k)
+ earnClaims := k.GetAllEarnClaims(ctx)
+ earnRewardState := getEarnGenesisRewardState(ctx, k)
+
return types.NewGenesisState(
params,
- usdxRewardState, hardSupplyRewardState, hardBorrowRewardState, delegatorRewardState, swapRewardState,
- savingsRewardState, usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims,
+ // Reward states
+ usdxRewardState, hardSupplyRewardState, hardBorrowRewardState, delegatorRewardState, swapRewardState, savingsRewardState, earnRewardState,
+ // Claims
+ usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, earnClaims,
)
}
@@ -257,6 +276,22 @@ func getSavingsGenesisRewardState(ctx sdk.Context, keeper keeper.Keeper) types.G
return types.NewGenesisRewardState(ats, mris)
}
+func getEarnGenesisRewardState(ctx sdk.Context, keeper keeper.Keeper) types.GenesisRewardState {
+ var ats types.AccumulationTimes
+ keeper.IterateEarnRewardAccrualTimes(ctx, func(ctype string, accTime time.Time) bool {
+ ats = append(ats, types.NewAccumulationTime(ctype, accTime))
+ return false
+ })
+
+ var mris types.MultiRewardIndexes
+ keeper.IterateEarnRewardIndexes(ctx, func(ctype string, indexes types.RewardIndexes) bool {
+ mris = append(mris, types.NewMultiRewardIndex(ctype, indexes))
+ return false
+ })
+
+ return types.NewGenesisRewardState(ats, mris)
+}
+
func ValidateAccumulationTime(previousAccumulationTime, genesisTime time.Time) error {
if previousAccumulationTime.Before(genesisTime.Add(-1 * EarliestValidAccumulationTime)) {
return fmt.Errorf(
diff --git a/x/incentive/genesis_test.go b/x/incentive/genesis_test.go
index d1281a35..887c8ea0 100644
--- a/x/incentive/genesis_test.go
+++ b/x/incentive/genesis_test.go
@@ -70,6 +70,7 @@ func (suite *GenesisTestSuite) SetupTest() {
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "btcb/usdx", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("swp", 122354)))},
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
+ types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultipliersPerDenoms{
{
Denom: "ukava",
@@ -100,11 +101,13 @@ func (suite *GenesisTestSuite) SetupTest() {
types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
+ types.DefaultGenesisRewardState,
types.DefaultUSDXClaims,
types.DefaultHardClaims,
types.DefaultDelegatorClaims,
types.DefaultSwapClaims,
types.DefaultSavingsClaims,
+ types.DefaultEarnClaims,
)
cdc := suite.app.AppCodec()
@@ -135,6 +138,7 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "btcb/usdx", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("swp", 122354)))},
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354)))},
+ types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultipliersPerDenoms{
{
Denom: "ukava",
@@ -207,6 +211,14 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.NewMultiRewardIndex("ukava", types.RewardIndexes{{CollateralType: "ukava", RewardFactor: d("0.2")}}),
},
),
+ types.NewGenesisRewardState(
+ types.AccumulationTimes{
+ types.NewAccumulationTime("usdx", genesisTime.Add(-3*time.Hour)),
+ },
+ types.MultiRewardIndexes{
+ types.NewMultiRewardIndex("usdx", types.RewardIndexes{{CollateralType: "usdx", RewardFactor: d("0.2")}}),
+ },
+ ),
types.USDXMintingClaims{
types.NewUSDXMintingClaim(
suite.addrs[0],
@@ -254,6 +266,13 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.MultiRewardIndexes{{CollateralType: "ukava", RewardIndexes: types.RewardIndexes{{CollateralType: "ukava", RewardFactor: d("0.0")}}}},
),
},
+ types.EarnClaims{
+ types.NewEarnClaim(
+ suite.addrs[3],
+ nil,
+ types.MultiRewardIndexes{{CollateralType: "usdx", RewardIndexes: types.RewardIndexes{{CollateralType: "earn", RewardFactor: d("0.0")}}}},
+ ),
+ },
)
tApp := app.NewTestApp()
diff --git a/x/incentive/keeper/claim.go b/x/incentive/keeper/claim.go
index 868e6f5b..ef75f93a 100644
--- a/x/incentive/keeper/claim.go
+++ b/x/incentive/keeper/claim.go
@@ -256,3 +256,51 @@ func (k Keeper) ClaimSavingsReward(ctx sdk.Context, owner, receiver sdk.AccAddre
)
return nil
}
+
+// ClaimEarnReward pays out funds from a claim to a receiver account.
+// Rewards are removed from a claim and paid out according to the multiplier, which reduces the reward amount in exchange for shorter vesting times.
+func (k Keeper) ClaimEarnReward(ctx sdk.Context, owner, receiver sdk.AccAddress, denom string, multiplierName string) error {
+ multiplier, found := k.GetMultiplierByDenom(ctx, denom, multiplierName)
+ if !found {
+ return sdkerrors.Wrapf(types.ErrInvalidMultiplier, "denom '%s' has no multiplier '%s'", denom, multiplierName)
+ }
+
+ claimEnd := k.GetClaimEnd(ctx)
+
+ if ctx.BlockTime().After(claimEnd) {
+ return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
+ }
+
+ syncedClaim, found := k.GetSynchronizedEarnClaim(ctx, owner)
+ if !found {
+ return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
+ }
+
+ amt := syncedClaim.Reward.AmountOf(denom)
+
+ claimingCoins := sdk.NewCoins(sdk.NewCoin(denom, amt))
+ rewardCoins := sdk.NewCoins(sdk.NewCoin(denom, amt.ToDec().Mul(multiplier.Factor).RoundInt()))
+ if rewardCoins.IsZero() {
+ return types.ErrZeroClaim
+ }
+ length := k.GetPeriodLength(ctx.BlockTime(), multiplier.MonthsLockup)
+
+ err := k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, receiver, rewardCoins, length)
+ if err != nil {
+ return err
+ }
+
+ // remove claimed coins (NOT reward coins)
+ syncedClaim.Reward = syncedClaim.Reward.Sub(claimingCoins)
+ k.SetEarnClaim(ctx, syncedClaim)
+
+ ctx.EventManager().EmitEvent(
+ sdk.NewEvent(
+ types.EventTypeClaim,
+ sdk.NewAttribute(types.AttributeKeyClaimedBy, owner.String()),
+ sdk.NewAttribute(types.AttributeKeyClaimAmount, claimingCoins.String()),
+ sdk.NewAttribute(types.AttributeKeyClaimType, syncedClaim.GetType()),
+ ),
+ )
+ return nil
+}
diff --git a/x/incentive/keeper/claim_test.go b/x/incentive/keeper/claim_test.go
index 9c42a4a8..e215eeae 100644
--- a/x/incentive/keeper/claim_test.go
+++ b/x/incentive/keeper/claim_test.go
@@ -36,7 +36,7 @@ func (suite *ClaimTests) TestCannotClaimWhenMultiplierNotRecognised() {
},
},
}
- suite.keeper = suite.NewKeeper(subspace, nil, nil, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(subspace, nil, nil, nil, nil, nil, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -70,7 +70,7 @@ func (suite *ClaimTests) TestCannotClaimAfterEndTime() {
ClaimEnd: endTime,
},
}
- suite.keeper = suite.NewKeeper(subspace, nil, nil, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(subspace, nil, nil, nil, nil, nil, nil, nil, nil)
suite.ctx = suite.ctx.WithBlockTime(endTime.Add(time.Nanosecond))
diff --git a/x/incentive/keeper/hooks.go b/x/incentive/keeper/hooks.go
index b52e95f5..593e0e98 100644
--- a/x/incentive/keeper/hooks.go
+++ b/x/incentive/keeper/hooks.go
@@ -5,6 +5,7 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
+ earntypes "github.com/kava-labs/kava/x/earn/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
savingstypes "github.com/kava-labs/kava/x/savings/types"
swaptypes "github.com/kava-labs/kava/x/swap/types"
@@ -21,6 +22,7 @@ var (
_ stakingtypes.StakingHooks = Hooks{}
_ swaptypes.SwapHooks = Hooks{}
_ savingstypes.SavingsHooks = Hooks{}
+ _ earntypes.EarnHooks = Hooks{}
)
// Hooks create new incentive hooks
@@ -177,3 +179,25 @@ func (h Hooks) AfterSavingsDepositCreated(ctx sdk.Context, deposit savingstypes.
func (h Hooks) BeforeSavingsDepositModified(ctx sdk.Context, deposit savingstypes.Deposit, incomingDenoms []string) {
h.k.SynchronizeSavingsReward(ctx, deposit, incomingDenoms)
}
+
+// ------------------- Earn Module Hooks -------------------
+
+// AfterVaultDepositCreated function that runs after a vault deposit is created
+func (h Hooks) AfterVaultDepositCreated(
+ ctx sdk.Context,
+ vaultDenom string,
+ depositor sdk.AccAddress,
+ _ sdk.Dec,
+) {
+ h.k.InitializeEarnReward(ctx, vaultDenom, depositor)
+}
+
+// BeforeVaultDepositModified function that runs before a vault deposit is modified
+func (h Hooks) BeforeVaultDepositModified(
+ ctx sdk.Context,
+ vaultDenom string,
+ depositor sdk.AccAddress,
+ sharesOwned sdk.Dec,
+) {
+ h.k.SynchronizeEarnReward(ctx, vaultDenom, depositor, sharesOwned)
+}
diff --git a/x/incentive/keeper/keeper.go b/x/incentive/keeper/keeper.go
index 28964acf..bce59550 100644
--- a/x/incentive/keeper/keeper.go
+++ b/x/incentive/keeper/keeper.go
@@ -22,13 +22,14 @@ type Keeper struct {
stakingKeeper types.StakingKeeper
swapKeeper types.SwapKeeper
savingsKeeper types.SavingsKeeper
+ earnKeeper types.EarnKeeper
}
// NewKeeper creates a new keeper
func NewKeeper(
cdc codec.Codec, key sdk.StoreKey, paramstore types.ParamSubspace, bk types.BankKeeper,
cdpk types.CdpKeeper, hk types.HardKeeper, ak types.AccountKeeper, stk types.StakingKeeper,
- swpk types.SwapKeeper, svk types.SavingsKeeper,
+ swpk types.SwapKeeper, svk types.SavingsKeeper, ek types.EarnKeeper,
) Keeper {
if !paramstore.HasKeyTable() {
paramstore = paramstore.WithKeyTable(types.ParamKeyTable())
@@ -45,6 +46,7 @@ func NewKeeper(
stakingKeeper: stk,
swapKeeper: swpk,
savingsKeeper: svk,
+ earnKeeper: ek,
}
}
@@ -372,6 +374,55 @@ func (k Keeper) GetAllSavingsClaims(ctx sdk.Context) types.SavingsClaims {
return cs
}
+// GetEarnClaim returns the claim in the store corresponding the the input address.
+func (k Keeper) GetEarnClaim(ctx sdk.Context, addr sdk.AccAddress) (types.EarnClaim, bool) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnClaimKeyPrefix)
+ bz := store.Get(addr)
+ if bz == nil {
+ return types.EarnClaim{}, false
+ }
+ var c types.EarnClaim
+ k.cdc.MustUnmarshal(bz, &c)
+ return c, true
+}
+
+// SetEarnClaim sets the claim in the store corresponding to the input address.
+func (k Keeper) SetEarnClaim(ctx sdk.Context, c types.EarnClaim) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnClaimKeyPrefix)
+ bz := k.cdc.MustMarshal(&c)
+ store.Set(c.Owner, bz)
+}
+
+// DeleteEarnClaim deletes the claim in the store corresponding to the input address.
+func (k Keeper) DeleteEarnClaim(ctx sdk.Context, owner sdk.AccAddress) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnClaimKeyPrefix)
+ store.Delete(owner)
+}
+
+// IterateEarnClaims iterates over all claim objects in the store and preforms a callback function
+func (k Keeper) IterateEarnClaims(ctx sdk.Context, cb func(c types.EarnClaim) (stop bool)) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnClaimKeyPrefix)
+ iterator := sdk.KVStorePrefixIterator(store, []byte{})
+ defer iterator.Close()
+ for ; iterator.Valid(); iterator.Next() {
+ var c types.EarnClaim
+ k.cdc.MustUnmarshal(iterator.Value(), &c)
+ if cb(c) {
+ break
+ }
+ }
+}
+
+// GetAllEarnClaims returns all Claim objects in the store
+func (k Keeper) GetAllEarnClaims(ctx sdk.Context) types.EarnClaims {
+ cs := types.EarnClaims{}
+ k.IterateEarnClaims(ctx, func(c types.EarnClaim) (stop bool) {
+ cs = append(cs, c)
+ return false
+ })
+ return cs
+}
+
// SetHardSupplyRewardIndexes sets the current reward indexes for an individual denom
func (k Keeper) SetHardSupplyRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix)
@@ -745,3 +796,77 @@ func (k Keeper) IterateSavingsRewardAccrualTimes(ctx sdk.Context, cb func(string
}
}
}
+
+// SetEarnRewardIndexes stores the global reward indexes that track total rewards to a earn vault.
+func (k Keeper) SetEarnRewardIndexes(ctx sdk.Context, vaultDenom string, indexes types.RewardIndexes) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnRewardIndexesKeyPrefix)
+ bz := k.cdc.MustMarshal(&types.RewardIndexesProto{
+ RewardIndexes: indexes,
+ })
+ store.Set([]byte(vaultDenom), bz)
+}
+
+// GetEarnRewardIndexes fetches the global reward indexes that track total rewards to a earn vault.
+func (k Keeper) GetEarnRewardIndexes(ctx sdk.Context, vaultDenom string) (types.RewardIndexes, bool) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnRewardIndexesKeyPrefix)
+ bz := store.Get([]byte(vaultDenom))
+ if bz == nil {
+ return types.RewardIndexes{}, false
+ }
+ var proto types.RewardIndexesProto
+ k.cdc.MustUnmarshal(bz, &proto)
+ return proto.RewardIndexes, true
+}
+
+// IterateEarnRewardIndexes iterates over all earn reward index objects in the store and preforms a callback function
+func (k Keeper) IterateEarnRewardIndexes(ctx sdk.Context, cb func(vaultDenom string, indexes types.RewardIndexes) (stop bool)) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.EarnRewardIndexesKeyPrefix)
+ iterator := sdk.KVStorePrefixIterator(store, []byte{})
+ defer iterator.Close()
+ for ; iterator.Valid(); iterator.Next() {
+ var proto types.RewardIndexesProto
+ k.cdc.MustUnmarshal(iterator.Value(), &proto)
+ if cb(string(iterator.Key()), proto.RewardIndexes) {
+ break
+ }
+ }
+}
+
+// GetEarnRewardAccrualTime fetches the last time rewards were accrued for an earn vault.
+func (k Keeper) GetEarnRewardAccrualTime(ctx sdk.Context, vaultDenom string) (blockTime time.Time, found bool) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousEarnRewardAccrualTimeKeyPrefix)
+ b := store.Get([]byte(vaultDenom))
+ if b == nil {
+ return time.Time{}, false
+ }
+ if err := blockTime.UnmarshalBinary(b); err != nil {
+ panic(err)
+ }
+ return blockTime, true
+}
+
+// SetEarnRewardAccrualTime stores the last time rewards were accrued for a earn vault.
+func (k Keeper) SetEarnRewardAccrualTime(ctx sdk.Context, vaultDenom string, blockTime time.Time) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousEarnRewardAccrualTimeKeyPrefix)
+ bz, err := blockTime.MarshalBinary()
+ if err != nil {
+ panic(err)
+ }
+ store.Set([]byte(vaultDenom), bz)
+}
+
+func (k Keeper) IterateEarnRewardAccrualTimes(ctx sdk.Context, cb func(string, time.Time) (stop bool)) {
+ store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousEarnRewardAccrualTimeKeyPrefix)
+ iterator := sdk.KVStorePrefixIterator(store, []byte{})
+ defer iterator.Close()
+ for ; iterator.Valid(); iterator.Next() {
+ poolID := string(iterator.Key())
+ var accrualTime time.Time
+ if err := accrualTime.UnmarshalBinary(iterator.Value()); err != nil {
+ panic(err)
+ }
+ if cb(poolID, accrualTime) {
+ break
+ }
+ }
+}
diff --git a/x/incentive/keeper/keeper_test.go b/x/incentive/keeper/keeper_test.go
index d19464e3..962ee55d 100644
--- a/x/incentive/keeper/keeper_test.go
+++ b/x/incentive/keeper/keeper_test.go
@@ -291,6 +291,215 @@ func (suite *KeeperTestSuite) TestGetSetSwapRewardAccrualTimes() {
}
}
+func (suite *KeeperTestSuite) TestGetSetDeleteEarnClaims() {
+ suite.SetupApp()
+ c := types.NewEarnClaim(suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes)
+
+ _, found := suite.keeper.GetEarnClaim(suite.ctx, suite.addrs[0])
+ suite.Require().False(found)
+
+ suite.Require().NotPanics(func() {
+ suite.keeper.SetEarnClaim(suite.ctx, c)
+ })
+ testC, found := suite.keeper.GetEarnClaim(suite.ctx, suite.addrs[0])
+ suite.Require().True(found)
+ suite.Require().Equal(c, testC)
+
+ suite.Require().NotPanics(func() {
+ suite.keeper.DeleteEarnClaim(suite.ctx, suite.addrs[0])
+ })
+ _, found = suite.keeper.GetEarnClaim(suite.ctx, suite.addrs[0])
+ suite.Require().False(found)
+}
+
+func (suite *KeeperTestSuite) TestIterateEarnClaims() {
+ suite.SetupApp()
+ claims := types.EarnClaims{
+ types.NewEarnClaim(suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes),
+ types.NewEarnClaim(suite.addrs[1], nil, nil), // different claim to the first
+ }
+ for _, claim := range claims {
+ suite.keeper.SetEarnClaim(suite.ctx, claim)
+ }
+
+ var actualClaims types.EarnClaims
+ suite.keeper.IterateEarnClaims(suite.ctx, func(c types.EarnClaim) bool {
+ actualClaims = append(actualClaims, c)
+ return false
+ })
+
+ suite.Require().Equal(claims, actualClaims)
+}
+
+func (suite *KeeperTestSuite) TestGetSetEarnRewardIndexes() {
+ testCases := []struct {
+ name string
+ vaultDenom string
+ indexes types.RewardIndexes
+ wantIndex types.RewardIndexes
+ panics bool
+ }{
+ {
+ name: "two factors can be written and read",
+ vaultDenom: "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 vault name panics",
+ vaultDenom: "",
+ 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",
+ vaultDenom: "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",
+ vaultDenom: "usdx",
+ indexes: nil,
+ wantIndex: nil,
+ panics: false,
+ },
+ }
+
+ for _, tc := range testCases {
+ suite.Run(tc.name, func() {
+ suite.SetupApp()
+
+ _, found := suite.keeper.GetEarnRewardIndexes(suite.ctx, tc.vaultDenom)
+ suite.False(found)
+
+ setFunc := func() { suite.keeper.SetEarnRewardIndexes(suite.ctx, tc.vaultDenom, tc.indexes) }
+ if tc.panics {
+ suite.Panics(setFunc)
+ return
+ } else {
+ suite.NotPanics(setFunc)
+ }
+
+ storedIndexes, found := suite.keeper.GetEarnRewardIndexes(suite.ctx, tc.vaultDenom)
+ suite.True(found)
+ suite.Equal(tc.wantIndex, storedIndexes)
+ })
+ }
+}
+
+func (suite *KeeperTestSuite) TestIterateEarnRewardIndexes() {
+ suite.SetupApp()
+ multiIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: "ukava",
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.0000002"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.04"),
+ },
+ },
+ },
+ {
+ CollateralType: "usdx",
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "hard",
+ RewardFactor: d("0.02"),
+ },
+ },
+ },
+ }
+ for _, mi := range multiIndexes {
+ suite.keeper.SetEarnRewardIndexes(suite.ctx, mi.CollateralType, mi.RewardIndexes)
+ }
+
+ var actualMultiIndexes types.MultiRewardIndexes
+ suite.keeper.IterateEarnRewardIndexes(suite.ctx, func(vaultDenom string, i types.RewardIndexes) bool {
+ actualMultiIndexes = actualMultiIndexes.With(vaultDenom, i)
+ return false
+ })
+
+ suite.Require().Equal(multiIndexes, actualMultiIndexes)
+}
+
+func (suite *KeeperTestSuite) TestGetSetEarnRewardAccrualTimes() {
+ testCases := []struct {
+ name string
+ vaultDenom string
+ accrualTime time.Time
+ panics bool
+ }{
+ {
+ name: "normal time can be written and read",
+ vaultDenom: "usdx",
+ accrualTime: time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
+ },
+ {
+ name: "zero time can be written and read",
+ vaultDenom: "usdx",
+ accrualTime: time.Time{},
+ },
+ }
+
+ for _, tc := range testCases {
+ suite.Run(tc.name, func() {
+ suite.SetupApp()
+
+ _, found := suite.keeper.GetEarnRewardAccrualTime(suite.ctx, tc.vaultDenom)
+ suite.False(found)
+
+ setFunc := func() { suite.keeper.SetEarnRewardAccrualTime(suite.ctx, tc.vaultDenom, tc.accrualTime) }
+ if tc.panics {
+ suite.Panics(setFunc)
+ return
+ } else {
+ suite.NotPanics(setFunc)
+ }
+
+ storedTime, found := suite.keeper.GetEarnRewardAccrualTime(suite.ctx, tc.vaultDenom)
+ suite.True(found)
+ suite.Equal(tc.accrualTime, storedTime)
+ })
+ }
+}
+
type accrualtime struct {
denom string
time time.Time
@@ -397,6 +606,24 @@ func (suite *KeeperTestSuite) TestIterateSwapRewardAccrualTimes() {
suite.Equal(expectedAccrualTimes, actualAccrualTimes)
}
+func (suite *KeeperTestSuite) TestIterateEarnRewardAccrualTimes() {
+ suite.SetupApp()
+
+ expectedAccrualTimes := nonEmptyAccrualTimes
+
+ for _, at := range expectedAccrualTimes {
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, at.denom, at.time)
+ }
+
+ var actualAccrualTimes []accrualtime
+ suite.keeper.IterateEarnRewardAccrualTimes(suite.ctx, func(denom string, accrualTime time.Time) bool {
+ actualAccrualTimes = append(actualAccrualTimes, accrualtime{denom: denom, time: accrualTime})
+ return false
+ })
+
+ suite.Equal(expectedAccrualTimes, actualAccrualTimes)
+}
+
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
diff --git a/x/incentive/keeper/msg_server.go b/x/incentive/keeper/msg_server.go
index 2a88ded8..a4f5cdc4 100644
--- a/x/incentive/keeper/msg_server.go
+++ b/x/incentive/keeper/msg_server.go
@@ -108,3 +108,21 @@ func (k msgServer) ClaimSavingsReward(goCtx context.Context, msg *types.MsgClaim
return &types.MsgClaimSavingsRewardResponse{}, nil
}
+
+func (k msgServer) ClaimEarnReward(goCtx context.Context, msg *types.MsgClaimEarnReward) (*types.MsgClaimEarnRewardResponse, error) {
+ ctx := sdk.UnwrapSDKContext(goCtx)
+
+ sender, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, selection := range msg.DenomsToClaim {
+ err := k.keeper.ClaimEarnReward(ctx, sender, sender, selection.Denom, selection.MultiplierName)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return &types.MsgClaimEarnRewardResponse{}, nil
+}
diff --git a/x/incentive/keeper/querier.go b/x/incentive/keeper/querier.go
index 1ca93cb6..43af52f2 100644
--- a/x/incentive/keeper/querier.go
+++ b/x/incentive/keeper/querier.go
@@ -29,6 +29,8 @@ func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
return queryGetSavingsRewards(ctx, req, k, legacyQuerierCdc)
case types.QueryGetRewardFactors:
return queryGetRewardFactors(ctx, req, k, legacyQuerierCdc)
+ case types.QueryGetEarnRewards:
+ return queryGetEarnRewards(ctx, req, k, legacyQuerierCdc)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName)
}
@@ -261,6 +263,51 @@ func queryGetSavingsRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper, le
return bz, nil
}
+func queryGetEarnRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) {
+ var params types.QueryRewardsParams
+ err := legacyQuerierCdc.UnmarshalJSON(req.Data, ¶ms)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
+ }
+ owner := len(params.Owner) > 0
+
+ var claims types.EarnClaims
+ switch {
+ case owner:
+ claim, found := k.GetEarnClaim(ctx, params.Owner)
+ if found {
+ claims = append(claims, claim)
+ }
+ default:
+ claims = k.GetAllEarnClaims(ctx)
+ }
+
+ var paginatedClaims types.EarnClaims
+ startH, endH := client.Paginate(len(claims), params.Page, params.Limit, 100)
+ if startH < 0 || endH < 0 {
+ paginatedClaims = types.EarnClaims{}
+ } else {
+ paginatedClaims = claims[startH:endH]
+ }
+
+ if !params.Unsynchronized {
+ for i, claim := range paginatedClaims {
+ syncedClaim, found := k.GetSynchronizedEarnClaim(ctx, claim.Owner)
+ if !found {
+ panic("previously found claim should still be found")
+ }
+ paginatedClaims[i] = syncedClaim
+ }
+ }
+
+ // Marshal claims
+ bz, err := codec.MarshalJSONIndent(legacyQuerierCdc, paginatedClaims)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
+ }
+ return bz, nil
+}
+
func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) {
var usdxFactors types.RewardIndexes
k.IterateUSDXMintingRewardFactors(ctx, func(collateralType string, factor sdk.Dec) (stop bool) {
@@ -298,6 +345,12 @@ func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper, leg
return false
})
+ var earnFactors types.MultiRewardIndexes
+ k.IterateEarnRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
+ earnFactors = earnFactors.With(denom, indexes)
+ return false
+ })
+
response := types.NewQueryGetRewardFactorsResponse(
usdxFactors,
supplyFactors,
@@ -305,6 +358,7 @@ func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper, leg
delegatorFactors,
swapFactors,
savingsFactors,
+ earnFactors,
)
bz, err := codec.MarshalJSONIndent(legacyQuerierCdc, response)
diff --git a/x/incentive/keeper/rewards_borrow_accum_test.go b/x/incentive/keeper/rewards_borrow_accum_test.go
index d426e15c..2fd39985 100644
--- a/x/incentive/keeper/rewards_borrow_accum_test.go
+++ b/x/incentive/keeper/rewards_borrow_accum_test.go
@@ -39,7 +39,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateUpdatedWhenBlockTimeHasIncre
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
suite.storeGlobalBorrowIndexes(types.MultiRewardIndexes{
{
@@ -91,7 +91,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateUnchangedWhenBlockTimeHasNot
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -136,7 +136,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoAccumulationWhenSourceSharesAre
denom := "bnb"
hardKeeper := newFakeHardKeeper() // zero total borrows
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -182,7 +182,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateAddedWhenStateDoesNotExist()
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -225,7 +225,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoPanicWhenStateDoesNotExist() {
denom := "bnb"
hardKeeper := newFakeHardKeeper()
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -253,7 +253,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoAccumulationWhenBeforeStartTime
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -299,7 +299,7 @@ func (suite *AccumulateBorrowRewardsTests) TestPanicWhenCurrentTimeLessThanPrevi
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, denom, previousAccrualTime)
diff --git a/x/incentive/keeper/rewards_delegator_accum_test.go b/x/incentive/keeper/rewards_delegator_accum_test.go
index 2f050e2b..a7537fc2 100644
--- a/x/incentive/keeper/rewards_delegator_accum_test.go
+++ b/x/incentive/keeper/rewards_delegator_accum_test.go
@@ -36,7 +36,7 @@ func TestAccumulateDelegatorRewards(t *testing.T) {
func (suite *AccumulateDelegatorRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreased() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
suite.storeGlobalDelegatorIndexes(types.MultiRewardIndexes{
{
@@ -86,7 +86,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateUpdatedWhenBlockTimeHasIn
func (suite *AccumulateDelegatorRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -129,7 +129,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateUnchangedWhenBlockTimeHas
func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenSourceSharesAreZero() {
stakingKeeper := newFakeStakingKeeper() // zero total bonded
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -173,7 +173,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenSourceShares
func (suite *AccumulateDelegatorRewardsTests) TestStateAddedWhenStateDoesNotExist() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -214,7 +214,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateAddedWhenStateDoesNotExis
func (suite *AccumulateDelegatorRewardsTests) TestNoPanicWhenStateDoesNotExist() {
stakingKeeper := newFakeStakingKeeper()
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -240,7 +240,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoPanicWhenStateDoesNotExist()
func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenBeforeStartTime() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -284,7 +284,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenBeforeStartT
func (suite *AccumulateDelegatorRewardsTests) TestPanicWhenCurrentTimeLessThanPrevious() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousDelegatorRewardAccrualTime(suite.ctx, types.BondDenom, previousAccrualTime)
diff --git a/x/incentive/keeper/rewards_delegator_init_test.go b/x/incentive/keeper/rewards_delegator_init_test.go
index 17fbdf62..8d1eda3f 100644
--- a/x/incentive/keeper/rewards_delegator_init_test.go
+++ b/x/incentive/keeper/rewards_delegator_init_test.go
@@ -58,7 +58,7 @@ func (suite *InitializeDelegatorRewardTests) TestClaimIsSyncedAndIndexesAreSetWh
DelegatorShares: d("1000"),
}},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, sk, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, sk, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
diff --git a/x/incentive/keeper/rewards_delegator_sync_test.go b/x/incentive/keeper/rewards_delegator_sync_test.go
index 735ebfde..f6f60f95 100644
--- a/x/incentive/keeper/rewards_delegator_sync_test.go
+++ b/x/incentive/keeper/rewards_delegator_sync_test.go
@@ -37,7 +37,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGl
delegator := arbitraryAddress()
stakingKeeper := &fakeStakingKeeper{} // use an empty staking keeper that returns no delegations
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -58,7 +58,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGl
func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUpdatedWhenGlobalFactorIncreased() {
delegator := arbitraryAddress()
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, &fakeStakingKeeper{}, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, &fakeStakingKeeper{}, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -97,7 +97,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsUnchangedWhenGlobalFac
unslashedBondedValidator(validatorAddress),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -142,7 +142,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsIncreasedWhenNewReward
unslashedBondedValidator(validatorAddress),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -192,7 +192,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsIncreasedWhenGlobalFac
unslashedBondedValidator(validatorAddress),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -299,7 +299,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenValAddrIsNil()
unslashedNotBondedValidator(validatorAddresses[3]),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
suite.Equal(
d("11"), // delegation to bonded validators
@@ -343,7 +343,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenExcludingAVali
unslashedNotBondedValidator(validatorAddresses[3]),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
suite.Equal(
d("10"),
@@ -387,7 +387,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenIncludingAVali
unslashedNotBondedValidator(validatorAddresses[3]),
},
}
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, stakingKeeper, nil, nil, nil)
suite.Equal(
d("111"),
diff --git a/x/incentive/keeper/rewards_earn.go b/x/incentive/keeper/rewards_earn.go
new file mode 100644
index 00000000..0e907317
--- /dev/null
+++ b/x/incentive/keeper/rewards_earn.go
@@ -0,0 +1,142 @@
+package keeper
+
+import (
+ "fmt"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+
+ earntypes "github.com/kava-labs/kava/x/earn/types"
+ "github.com/kava-labs/kava/x/incentive/types"
+)
+
+// AccumulateEarnRewards 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) AccumulateEarnRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) {
+ previousAccrualTime, found := k.GetEarnRewardAccrualTime(ctx, rewardPeriod.CollateralType)
+ if !found {
+ previousAccrualTime = ctx.BlockTime()
+ }
+
+ indexes, found := k.GetEarnRewardIndexes(ctx, rewardPeriod.CollateralType)
+ if !found {
+ indexes = types.RewardIndexes{}
+ }
+
+ acc := types.NewAccumulator(previousAccrualTime, indexes)
+
+ totalSource := k.getEarnTotalSourceShares(ctx, rewardPeriod.CollateralType)
+
+ acc.Accumulate(rewardPeriod, totalSource, ctx.BlockTime())
+
+ k.SetEarnRewardAccrualTime(ctx, rewardPeriod.CollateralType, acc.PreviousAccumulationTime)
+ if len(acc.Indexes) > 0 {
+ // the store panics when setting empty or nil indexes
+ k.SetEarnRewardIndexes(ctx, rewardPeriod.CollateralType, acc.Indexes)
+ }
+}
+
+// getEarnTotalSourceShares fetches the sum of all source shares for a earn reward.
+// In the case of earn, these are the total (earn module) shares in a particular vault.
+func (k Keeper) getEarnTotalSourceShares(ctx sdk.Context, vaultDenom string) sdk.Dec {
+ totalShares, found := k.earnKeeper.GetVaultTotalShares(ctx, vaultDenom)
+ if !found {
+ return sdk.ZeroDec()
+ }
+ return totalShares.Amount
+}
+
+// InitializeEarnReward 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) InitializeEarnReward(ctx sdk.Context, vaultDenom string, owner sdk.AccAddress) {
+ claim, found := k.GetEarnClaim(ctx, owner)
+ if !found {
+ claim = types.NewEarnClaim(owner, sdk.Coins{}, nil)
+ }
+
+ globalRewardIndexes, found := k.GetEarnRewardIndexes(ctx, vaultDenom)
+ if !found {
+ globalRewardIndexes = types.RewardIndexes{}
+ }
+ claim.RewardIndexes = claim.RewardIndexes.With(vaultDenom, globalRewardIndexes)
+
+ k.SetEarnClaim(ctx, claim)
+}
+
+// SynchronizeEarnReward updates the claim object by adding any accumulated rewards
+// and updating the reward index value.
+func (k Keeper) SynchronizeEarnReward(
+ ctx sdk.Context,
+ vaultDenom string,
+ owner sdk.AccAddress,
+ shares sdk.Dec,
+) {
+ claim, found := k.GetEarnClaim(ctx, owner)
+ if !found {
+ return
+ }
+ claim = k.synchronizeEarnReward(ctx, claim, vaultDenom, owner, shares)
+
+ k.SetEarnClaim(ctx, claim)
+}
+
+// synchronizeEarnReward updates the reward and indexes in a earn claim for one vault.
+func (k *Keeper) synchronizeEarnReward(
+ ctx sdk.Context,
+ claim types.EarnClaim,
+ vaultDenom string,
+ owner sdk.AccAddress,
+ shares sdk.Dec,
+) types.EarnClaim {
+ globalRewardIndexes, found := k.GetEarnRewardIndexes(ctx, vaultDenom)
+ if !found {
+ // The global factor is only not found if
+ // - the vault 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 vaults.
+ // 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(vaultDenom)
+ if !found {
+ // Normally the reward indexes should always be found.
+ // But if a vault was not rewarded then becomes rewarded (ie a reward period is added to params), then the indexes will be missing from claims for that vault.
+ // 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(vaultDenom, globalRewardIndexes)
+
+ return claim
+}
+
+// GetSynchronizedEarnClaim fetches a earn claim from the store and syncs rewards for all rewarded vaults.
+func (k Keeper) GetSynchronizedEarnClaim(ctx sdk.Context, owner sdk.AccAddress) (types.EarnClaim, bool) {
+ claim, found := k.GetEarnClaim(ctx, owner)
+ if !found {
+ return types.EarnClaim{}, false
+ }
+
+ shares, found := k.earnKeeper.GetVaultAccountShares(ctx, owner)
+ if !found {
+ shares = earntypes.NewVaultShares()
+ }
+
+ k.IterateEarnRewardIndexes(ctx, func(vaultDenom string, _ types.RewardIndexes) bool {
+ vaultAmount := shares.AmountOf(vaultDenom)
+ claim = k.synchronizeEarnReward(ctx, claim, vaultDenom, owner, vaultAmount)
+
+ return false
+ })
+
+ return claim, true
+}
diff --git a/x/incentive/keeper/rewards_earn_accum_test.go b/x/incentive/keeper/rewards_earn_accum_test.go
new file mode 100644
index 00000000..d2d931e5
--- /dev/null
+++ b/x/incentive/keeper/rewards_earn_accum_test.go
@@ -0,0 +1,321 @@
+package keeper_test
+
+import (
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/suite"
+
+ earntypes "github.com/kava-labs/kava/x/earn/types"
+ "github.com/kava-labs/kava/x/incentive/types"
+)
+
+type AccumulateEarnRewardsTests struct {
+ unitTester
+}
+
+func (suite *AccumulateEarnRewardsTests) storedTimeEquals(vaultDenom string, expected time.Time) {
+ storedTime, found := suite.keeper.GetEarnRewardAccrualTime(suite.ctx, vaultDenom)
+ suite.True(found)
+ suite.Equal(expected, storedTime)
+}
+
+func (suite *AccumulateEarnRewardsTests) storedIndexesEqual(vaultDenom string, expected types.RewardIndexes) {
+ storedIndexes, found := suite.keeper.GetEarnRewardIndexes(suite.ctx, vaultDenom)
+ suite.Equal(found, expected != nil, "expected indexes is %v but indexes found = %v", expected, found)
+ if found {
+ suite.Equal(expected, storedIndexes)
+ } else {
+ suite.Empty(storedIndexes)
+ }
+}
+
+func TestAccumulateEarnRewards(t *testing.T) {
+ suite.Run(t, new(AccumulateEarnRewardsTests))
+}
+
+func (suite *AccumulateEarnRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreased() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper().addVault(vaultDenom, earntypes.NewVaultShare(vaultDenom, d("1000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ suite.storeGlobalEarnIndexes(types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.02"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.04"),
+ },
+ },
+ },
+ })
+ previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, vaultDenom, previousAccrualTime)
+
+ newAccrualTime := previousAccrualTime.Add(1 * time.Hour)
+ suite.ctx = suite.ctx.WithBlockTime(newAccrualTime)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ 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
+ )
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+
+ // check time and factors
+
+ suite.storedTimeEquals(vaultDenom, newAccrualTime)
+ suite.storedIndexesEqual(vaultDenom, types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("7.22"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("3.64"),
+ },
+ })
+}
+
+func (suite *AccumulateEarnRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper().addVault(vaultDenom, earntypes.NewVaultShare(vaultDenom, d("1000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ previousIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.02"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.04"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(previousIndexes)
+ previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, vaultDenom, previousAccrualTime)
+
+ suite.ctx = suite.ctx.WithBlockTime(previousAccrualTime)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ 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
+ )
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+
+ // check time and factors
+
+ suite.storedTimeEquals(vaultDenom, previousAccrualTime)
+ expected, f := previousIndexes.Get(vaultDenom)
+ suite.True(f)
+ suite.storedIndexesEqual(vaultDenom, expected)
+}
+
+func (suite *AccumulateEarnRewardsTests) TestNoAccumulationWhenSourceSharesAreZero() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper() // no vault, so no source shares
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ previousIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.02"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.04"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(previousIndexes)
+ previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, vaultDenom, previousAccrualTime)
+
+ firstAccrualTime := previousAccrualTime.Add(7 * time.Second)
+ suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ 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
+ )
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+
+ // check time and factors
+
+ suite.storedTimeEquals(vaultDenom, firstAccrualTime)
+ expected, f := previousIndexes.Get(vaultDenom)
+ suite.True(f)
+ suite.storedIndexesEqual(vaultDenom, expected)
+}
+
+func (suite *AccumulateEarnRewardsTests) TestStateAddedWhenStateDoesNotExist() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper().addVault(vaultDenom, earntypes.NewVaultShare(vaultDenom, d("1000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ time.Unix(0, 0), // ensure the test is within start and end times
+ distantFuture,
+ cs(c("earn", 2000), c("ukava", 1000)),
+ )
+
+ firstAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, 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(vaultDenom, firstAccrualTime)
+ suite.storedIndexesEqual(vaultDenom, nil)
+
+ secondAccrualTime := firstAccrualTime.Add(10 * time.Second)
+ suite.ctx = suite.ctx.WithBlockTime(secondAccrualTime)
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+
+ // After the second accumulation both current block time and indexes should be stored.
+ suite.storedTimeEquals(vaultDenom, secondAccrualTime)
+ suite.storedIndexesEqual(vaultDenom, types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.02"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.01"),
+ },
+ })
+}
+
+func (suite *AccumulateEarnRewardsTests) TestNoPanicWhenStateDoesNotExist() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper()
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ 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 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() {
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+ })
+
+ suite.storedTimeEquals(vaultDenom, accrualTime)
+ suite.storedIndexesEqual(vaultDenom, nil)
+}
+
+func (suite *AccumulateEarnRewardsTests) TestNoAccumulationWhenBeforeStartTime() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper().addVault(vaultDenom, earntypes.NewVaultShare(vaultDenom, d("1000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ previousIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "earn",
+ RewardFactor: d("0.02"),
+ },
+ {
+ CollateralType: "ukava",
+ RewardFactor: d("0.04"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(previousIndexes)
+ previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, vaultDenom, previousAccrualTime)
+
+ firstAccrualTime := previousAccrualTime.Add(10 * time.Second)
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ firstAccrualTime.Add(time.Nanosecond), // start time after accrual time
+ distantFuture,
+ cs(c("earn", 2000), c("ukava", 1000)),
+ )
+
+ suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
+
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+
+ // The accrual time should be updated, but the indexes unchanged
+ suite.storedTimeEquals(vaultDenom, firstAccrualTime)
+ expectedIndexes, f := previousIndexes.Get(vaultDenom)
+ suite.True(f)
+ suite.storedIndexesEqual(vaultDenom, expectedIndexes)
+}
+
+func (suite *AccumulateEarnRewardsTests) TestPanicWhenCurrentTimeLessThanPrevious() {
+ vaultDenom := "usdx"
+
+ earnKeeper := newFakeEarnKeeper().addVault(vaultDenom, earntypes.NewVaultShare(vaultDenom, d("1000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
+ suite.keeper.SetEarnRewardAccrualTime(suite.ctx, vaultDenom, previousAccrualTime)
+
+ firstAccrualTime := time.Time{}
+
+ period := types.NewMultiRewardPeriod(
+ true,
+ vaultDenom,
+ time.Time{}, // start time after accrual time
+ distantFuture,
+ cs(c("earn", 2000), c("ukava", 1000)),
+ )
+
+ suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
+
+ suite.Panics(func() {
+ suite.keeper.AccumulateEarnRewards(suite.ctx, period)
+ })
+}
diff --git a/x/incentive/keeper/rewards_earn_init_test.go b/x/incentive/keeper/rewards_earn_init_test.go
new file mode 100644
index 00000000..4931ae0b
--- /dev/null
+++ b/x/incentive/keeper/rewards_earn_init_test.go
@@ -0,0 +1,195 @@
+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"
+)
+
+// InitializeEarnRewardTests runs unit tests for the keeper.InitializeEarnReward method
+//
+// inputs
+// - claim in store if it exists
+// - global indexes in store
+//
+// outputs
+// - sets or creates a claim
+type InitializeEarnRewardTests struct {
+ unitTester
+}
+
+func TestInitializeEarnReward(t *testing.T) {
+ suite.Run(t, new(InitializeEarnRewardTests))
+}
+
+func (suite *InitializeEarnRewardTests) 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
+
+ vaultDenom := "usdx"
+
+ // no global indexes stored as this pool is not rewarded
+
+ owner := arbitraryAddress()
+
+ suite.keeper.InitializeEarnReward(suite.ctx, vaultDenom, owner)
+
+ syncedClaim, found := suite.keeper.GetEarnClaim(suite.ctx, owner)
+ suite.True(found)
+ // A new claim should have empty indexes. It doesn't strictly need the vaultDenom either.
+ expectedIndexes := types.MultiRewardIndexes{{
+ CollateralType: vaultDenom,
+ RewardIndexes: nil,
+ }}
+ suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
+ // a new claim should start with 0 rewards
+ suite.Equal(sdk.Coins(nil), syncedClaim.Reward)
+}
+
+func (suite *InitializeEarnRewardTests) 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
+
+ vaultDenom := "usdx"
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ owner := arbitraryAddress()
+
+ suite.keeper.InitializeEarnReward(suite.ctx, vaultDenom, owner)
+
+ syncedClaim, found := suite.keeper.GetEarnClaim(suite.ctx, 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 *InitializeEarnRewardTests) TestClaimUpdatedWhenClaimExistsAndNoRewards() {
+ // When a claim exists, and a user deposits to a new non-rewarded pool;
+ // then the claim's rewards don't change
+
+ preexistingvaultDenom := "preexisting"
+ preexistingIndexes := types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ }
+
+ newVaultDenom := "btcb:usdx"
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: preexistingvaultDenom,
+ RewardIndexes: preexistingIndexes,
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ // no global indexes stored as the new pool is not rewarded
+
+ suite.keeper.InitializeEarnReward(suite.ctx, newVaultDenom, claim.Owner)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ // The preexisting indexes shouldn't be changed. It doesn't strictly need the new vaultDenom either.
+ expectedIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: preexistingvaultDenom,
+ RewardIndexes: preexistingIndexes,
+ },
+ {
+ CollateralType: newVaultDenom,
+ RewardIndexes: nil,
+ },
+ }
+ suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
+ // init should never alter the rewards
+ suite.Equal(claim.Reward, syncedClaim.Reward)
+}
+
+func (suite *InitializeEarnRewardTests) 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
+
+ preexistingvaultDenom := "preexisting"
+ preexistingIndexes := types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ }
+
+ newVaultDenom := "btcb:usdx"
+ newIndexes := types.RewardIndexes{
+ {
+ CollateralType: "otherrewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ }
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: preexistingvaultDenom,
+ RewardIndexes: preexistingIndexes,
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: preexistingvaultDenom,
+ RewardIndexes: increaseRewardFactors(preexistingIndexes),
+ },
+ {
+ CollateralType: newVaultDenom,
+ RewardIndexes: newIndexes,
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ suite.keeper.InitializeEarnReward(suite.ctx, newVaultDenom, claim.Owner)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ // only the indexes for the new pool should be updated
+ expectedIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: preexistingvaultDenom,
+ RewardIndexes: preexistingIndexes,
+ },
+ {
+ CollateralType: newVaultDenom,
+ RewardIndexes: newIndexes,
+ },
+ }
+ suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
+ // init should never alter the rewards
+ suite.Equal(claim.Reward, syncedClaim.Reward)
+}
diff --git a/x/incentive/keeper/rewards_earn_sync_test.go b/x/incentive/keeper/rewards_earn_sync_test.go
new file mode 100644
index 00000000..9269cf24
--- /dev/null
+++ b/x/incentive/keeper/rewards_earn_sync_test.go
@@ -0,0 +1,473 @@
+package keeper_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/suite"
+
+ earntypes "github.com/kava-labs/kava/x/earn/types"
+ "github.com/kava-labs/kava/x/incentive/types"
+)
+
+// SynchronizeEarnRewardTests runs unit tests for the keeper.SynchronizeEarnReward method
+//
+// inputs
+// - claim in store (only claim.RewardIndexes, claim.Reward)
+// - global indexes in store
+// - shares function arg
+//
+// outputs
+// - sets a claim
+type SynchronizeEarnRewardTests struct {
+ unitTester
+}
+
+func TestSynchronizeEarnReward(t *testing.T) {
+ suite.Run(t, new(SynchronizeEarnRewardTests))
+}
+
+func (suite *SynchronizeEarnRewardTests) 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()
+ vaultDenom := "cats"
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: originalReward,
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ userShares := d("1000000000")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, vaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, 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 *SynchronizeEarnRewardTests) TestClaimUnchangedWhenGlobalIndexesUnchanged() {
+ // It should be safe to call SynchronizeEarnReward multiple times
+
+ vaultDenom := "cats"
+ unchangingIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ }
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: unchangingIndexes,
+ }
+ suite.storeEarnClaim(claim)
+
+ suite.storeGlobalEarnIndexes(unchangingIndexes)
+
+ userShares := d("1000000000")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, vaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ // claim should have the same rewards and indexes as before
+ suite.Equal(claim, syncedClaim)
+}
+
+func (suite *SynchronizeEarnRewardTests) TestClaimUpdatedWhenNewRewardAdded() {
+ // When a new reward is added (via gov) for a vault 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()
+ newlyRewardVaultDenom := "newlyRewardedVault"
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: originalReward,
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: "currentlyRewardedVault",
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "reward",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: "currentlyRewardedVault",
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "reward",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ {
+ CollateralType: newlyRewardVaultDenom,
+ 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.storeGlobalEarnIndexes(globalIndexes)
+
+ userShares := d("1000000000")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, newlyRewardVaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ // the new indexes should be added to the claim, but the old ones should be unchanged
+ newlyRewrdedIndexes, _ := globalIndexes.Get(newlyRewardVaultDenom)
+ expectedIndexes := claim.RewardIndexes.With(newlyRewardVaultDenom, newlyRewrdedIndexes)
+ suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
+ // new reward is (new index - old index) * shares for the synced vault
+ // 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 *SynchronizeEarnRewardTests) TestClaimUnchangedWhenNoReward() {
+ // When a vault is not rewarded but the user has deposited to that vault, and the claim is synced;
+ // Then the claim should be the same.
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: nonEmptyMultiRewardIndexes,
+ }
+ suite.storeEarnClaim(claim)
+
+ vaultDenom := "nonRewardVault"
+ // No global indexes stored as this vault is not rewarded
+
+ userShares := d("1000000000")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, vaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ suite.Equal(claim, syncedClaim)
+}
+
+func (suite *SynchronizeEarnRewardTests) TestClaimUpdatedWhenNewRewardDenomAdded() {
+ // When a new reward coin is added (via gov) to an already rewarded vault (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()
+ vaultDenom := "cats"
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: originalReward,
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "reward",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ 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.storeGlobalEarnIndexes(globalIndexes)
+
+ userShares := d("1000000000")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, vaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, 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 *SynchronizeEarnRewardTests) 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
+
+ vaultDenom := "cats"
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: arbitraryAddress(),
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ userShares := d("0")
+
+ suite.keeper.SynchronizeEarnReward(suite.ctx, vaultDenom, claim.Owner, userShares)
+
+ syncedClaim, _ := suite.keeper.GetEarnClaim(suite.ctx, claim.Owner)
+ // indexes updated from global
+ suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
+ // reward is unchanged
+ suite.Equal(claim.Reward, syncedClaim.Reward)
+}
+
+func (suite *SynchronizeEarnRewardTests) TestGetSyncedClaim_ClaimUnchangedWhenNoGlobalIndexes() {
+ vaultDenom_1 := "usdx"
+ owner := arbitraryAddress()
+
+ earnKeeper := newFakeEarnKeeper().
+ addDeposit(owner, earntypes.NewVaultShare("usdx", d("1000000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: owner,
+ Reward: nil,
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom_1,
+ RewardIndexes: nil, // this state only happens because Init stores empty indexes
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ // no global indexes for any vault
+
+ syncedClaim, f := suite.keeper.GetSynchronizedEarnClaim(suite.ctx, 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 *SynchronizeEarnRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexAndHasNoSourceShares() {
+ vaultDenom_1 := "usdx"
+ vaultDenom_2 := "ukava"
+ owner := arbitraryAddress()
+
+ // owner has no shares in any vault
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, newFakeEarnKeeper())
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: owner,
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom_1,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom1",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: vaultDenom_1,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom1",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ {
+ CollateralType: vaultDenom_2,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom2",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ syncedClaim, f := suite.keeper.GetSynchronizedEarnClaim(suite.ctx, 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 *SynchronizeEarnRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexButHasSourceShares() {
+ VaultDenom_1 := "usdx"
+ VaultDenom_2 := "ukava"
+ owner := arbitraryAddress()
+
+ earnKeeper := newFakeEarnKeeper().
+ addVault(VaultDenom_1, earntypes.NewVaultShare(VaultDenom_1, d("1000000000"))).
+ addVault(VaultDenom_2, earntypes.NewVaultShare(VaultDenom_2, d("1000000000"))).
+ addDeposit(owner, earntypes.NewVaultShare(VaultDenom_1, d("1000000000"))).
+ addDeposit(owner, earntypes.NewVaultShare(VaultDenom_2, d("1000000000")))
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, earnKeeper)
+
+ claim := types.EarnClaim{
+ BaseMultiClaim: types.BaseMultiClaim{
+ Owner: owner,
+ Reward: arbitraryCoins(),
+ },
+ RewardIndexes: types.MultiRewardIndexes{
+ {
+ CollateralType: VaultDenom_1,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom1",
+ RewardFactor: d("1000.001"),
+ },
+ },
+ },
+ },
+ }
+ suite.storeEarnClaim(claim)
+
+ globalIndexes := types.MultiRewardIndexes{
+ {
+ CollateralType: VaultDenom_1,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom1",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ {
+ CollateralType: VaultDenom_2,
+ RewardIndexes: types.RewardIndexes{
+ {
+ CollateralType: "rewarddenom2",
+ RewardFactor: d("2000.002"),
+ },
+ },
+ },
+ }
+ suite.storeGlobalEarnIndexes(globalIndexes)
+
+ syncedClaim, f := suite.keeper.GetSynchronizedEarnClaim(suite.ctx, 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)
+}
diff --git a/x/incentive/keeper/rewards_supply_accum_test.go b/x/incentive/keeper/rewards_supply_accum_test.go
index b3e134e6..145cd68d 100644
--- a/x/incentive/keeper/rewards_supply_accum_test.go
+++ b/x/incentive/keeper/rewards_supply_accum_test.go
@@ -38,7 +38,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateUpdatedWhenBlockTimeHasIncre
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
suite.storeGlobalSupplyIndexes(types.MultiRewardIndexes{
{
@@ -90,7 +90,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateUnchangedWhenBlockTimeHasNot
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -135,7 +135,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoAccumulationWhenSourceSharesAre
denom := "bnb"
hardKeeper := newFakeHardKeeper() // zero total supplys
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -181,7 +181,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateAddedWhenStateDoesNotExist()
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -224,7 +224,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoPanicWhenStateDoesNotExist() {
denom := "bnb"
hardKeeper := newFakeHardKeeper()
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -252,7 +252,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoAccumulationWhenBeforeStartTime
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -298,7 +298,7 @@ func (suite *AccumulateSupplyRewardsTests) TestPanicWhenCurrentTimeLessThanPrevi
denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, hardKeeper, nil, nil, nil, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, denom, previousAccrualTime)
diff --git a/x/incentive/keeper/rewards_swap_accum_test.go b/x/incentive/keeper/rewards_swap_accum_test.go
index 0bc082b6..c836b931 100644
--- a/x/incentive/keeper/rewards_swap_accum_test.go
+++ b/x/incentive/keeper/rewards_swap_accum_test.go
@@ -37,7 +37,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreas
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
suite.storeGlobalSwapIndexes(types.MultiRewardIndexes{
{
@@ -89,7 +89,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIn
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -134,7 +134,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoAccumulationWhenSourceSharesAreZe
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper() // no pools, so no source shares
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -180,7 +180,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateAddedWhenStateDoesNotExist() {
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -223,7 +223,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoPanicWhenStateDoesNotExist() {
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper()
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
period := types.NewMultiRewardPeriod(
true,
@@ -251,7 +251,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoAccumulationWhenBeforeStartTime()
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
@@ -297,7 +297,7 @@ func (suite *AccumulateSwapRewardsTests) TestPanicWhenCurrentTimeLessThanPreviou
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetSwapRewardAccrualTime(suite.ctx, pool, previousAccrualTime)
diff --git a/x/incentive/keeper/rewards_swap_sync_test.go b/x/incentive/keeper/rewards_swap_sync_test.go
index feb5f597..63570439 100644
--- a/x/incentive/keeper/rewards_swap_sync_test.go
+++ b/x/incentive/keeper/rewards_swap_sync_test.go
@@ -323,7 +323,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUnchangedWhenNo
swapKeeper := newFakeSwapKeeper().
addDeposit(poolID_1, owner, i(1e9))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -356,7 +356,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMiss
owner := arbitraryAddress()
// owner has no shares in any pool
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, newFakeSwapKeeper(), nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, newFakeSwapKeeper(), nil, nil)
claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{
@@ -416,7 +416,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMiss
swapKeeper := newFakeSwapKeeper().
addDeposit(poolID_1, owner, i(1e9)).
addDeposit(poolID_2, owner, i(1e9))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil)
claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{
diff --git a/x/incentive/keeper/rewards_usdx_accum_test.go b/x/incentive/keeper/rewards_usdx_accum_test.go
index 0d354094..1fb67824 100644
--- a/x/incentive/keeper/rewards_usdx_accum_test.go
+++ b/x/incentive/keeper/rewards_usdx_accum_test.go
@@ -34,7 +34,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreas
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
suite.storeGlobalUSDXIndexes(types.RewardIndexes{
{
@@ -68,7 +68,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIn
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
previousIndexes := types.RewardIndexes{
{
@@ -104,7 +104,7 @@ func (suite *AccumulateUSDXRewardsTests) TestNoAccumulationWhenSourceSharesAreZe
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper() // zero total borrows
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
previousIndexes := types.RewardIndexes{
{
@@ -141,7 +141,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateAddedWhenStateDoesNotExist() {
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
period := types.NewRewardPeriod(
true,
@@ -174,7 +174,7 @@ func (suite *AccumulateUSDXRewardsTests) TestNoAccumulationWhenBeforeStartTime()
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
previousIndexes := types.RewardIndexes{
{
@@ -211,7 +211,7 @@ func (suite *AccumulateUSDXRewardsTests) TestPanicWhenCurrentTimeLessThanPreviou
cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1"))
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, cdpKeeper, nil, nil, nil, nil, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousUSDXMintingAccrualTime(suite.ctx, cType, previousAccrualTime)
diff --git a/x/incentive/keeper/unit_test.go b/x/incentive/keeper/unit_test.go
index fe53c092..14f527cc 100644
--- a/x/incentive/keeper/unit_test.go
+++ b/x/incentive/keeper/unit_test.go
@@ -15,6 +15,7 @@ import (
"github.com/kava-labs/kava/app"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
+ earntypes "github.com/kava-labs/kava/x/earn/types"
tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
@@ -58,7 +59,7 @@ func (suite *unitTester) SetupSuite() {
func (suite *unitTester) SetupTest() {
suite.ctx = NewTestContext(suite.incentiveStoreKey)
- suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil)
+ suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, nil, nil, nil)
}
func (suite *unitTester) TearDownTest() {
@@ -66,8 +67,8 @@ func (suite *unitTester) TearDownTest() {
suite.ctx = sdk.Context{}
}
-func (suite *unitTester) NewKeeper(paramSubspace types.ParamSubspace, bk types.BankKeeper, cdpk types.CdpKeeper, hk types.HardKeeper, ak types.AccountKeeper, stk types.StakingKeeper, swk types.SwapKeeper, svk types.SavingsKeeper) keeper.Keeper {
- return keeper.NewKeeper(suite.cdc, suite.incentiveStoreKey, paramSubspace, bk, cdpk, hk, ak, stk, swk, svk)
+func (suite *unitTester) NewKeeper(paramSubspace types.ParamSubspace, bk types.BankKeeper, cdpk types.CdpKeeper, hk types.HardKeeper, ak types.AccountKeeper, stk types.StakingKeeper, swk types.SwapKeeper, svk types.SavingsKeeper, ek types.EarnKeeper) keeper.Keeper {
+ return keeper.NewKeeper(suite.cdc, suite.incentiveStoreKey, paramSubspace, bk, cdpk, hk, ak, stk, swk, svk, ek)
}
func (suite *unitTester) storeGlobalBorrowIndexes(indexes types.MultiRewardIndexes) {
@@ -100,6 +101,12 @@ func (suite *unitTester) storeGlobalSavingsIndexes(indexes types.MultiRewardInde
}
}
+func (suite *unitTester) storeGlobalEarnIndexes(indexes types.MultiRewardIndexes) {
+ for _, i := range indexes {
+ suite.keeper.SetEarnRewardIndexes(suite.ctx, i.CollateralType, i.RewardIndexes)
+ }
+}
+
func (suite *unitTester) storeHardClaim(claim types.HardLiquidityProviderClaim) {
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim)
}
@@ -116,6 +123,10 @@ func (suite *unitTester) storeSavingsClaim(claim types.SavingsClaim) {
suite.keeper.SetSavingsClaim(suite.ctx, claim)
}
+func (suite *unitTester) storeEarnClaim(claim types.EarnClaim) {
+ suite.keeper.SetEarnClaim(suite.ctx, claim)
+}
+
// fakeParamSubspace is a stub paramSpace to simplify keeper unit test setup.
type fakeParamSubspace struct {
params types.Params
@@ -351,6 +362,56 @@ func (k *fakeCDPKeeper) GetCollateral(_ sdk.Context, collateralType string) (cdp
return cdptypes.CollateralParam{}, false
}
+// fakeEarnKeeper is a stub earn keeper.
+// It can be used to return values to the incentive keeper without having to initialize a full earn keeper.
+type fakeEarnKeeper struct {
+ vaultShares map[string]earntypes.VaultShare
+ depositShares map[string]earntypes.VaultShares
+}
+
+var _ types.EarnKeeper = newFakeEarnKeeper()
+
+func newFakeEarnKeeper() *fakeEarnKeeper {
+ return &fakeEarnKeeper{
+ vaultShares: map[string]earntypes.VaultShare{},
+ depositShares: map[string]earntypes.VaultShares{},
+ }
+}
+
+func (k *fakeEarnKeeper) addVault(vaultDenom string, shares earntypes.VaultShare) *fakeEarnKeeper {
+ k.vaultShares[vaultDenom] = shares
+ return k
+}
+
+func (k *fakeEarnKeeper) addDeposit(
+ depositor sdk.AccAddress,
+ shares earntypes.VaultShare,
+) *fakeEarnKeeper {
+ if k.depositShares[depositor.String()] == nil {
+ k.depositShares[depositor.String()] = earntypes.NewVaultShares()
+ }
+
+ k.depositShares[depositor.String()] = k.depositShares[depositor.String()].Add(shares)
+
+ return k
+}
+
+func (k *fakeEarnKeeper) GetVaultTotalShares(
+ ctx sdk.Context,
+ denom string,
+) (shares earntypes.VaultShare, found bool) {
+ vaultShares, found := k.vaultShares[denom]
+ return vaultShares, found
+}
+
+func (k *fakeEarnKeeper) GetVaultAccountShares(
+ ctx sdk.Context,
+ acc sdk.AccAddress,
+) (shares earntypes.VaultShares, found bool) {
+ accShares, found := k.depositShares[acc.String()]
+ return accShares, found
+}
+
// Assorted Testing Data
// note: amino panics when encoding times ≥ the start of year 10000.
diff --git a/x/incentive/legacy/go.mod b/x/incentive/legacy/go.mod
new file mode 100644
index 00000000..e69de29b
diff --git a/x/incentive/types/claims.go b/x/incentive/types/claims.go
index 9d1ce889..ac7bc5f6 100644
--- a/x/incentive/types/claims.go
+++ b/x/incentive/types/claims.go
@@ -14,6 +14,7 @@ const (
DelegatorClaimType = "delegator_claim"
SwapClaimType = "swap"
SavingsClaimType = "savings"
+ EarnClaimType = "earn"
)
// GetOwner is a getter for Claim Owner
@@ -339,6 +340,58 @@ func (cs SavingsClaims) Validate() error {
return nil
}
+// NewEarnClaim returns a new EarnClaim
+func NewEarnClaim(owner sdk.AccAddress, rewards sdk.Coins, rewardIndexes MultiRewardIndexes) EarnClaim {
+ return EarnClaim{
+ BaseMultiClaim: BaseMultiClaim{
+ Owner: owner,
+ Reward: rewards,
+ },
+ RewardIndexes: rewardIndexes,
+ }
+}
+
+// GetType returns the claim's type
+func (c EarnClaim) GetType() string { return EarnClaimType }
+
+// GetReward returns the claim's reward coin
+func (c EarnClaim) GetReward() sdk.Coins { return c.Reward }
+
+// GetOwner returns the claim's owner
+func (c EarnClaim) GetOwner() sdk.AccAddress { return c.Owner }
+
+// Validate performs a basic check of a SwapClaim fields
+func (c EarnClaim) Validate() error {
+ if err := c.RewardIndexes.Validate(); err != nil {
+ return err
+ }
+ return c.BaseMultiClaim.Validate()
+}
+
+// HasRewardIndex check if a claim has a reward index for the input pool ID.
+func (c EarnClaim) HasRewardIndex(poolID string) (int64, bool) {
+ for index, ri := range c.RewardIndexes {
+ if ri.CollateralType == poolID {
+ return int64(index), true
+ }
+ }
+ return 0, false
+}
+
+// EarnClaims slice of EarnClaim
+type EarnClaims []EarnClaim
+
+// Validate checks if all the claims are valid.
+func (cs EarnClaims) Validate() error {
+ for _, c := range cs {
+ if err := c.Validate(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
// ---------------------- Reward indexes are used internally in the store ----------------------
// NewRewardIndex returns a new RewardIndex
diff --git a/x/incentive/types/claims.pb.go b/x/incentive/types/claims.pb.go
index 44f553f5..77839b79 100644
--- a/x/incentive/types/claims.pb.go
+++ b/x/incentive/types/claims.pb.go
@@ -454,6 +454,45 @@ func (m *SavingsClaim) XXX_DiscardUnknown() {
var xxx_messageInfo_SavingsClaim proto.InternalMessageInfo
+// EarnClaim stores the earn rewards that can be claimed by owner
+type EarnClaim struct {
+ BaseMultiClaim `protobuf:"bytes,1,opt,name=base_claim,json=baseClaim,proto3,embedded=base_claim" json:"base_claim"`
+ RewardIndexes MultiRewardIndexes `protobuf:"bytes,2,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=MultiRewardIndexes" json:"reward_indexes"`
+}
+
+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{11}
+}
+func (m *EarnClaim) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *EarnClaim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_EarnClaim.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 *EarnClaim) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_EarnClaim.Merge(m, src)
+}
+func (m *EarnClaim) XXX_Size() int {
+ return m.Size()
+}
+func (m *EarnClaim) XXX_DiscardUnknown() {
+ xxx_messageInfo_EarnClaim.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EarnClaim proto.InternalMessageInfo
+
func init() {
proto.RegisterType((*BaseClaim)(nil), "kava.incentive.v1beta1.BaseClaim")
proto.RegisterType((*BaseMultiClaim)(nil), "kava.incentive.v1beta1.BaseMultiClaim")
@@ -466,6 +505,7 @@ func init() {
proto.RegisterType((*DelegatorClaim)(nil), "kava.incentive.v1beta1.DelegatorClaim")
proto.RegisterType((*SwapClaim)(nil), "kava.incentive.v1beta1.SwapClaim")
proto.RegisterType((*SavingsClaim)(nil), "kava.incentive.v1beta1.SavingsClaim")
+ proto.RegisterType((*EarnClaim)(nil), "kava.incentive.v1beta1.EarnClaim")
}
func init() {
@@ -473,50 +513,51 @@ func init() {
}
var fileDescriptor_5f7515029623a895 = []byte{
- // 686 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0x4f, 0x4f, 0x13, 0x4f,
- 0x18, 0xc7, 0x3b, 0xf0, 0x83, 0xfc, 0x3a, 0x94, 0x4a, 0x16, 0x50, 0xe8, 0x61, 0x8b, 0x25, 0xc1,
- 0x26, 0xa6, 0xbb, 0x82, 0x07, 0x13, 0x6f, 0x2c, 0xc4, 0x80, 0x91, 0x48, 0xb6, 0x9a, 0x18, 0x0f,
- 0x36, 0xb3, 0xbb, 0x63, 0x9d, 0xb0, 0xdd, 0xa9, 0x3b, 0xd3, 0x96, 0xbe, 0x06, 0x2f, 0xfa, 0x06,
- 0x7c, 0x01, 0x5e, 0xbc, 0xf0, 0x22, 0x88, 0xf1, 0x40, 0x8c, 0x89, 0x7f, 0x0e, 0x15, 0xe1, 0xea,
- 0x2b, 0xf0, 0x64, 0xe6, 0x0f, 0xb0, 0x40, 0x4b, 0x88, 0x29, 0x1e, 0x38, 0xb5, 0xf3, 0xcc, 0xb3,
- 0xcf, 0xf7, 0xf3, 0x7c, 0xf7, 0xd9, 0xd9, 0x85, 0xb3, 0x1b, 0xa8, 0x89, 0x6c, 0x12, 0xf9, 0x38,
- 0xe2, 0xa4, 0x89, 0xed, 0xe6, 0xbc, 0x87, 0x39, 0x9a, 0xb7, 0xfd, 0x10, 0x91, 0x1a, 0xb3, 0xea,
- 0x31, 0xe5, 0xd4, 0xb8, 0x2a, 0x92, 0xac, 0xc3, 0x24, 0x4b, 0x27, 0xe5, 0x26, 0xaa, 0xb4, 0x4a,
- 0x65, 0x8a, 0x2d, 0xfe, 0xa9, 0xec, 0xdc, 0xb4, 0x4f, 0x59, 0x8d, 0xb2, 0x8a, 0xda, 0x50, 0x0b,
- 0xbd, 0x65, 0xaa, 0x95, 0xed, 0x21, 0x96, 0x90, 0xa2, 0x24, 0x52, 0xfb, 0x85, 0xf7, 0x00, 0xa6,
- 0x1d, 0xc4, 0xf0, 0x92, 0x50, 0x37, 0x9e, 0xc1, 0x21, 0xda, 0x8a, 0x70, 0x3c, 0x05, 0x66, 0x40,
- 0x31, 0xe3, 0xac, 0xfc, 0xee, 0xe4, 0x4b, 0x55, 0xc2, 0x5f, 0x34, 0x3c, 0xcb, 0xa7, 0x35, 0x5d,
- 0x59, 0xff, 0x94, 0x58, 0xb0, 0x61, 0xf3, 0x76, 0x1d, 0x33, 0x6b, 0xd1, 0xf7, 0x17, 0x83, 0x20,
- 0xc6, 0x8c, 0x7d, 0xda, 0x2a, 0x8d, 0x6b, 0x7d, 0x1d, 0x71, 0xda, 0x1c, 0x33, 0x57, 0x95, 0x35,
- 0xee, 0xc0, 0xe1, 0x18, 0xb7, 0x50, 0x1c, 0x4c, 0x0d, 0xcc, 0x80, 0xe2, 0xc8, 0xc2, 0xb4, 0xa5,
- 0x93, 0x05, 0xde, 0x41, 0x93, 0xd6, 0x12, 0x25, 0x91, 0xf3, 0xdf, 0x76, 0x27, 0x9f, 0x72, 0x75,
- 0xfa, 0xdd, 0xf4, 0x87, 0xad, 0xd2, 0x90, 0x64, 0x2c, 0xec, 0x02, 0x98, 0x15, 0xc4, 0x6b, 0x8d,
- 0x90, 0x93, 0x7f, 0x83, 0xed, 0x27, 0xb0, 0x07, 0xcf, 0xc6, 0xbe, 0x25, 0xb0, 0xdf, 0xfd, 0xc8,
- 0x17, 0xcf, 0xa1, 0x2f, 0x2e, 0x60, 0xdd, 0x5a, 0x7c, 0x05, 0xe0, 0x88, 0x2b, 0xa3, 0xab, 0x51,
- 0x80, 0x37, 0x8d, 0x1b, 0xf0, 0x8a, 0x4f, 0xc3, 0x10, 0x71, 0x1c, 0xa3, 0xb0, 0x22, 0x2e, 0x96,
- 0x9d, 0xa6, 0xdd, 0xec, 0x51, 0xf8, 0x51, 0xbb, 0x8e, 0x8d, 0x32, 0x1c, 0x55, 0xd5, 0x2a, 0xcf,
- 0x91, 0xcf, 0x69, 0x2c, 0x6d, 0xce, 0x38, 0x96, 0x80, 0xfa, 0xde, 0xc9, 0xcf, 0x9d, 0x03, 0x6a,
- 0x19, 0xfb, 0x6e, 0x46, 0x15, 0xb9, 0x27, 0x6b, 0x14, 0x5a, 0xd0, 0x48, 0xc0, 0x60, 0xb6, 0x2e,
- 0x27, 0x14, 0xc1, 0xac, 0x96, 0x22, 0x2a, 0x3c, 0x05, 0xa4, 0x37, 0xb3, 0x56, 0xf7, 0xd1, 0xb5,
- 0x12, 0x35, 0x9c, 0x49, 0xed, 0xd2, 0xe8, 0xb1, 0xc2, 0xae, 0x86, 0xd7, 0xcb, 0xc2, 0x5b, 0x00,
- 0xc7, 0xe4, 0x5d, 0xfe, 0x2b, 0x2f, 0x4e, 0x03, 0x0e, 0xf4, 0x1b, 0xf0, 0x0d, 0x80, 0xd7, 0x4e,
- 0x02, 0x1e, 0xf8, 0xd3, 0x84, 0x13, 0x35, 0xb1, 0x55, 0xe9, 0xea, 0x52, 0xb1, 0x17, 0xc4, 0xc9,
- 0x72, 0x4e, 0x4e, 0x93, 0x18, 0xa7, 0x85, 0x5c, 0xa3, 0x76, 0x2a, 0x56, 0xf8, 0x08, 0xe0, 0xd8,
- 0xe3, 0xf2, 0xf2, 0x93, 0x35, 0x12, 0x71, 0x12, 0x55, 0xd5, 0x03, 0x72, 0x1f, 0x42, 0x31, 0xaa,
- 0x15, 0x79, 0xc6, 0x48, 0xbf, 0x46, 0x16, 0xae, 0xf7, 0x42, 0x38, 0x3c, 0x0e, 0x9c, 0xff, 0x85,
- 0xf6, 0x4e, 0x27, 0x0f, 0xdc, 0xb4, 0x77, 0x78, 0x46, 0x5c, 0xbc, 0xaf, 0xc9, 0x47, 0xe1, 0xd7,
- 0x00, 0xcc, 0xad, 0xa0, 0x38, 0x78, 0x40, 0x5e, 0x36, 0x48, 0x40, 0x78, 0x7b, 0x3d, 0xa6, 0x4d,
- 0x12, 0xe0, 0x58, 0xc1, 0x3c, 0xec, 0xd2, 0xd8, 0xdc, 0x59, 0x8d, 0x1d, 0x9d, 0x1a, 0xdd, 0xbb,
- 0xdb, 0x84, 0x93, 0xac, 0x51, 0xaf, 0x87, 0xed, 0x4a, 0xd7, 0x26, 0xfb, 0x73, 0xdf, 0xc6, 0x95,
- 0xc4, 0xb1, 0xa0, 0x50, 0xf6, 0x68, 0x1c, 0xd3, 0xd6, 0x49, 0xe5, 0xc1, 0x7e, 0x2a, 0x2b, 0x09,
- 0xb7, 0x97, 0xdd, 0xdf, 0x00, 0xcc, 0x2e, 0xe3, 0x10, 0x57, 0x11, 0xa7, 0x17, 0x65, 0xf1, 0x46,
- 0x8f, 0x01, 0xea, 0x4f, 0x87, 0xbd, 0x47, 0xe9, 0x33, 0x80, 0xe9, 0x72, 0x0b, 0xd5, 0x2f, 0x59,
- 0x5b, 0x5f, 0x00, 0xcc, 0x94, 0x51, 0x93, 0x44, 0x55, 0x76, 0xb9, 0x3a, 0x73, 0x56, 0xb7, 0x7f,
- 0x9a, 0xa9, 0xed, 0x3d, 0x13, 0xec, 0xec, 0x99, 0x60, 0x77, 0xcf, 0x04, 0xaf, 0xf7, 0xcd, 0xd4,
- 0xce, 0xbe, 0x99, 0xfa, 0xba, 0x6f, 0xa6, 0x9e, 0xde, 0x4c, 0xbc, 0xcc, 0x04, 0x47, 0x29, 0x44,
- 0x1e, 0x93, 0xff, 0xec, 0xcd, 0xc4, 0xe7, 0x95, 0x7c, 0xab, 0x79, 0xc3, 0xf2, 0x6b, 0xe7, 0xf6,
- 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x6c, 0x47, 0x50, 0x7d, 0x09, 0x00, 0x00,
+ // 693 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0x4f, 0x4f, 0x13, 0x4d,
+ 0x1c, 0xc7, 0x3b, 0xf0, 0x40, 0x9e, 0x0e, 0xa5, 0x0f, 0x59, 0xe0, 0x11, 0x7a, 0xd8, 0x62, 0x49,
+ 0xb0, 0x89, 0xe9, 0xae, 0xe0, 0xc1, 0xc4, 0x1b, 0x0b, 0x1a, 0x30, 0x12, 0xc9, 0x56, 0x13, 0xe3,
+ 0xc1, 0x66, 0x76, 0x77, 0xac, 0x13, 0xb6, 0x3b, 0x75, 0x66, 0xdb, 0xd2, 0xd7, 0xe0, 0x45, 0xdf,
+ 0x80, 0x2f, 0xc0, 0x8b, 0x17, 0x5e, 0x04, 0x31, 0x1e, 0x88, 0x31, 0xf1, 0xcf, 0xa1, 0x22, 0x5c,
+ 0x7d, 0x05, 0x9e, 0xcc, 0xfc, 0x01, 0x16, 0x68, 0x09, 0x31, 0xc5, 0x03, 0xa7, 0xdd, 0xf9, 0xcd,
+ 0x6f, 0x7f, 0xdf, 0xcf, 0xef, 0x3b, 0xb3, 0xb3, 0x0b, 0x67, 0x37, 0x50, 0x13, 0xd9, 0x24, 0xf2,
+ 0x71, 0x14, 0x93, 0x26, 0xb6, 0x9b, 0xf3, 0x1e, 0x8e, 0xd1, 0xbc, 0xed, 0x87, 0x88, 0xd4, 0xb8,
+ 0x55, 0x67, 0x34, 0xa6, 0xc6, 0xff, 0x22, 0xc9, 0x3a, 0x4c, 0xb2, 0x74, 0x52, 0x6e, 0xa2, 0x4a,
+ 0xab, 0x54, 0xa6, 0xd8, 0xe2, 0x4e, 0x65, 0xe7, 0xa6, 0x7d, 0xca, 0x6b, 0x94, 0x57, 0xd4, 0x84,
+ 0x1a, 0xe8, 0x29, 0x53, 0x8d, 0x6c, 0x0f, 0xf1, 0x84, 0x14, 0x25, 0x91, 0x9a, 0x2f, 0xbc, 0x03,
+ 0x30, 0xed, 0x20, 0x8e, 0x97, 0x84, 0xba, 0xf1, 0x14, 0x0e, 0xd1, 0x56, 0x84, 0xd9, 0x14, 0x98,
+ 0x01, 0xc5, 0x8c, 0xb3, 0xf2, 0xab, 0x93, 0x2f, 0x55, 0x49, 0xfc, 0xbc, 0xe1, 0x59, 0x3e, 0xad,
+ 0xe9, 0xca, 0xfa, 0x52, 0xe2, 0xc1, 0x86, 0x1d, 0xb7, 0xeb, 0x98, 0x5b, 0x8b, 0xbe, 0xbf, 0x18,
+ 0x04, 0x0c, 0x73, 0xfe, 0x71, 0xab, 0x34, 0xae, 0xf5, 0x75, 0xc4, 0x69, 0xc7, 0x98, 0xbb, 0xaa,
+ 0xac, 0x71, 0x0b, 0x0e, 0x33, 0xdc, 0x42, 0x2c, 0x98, 0x1a, 0x98, 0x01, 0xc5, 0x91, 0x85, 0x69,
+ 0x4b, 0x27, 0x0b, 0xbc, 0x83, 0x26, 0xad, 0x25, 0x4a, 0x22, 0xe7, 0x9f, 0xed, 0x4e, 0x3e, 0xe5,
+ 0xea, 0xf4, 0xdb, 0xe9, 0xf7, 0x5b, 0xa5, 0x21, 0xc9, 0x58, 0xd8, 0x05, 0x30, 0x2b, 0x88, 0xd7,
+ 0x1a, 0x61, 0x4c, 0xfe, 0x0e, 0xb6, 0x9f, 0xc0, 0x1e, 0x3c, 0x1b, 0xfb, 0x86, 0xc0, 0x7e, 0xfb,
+ 0x3d, 0x5f, 0x3c, 0x87, 0xbe, 0x78, 0x80, 0x77, 0x6b, 0xf1, 0x25, 0x80, 0x23, 0xae, 0x8c, 0xae,
+ 0x46, 0x01, 0xde, 0x34, 0xae, 0xc1, 0xff, 0x7c, 0x1a, 0x86, 0x28, 0xc6, 0x0c, 0x85, 0x15, 0xf1,
+ 0xb0, 0xec, 0x34, 0xed, 0x66, 0x8f, 0xc2, 0x0f, 0xdb, 0x75, 0x6c, 0x94, 0xe1, 0xa8, 0xaa, 0x56,
+ 0x79, 0x86, 0xfc, 0x98, 0x32, 0x69, 0x73, 0xc6, 0xb1, 0x04, 0xd4, 0xb7, 0x4e, 0x7e, 0xee, 0x1c,
+ 0x50, 0xcb, 0xd8, 0x77, 0x33, 0xaa, 0xc8, 0x5d, 0x59, 0xa3, 0xd0, 0x82, 0x46, 0x02, 0x06, 0xf3,
+ 0x75, 0xb9, 0x43, 0x11, 0xcc, 0x6a, 0x29, 0xa2, 0xc2, 0x53, 0x40, 0x7a, 0x33, 0x6b, 0x75, 0xdf,
+ 0xba, 0x56, 0xa2, 0x86, 0x33, 0xa9, 0x5d, 0x1a, 0x3d, 0x56, 0xd8, 0xd5, 0xf0, 0x7a, 0x58, 0x78,
+ 0x03, 0xe0, 0x98, 0x5c, 0xe5, 0x3f, 0xf2, 0xe2, 0x34, 0xe0, 0x40, 0xbf, 0x01, 0x5f, 0x03, 0x78,
+ 0xe5, 0x24, 0xe0, 0x81, 0x3f, 0x4d, 0x38, 0x51, 0x13, 0x53, 0x95, 0xae, 0x2e, 0x15, 0x7b, 0x41,
+ 0x9c, 0x2c, 0xe7, 0xe4, 0x34, 0x89, 0x71, 0x5a, 0xc8, 0x35, 0x6a, 0xa7, 0x62, 0x85, 0x0f, 0x00,
+ 0x8e, 0x3d, 0x2a, 0x2f, 0x3f, 0x5e, 0x23, 0x51, 0x4c, 0xa2, 0xaa, 0x7a, 0x41, 0xee, 0x41, 0x28,
+ 0xb6, 0x6a, 0x45, 0x9e, 0x31, 0xd2, 0xaf, 0x91, 0x85, 0xab, 0xbd, 0x10, 0x0e, 0x8f, 0x03, 0xe7,
+ 0x5f, 0xa1, 0xbd, 0xd3, 0xc9, 0x03, 0x37, 0xed, 0x1d, 0x9e, 0x11, 0x17, 0xef, 0x6b, 0xf2, 0x55,
+ 0xf8, 0x39, 0x00, 0x73, 0x2b, 0x88, 0x05, 0xf7, 0xc9, 0x8b, 0x06, 0x09, 0x48, 0xdc, 0x5e, 0x67,
+ 0xb4, 0x49, 0x02, 0xcc, 0x14, 0xcc, 0x83, 0x2e, 0x8d, 0xcd, 0x9d, 0xd5, 0xd8, 0xd1, 0xa9, 0xd1,
+ 0xbd, 0xbb, 0x4d, 0x38, 0xc9, 0x1b, 0xf5, 0x7a, 0xd8, 0xae, 0x74, 0x6d, 0xb2, 0x3f, 0xeb, 0x36,
+ 0xae, 0x24, 0x8e, 0x05, 0x85, 0xb2, 0x47, 0x19, 0xa3, 0xad, 0x93, 0xca, 0x83, 0xfd, 0x54, 0x56,
+ 0x12, 0x6e, 0x2f, 0xbb, 0xbf, 0x02, 0x98, 0x5d, 0xc6, 0x21, 0xae, 0xa2, 0x98, 0x5e, 0x94, 0xc5,
+ 0x1b, 0x3d, 0x36, 0x50, 0x7f, 0x3a, 0xec, 0xbd, 0x95, 0x3e, 0x01, 0x98, 0x2e, 0xb7, 0x50, 0xfd,
+ 0x92, 0xb5, 0xf5, 0x19, 0xc0, 0x4c, 0x19, 0x35, 0x49, 0x54, 0xe5, 0x97, 0x70, 0xc1, 0xee, 0x20,
+ 0x16, 0x5d, 0xae, 0xb6, 0x9c, 0xd5, 0xed, 0x1f, 0x66, 0x6a, 0x7b, 0xcf, 0x04, 0x3b, 0x7b, 0x26,
+ 0xd8, 0xdd, 0x33, 0xc1, 0xab, 0x7d, 0x33, 0xb5, 0xb3, 0x6f, 0xa6, 0xbe, 0xec, 0x9b, 0xa9, 0x27,
+ 0xd7, 0x13, 0xdf, 0x68, 0xc1, 0x51, 0x0a, 0x91, 0xc7, 0xe5, 0x9d, 0xbd, 0x99, 0xf8, 0x6b, 0x94,
+ 0x1f, 0x6b, 0x6f, 0x58, 0xfe, 0xc4, 0xdd, 0xfc, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x1b, 0x3b,
+ 0x5a, 0x54, 0x0a, 0x00, 0x00,
}
func (m *BaseClaim) Marshal() (dAtA []byte, err error) {
@@ -1010,6 +1051,53 @@ func (m *SavingsClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *EarnClaim) 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 *EarnClaim) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EarnClaim) 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] = 0x12
+ }
+ }
+ {
+ size, err := m.BaseMultiClaim.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintClaims(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
func encodeVarintClaims(dAtA []byte, offset int, v uint64) int {
offset -= sovClaims(v)
base := offset
@@ -1210,6 +1298,23 @@ func (m *SavingsClaim) Size() (n int) {
return n
}
+func (m *EarnClaim) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.BaseMultiClaim.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
}
@@ -2469,6 +2574,123 @@ func (m *SavingsClaim) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *EarnClaim) 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: EarnClaim: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: EarnClaim: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field BaseMultiClaim", 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
+ }
+ if err := m.BaseMultiClaim.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ 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
diff --git a/x/incentive/types/codec.go b/x/incentive/types/codec.go
index 1f3af6b8..5e606cd5 100644
--- a/x/incentive/types/codec.go
+++ b/x/incentive/types/codec.go
@@ -17,6 +17,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgClaimDelegatorReward{}, "incentive/MsgClaimDelegatorReward", nil)
cdc.RegisterConcrete(&MsgClaimSwapReward{}, "incentive/MsgClaimSwapReward", nil)
cdc.RegisterConcrete(&MsgClaimSavingsReward{}, "incentive/MsgClaimSavingsReward", nil)
+ cdc.RegisterConcrete(&MsgClaimEarnReward{}, "incentive/MsgClaimEarnReward", nil)
}
func RegisterInterfaces(registry types.InterfaceRegistry) {
@@ -26,6 +27,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgClaimDelegatorReward{},
&MsgClaimSwapReward{},
&MsgClaimSavingsReward{},
+ &MsgClaimEarnReward{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
diff --git a/x/incentive/types/expected_keepers.go b/x/incentive/types/expected_keepers.go
index 3d9d5716..4a38486f 100644
--- a/x/incentive/types/expected_keepers.go
+++ b/x/incentive/types/expected_keepers.go
@@ -6,6 +6,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
cdptypes "github.com/kava-labs/kava/x/cdp/types"
+ earntypes "github.com/kava-labs/kava/x/earn/types"
hardtypes "github.com/kava-labs/kava/x/hard/types"
savingstypes "github.com/kava-labs/kava/x/savings/types"
)
@@ -63,6 +64,12 @@ type SavingsKeeper interface {
GetSavingsModuleAccountBalances(ctx sdk.Context) sdk.Coins
}
+// EarnKeeper defines the required methods needed by this modules keeper
+type EarnKeeper interface {
+ GetVaultTotalShares(ctx sdk.Context, denom string) (shares earntypes.VaultShare, found bool)
+ GetVaultAccountShares(ctx sdk.Context, acc sdk.AccAddress) (shares earntypes.VaultShares, found bool)
+}
+
// AccountKeeper expected interface for the account keeper (noalias)
type AccountKeeper interface {
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
diff --git a/x/incentive/types/genesis.go b/x/incentive/types/genesis.go
index 3790cad0..1955617b 100644
--- a/x/incentive/types/genesis.go
+++ b/x/incentive/types/genesis.go
@@ -15,13 +15,15 @@ var (
AccumulationTimes{},
MultiRewardIndexes{},
)
+ DefaultEarnClaims = EarnClaims{}
)
// NewGenesisState returns a new genesis state
func NewGenesisState(
params Params,
- usdxState, hardSupplyState, hardBorrowState, delegatorState, swapState, savingsState GenesisRewardState,
+ usdxState, hardSupplyState, hardBorrowState, delegatorState, swapState, savingsState, earnState GenesisRewardState,
c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims,
+ earnc EarnClaims,
) GenesisState {
return GenesisState{
Params: params,
@@ -32,12 +34,14 @@ func NewGenesisState(
DelegatorRewardState: delegatorState,
SwapRewardState: swapState,
SavingsRewardState: savingsState,
+ EarnRewardState: earnState,
USDXMintingClaims: c,
HardLiquidityProviderClaims: hc,
DelegatorClaims: dc,
SwapClaims: sc,
SavingsClaims: savingsc,
+ EarnClaims: earnc,
}
}
@@ -51,11 +55,13 @@ func DefaultGenesisState() GenesisState {
DelegatorRewardState: DefaultGenesisRewardState,
SwapRewardState: DefaultGenesisRewardState,
SavingsRewardState: DefaultGenesisRewardState,
+ EarnRewardState: DefaultGenesisRewardState,
USDXMintingClaims: DefaultUSDXClaims,
HardLiquidityProviderClaims: DefaultHardClaims,
DelegatorClaims: DefaultDelegatorClaims,
SwapClaims: DefaultSwapClaims,
SavingsClaims: DefaultSavingsClaims,
+ EarnClaims: DefaultEarnClaims,
}
}
@@ -84,6 +90,9 @@ func (gs GenesisState) Validate() error {
if err := gs.SavingsRewardState.Validate(); err != nil {
return err
}
+ if err := gs.EarnRewardState.Validate(); err != nil {
+ return err
+ }
if err := gs.USDXMintingClaims.Validate(); err != nil {
return err
@@ -97,7 +106,12 @@ func (gs GenesisState) Validate() error {
if err := gs.SwapClaims.Validate(); err != nil {
return err
}
- return gs.SavingsClaims.Validate()
+
+ if err := gs.SavingsClaims.Validate(); err != nil {
+ return err
+ }
+
+ return gs.EarnClaims.Validate()
}
// NewGenesisRewardState returns a new GenesisRewardState
diff --git a/x/incentive/types/genesis.pb.go b/x/incentive/types/genesis.pb.go
index ff2a35c3..3178c213 100644
--- a/x/incentive/types/genesis.pb.go
+++ b/x/incentive/types/genesis.pb.go
@@ -119,6 +119,8 @@ type GenesisState struct {
SwapClaims SwapClaims `protobuf:"bytes,10,rep,name=swap_claims,json=swapClaims,proto3,castrepeated=SwapClaims" json:"swap_claims"`
SavingsRewardState GenesisRewardState `protobuf:"bytes,11,opt,name=savings_reward_state,json=savingsRewardState,proto3" json:"savings_reward_state"`
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"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
@@ -165,54 +167,57 @@ func init() {
}
var fileDescriptor_8b76737885d05afd = []byte{
- // 744 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x4f, 0x13, 0x41,
- 0x14, 0xc7, 0xbb, 0x80, 0x08, 0x53, 0xa0, 0x74, 0x2c, 0x50, 0x4b, 0xb2, 0x45, 0x20, 0xda, 0x68,
- 0xdc, 0x0d, 0xf5, 0xea, 0xc5, 0x95, 0x44, 0x49, 0x24, 0x21, 0x5b, 0x34, 0xc6, 0x98, 0x34, 0xb3,
- 0xdd, 0x61, 0x19, 0xdd, 0x5f, 0xee, 0xec, 0xb6, 0xf4, 0xe6, 0xd1, 0x9b, 0xfc, 0x01, 0x26, 0xde,
- 0xfd, 0x4b, 0x38, 0x72, 0xf4, 0x04, 0x5a, 0xfe, 0x11, 0x33, 0xb3, 0xb3, 0x65, 0xb7, 0x65, 0x31,
- 0xe2, 0x6d, 0xfa, 0xe6, 0xbd, 0xef, 0xe7, 0x3b, 0xf3, 0xde, 0x76, 0xc0, 0xe6, 0x47, 0xd4, 0x45,
- 0x2a, 0x71, 0x3b, 0xd8, 0x0d, 0x49, 0x17, 0xab, 0xdd, 0x2d, 0x03, 0x87, 0x68, 0x4b, 0xb5, 0xb0,
- 0x8b, 0x29, 0xa1, 0x8a, 0x1f, 0x78, 0xa1, 0x07, 0x97, 0x59, 0x96, 0x32, 0xcc, 0x52, 0x44, 0x56,
- 0xad, 0x62, 0x79, 0x96, 0xc7, 0x53, 0x54, 0xb6, 0x8a, 0xb3, 0x6b, 0x1b, 0x39, 0x9a, 0x1d, 0x1b,
- 0x11, 0x87, 0xfe, 0x25, 0xc9, 0x47, 0x01, 0x1a, 0x26, 0xd5, 0x2d, 0xcf, 0xb3, 0x6c, 0xac, 0xf2,
- 0x5f, 0x46, 0x74, 0xa0, 0x86, 0xc4, 0xc1, 0x34, 0x44, 0x8e, 0x1f, 0x27, 0xac, 0x7f, 0x97, 0xc0,
- 0xe2, 0xb3, 0x4e, 0x27, 0x72, 0x22, 0x1b, 0x85, 0xc4, 0x73, 0xf7, 0x89, 0x83, 0xe1, 0x03, 0x50,
- 0xea, 0x78, 0xb6, 0x8d, 0x42, 0x1c, 0x20, 0xbb, 0x1d, 0xf6, 0x7d, 0x5c, 0x95, 0xd6, 0xa4, 0xc6,
- 0xac, 0xbe, 0x70, 0x19, 0xde, 0xef, 0xfb, 0x18, 0x1a, 0xa0, 0xe6, 0x07, 0xb8, 0x4b, 0xbc, 0x88,
- 0xb6, 0x51, 0x4a, 0xa5, 0xcd, 0x30, 0xd5, 0x89, 0x35, 0xa9, 0x51, 0x6c, 0xd6, 0x94, 0xd8, 0x83,
- 0x92, 0x78, 0x50, 0xf6, 0x13, 0x0f, 0xda, 0xcc, 0xc9, 0x59, 0xbd, 0x70, 0x7c, 0x5e, 0x97, 0xf4,
- 0x6a, 0xa2, 0x33, 0x6a, 0x66, 0xfd, 0xf3, 0x04, 0x80, 0x2f, 0xe2, 0xcb, 0xd4, 0x71, 0x0f, 0x05,
- 0x66, 0x2b, 0x44, 0x21, 0x86, 0x01, 0x80, 0x63, 0x44, 0x5a, 0x95, 0xd6, 0x26, 0x1b, 0xc5, 0x66,
- 0x43, 0xb9, 0xfa, 0xba, 0x95, 0x51, 0x71, 0xed, 0x2e, 0x33, 0xf0, 0xe3, 0xbc, 0x5e, 0x1e, 0xdd,
- 0xa1, 0x7a, 0x19, 0x8d, 0x86, 0x60, 0x17, 0x54, 0x9c, 0xc8, 0x0e, 0x49, 0x3b, 0xe0, 0x46, 0xda,
- 0xc4, 0x35, 0xf1, 0x11, 0xa6, 0xd5, 0x89, 0xeb, 0xa9, 0xbb, 0xac, 0x26, 0xf6, 0xbe, 0xc3, 0x2a,
- 0xb4, 0x9a, 0xa0, 0xc2, 0xd1, 0x1d, 0x4c, 0x75, 0xe8, 0x8c, 0xc5, 0xd6, 0xbf, 0x02, 0x30, 0x27,
- 0xae, 0x20, 0x3e, 0xfc, 0x53, 0x30, 0x1d, 0xb7, 0x99, 0xf7, 0xa5, 0xd8, 0x94, 0xf3, 0xd0, 0x7b,
- 0x3c, 0x4b, 0x9b, 0x62, 0x40, 0x5d, 0xd4, 0x40, 0x0f, 0x94, 0x23, 0x6a, 0x1e, 0x25, 0xa7, 0xa0,
- 0x4c, 0x52, 0x34, 0xeb, 0x61, 0x9e, 0xd0, 0x78, 0x07, 0xb4, 0x15, 0x26, 0x3a, 0x38, 0xab, 0x97,
- 0x5e, 0xb7, 0xb6, 0xdf, 0xa6, 0x36, 0xf4, 0x12, 0x53, 0x4f, 0xf7, 0x8a, 0x80, 0xea, 0x21, 0x27,
- 0x45, 0xbe, 0x6f, 0xf7, 0xb3, 0xdc, 0xc9, 0x7f, 0xe6, 0xc6, 0x87, 0x59, 0x62, 0x8a, 0x2d, 0x2e,
- 0x78, 0x15, 0xca, 0xf0, 0x82, 0xc0, 0xeb, 0x65, 0x51, 0x53, 0xff, 0x83, 0xd2, 0xb8, 0x60, 0x1a,
- 0x75, 0x00, 0x96, 0x4d, 0x6c, 0x63, 0x0b, 0x85, 0x5e, 0x90, 0x05, 0xdd, 0xba, 0x21, 0xa8, 0x32,
- 0xd4, 0x4b, 0x73, 0xde, 0x83, 0x32, 0xed, 0x21, 0x3f, 0x8b, 0x98, 0xbe, 0x21, 0xa2, 0xc4, 0xa4,
- 0xd2, 0xea, 0x5f, 0x24, 0x70, 0x87, 0x4f, 0x83, 0x43, 0xdc, 0x90, 0xb8, 0x56, 0x3b, 0xfe, 0x93,
- 0xa9, 0xde, 0xbe, 0x7e, 0xa6, 0x59, 0xcf, 0x77, 0xe3, 0x8a, 0xe7, 0xac, 0x40, 0x53, 0xc4, 0x34,
- 0x94, 0x47, 0x77, 0x28, 0xfb, 0xbc, 0xc6, 0x82, 0x3a, 0x1f, 0xc1, 0x4c, 0x08, 0x7e, 0x93, 0x80,
- 0xcc, 0x9b, 0x67, 0x93, 0x4f, 0x11, 0x31, 0x49, 0xd8, 0x6f, 0xfb, 0x81, 0xd7, 0x25, 0x26, 0x0e,
- 0x12, 0x57, 0x33, 0xdc, 0x55, 0x33, 0xcf, 0xd5, 0x4b, 0x14, 0x98, 0xaf, 0x92, 0xe2, 0x3d, 0x51,
- 0x1b, 0xfb, 0xdb, 0x10, 0xdf, 0xdc, 0x6a, 0x7e, 0x0e, 0xd5, 0x57, 0x0f, 0xf3, 0x37, 0xe1, 0x07,
- 0xb0, 0x78, 0xd9, 0x6f, 0xe1, 0x67, 0x96, 0xfb, 0xb9, 0x9f, 0xe7, 0x67, 0x3b, 0xc9, 0x8f, 0x3d,
- 0xac, 0x08, 0x0f, 0xa5, 0x6c, 0x9c, 0xea, 0x25, 0x33, 0x1b, 0x80, 0x6f, 0x40, 0x91, 0xf7, 0x5c,
- 0x60, 0x00, 0xc7, 0xdc, 0xcb, 0xc3, 0xb4, 0x7a, 0xc8, 0x8f, 0x09, 0x50, 0x10, 0xc0, 0x30, 0x44,
- 0x75, 0x40, 0x87, 0x6b, 0x68, 0x80, 0x0a, 0x45, 0x5d, 0xe2, 0x5a, 0x34, 0x3b, 0x4e, 0xc5, 0x1b,
- 0x8e, 0x13, 0x14, 0x6a, 0xe9, 0x89, 0x32, 0xc0, 0x42, 0xc2, 0x10, 0xf6, 0xe7, 0xb8, 0xfd, 0xcd,
- 0x5c, 0xfb, 0x71, 0x76, 0x7c, 0x82, 0x25, 0x71, 0x82, 0xf9, 0x74, 0x94, 0xea, 0xf3, 0x34, 0xfd,
- 0x53, 0xdb, 0x39, 0xf9, 0x2d, 0x17, 0x4e, 0x06, 0xb2, 0x74, 0x3a, 0x90, 0xa5, 0x5f, 0x03, 0x59,
- 0x3a, 0xbe, 0x90, 0x0b, 0xa7, 0x17, 0x72, 0xe1, 0xe7, 0x85, 0x5c, 0x78, 0xf7, 0xc8, 0x22, 0xe1,
- 0x61, 0x64, 0x28, 0x1d, 0xcf, 0x51, 0x19, 0xf3, 0xb1, 0x8d, 0x0c, 0xca, 0x57, 0xea, 0x51, 0xea,
- 0xc5, 0x64, 0x0f, 0x1b, 0x35, 0xa6, 0xf9, 0xbb, 0xf4, 0xe4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xfd, 0x2b, 0xb5, 0x5f, 0xc9, 0x07, 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, 0xb6,
+ 0x72, 0x34, 0x3b, 0x36, 0x22, 0x0e, 0xfd, 0x49, 0x92, 0x8f, 0x02, 0x34, 0x4c, 0xaa, 0x5b, 0x9e,
+ 0x67, 0xd9, 0x58, 0xe5, 0xbf, 0x8c, 0xe8, 0x58, 0x0d, 0x89, 0x83, 0x69, 0x88, 0x1c, 0x3f, 0x4e,
+ 0xd8, 0xfc, 0x24, 0x81, 0xe5, 0x47, 0x9d, 0x4e, 0xe4, 0x44, 0x36, 0x0a, 0x89, 0xe7, 0x1e, 0x12,
+ 0x07, 0xc3, 0xff, 0x40, 0xa9, 0xe3, 0xd9, 0x36, 0x0a, 0x71, 0x80, 0xec, 0x76, 0xd8, 0xf7, 0x71,
+ 0x55, 0xda, 0x90, 0x1a, 0xf3, 0xfa, 0xd2, 0x4d, 0xf8, 0xb0, 0xef, 0x63, 0x68, 0x80, 0x9a, 0x1f,
+ 0xe0, 0x2e, 0xf1, 0x22, 0xda, 0x46, 0x29, 0x95, 0x36, 0xc3, 0x54, 0xa7, 0x36, 0xa4, 0x46, 0xb1,
+ 0x59, 0x53, 0x62, 0x0f, 0x4a, 0xe2, 0x41, 0x39, 0x4c, 0x3c, 0x68, 0x73, 0xe7, 0x97, 0xf5, 0xc2,
+ 0xd9, 0x55, 0x5d, 0xd2, 0xab, 0x89, 0xce, 0xa8, 0x99, 0xcd, 0xf7, 0x53, 0x00, 0x3e, 0x8d, 0x2f,
+ 0x53, 0xc7, 0x3d, 0x14, 0x98, 0xad, 0x10, 0x85, 0x18, 0x06, 0x00, 0x8e, 0x11, 0x69, 0x55, 0xda,
+ 0x98, 0x6e, 0x14, 0x9b, 0x0d, 0xe5, 0xf6, 0xeb, 0x56, 0x46, 0xc5, 0xb5, 0xbf, 0x99, 0x81, 0xcf,
+ 0x57, 0xf5, 0xf2, 0xe8, 0x0e, 0xd5, 0xcb, 0x68, 0x34, 0x04, 0xbb, 0xa0, 0xe2, 0x44, 0x76, 0x48,
+ 0xda, 0x01, 0x37, 0xd2, 0x26, 0xae, 0x89, 0x4f, 0x31, 0xad, 0x4e, 0xdd, 0x4d, 0xdd, 0x67, 0x67,
+ 0x62, 0xef, 0x7b, 0xec, 0x84, 0x56, 0x13, 0x54, 0x38, 0xba, 0x83, 0xa9, 0x0e, 0x9d, 0xb1, 0xd8,
+ 0xe6, 0x97, 0x22, 0x58, 0x10, 0x57, 0x10, 0x17, 0xff, 0x10, 0xcc, 0xc6, 0x6d, 0xe6, 0x7d, 0x29,
+ 0x36, 0xe5, 0x3c, 0xf4, 0x01, 0xcf, 0xd2, 0x66, 0x18, 0x50, 0x17, 0x67, 0xa0, 0x07, 0xca, 0x11,
+ 0x35, 0x4f, 0x93, 0x2a, 0x28, 0x93, 0x14, 0xcd, 0xfa, 0x3f, 0x4f, 0x68, 0xbc, 0x03, 0xda, 0x1a,
+ 0x13, 0x1d, 0x5c, 0xd6, 0x4b, 0x2f, 0x5a, 0xbb, 0x2f, 0x53, 0x1b, 0x7a, 0x89, 0xa9, 0xa7, 0x7b,
+ 0x45, 0x40, 0xf5, 0x84, 0x93, 0x22, 0xdf, 0xb7, 0xfb, 0x59, 0xee, 0xf4, 0x2f, 0x73, 0xe3, 0x62,
+ 0x56, 0x98, 0x62, 0x8b, 0x0b, 0xde, 0x86, 0x32, 0xbc, 0x20, 0xf0, 0x7a, 0x59, 0xd4, 0xcc, 0xef,
+ 0xa0, 0x34, 0x2e, 0x98, 0x46, 0x1d, 0x83, 0x55, 0x13, 0xdb, 0xd8, 0x42, 0xa1, 0x17, 0x64, 0x41,
+ 0x7f, 0x4c, 0x08, 0xaa, 0x0c, 0xf5, 0xd2, 0x9c, 0xd7, 0xa0, 0x4c, 0x7b, 0xc8, 0xcf, 0x22, 0x66,
+ 0x27, 0x44, 0x94, 0x98, 0x54, 0x5a, 0xfd, 0x83, 0x04, 0xfe, 0xe2, 0xd3, 0xe0, 0x10, 0x37, 0x24,
+ 0xae, 0xd5, 0x8e, 0xff, 0x64, 0xaa, 0x7f, 0xde, 0x3d, 0xd3, 0xac, 0xe7, 0xfb, 0xf1, 0x89, 0xc7,
+ 0xec, 0x80, 0xa6, 0x88, 0x69, 0x28, 0x8f, 0xee, 0x50, 0xf6, 0xbc, 0xc6, 0x82, 0x3a, 0x1f, 0xc1,
+ 0x4c, 0x08, 0x7e, 0x94, 0x80, 0xcc, 0x9b, 0x67, 0x93, 0x77, 0x11, 0x31, 0x49, 0xd8, 0x6f, 0xfb,
+ 0x81, 0xd7, 0x25, 0x26, 0x0e, 0x12, 0x57, 0x73, 0xdc, 0x55, 0x33, 0xcf, 0xd5, 0x33, 0x14, 0x98,
+ 0xcf, 0x93, 0xc3, 0x07, 0xe2, 0x6c, 0xec, 0x6f, 0x4b, 0xbc, 0xb9, 0xf5, 0xfc, 0x1c, 0xaa, 0xaf,
+ 0x9f, 0xe4, 0x6f, 0xc2, 0x37, 0x60, 0xf9, 0xa6, 0xdf, 0xc2, 0xcf, 0x3c, 0xf7, 0xf3, 0x6f, 0x9e,
+ 0x9f, 0xdd, 0x24, 0x3f, 0xf6, 0xb0, 0x26, 0x3c, 0x94, 0xb2, 0x71, 0xaa, 0x97, 0xcc, 0x6c, 0x00,
+ 0x1e, 0x81, 0x22, 0xef, 0xb9, 0xc0, 0x00, 0x8e, 0xf9, 0x27, 0x0f, 0xd3, 0xea, 0x21, 0x3f, 0x26,
+ 0x40, 0x41, 0x00, 0xc3, 0x10, 0xd5, 0x01, 0x1d, 0xae, 0xa1, 0x01, 0x2a, 0x14, 0x75, 0x89, 0x6b,
+ 0xd1, 0xec, 0x38, 0x15, 0x27, 0x1c, 0x27, 0x28, 0xd4, 0xd2, 0x13, 0x65, 0x80, 0xa5, 0x84, 0x21,
+ 0xec, 0x2f, 0x70, 0xfb, 0xdb, 0xb9, 0xf6, 0xe3, 0xec, 0xb8, 0x82, 0x15, 0x51, 0xc1, 0x62, 0x3a,
+ 0x4a, 0xf5, 0x45, 0x9a, 0xfe, 0xc9, 0xde, 0x04, 0x46, 0x81, 0x9b, 0x2d, 0x62, 0x71, 0xd2, 0x37,
+ 0xc1, 0xa4, 0xd2, 0x15, 0x1c, 0x81, 0x22, 0x57, 0x17, 0xf6, 0x97, 0xee, 0xbe, 0xfd, 0x27, 0x28,
+ 0x70, 0x47, 0x6e, 0x7f, 0x18, 0xa2, 0x3a, 0xc0, 0xc3, 0xb5, 0xb6, 0x77, 0xfe, 0x5d, 0x2e, 0x9c,
+ 0x0f, 0x64, 0xe9, 0x62, 0x20, 0x4b, 0xdf, 0x06, 0xb2, 0x74, 0x76, 0x2d, 0x17, 0x2e, 0xae, 0xe5,
+ 0xc2, 0xd7, 0x6b, 0xb9, 0xf0, 0xea, 0x9e, 0x45, 0xc2, 0x93, 0xc8, 0x50, 0x3a, 0x9e, 0xa3, 0x32,
+ 0xd4, 0x7d, 0x1b, 0x19, 0x94, 0xaf, 0xd4, 0xd3, 0xd4, 0x77, 0x9e, 0x7d, 0x8e, 0xa9, 0x31, 0xcb,
+ 0xbf, 0xa6, 0x0f, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0x40, 0x8f, 0xb7, 0x18, 0x7f, 0x08, 0x00,
+ 0x00,
}
func (m *AccumulationTime) Marshal() (dAtA []byte, err error) {
@@ -324,6 +329,30 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.EarnClaims) > 0 {
+ for iNdEx := len(m.EarnClaims) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.EarnClaims[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x72
+ }
+ }
+ {
+ size, err := m.EarnRewardState.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenesis(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x6a
if len(m.SavingsClaims) > 0 {
for iNdEx := len(m.SavingsClaims) - 1; iNdEx >= 0; iNdEx-- {
{
@@ -564,6 +593,14 @@ func (m *GenesisState) Size() (n int) {
n += 1 + l + sovGenesis(uint64(l))
}
}
+ l = m.EarnRewardState.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ if len(m.EarnClaims) > 0 {
+ for _, e := range m.EarnClaims {
+ l = e.Size()
+ n += 1 + l + sovGenesis(uint64(l))
+ }
+ }
return n
}
@@ -1236,6 +1273,73 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 13:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EarnRewardState", 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 := m.EarnRewardState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 14:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EarnClaims", 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.EarnClaims = append(m.EarnClaims, EarnClaim{})
+ if err := m.EarnClaims[len(m.EarnClaims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
diff --git a/x/incentive/types/genesis_test.go b/x/incentive/types/genesis_test.go
index 87a70bad..c3fa9f8f 100644
--- a/x/incentive/types/genesis_test.go
+++ b/x/incentive/types/genesis_test.go
@@ -46,6 +46,7 @@ func TestGenesisState_Validate(t *testing.T) {
DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
+ DefaultMultiRewardPeriods,
MultipliersPerDenoms{
{
Denom: "ukava",
diff --git a/x/incentive/types/keys.go b/x/incentive/types/keys.go
index f3caca0f..db921b3d 100644
--- a/x/incentive/types/keys.go
+++ b/x/incentive/types/keys.go
@@ -36,4 +36,7 @@ var (
SavingsClaimKeyPrefix = []byte{0x15} // prefix for keys that store savings claims
SavingsRewardIndexesKeyPrefix = []byte{0x16} // prefix for key that stores savings reward indexes
PreviousSavingsRewardAccrualTimeKeyPrefix = []byte{0x17} // prefix for key that stores the previous time savings rewards accrued
+ 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
)
diff --git a/x/incentive/types/msg.go b/x/incentive/types/msg.go
index 4b0578d1..bcaa1b66 100644
--- a/x/incentive/types/msg.go
+++ b/x/incentive/types/msg.go
@@ -3,18 +3,35 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+ "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
const MaxDenomsToClaim = 1000
// ensure Msg interface compliance at compile time
-var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
-
var (
+ _ sdk.Msg = &MsgClaimUSDXMintingReward{}
_ sdk.Msg = &MsgClaimHardReward{}
_ sdk.Msg = &MsgClaimDelegatorReward{}
_ sdk.Msg = &MsgClaimSwapReward{}
_ sdk.Msg = &MsgClaimSavingsReward{}
+ _ sdk.Msg = &MsgClaimEarnReward{}
+
+ _ legacytx.LegacyMsg = &MsgClaimUSDXMintingReward{}
+ _ legacytx.LegacyMsg = &MsgClaimHardReward{}
+ _ legacytx.LegacyMsg = &MsgClaimDelegatorReward{}
+ _ legacytx.LegacyMsg = &MsgClaimSwapReward{}
+ _ legacytx.LegacyMsg = &MsgClaimSavingsReward{}
+ _ legacytx.LegacyMsg = &MsgClaimEarnReward{}
+)
+
+const (
+ TypeMsgClaimUSDXMintingReward = "claim_usdx_minting_reward"
+ TypeMsgClaimHardReward = "claim_hard_reward"
+ TypeMsgClaimDelegatorReward = "claim_delegator_reward"
+ TypeMsgClaimSwapReward = "claim_swap_reward"
+ TypeMsgClaimSavingsReward = "claim_savings_reward"
+ TypeMsgClaimEarnReward = "claim_earn_reward"
)
// NewMsgClaimUSDXMintingReward returns a new MsgClaimUSDXMintingReward.
@@ -29,7 +46,7 @@ func NewMsgClaimUSDXMintingReward(sender string, multiplierName string) MsgClaim
func (msg MsgClaimUSDXMintingReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags.
-func (msg MsgClaimUSDXMintingReward) Type() string { return "claim_usdx_minting_reward" }
+func (msg MsgClaimUSDXMintingReward) Type() string { return TypeMsgClaimUSDXMintingReward }
// ValidateBasic does a simple validation check that doesn't require access to state.
func (msg MsgClaimUSDXMintingReward) ValidateBasic() error {
@@ -71,7 +88,7 @@ func (msg MsgClaimHardReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimHardReward) Type() string {
- return "claim_hard_reward"
+ return TypeMsgClaimHardReward
}
// ValidateBasic does a simple validation check that doesn't require access to state.
@@ -114,7 +131,7 @@ func (msg MsgClaimDelegatorReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimDelegatorReward) Type() string {
- return "claim_delegator_reward"
+ return TypeMsgClaimDelegatorReward
}
// ValidateBasic does a simple validation check that doesn't require access to state.
@@ -157,7 +174,7 @@ func (msg MsgClaimSwapReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimSwapReward) Type() string {
- return "claim_swap_reward"
+ return TypeMsgClaimSwapReward
}
// ValidateBasic does a simple validation check that doesn't require access to state.
@@ -200,7 +217,7 @@ func (msg MsgClaimSavingsReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimSavingsReward) Type() string {
- return "claim_savings_reward"
+ return TypeMsgClaimSavingsReward
}
// ValidateBasic does a simple validation check that doesn't require access to state.
@@ -229,3 +246,46 @@ func (msg MsgClaimSavingsReward) GetSigners() []sdk.AccAddress {
}
return []sdk.AccAddress{sender}
}
+
+// NewMsgClaimEarnReward returns a new MsgClaimEarnReward.
+func NewMsgClaimEarnReward(sender string, denomsToClaim Selections) MsgClaimEarnReward {
+ return MsgClaimEarnReward{
+ Sender: sender,
+ DenomsToClaim: denomsToClaim,
+ }
+}
+
+// Route return the message type used for routing the message.
+func (msg MsgClaimEarnReward) Route() string { return RouterKey }
+
+// Type returns a human-readable string for the message, intended for utilization within tags.
+func (msg MsgClaimEarnReward) Type() string {
+ return TypeMsgClaimEarnReward
+}
+
+// ValidateBasic does a simple validation check that doesn't require access to state.
+func (msg MsgClaimEarnReward) ValidateBasic() error {
+ _, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty or invalid")
+ }
+ if err := msg.DenomsToClaim.Validate(); err != nil {
+ return err
+ }
+ return nil
+}
+
+// GetSignBytes gets the canonical byte representation of the Msg.
+func (msg MsgClaimEarnReward) GetSignBytes() []byte {
+ bz := ModuleCdc.MustMarshalJSON(&msg)
+ return sdk.MustSortJSON(bz)
+}
+
+// GetSigners returns the addresses of signers that must sign.
+func (msg MsgClaimEarnReward) GetSigners() []sdk.AccAddress {
+ sender, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+ panic(err)
+ }
+ return []sdk.AccAddress{sender}
+}
diff --git a/x/incentive/types/params.go b/x/incentive/types/params.go
index 62394944..05184a7f 100644
--- a/x/incentive/types/params.go
+++ b/x/incentive/types/params.go
@@ -21,6 +21,7 @@ var (
KeyDelegatorRewardPeriods = []byte("DelegatorRewardPeriods")
KeySwapRewardPeriods = []byte("SwapRewardPeriods")
KeySavingsRewardPeriods = []byte("SavingsRewardPeriods")
+ KeyEarnRewardPeriods = []byte("EarnRewardPeriods")
KeyClaimEnd = []byte("ClaimEnd")
KeyMultipliers = []byte("ClaimMultipliers")
@@ -37,8 +38,12 @@ var (
)
// NewParams returns a new params object
-func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow, delegator, swap,
- savings MultiRewardPeriods, multipliers MultipliersPerDenoms, claimEnd time.Time,
+func NewParams(
+ usdxMinting RewardPeriods,
+ // MultiRewardPeriods
+ hardSupply, hardBorrow, delegator, swap, savings, earn MultiRewardPeriods,
+ multipliers MultipliersPerDenoms,
+ claimEnd time.Time,
) Params {
return Params{
USDXMintingRewardPeriods: usdxMinting,
@@ -61,6 +66,7 @@ func DefaultParams() Params {
DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
+ DefaultMultiRewardPeriods,
DefaultMultipliers,
DefaultClaimEnd,
)
@@ -80,6 +86,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(KeyDelegatorRewardPeriods, &p.DelegatorRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeySwapRewardPeriods, &p.SwapRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeySavingsRewardPeriods, &p.SavingsRewardPeriods, validateMultiRewardPeriodsParam),
+ paramtypes.NewParamSetPair(KeyEarnRewardPeriods, &p.EarnRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersPerDenomParam),
paramtypes.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
}
@@ -115,6 +122,10 @@ func (p Params) Validate() error {
return err
}
+ if err := validateMultiRewardPeriodsParam(p.EarnRewardPeriods); err != nil {
+ return err
+ }
+
return nil
}
diff --git a/x/incentive/types/params.pb.go b/x/incentive/types/params.pb.go
index 6c45105c..69582b02 100644
--- a/x/incentive/types/params.pb.go
+++ b/x/incentive/types/params.pb.go
@@ -202,6 +202,7 @@ type Params struct {
ClaimMultipliers MultipliersPerDenoms `protobuf:"bytes,6,rep,name=claim_multipliers,json=claimMultipliers,proto3,castrepeated=MultipliersPerDenoms" json:"claim_multipliers"`
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"`
}
func (m *Params) Reset() { *m = Params{} }
@@ -250,55 +251,56 @@ func init() {
}
var fileDescriptor_bb8833f5d745eac9 = []byte{
- // 760 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x96, 0x4f, 0x4f, 0x13, 0x4f,
- 0x18, 0xc7, 0xbb, 0xfd, 0x47, 0x19, 0xe0, 0xf7, 0x83, 0xa1, 0xa9, 0x6b, 0x35, 0x5b, 0x52, 0x8c,
- 0xd6, 0x10, 0x76, 0x45, 0x13, 0x0f, 0xde, 0x5c, 0xd1, 0xc4, 0x44, 0x12, 0xb2, 0x60, 0xa2, 0x5e,
- 0x9a, 0xe9, 0xee, 0xb0, 0x6c, 0xd8, 0xdd, 0xd9, 0xcc, 0x4c, 0x0b, 0x8d, 0x07, 0x13, 0x0f, 0xde,
- 0x4c, 0x88, 0x07, 0x5f, 0x04, 0x6f, 0xc3, 0x0b, 0x47, 0x8e, 0x46, 0x13, 0xd0, 0xf2, 0x46, 0xcc,
- 0xcc, 0x2e, 0x74, 0x5b, 0x0b, 0x4a, 0xd2, 0x8b, 0x27, 0x66, 0x9e, 0x79, 0x9e, 0xe7, 0xf3, 0x9d,
- 0x2f, 0xfb, 0x4c, 0x0a, 0x16, 0x77, 0x50, 0x07, 0x19, 0x5e, 0x68, 0xe3, 0x90, 0x7b, 0x1d, 0x6c,
- 0x74, 0x56, 0x5a, 0x98, 0xa3, 0x15, 0x23, 0x42, 0x14, 0x05, 0x4c, 0x8f, 0x28, 0xe1, 0x04, 0x56,
- 0x44, 0x92, 0x7e, 0x9e, 0xa4, 0x27, 0x49, 0xd5, 0xb2, 0x4b, 0x5c, 0x22, 0x53, 0x0c, 0xb1, 0x8a,
- 0xb3, 0xab, 0x35, 0x97, 0x10, 0xd7, 0xc7, 0x86, 0xdc, 0xb5, 0xda, 0x5b, 0x06, 0xf7, 0x02, 0xcc,
- 0x38, 0x0a, 0xa2, 0x24, 0x41, 0xb3, 0x09, 0x0b, 0x08, 0x33, 0x5a, 0x88, 0xf5, 0x81, 0x36, 0xf1,
- 0xc2, 0xf8, 0xbc, 0xfe, 0x29, 0x0b, 0xa6, 0x2d, 0xbc, 0x8b, 0xa8, 0xb3, 0x8e, 0xa9, 0x47, 0x1c,
- 0x58, 0x01, 0x45, 0x64, 0x0b, 0xb2, 0xaa, 0x2c, 0x28, 0x8d, 0x92, 0x95, 0xec, 0xe0, 0x1d, 0xf0,
- 0xbf, 0x4d, 0x7c, 0x1f, 0x71, 0x4c, 0x91, 0xdf, 0xe4, 0xdd, 0x08, 0xab, 0xd9, 0x05, 0xa5, 0x31,
- 0x69, 0xfd, 0xd7, 0x0f, 0x6f, 0x76, 0x23, 0x0c, 0x1f, 0x81, 0x02, 0xe3, 0x88, 0x72, 0x35, 0xb7,
- 0xa0, 0x34, 0xa6, 0xee, 0x57, 0xf5, 0x58, 0xa2, 0x7e, 0x26, 0x51, 0xdf, 0x3c, 0x93, 0x68, 0x96,
- 0x0e, 0x8f, 0x6b, 0x99, 0xfd, 0x93, 0x9a, 0x62, 0xc5, 0x25, 0xf0, 0x21, 0xc8, 0xe1, 0xd0, 0x51,
- 0xf3, 0x57, 0xa8, 0x14, 0x05, 0x70, 0x0d, 0x40, 0x2a, 0x2f, 0xc1, 0x9a, 0x11, 0xa6, 0x4d, 0x86,
- 0x6d, 0x12, 0x3a, 0x6a, 0x41, 0xb6, 0xb9, 0xae, 0xc7, 0x16, 0xe8, 0xc2, 0x82, 0x33, 0x3b, 0xf5,
- 0x27, 0xc4, 0x0b, 0xcd, 0xbc, 0xe8, 0x62, 0xcd, 0x26, 0xa5, 0xeb, 0x98, 0x6e, 0xc8, 0xc2, 0xfa,
- 0x97, 0x2c, 0x98, 0x5b, 0x6b, 0xfb, 0xdc, 0xfb, 0xf7, 0x9d, 0xe9, 0x5e, 0xe0, 0x4c, 0xee, 0x72,
- 0x67, 0xee, 0x89, 0x2e, 0x07, 0x27, 0xb5, 0x86, 0xeb, 0xf1, 0xed, 0x76, 0x4b, 0xb7, 0x49, 0x60,
- 0x24, 0x5f, 0x52, 0xfc, 0x67, 0x99, 0x39, 0x3b, 0x86, 0xb8, 0x2b, 0x93, 0x05, 0x6c, 0x84, 0x8b,
- 0x1f, 0x15, 0x00, 0xa4, 0x8b, 0x91, 0xef, 0x61, 0x0a, 0x21, 0xc8, 0x87, 0x28, 0x88, 0xcd, 0x9b,
- 0xb4, 0xe4, 0x1a, 0x2e, 0x82, 0x99, 0x80, 0x84, 0x7c, 0x9b, 0x35, 0x7d, 0x62, 0xef, 0xb4, 0x23,
- 0x69, 0x5c, 0xce, 0x9a, 0x8e, 0x83, 0x2f, 0x64, 0x0c, 0x3e, 0x03, 0xc5, 0x2d, 0x64, 0x73, 0x42,
- 0xa5, 0x6f, 0xd3, 0xa6, 0x2e, 0xb4, 0x7d, 0x3b, 0xae, 0xdd, 0xfe, 0x0b, 0x6d, 0xab, 0xd8, 0xb6,
- 0x92, 0xea, 0xfa, 0x07, 0x05, 0xcc, 0xf7, 0xf5, 0x08, 0xa1, 0xab, 0x38, 0x24, 0x01, 0x2c, 0x83,
- 0x82, 0x23, 0x16, 0x89, 0xb2, 0x78, 0x03, 0x5f, 0x83, 0xa9, 0xa0, 0x9f, 0xac, 0x66, 0xa5, 0x63,
- 0x75, 0x7d, 0xf4, 0x74, 0xea, 0xfd, 0xbe, 0xe6, 0x7c, 0x62, 0xdd, 0x54, 0x8a, 0x65, 0xa5, 0x7b,
- 0xd5, 0xbf, 0x4f, 0x80, 0xe2, 0xba, 0x9c, 0x79, 0xf8, 0x59, 0x01, 0x37, 0xda, 0xcc, 0xd9, 0x6b,
- 0x06, 0x5e, 0xc8, 0xbd, 0xd0, 0x6d, 0xc6, 0x2e, 0x8a, 0xff, 0x95, 0x47, 0x1c, 0xa6, 0x2a, 0x12,
- 0x7b, 0xeb, 0x22, 0x6c, 0xfa, 0xfb, 0x34, 0x57, 0x04, 0xb8, 0x77, 0x5c, 0x53, 0x5f, 0x6e, 0xac,
- 0xbe, 0x5a, 0x8b, 0xfb, 0xa5, 0x13, 0xd8, 0xc1, 0x49, 0x6d, 0x66, 0x20, 0x60, 0xa9, 0x82, 0x3d,
- 0x2a, 0x15, 0xbe, 0x57, 0x40, 0x75, 0x5b, 0x28, 0x61, 0xed, 0x28, 0xf2, 0xbb, 0xc3, 0xba, 0x62,
- 0x3b, 0xee, 0x5e, 0x6a, 0xc7, 0x80, 0xb8, 0x6a, 0xe2, 0x0a, 0xfc, 0xed, 0x88, 0x59, 0xd7, 0x04,
- 0x68, 0x43, 0x72, 0x2e, 0x10, 0xd1, 0x22, 0x94, 0x92, 0xdd, 0x61, 0x11, 0xb9, 0xb1, 0x8b, 0x30,
- 0x25, 0x67, 0x50, 0xc4, 0x3b, 0xa0, 0x3a, 0xd8, 0xc7, 0x2e, 0xe2, 0x84, 0x0e, 0x2b, 0xc8, 0x8f,
- 0x53, 0x41, 0xe5, 0x1c, 0x33, 0x28, 0xa0, 0x0d, 0xe6, 0xd9, 0x2e, 0x8a, 0x86, 0xd9, 0x85, 0x71,
- 0xb2, 0xe7, 0x04, 0x61, 0x10, 0xdb, 0x01, 0x73, 0xb6, 0x8f, 0xbc, 0xa0, 0x99, 0x1e, 0x83, 0xa2,
- 0x84, 0x2e, 0xfd, 0x79, 0x0c, 0xce, 0xc7, 0xcb, 0xbc, 0x99, 0x60, 0xcb, 0x23, 0x0e, 0x99, 0x35,
- 0x2b, 0x19, 0xa9, 0x23, 0xf8, 0x18, 0x4c, 0xc6, 0x5c, 0xf1, 0xde, 0x4d, 0x5c, 0xe1, 0xbd, 0x2b,
- 0xc9, 0xb2, 0xa7, 0xa1, 0x03, 0xdf, 0x82, 0x0a, 0x43, 0x1d, 0x2f, 0x74, 0xd9, 0xb0, 0x69, 0xa5,
- 0x71, 0x9a, 0x56, 0x4e, 0x20, 0x03, 0x51, 0xf3, 0xf9, 0xe1, 0x4f, 0x2d, 0x73, 0xd8, 0xd3, 0x94,
- 0xa3, 0x9e, 0xa6, 0xfc, 0xe8, 0x69, 0xca, 0xfe, 0xa9, 0x96, 0x39, 0x3a, 0xd5, 0x32, 0x5f, 0x4f,
- 0xb5, 0xcc, 0x9b, 0xa5, 0xd4, 0xa3, 0x25, 0x44, 0x2c, 0xfb, 0xa8, 0xc5, 0xe4, 0xca, 0xd8, 0x4b,
- 0xfd, 0x34, 0x90, 0xaf, 0x57, 0xab, 0x28, 0xef, 0xfb, 0xe0, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x8f, 0x22, 0xdc, 0x69, 0x39, 0x08, 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, 0x55, 0x5c, 0xe2, 0x12, 0x99, 0x62,
+ 0x88, 0x55, 0x9c, 0x5d, 0xab, 0xbb, 0x84, 0xb8, 0x3e, 0x36, 0xe4, 0x53, 0xbb, 0xb3, 0x65, 0x70,
+ 0x2f, 0xc0, 0x8c, 0xa3, 0x20, 0x4a, 0x12, 0x34, 0x9b, 0xb0, 0x80, 0x30, 0xa3, 0x8d, 0xd8, 0x00,
+ 0x68, 0x13, 0x2f, 0x8c, 0xf7, 0x1b, 0x1f, 0xb3, 0x60, 0xda, 0xc2, 0xbb, 0x88, 0x3a, 0xeb, 0x98,
+ 0x7a, 0xc4, 0x81, 0x55, 0x50, 0x44, 0xb6, 0x20, 0xab, 0xca, 0x82, 0xd2, 0x2c, 0x59, 0xc9, 0x13,
+ 0xbc, 0x0d, 0xfe, 0xb1, 0x89, 0xef, 0x23, 0x8e, 0x29, 0xf2, 0x5b, 0xbc, 0x17, 0x61, 0x35, 0xbb,
+ 0xa0, 0x34, 0xcb, 0xd6, 0xdf, 0x83, 0xf0, 0x66, 0x2f, 0xc2, 0xf0, 0x21, 0x28, 0x30, 0x8e, 0x28,
+ 0x57, 0x73, 0x0b, 0x4a, 0x73, 0xea, 0x5e, 0x4d, 0x8f, 0x25, 0xea, 0x67, 0x12, 0xf5, 0xcd, 0x33,
+ 0x89, 0x66, 0xe9, 0xf0, 0xb8, 0x9e, 0xd9, 0x3f, 0xa9, 0x2b, 0x56, 0x5c, 0x02, 0x1f, 0x80, 0x1c,
+ 0x0e, 0x1d, 0x35, 0x7f, 0x8d, 0x4a, 0x51, 0x00, 0xd7, 0x00, 0xa4, 0xf2, 0x25, 0x58, 0x2b, 0xc2,
+ 0xb4, 0xc5, 0xb0, 0x4d, 0x42, 0x47, 0x2d, 0xc8, 0x36, 0xff, 0xe9, 0xb1, 0x05, 0xba, 0xb0, 0xe0,
+ 0xcc, 0x4e, 0xfd, 0x31, 0xf1, 0x42, 0x33, 0x2f, 0xba, 0x58, 0xb3, 0x49, 0xe9, 0x3a, 0xa6, 0x1b,
+ 0xb2, 0xb0, 0xf1, 0x39, 0x0b, 0xe6, 0xd6, 0x3a, 0x3e, 0xf7, 0xfe, 0x7c, 0x67, 0x7a, 0x97, 0x38,
+ 0x93, 0xbb, 0xda, 0x99, 0xbb, 0xa2, 0xcb, 0xc1, 0x49, 0xbd, 0xe9, 0x7a, 0x7c, 0xbb, 0xd3, 0xd6,
+ 0x6d, 0x12, 0x18, 0xc9, 0x97, 0x14, 0xff, 0x2c, 0x33, 0x67, 0xc7, 0x10, 0xef, 0xca, 0x64, 0x01,
+ 0x1b, 0xe3, 0xe2, 0x07, 0x05, 0x00, 0xe9, 0x62, 0xe4, 0x7b, 0x98, 0x42, 0x08, 0xf2, 0x21, 0x0a,
+ 0x62, 0xf3, 0xca, 0x96, 0x5c, 0xc3, 0x45, 0x30, 0x13, 0x90, 0x90, 0x6f, 0xb3, 0x96, 0x4f, 0xec,
+ 0x9d, 0x4e, 0x24, 0x8d, 0xcb, 0x59, 0xd3, 0x71, 0xf0, 0xb9, 0x8c, 0xc1, 0xa7, 0xa0, 0xb8, 0x85,
+ 0x6c, 0x4e, 0xa8, 0xf4, 0x6d, 0xda, 0xd4, 0x85, 0xb6, 0x6f, 0xc7, 0xf5, 0x5b, 0xbf, 0xa1, 0x6d,
+ 0x15, 0xdb, 0x56, 0x52, 0xdd, 0x78, 0xaf, 0x80, 0xf9, 0x81, 0x1e, 0x21, 0x74, 0x15, 0x87, 0x24,
+ 0x80, 0x15, 0x50, 0x70, 0xc4, 0x22, 0x51, 0x16, 0x3f, 0xc0, 0x57, 0x60, 0x2a, 0x18, 0x24, 0xab,
+ 0x59, 0xe9, 0x58, 0x43, 0x1f, 0x3f, 0x9d, 0xfa, 0xa0, 0xaf, 0x39, 0x9f, 0x58, 0x37, 0x95, 0x62,
+ 0x59, 0xe9, 0x5e, 0x8d, 0x2f, 0x25, 0x50, 0x5c, 0x97, 0x33, 0x0f, 0x3f, 0x29, 0xe0, 0xff, 0x0e,
+ 0x73, 0xf6, 0x5a, 0x81, 0x17, 0x72, 0x2f, 0x74, 0x5b, 0xb1, 0x8b, 0xe2, 0xac, 0x3c, 0xe2, 0x30,
+ 0x55, 0x91, 0xd8, 0x9b, 0x97, 0x61, 0xd3, 0xdf, 0xa7, 0xb9, 0x22, 0xc0, 0xfd, 0xe3, 0xba, 0xfa,
+ 0x62, 0x63, 0xf5, 0xe5, 0x5a, 0xdc, 0x2f, 0x9d, 0xc0, 0x0e, 0x4e, 0xea, 0x33, 0x43, 0x01, 0x4b,
+ 0x15, 0xec, 0x71, 0xa9, 0xf0, 0x9d, 0x02, 0x6a, 0xdb, 0x42, 0x09, 0xeb, 0x44, 0x91, 0xdf, 0x1b,
+ 0xd5, 0x15, 0xdb, 0x71, 0xe7, 0x4a, 0x3b, 0x86, 0xc4, 0xd5, 0x12, 0x57, 0xe0, 0x85, 0x2d, 0x66,
+ 0xfd, 0x2b, 0x40, 0x1b, 0x92, 0x73, 0x89, 0x88, 0x36, 0xa1, 0x94, 0xec, 0x8e, 0x8a, 0xc8, 0x4d,
+ 0x5c, 0x84, 0x29, 0x39, 0xc3, 0x22, 0xde, 0x02, 0xd5, 0xc1, 0x3e, 0x76, 0x11, 0x27, 0x74, 0x54,
+ 0x41, 0x7e, 0x92, 0x0a, 0xaa, 0xe7, 0x98, 0x61, 0x01, 0x1d, 0x30, 0xcf, 0x76, 0x51, 0x34, 0xca,
+ 0x2e, 0x4c, 0x92, 0x3d, 0x27, 0x08, 0xc3, 0xd8, 0x2e, 0x98, 0xb3, 0x7d, 0xe4, 0x05, 0xad, 0xf4,
+ 0x18, 0x14, 0x25, 0x74, 0xe9, 0xd7, 0x63, 0x70, 0x3e, 0x5e, 0xe6, 0x8d, 0x04, 0x5b, 0x19, 0xb3,
+ 0xc9, 0xac, 0x59, 0xc9, 0x48, 0x6d, 0xc1, 0x47, 0xa0, 0x1c, 0x73, 0xc5, 0x7d, 0xf7, 0xd7, 0x35,
+ 0xee, 0xbb, 0x92, 0x2c, 0x7b, 0x12, 0x3a, 0xf0, 0x0d, 0xa8, 0x32, 0xd4, 0xf5, 0x42, 0x97, 0x8d,
+ 0x9a, 0x56, 0x9a, 0xa4, 0x69, 0x95, 0x04, 0x72, 0xe1, 0xb8, 0x30, 0xa2, 0xe1, 0x28, 0xb9, 0x3c,
+ 0xd1, 0xe3, 0x12, 0x84, 0xa1, 0x90, 0xf9, 0xec, 0xf0, 0x87, 0x96, 0x39, 0xec, 0x6b, 0xca, 0x51,
+ 0x5f, 0x53, 0xbe, 0xf7, 0x35, 0x65, 0xff, 0x54, 0xcb, 0x1c, 0x9d, 0x6a, 0x99, 0xaf, 0xa7, 0x5a,
+ 0xe6, 0xf5, 0x52, 0xea, 0xae, 0x14, 0x0a, 0x96, 0x7d, 0xd4, 0x66, 0x72, 0x65, 0xec, 0xa5, 0xfe,
+ 0x91, 0xc8, 0x4b, 0xb3, 0x5d, 0x94, 0x36, 0xdf, 0xff, 0x19, 0x00, 0x00, 0xff, 0xff, 0x18, 0x89,
+ 0x03, 0xa4, 0xb0, 0x08, 0x00, 0x00,
}
func (m *RewardPeriod) Marshal() (dAtA []byte, err error) {
@@ -546,6 +548,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.EarnRewardPeriods) > 0 {
+ for iNdEx := len(m.EarnRewardPeriods) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.EarnRewardPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintParams(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x4a
+ }
+ }
if len(m.SavingsRewardPeriods) > 0 {
for iNdEx := len(m.SavingsRewardPeriods) - 1; iNdEx >= 0; iNdEx-- {
{
@@ -801,6 +817,12 @@ func (m *Params) Size() (n int) {
n += 1 + l + sovParams(uint64(l))
}
}
+ if len(m.EarnRewardPeriods) > 0 {
+ for _, e := range m.EarnRewardPeriods {
+ l = e.Size()
+ n += 1 + l + sovParams(uint64(l))
+ }
+ }
return n
}
@@ -1763,6 +1785,40 @@ func (m *Params) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 9:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field EarnRewardPeriods", 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.EarnRewardPeriods = append(m.EarnRewardPeriods, MultiRewardPeriod{})
+ if err := m.EarnRewardPeriods[len(m.EarnRewardPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])
diff --git a/x/incentive/types/querier.go b/x/incentive/types/querier.go
index f46435a8..6cbffa63 100644
--- a/x/incentive/types/querier.go
+++ b/x/incentive/types/querier.go
@@ -11,6 +11,7 @@ const (
QueryGetDelegatorRewards = "delegator-rewards"
QueryGetSwapRewards = "swap-rewards"
QueryGetSavingsRewards = "savings-rewards"
+ QueryGetEarnRewards = "earn-rewards"
QueryGetRewardFactors = "reward-factors"
QueryGetParams = "parameters"
@@ -46,11 +47,12 @@ type QueryGetRewardFactorsResponse struct {
DelegatorRewardFactors MultiRewardIndexes `json:"delegator_reward_factors" yaml:"delegator_reward_factors"`
SwapRewardFactors MultiRewardIndexes `json:"swap_reward_factors" yaml:"swap_reward_factors"`
SavingsRewardFactors MultiRewardIndexes `json:"savings_reward_factors" yaml:"savings_reward_factors"`
+ EarnRewardFactors MultiRewardIndexes `json:"earn_reward_factors" yaml:"earn_reward_factors"`
}
// NewQueryGetRewardFactorsResponse returns a new instance of QueryAllRewardFactorsResponse
func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFactors,
- hardBorrowFactors, delegatorFactors, swapFactors, savingsFactors MultiRewardIndexes,
+ hardBorrowFactors, delegatorFactors, swapFactors, savingsFactors, earnFactors MultiRewardIndexes,
) QueryGetRewardFactorsResponse {
return QueryGetRewardFactorsResponse{
USDXMintingRewardFactors: usdxMintingFactors,
@@ -59,5 +61,6 @@ func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFa
DelegatorRewardFactors: delegatorFactors,
SwapRewardFactors: swapFactors,
SavingsRewardFactors: savingsFactors,
+ EarnRewardFactors: earnFactors,
}
}
diff --git a/x/incentive/types/tx.pb.go b/x/incentive/types/tx.pb.go
index 53c8b5ee..7a700217 100644
--- a/x/incentive/types/tx.pb.go
+++ b/x/incentive/types/tx.pb.go
@@ -448,6 +448,82 @@ func (m *MsgClaimSavingsRewardResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_MsgClaimSavingsRewardResponse proto.InternalMessageInfo
+// MsgClaimEarnReward message type used to claim earn rewards
+type MsgClaimEarnReward struct {
+ Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
+ DenomsToClaim Selections `protobuf:"bytes,2,rep,name=denoms_to_claim,json=denomsToClaim,proto3,castrepeated=Selections" json:"denoms_to_claim"`
+}
+
+func (m *MsgClaimEarnReward) Reset() { *m = MsgClaimEarnReward{} }
+func (m *MsgClaimEarnReward) String() string { return proto.CompactTextString(m) }
+func (*MsgClaimEarnReward) ProtoMessage() {}
+func (*MsgClaimEarnReward) Descriptor() ([]byte, []int) {
+ return fileDescriptor_b1cec058e3ff75d5, []int{11}
+}
+func (m *MsgClaimEarnReward) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgClaimEarnReward) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgClaimEarnReward.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 *MsgClaimEarnReward) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgClaimEarnReward.Merge(m, src)
+}
+func (m *MsgClaimEarnReward) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgClaimEarnReward) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgClaimEarnReward.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgClaimEarnReward proto.InternalMessageInfo
+
+// MsgClaimEarnRewardResponse defines the Msg/ClaimEarnReward response type.
+type MsgClaimEarnRewardResponse struct {
+}
+
+func (m *MsgClaimEarnRewardResponse) Reset() { *m = MsgClaimEarnRewardResponse{} }
+func (m *MsgClaimEarnRewardResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgClaimEarnRewardResponse) ProtoMessage() {}
+func (*MsgClaimEarnRewardResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_b1cec058e3ff75d5, []int{12}
+}
+func (m *MsgClaimEarnRewardResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgClaimEarnRewardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgClaimEarnRewardResponse.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 *MsgClaimEarnRewardResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgClaimEarnRewardResponse.Merge(m, src)
+}
+func (m *MsgClaimEarnRewardResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgClaimEarnRewardResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgClaimEarnRewardResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgClaimEarnRewardResponse proto.InternalMessageInfo
+
func init() {
proto.RegisterType((*Selection)(nil), "kava.incentive.v1beta1.Selection")
proto.RegisterType((*MsgClaimUSDXMintingReward)(nil), "kava.incentive.v1beta1.MsgClaimUSDXMintingReward")
@@ -460,44 +536,47 @@ func init() {
proto.RegisterType((*MsgClaimSwapRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimSwapRewardResponse")
proto.RegisterType((*MsgClaimSavingsReward)(nil), "kava.incentive.v1beta1.MsgClaimSavingsReward")
proto.RegisterType((*MsgClaimSavingsRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimSavingsRewardResponse")
+ proto.RegisterType((*MsgClaimEarnReward)(nil), "kava.incentive.v1beta1.MsgClaimEarnReward")
+ proto.RegisterType((*MsgClaimEarnRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimEarnRewardResponse")
}
func init() { proto.RegisterFile("kava/incentive/v1beta1/tx.proto", fileDescriptor_b1cec058e3ff75d5) }
var fileDescriptor_b1cec058e3ff75d5 = []byte{
- // 504 bytes of a gzipped FileDescriptorProto
+ // 525 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x95, 0x31, 0x6f, 0xd3, 0x40,
- 0x14, 0xc7, 0x7d, 0x2d, 0x54, 0xf4, 0x21, 0x88, 0x74, 0x0a, 0x21, 0x58, 0x60, 0x37, 0x61, 0xa0,
- 0x02, 0xd5, 0x56, 0x82, 0x10, 0x82, 0xb1, 0x14, 0x89, 0x25, 0x0c, 0x49, 0x91, 0x10, 0x12, 0x8a,
- 0x2e, 0xc9, 0x71, 0x9c, 0xb0, 0xef, 0x8c, 0xef, 0x9a, 0x16, 0x26, 0x26, 0xc4, 0xc8, 0x82, 0x84,
- 0x98, 0x3a, 0xf3, 0x49, 0x3a, 0x76, 0x64, 0x02, 0x94, 0x2c, 0xec, 0x7c, 0x01, 0x14, 0x27, 0x76,
- 0xa2, 0xc4, 0xc6, 0x84, 0x29, 0xdb, 0xdd, 0xbd, 0xff, 0x7b, 0xef, 0xf7, 0x9e, 0xde, 0xd3, 0x81,
- 0xfd, 0x8a, 0xf4, 0x89, 0xcb, 0x45, 0x97, 0x0a, 0xcd, 0xfb, 0xd4, 0xed, 0xd7, 0x3a, 0x54, 0x93,
- 0x9a, 0xab, 0x8f, 0x9c, 0x20, 0x94, 0x5a, 0xe2, 0xd2, 0x48, 0xe0, 0x24, 0x02, 0x67, 0x22, 0x30,
- 0x8b, 0x4c, 0x32, 0x19, 0x49, 0xdc, 0xd1, 0x69, 0xac, 0xae, 0xee, 0xc3, 0x66, 0x8b, 0x7a, 0xb4,
- 0xab, 0xb9, 0x14, 0xb8, 0x08, 0x67, 0x7b, 0x54, 0x48, 0xbf, 0x8c, 0xb6, 0xd0, 0xf6, 0x66, 0x73,
- 0x7c, 0xc1, 0x37, 0xa0, 0xe0, 0x1f, 0x78, 0x9a, 0x07, 0x1e, 0xa7, 0x61, 0x5b, 0x10, 0x9f, 0x96,
- 0xd7, 0x22, 0xfb, 0xc5, 0xe9, 0xf3, 0x63, 0xe2, 0xd3, 0xfb, 0xe7, 0x3e, 0x1c, 0xdb, 0xc6, 0xaf,
- 0x63, 0xdb, 0xa8, 0xbe, 0x80, 0x2b, 0x0d, 0xc5, 0x1e, 0x78, 0x84, 0xfb, 0x4f, 0x5a, 0x7b, 0x4f,
- 0x1b, 0x5c, 0x68, 0x2e, 0x58, 0x93, 0x1e, 0x92, 0xb0, 0x87, 0x4b, 0xb0, 0xa1, 0xa8, 0xe8, 0xd1,
- 0x70, 0x92, 0x66, 0x72, 0xfb, 0x9f, 0x3c, 0xd7, 0xa1, 0x92, 0x99, 0xa7, 0x49, 0x55, 0x20, 0x85,
- 0xa2, 0xd5, 0x4f, 0x08, 0x70, 0xac, 0x7a, 0x14, 0x19, 0xfe, 0x8a, 0xf1, 0x1c, 0x0a, 0x51, 0xdd,
- 0xaa, 0xad, 0x65, 0xbb, 0x3b, 0x72, 0x2a, 0xaf, 0x6d, 0xad, 0x6f, 0x9f, 0xaf, 0x57, 0x9c, 0xf4,
- 0xce, 0x3a, 0x49, 0x03, 0x77, 0xf1, 0xc9, 0x77, 0xdb, 0xf8, 0xfa, 0xc3, 0x86, 0xe4, 0x49, 0x35,
- 0x2f, 0x8c, 0xa3, 0xed, 0xcb, 0x08, 0x60, 0x06, 0xfe, 0x2a, 0x98, 0x8b, 0x58, 0x09, 0xf5, 0x17,
- 0x04, 0x97, 0x63, 0xf3, 0x1e, 0xf5, 0x28, 0x23, 0x5a, 0x86, 0xab, 0x82, 0x5e, 0x01, 0x3b, 0x83,
- 0x2d, 0xb5, 0xeb, 0xad, 0x43, 0x12, 0xac, 0x60, 0xd7, 0xa7, 0x58, 0x09, 0xf5, 0x67, 0x04, 0x97,
- 0x12, 0x33, 0xe9, 0x73, 0xc1, 0xd4, 0xaa, 0x80, 0xdb, 0x70, 0x2d, 0x95, 0x2c, 0x66, 0xaf, 0xff,
- 0x3e, 0x03, 0xeb, 0x0d, 0xc5, 0xf0, 0x7b, 0x04, 0xa5, 0x8c, 0xd5, 0xab, 0x65, 0x31, 0x65, 0x6e,
- 0x91, 0x79, 0x6f, 0x69, 0x97, 0x18, 0x08, 0xbf, 0x86, 0xc2, 0xfc, 0xd2, 0xdd, 0xcc, 0x8b, 0x36,
- 0xd5, 0x9a, 0xf5, 0x7f, 0xd7, 0x26, 0x29, 0xdf, 0x21, 0x28, 0xa6, 0xae, 0x8c, 0x9b, 0x17, 0x6c,
- 0xce, 0xc1, 0xbc, 0xbb, 0xa4, 0xc3, 0x42, 0xd5, 0x33, 0x43, 0x9f, 0x5b, 0xf5, 0x54, 0x9b, 0x5f,
- 0xf5, 0xe2, 0xd4, 0xe2, 0xb7, 0x80, 0x53, 0x26, 0x76, 0x27, 0x37, 0xd2, 0xac, 0xdc, 0xbc, 0xb3,
- 0x94, 0x3c, 0xce, 0xbd, 0xfb, 0xf0, 0x64, 0x60, 0xa1, 0xd3, 0x81, 0x85, 0x7e, 0x0e, 0x2c, 0xf4,
- 0x71, 0x68, 0x19, 0xa7, 0x43, 0xcb, 0xf8, 0x36, 0xb4, 0x8c, 0x67, 0xb7, 0x18, 0xd7, 0x2f, 0x0f,
- 0x3a, 0x4e, 0x57, 0xfa, 0xee, 0x28, 0xf4, 0x8e, 0x47, 0x3a, 0x2a, 0x3a, 0xb9, 0x47, 0x33, 0x1f,
- 0x98, 0x7e, 0x13, 0x50, 0xd5, 0xd9, 0x88, 0xbe, 0xa3, 0xdb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff,
- 0x7e, 0x03, 0x15, 0xb3, 0xdf, 0x06, 0x00, 0x00,
+ 0x14, 0xc7, 0x7d, 0xad, 0x5a, 0xd1, 0x87, 0x20, 0xd2, 0x29, 0x84, 0x60, 0x81, 0xdd, 0x84, 0x81,
+ 0x0a, 0x54, 0x5b, 0x09, 0x42, 0x08, 0xc6, 0xd2, 0x4a, 0x2c, 0x61, 0x48, 0x8a, 0x84, 0x90, 0x50,
+ 0x74, 0x49, 0x0e, 0x73, 0xc2, 0xbe, 0x33, 0xbe, 0x6b, 0x5a, 0x98, 0x98, 0x10, 0x23, 0x0b, 0x12,
+ 0x62, 0xea, 0xcc, 0x27, 0xe9, 0xd8, 0x91, 0x09, 0x50, 0x22, 0x21, 0x3e, 0x06, 0x8a, 0x93, 0xd8,
+ 0x56, 0x6d, 0x63, 0xd2, 0x29, 0x9b, 0xed, 0xf7, 0x7f, 0xef, 0xfd, 0xfe, 0x4f, 0x7e, 0x77, 0x60,
+ 0xbe, 0x26, 0x43, 0x62, 0x33, 0xde, 0xa7, 0x5c, 0xb1, 0x21, 0xb5, 0x87, 0x8d, 0x1e, 0x55, 0xa4,
+ 0x61, 0xab, 0x23, 0xcb, 0x0f, 0x84, 0x12, 0xb8, 0x32, 0x11, 0x58, 0x91, 0xc0, 0x9a, 0x09, 0xf4,
+ 0xb2, 0x23, 0x1c, 0x11, 0x4a, 0xec, 0xc9, 0xd3, 0x54, 0x5d, 0xdf, 0x87, 0x8d, 0x0e, 0x75, 0x69,
+ 0x5f, 0x31, 0xc1, 0x71, 0x19, 0xd6, 0x06, 0x94, 0x0b, 0xaf, 0x8a, 0x36, 0xd1, 0xd6, 0x46, 0x7b,
+ 0xfa, 0x82, 0x6f, 0x41, 0xc9, 0x3b, 0x70, 0x15, 0xf3, 0x5d, 0x46, 0x83, 0x2e, 0x27, 0x1e, 0xad,
+ 0xae, 0x84, 0xf1, 0xcb, 0xf1, 0xe7, 0x27, 0xc4, 0xa3, 0x0f, 0x2f, 0x7c, 0x3c, 0x36, 0xb5, 0x3f,
+ 0xc7, 0xa6, 0x56, 0x7f, 0x09, 0xd7, 0x5a, 0xd2, 0x79, 0xe4, 0x12, 0xe6, 0x3d, 0xed, 0xec, 0x3e,
+ 0x6b, 0x31, 0xae, 0x18, 0x77, 0xda, 0xf4, 0x90, 0x04, 0x03, 0x5c, 0x81, 0x75, 0x49, 0xf9, 0x80,
+ 0x06, 0xb3, 0x36, 0xb3, 0xb7, 0xf3, 0xf4, 0xb9, 0x09, 0xb5, 0xdc, 0x3e, 0x6d, 0x2a, 0x7d, 0xc1,
+ 0x25, 0xad, 0x7f, 0x46, 0x80, 0xe7, 0xaa, 0xc7, 0x61, 0xe0, 0x9f, 0x18, 0x2f, 0xa0, 0x14, 0xfa,
+ 0x96, 0x5d, 0x25, 0xba, 0xfd, 0x49, 0x52, 0x75, 0x65, 0x73, 0x75, 0xeb, 0x62, 0xb3, 0x66, 0x65,
+ 0x4f, 0xd6, 0x8a, 0x06, 0xb8, 0x83, 0x4f, 0x7e, 0x98, 0xda, 0xb7, 0x9f, 0x26, 0x44, 0x9f, 0x64,
+ 0xfb, 0xd2, 0xb4, 0xda, 0xbe, 0x08, 0x01, 0x12, 0xf0, 0xd7, 0x41, 0x4f, 0x63, 0x45, 0xd4, 0x5f,
+ 0x11, 0x5c, 0x9d, 0x87, 0x77, 0xa9, 0x4b, 0x1d, 0xa2, 0x44, 0xb0, 0x2c, 0xe8, 0x35, 0x30, 0x73,
+ 0xd8, 0x32, 0xa7, 0xde, 0x39, 0x24, 0xfe, 0x12, 0x4e, 0x3d, 0xc6, 0x8a, 0xa8, 0xbf, 0x20, 0xb8,
+ 0x12, 0x85, 0xc9, 0x90, 0x71, 0x47, 0x2e, 0x0b, 0xb8, 0x09, 0x37, 0x32, 0xc9, 0x32, 0x27, 0xbe,
+ 0x47, 0x02, 0xbe, 0x84, 0x13, 0x8f, 0xb1, 0xe6, 0xd4, 0xcd, 0xdf, 0x6b, 0xb0, 0xda, 0x92, 0x0e,
+ 0xfe, 0x80, 0xa0, 0x92, 0x73, 0x60, 0x34, 0xf2, 0x80, 0x72, 0x77, 0x5f, 0x7f, 0xb0, 0x70, 0xca,
+ 0x1c, 0x08, 0xbf, 0x81, 0xd2, 0xd9, 0xa3, 0xe2, 0x76, 0x51, 0xb5, 0x58, 0xab, 0x37, 0xff, 0x5f,
+ 0x1b, 0xb5, 0x7c, 0x8f, 0xa0, 0x9c, 0xb9, 0xe8, 0x76, 0x51, 0xb1, 0x33, 0x09, 0xfa, 0xfd, 0x05,
+ 0x13, 0x52, 0xae, 0x13, 0xab, 0x5a, 0xe8, 0x3a, 0xd6, 0x16, 0xbb, 0x4e, 0xef, 0x1a, 0x7e, 0x07,
+ 0x38, 0x63, 0xcf, 0xb6, 0x0b, 0x2b, 0x25, 0xe5, 0xfa, 0xbd, 0x85, 0xe4, 0x29, 0xbb, 0x89, 0x3d,
+ 0x29, 0xb4, 0x1b, 0x6b, 0x8b, 0xed, 0xa6, 0x7f, 0xf4, 0x9d, 0xbd, 0x93, 0x91, 0x81, 0x4e, 0x47,
+ 0x06, 0xfa, 0x35, 0x32, 0xd0, 0xa7, 0xb1, 0xa1, 0x9d, 0x8e, 0x0d, 0xed, 0xfb, 0xd8, 0xd0, 0x9e,
+ 0xdf, 0x71, 0x98, 0x7a, 0x75, 0xd0, 0xb3, 0xfa, 0xc2, 0xb3, 0x27, 0x75, 0xb7, 0x5d, 0xd2, 0x93,
+ 0xe1, 0x93, 0x7d, 0x94, 0xb8, 0xe9, 0xd5, 0x5b, 0x9f, 0xca, 0xde, 0x7a, 0x78, 0x6f, 0xdf, 0xfd,
+ 0x1b, 0x00, 0x00, 0xff, 0xff, 0x28, 0x8b, 0x70, 0xee, 0x08, 0x08, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -518,10 +597,12 @@ type MsgClient interface {
ClaimHardReward(ctx context.Context, in *MsgClaimHardReward, opts ...grpc.CallOption) (*MsgClaimHardRewardResponse, error)
// ClaimDelegatorReward is a message type used to claim delegator rewards
ClaimDelegatorReward(ctx context.Context, in *MsgClaimDelegatorReward, opts ...grpc.CallOption) (*MsgClaimDelegatorRewardResponse, error)
- // ClaimSwapReward is a message type used to claim delegator rewards
+ // ClaimSwapReward is a message type used to claim swap rewards
ClaimSwapReward(ctx context.Context, in *MsgClaimSwapReward, opts ...grpc.CallOption) (*MsgClaimSwapRewardResponse, error)
// ClaimSavingsReward is a message type used to claim savings rewards
ClaimSavingsReward(ctx context.Context, in *MsgClaimSavingsReward, opts ...grpc.CallOption) (*MsgClaimSavingsRewardResponse, error)
+ // ClaimEarnReward is a message type used to claim earn rewards
+ ClaimEarnReward(ctx context.Context, in *MsgClaimEarnReward, opts ...grpc.CallOption) (*MsgClaimEarnRewardResponse, error)
}
type msgClient struct {
@@ -577,6 +658,15 @@ func (c *msgClient) ClaimSavingsReward(ctx context.Context, in *MsgClaimSavingsR
return out, nil
}
+func (c *msgClient) ClaimEarnReward(ctx context.Context, in *MsgClaimEarnReward, opts ...grpc.CallOption) (*MsgClaimEarnRewardResponse, error) {
+ out := new(MsgClaimEarnRewardResponse)
+ err := c.cc.Invoke(ctx, "/kava.incentive.v1beta1.Msg/ClaimEarnReward", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// MsgServer is the server API for Msg service.
type MsgServer interface {
// ClaimUSDXMintingReward is a message type used to claim USDX minting rewards
@@ -585,10 +675,12 @@ type MsgServer interface {
ClaimHardReward(context.Context, *MsgClaimHardReward) (*MsgClaimHardRewardResponse, error)
// ClaimDelegatorReward is a message type used to claim delegator rewards
ClaimDelegatorReward(context.Context, *MsgClaimDelegatorReward) (*MsgClaimDelegatorRewardResponse, error)
- // ClaimSwapReward is a message type used to claim delegator rewards
+ // ClaimSwapReward is a message type used to claim swap rewards
ClaimSwapReward(context.Context, *MsgClaimSwapReward) (*MsgClaimSwapRewardResponse, error)
// ClaimSavingsReward is a message type used to claim savings rewards
ClaimSavingsReward(context.Context, *MsgClaimSavingsReward) (*MsgClaimSavingsRewardResponse, error)
+ // ClaimEarnReward is a message type used to claim earn rewards
+ ClaimEarnReward(context.Context, *MsgClaimEarnReward) (*MsgClaimEarnRewardResponse, error)
}
// UnimplementedMsgServer can be embedded to have forward compatible implementations.
@@ -610,6 +702,9 @@ func (*UnimplementedMsgServer) ClaimSwapReward(ctx context.Context, req *MsgClai
func (*UnimplementedMsgServer) ClaimSavingsReward(ctx context.Context, req *MsgClaimSavingsReward) (*MsgClaimSavingsRewardResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ClaimSavingsReward not implemented")
}
+func (*UnimplementedMsgServer) ClaimEarnReward(ctx context.Context, req *MsgClaimEarnReward) (*MsgClaimEarnRewardResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ClaimEarnReward not implemented")
+}
func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
s.RegisterService(&_Msg_serviceDesc, srv)
@@ -705,6 +800,24 @@ func _Msg_ClaimSavingsReward_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
+func _Msg_ClaimEarnReward_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgClaimEarnReward)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).ClaimEarnReward(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/kava.incentive.v1beta1.Msg/ClaimEarnReward",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).ClaimEarnReward(ctx, req.(*MsgClaimEarnReward))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Msg_serviceDesc = grpc.ServiceDesc{
ServiceName: "kava.incentive.v1beta1.Msg",
HandlerType: (*MsgServer)(nil),
@@ -729,6 +842,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{
MethodName: "ClaimSavingsReward",
Handler: _Msg_ClaimSavingsReward_Handler,
},
+ {
+ MethodName: "ClaimEarnReward",
+ Handler: _Msg_ClaimEarnReward_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "kava/incentive/v1beta1/tx.proto",
@@ -1099,6 +1216,73 @@ func (m *MsgClaimSavingsRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int,
return len(dAtA) - i, nil
}
+func (m *MsgClaimEarnReward) 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 *MsgClaimEarnReward) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgClaimEarnReward) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if len(m.DenomsToClaim) > 0 {
+ for iNdEx := len(m.DenomsToClaim) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.DenomsToClaim[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintTx(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ if len(m.Sender) > 0 {
+ i -= len(m.Sender)
+ copy(dAtA[i:], m.Sender)
+ i = encodeVarintTx(dAtA, i, uint64(len(m.Sender)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgClaimEarnRewardResponse) 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 *MsgClaimEarnRewardResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgClaimEarnRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
func encodeVarintTx(dAtA []byte, offset int, v uint64) int {
offset -= sovTx(v)
base := offset
@@ -1265,6 +1449,34 @@ func (m *MsgClaimSavingsRewardResponse) Size() (n int) {
return n
}
+func (m *MsgClaimEarnReward) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Sender)
+ if l > 0 {
+ n += 1 + l + sovTx(uint64(l))
+ }
+ if len(m.DenomsToClaim) > 0 {
+ for _, e := range m.DenomsToClaim {
+ l = e.Size()
+ n += 1 + l + sovTx(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *MsgClaimEarnRewardResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
func sovTx(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -2213,6 +2425,172 @@ func (m *MsgClaimSavingsRewardResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *MsgClaimEarnReward) 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 ErrIntOverflowTx
+ }
+ 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: MsgClaimEarnReward: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgClaimEarnReward: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ 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 ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Sender = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field DenomsToClaim", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.DenomsToClaim = append(m.DenomsToClaim, Selection{})
+ if err := m.DenomsToClaim[len(m.DenomsToClaim)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgClaimEarnRewardResponse) 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 ErrIntOverflowTx
+ }
+ 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: MsgClaimEarnRewardResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgClaimEarnRewardResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipTx(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0