Add base earn incentives (#1292)

* Add incentive types

* Add earn state methods

* Update earn incentives

* Update unit test NewKeeper to include earn keeper

* Fix sharesOwned typo

* Shares not used for AfterVaultDepositCreated

* Add earn to init genesis

* Pass earn keeper to incentive keeper

* Add sdk.Msg impl, disable legacy migrations

* Disable migrations

* Update incentive earn sync test

* Add earn to client and querier

* Add accum and init tests

* Add additional earn tests

* Fill in fakeEarnKeeper methods to fix tests

* Add earn reward periods to params, begin blocker earn reward

* Add earn to query

* Update genesis_test with missing DefaultMultiRewardPeriods parameter

* Remove disable of migration package

* Fix proto type comments

* Remove unused migration state

* Add legacytx.LegacyMsg compile time interface check

* add earn state validation to genesis validation

Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com>
This commit is contained in:
Derrick Lee 2022-09-22 11:26:08 -07:00 committed by GitHub
parent 9fb64b1f11
commit 26a4b93588
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 3081 additions and 276 deletions

View File

@ -597,6 +597,17 @@ func NewApp(
app.bankKeeper, app.bankKeeper,
&app.stakingKeeper, &app.stakingKeeper,
) )
earnKeeper := earnkeeper.NewKeeper(
appCodec,
keys[earntypes.StoreKey],
earnSubspace,
app.accountKeeper,
app.bankKeeper,
&app.liquidKeeper,
&hardKeeper,
&savingsKeeper,
)
app.incentiveKeeper = incentivekeeper.NewKeeper( app.incentiveKeeper = incentivekeeper.NewKeeper(
appCodec, appCodec,
keys[incentivetypes.StoreKey], keys[incentivetypes.StoreKey],
@ -608,16 +619,7 @@ func NewApp(
app.stakingKeeper, app.stakingKeeper,
&swapKeeper, &swapKeeper,
&savingsKeeper, &savingsKeeper,
) &earnKeeper,
app.earnKeeper = earnkeeper.NewKeeper(
appCodec,
keys[earntypes.StoreKey],
earnSubspace,
app.accountKeeper,
app.bankKeeper,
app.liquidKeeper,
&hardKeeper,
&savingsKeeper,
) )
// create committee keeper with router // create committee keeper with router
@ -667,6 +669,7 @@ func NewApp(
app.cdpKeeper = *cdpKeeper.SetHooks(cdptypes.NewMultiCDPHooks(app.incentiveKeeper.Hooks())) app.cdpKeeper = *cdpKeeper.SetHooks(cdptypes.NewMultiCDPHooks(app.incentiveKeeper.Hooks()))
app.hardKeeper = *hardKeeper.SetHooks(hardtypes.NewMultiHARDHooks(app.incentiveKeeper.Hooks())) app.hardKeeper = *hardKeeper.SetHooks(hardtypes.NewMultiHARDHooks(app.incentiveKeeper.Hooks()))
app.savingsKeeper = *savingsKeeper.SetHooks(savingstypes.NewMultiSavingsHooks(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 // create the module manager (Note: Any module instantiated in the module manager that is later modified
// must be passed by reference here.) // must be passed by reference here.)

View File

@ -302,6 +302,7 @@
- [BaseClaim](#kava.incentive.v1beta1.BaseClaim) - [BaseClaim](#kava.incentive.v1beta1.BaseClaim)
- [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim) - [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim)
- [DelegatorClaim](#kava.incentive.v1beta1.DelegatorClaim) - [DelegatorClaim](#kava.incentive.v1beta1.DelegatorClaim)
- [EarnClaim](#kava.incentive.v1beta1.EarnClaim)
- [HardLiquidityProviderClaim](#kava.incentive.v1beta1.HardLiquidityProviderClaim) - [HardLiquidityProviderClaim](#kava.incentive.v1beta1.HardLiquidityProviderClaim)
- [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex) - [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex)
- [MultiRewardIndexesProto](#kava.incentive.v1beta1.MultiRewardIndexesProto) - [MultiRewardIndexesProto](#kava.incentive.v1beta1.MultiRewardIndexesProto)
@ -326,6 +327,8 @@
- [kava/incentive/v1beta1/tx.proto](#kava/incentive/v1beta1/tx.proto) - [kava/incentive/v1beta1/tx.proto](#kava/incentive/v1beta1/tx.proto)
- [MsgClaimDelegatorReward](#kava.incentive.v1beta1.MsgClaimDelegatorReward) - [MsgClaimDelegatorReward](#kava.incentive.v1beta1.MsgClaimDelegatorReward)
- [MsgClaimDelegatorRewardResponse](#kava.incentive.v1beta1.MsgClaimDelegatorRewardResponse) - [MsgClaimDelegatorRewardResponse](#kava.incentive.v1beta1.MsgClaimDelegatorRewardResponse)
- [MsgClaimEarnReward](#kava.incentive.v1beta1.MsgClaimEarnReward)
- [MsgClaimEarnRewardResponse](#kava.incentive.v1beta1.MsgClaimEarnRewardResponse)
- [MsgClaimHardReward](#kava.incentive.v1beta1.MsgClaimHardReward) - [MsgClaimHardReward](#kava.incentive.v1beta1.MsgClaimHardReward)
- [MsgClaimHardRewardResponse](#kava.incentive.v1beta1.MsgClaimHardRewardResponse) - [MsgClaimHardRewardResponse](#kava.incentive.v1beta1.MsgClaimHardRewardResponse)
- [MsgClaimSavingsReward](#kava.incentive.v1beta1.MsgClaimSavingsReward) - [MsgClaimSavingsReward](#kava.incentive.v1beta1.MsgClaimSavingsReward)
@ -4353,6 +4356,22 @@ DelegatorClaim stores delegation rewards that can be claimed by owner
<a name="kava.incentive.v1beta1.EarnClaim"></a>
### 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 | |
<a name="kava.incentive.v1beta1.HardLiquidityProviderClaim"></a> <a name="kava.incentive.v1beta1.HardLiquidityProviderClaim"></a>
### HardLiquidityProviderClaim ### HardLiquidityProviderClaim
@ -4564,6 +4583,7 @@ Params
| `claim_multipliers` | [MultipliersPerDenom](#kava.incentive.v1beta1.MultipliersPerDenom) | repeated | | | `claim_multipliers` | [MultipliersPerDenom](#kava.incentive.v1beta1.MultipliersPerDenom) | repeated | |
| `claim_end` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | | | `claim_end` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
| `savings_reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated | | | `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 | | | `swap_claims` | [SwapClaim](#kava.incentive.v1beta1.SwapClaim) | repeated | |
| `savings_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | | | | `savings_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | | |
| `savings_claims` | [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim) | repeated | | | `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
<a name="kava.incentive.v1beta1.MsgClaimEarnReward"></a>
### 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 | |
<a name="kava.incentive.v1beta1.MsgClaimEarnRewardResponse"></a>
### MsgClaimEarnRewardResponse
MsgClaimEarnRewardResponse defines the Msg/ClaimEarnReward response type.
<a name="kava.incentive.v1beta1.MsgClaimHardReward"></a> <a name="kava.incentive.v1beta1.MsgClaimHardReward"></a>
### MsgClaimHardReward ### 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 | | | `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 | | | `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 | | | `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 | | | `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 | |
<!-- end services --> <!-- end services -->

View File

@ -115,3 +115,13 @@ message SavingsClaim {
repeated MultiRewardIndex reward_indexes = 2 repeated MultiRewardIndex reward_indexes = 2
[(gogoproto.castrepeated) = "MultiRewardIndexes", (gogoproto.nullable) = false]; [(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];
}

View File

@ -60,4 +60,8 @@ message GenesisState {
GenesisRewardState savings_reward_state = 11 [(gogoproto.nullable) = false]; GenesisRewardState savings_reward_state = 11 [(gogoproto.nullable) = false];
repeated SavingsClaim savings_claims = 12 [(gogoproto.castrepeated) = "SavingsClaims", (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];
} }

View File

@ -79,4 +79,7 @@ message Params {
repeated MultiRewardPeriod savings_reward_periods = 8 repeated MultiRewardPeriod savings_reward_periods = 8
[(gogoproto.castrepeated) = "MultiRewardPeriods", (gogoproto.nullable) = false]; [(gogoproto.castrepeated) = "MultiRewardPeriods", (gogoproto.nullable) = false];
repeated MultiRewardPeriod earn_reward_periods = 9
[(gogoproto.castrepeated) = "MultiRewardPeriods", (gogoproto.nullable) = false];
} }

View File

@ -16,11 +16,14 @@ service Msg {
// ClaimDelegatorReward is a message type used to claim delegator rewards // ClaimDelegatorReward is a message type used to claim delegator rewards
rpc ClaimDelegatorReward(MsgClaimDelegatorReward) returns (MsgClaimDelegatorRewardResponse); 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); rpc ClaimSwapReward(MsgClaimSwapReward) returns (MsgClaimSwapRewardResponse);
// ClaimSavingsReward is a message type used to claim savings rewards // ClaimSavingsReward is a message type used to claim savings rewards
rpc ClaimSavingsReward(MsgClaimSavingsReward) returns (MsgClaimSavingsRewardResponse); 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 // 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. // MsgClaimSavingsRewardResponse defines the Msg/ClaimSavingsReward response type.
message MsgClaimSavingsRewardResponse {} 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 {}

View File

@ -48,6 +48,6 @@ type SavingsKeeper interface {
// EarnHooks are event hooks called when a user's deposit to a earn vault changes. // EarnHooks are event hooks called when a user's deposit to a earn vault changes.
type EarnHooks interface { type EarnHooks interface {
AfterVaultDepositCreated(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, sharedOwned sdk.Dec) BeforeVaultDepositModified(ctx sdk.Context, vaultDenom string, depositor sdk.AccAddress, sharesOwned sdk.Dec)
} }

View File

@ -12,14 +12,14 @@ type EarnHooks struct {
mock.Mock mock.Mock
} }
// AfterVaultDepositCreated provides a mock function with given fields: 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, sharedOwned types.Dec) { func (_m *EarnHooks) AfterVaultDepositCreated(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharesOwned types.Dec) {
_m.Called(ctx, vaultDenom, depositor, sharedOwned) _m.Called(ctx, vaultDenom, depositor, sharesOwned)
} }
// BeforeVaultDepositModified provides a mock function with given fields: 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, sharedOwned types.Dec) { func (_m *EarnHooks) BeforeVaultDepositModified(ctx types.Context, vaultDenom string, depositor types.AccAddress, sharesOwned types.Dec) {
_m.Called(ctx, vaultDenom, depositor, sharedOwned) _m.Called(ctx, vaultDenom, depositor, sharesOwned)
} }
type mockConstructorTestingTNewEarnHooks interface { type mockConstructorTestingTNewEarnHooks interface {

View File

@ -28,4 +28,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
for _, rp := range params.SavingsRewardPeriods { for _, rp := range params.SavingsRewardPeriods {
k.AccumulateSavingsRewards(ctx, rp) k.AccumulateSavingsRewards(ctx, rp)
} }
for _, rp := range params.EarnRewardPeriods {
k.AccumulateEarnRewards(ctx, rp)
}
} }

View File

@ -25,9 +25,10 @@ const (
typeUSDXMinting = "usdx-minting" typeUSDXMinting = "usdx-minting"
typeSwap = "swap" typeSwap = "swap"
typeSavings = "savings" 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 // GetQueryCmd returns the cli query commands for the incentive module
func GetQueryCmd() *cobra.Command { func GetQueryCmd() *cobra.Command {
@ -59,20 +60,17 @@ func queryRewardsCmd() *cobra.Command {
fmt.Sprintf(`Query rewards with optional flags for owner and type fmt.Sprintf(`Query rewards with optional flags for owner and type
Example: Example:
$ %s query %s rewards $ %[1]s query %[2]s rewards
$ %s query %s rewards --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw $ %[1]s query %[2]s rewards --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
$ %s query %s rewards --type hard $ %[1]s query %[2]s rewards --type hard
$ %s query %s rewards --type usdx-minting $ %[1]s query %[2]s rewards --type usdx-minting
$ %s query %s rewards --type delegator $ %[1]s query %[2]s rewards --type delegator
$ %s query %s rewards --type swap $ %[1]s query %[2]s rewards --type swap
$ %s query %s rewards --type savings $ %[1]s query %[2]s rewards --type savings
$ %s query %s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw $ %[1]s query %[2]s rewards --type earn
$ %s query %s rewards --type hard --unsynced $ %[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)), version.AppName, types.ModuleName)),
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -131,6 +129,13 @@ func queryRewardsCmd() *cobra.Command {
return err return err
} }
return cliCtx.PrintObjectLegacy(claims) 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: default:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced) params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
@ -362,3 +367,25 @@ func executeSavingsRewardsQuery(cliCtx client.Context, params types.QueryRewards
return claims, nil 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
}

View File

@ -68,6 +68,8 @@ func queryRewardsHandlerFn(cliCtx client.Context) http.HandlerFunc {
executeDelegatorRewardsQuery(w, cliCtx, params) executeDelegatorRewardsQuery(w, cliCtx, params)
case "swap": case "swap":
executeSwapRewardsQuery(w, cliCtx, params) executeSwapRewardsQuery(w, cliCtx, params)
case "earn":
executeEarnRewardsQuery(w, cliCtx, params)
default: default:
executeAllRewardQueries(w, cliCtx, params) executeAllRewardQueries(w, cliCtx, params)
} }
@ -182,6 +184,23 @@ func executeSwapRewardsQuery(w http.ResponseWriter, cliCtx client.Context, param
rest.PostProcessResponse(w, cliCtx, res) 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) { func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, params types.QueryRewardsParams) {
paramsBz, err := cliCtx.LegacyAmino.MarshalJSON(params) paramsBz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil { if err != nil {
@ -212,7 +231,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
var delegatorClaims types.DelegatorClaims var delegatorClaims types.DelegatorClaims
cliCtx.LegacyAmino.MustUnmarshalJSON(delegatorRes, &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 { if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return return
@ -220,6 +239,14 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
var swapClaims types.SwapClaims var swapClaims types.SwapClaims
cliCtx.LegacyAmino.MustUnmarshalJSON(swapRes, &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) cliCtx = cliCtx.WithHeight(height)
type rewardResult struct { 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"` UsdxMintingClaims types.USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
DelegatorClaims types.DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"` DelegatorClaims types.DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"`
SwapClaims types.SwapClaims `json:"swap_claims" yaml:"swap_claims"` SwapClaims types.SwapClaims `json:"swap_claims" yaml:"swap_claims"`
EarnClaims types.EarnClaims `json:"earn_claims" yaml:"earn_claims"`
} }
res := rewardResult{ res := rewardResult{
@ -234,6 +262,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx client.Context, param
UsdxMintingClaims: usdxMintingClaims, UsdxMintingClaims: usdxMintingClaims,
DelegatorClaims: delegatorClaims, DelegatorClaims: delegatorClaims,
SwapClaims: swapClaims, SwapClaims: swapClaims,
EarnClaims: earnClaims,
} }
resBz, err := cliCtx.LegacyAmino.MarshalJSON(res) resBz, err := cliCtx.LegacyAmino.MarshalJSON(res)

View File

@ -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-hard", postClaimHandlerFn(cliCtx, hardGenerator)).Methods("POST")
r.HandleFunc("/incentive/claim-delegator", postClaimHandlerFn(cliCtx, delegatorGenerator)).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-swap", postClaimHandlerFn(cliCtx, swapGenerator)).Methods("POST")
r.HandleFunc("/incentive/claim-earn", postClaimHandlerFn(cliCtx, earnGenerator)).Methods("POST")
} }
func usdxMintingGenerator(req PostClaimReq) (sdk.Msg, error) { func usdxMintingGenerator(req PostClaimReq) (sdk.Msg, error) {
@ -45,6 +46,11 @@ func swapGenerator(req PostClaimReq) (sdk.Msg, error) {
return &msg, nil 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 { func postClaimHandlerFn(cliCtx client.Context, msgGenerator func(req PostClaimReq) (sdk.Msg, error)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var requestBody PostClaimReq var requestBody PostClaimReq

View File

@ -126,6 +126,20 @@ func InitGenesis(
for _, mri := range gs.SavingsRewardState.MultiRewardIndexes { for _, mri := range gs.SavingsRewardState.MultiRewardIndexes {
k.SetSavingsRewardIndexes(ctx, mri.CollateralType, mri.RewardIndexes) 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 // 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) savingsClaims := k.GetAllSavingsClaims(ctx)
savingsRewardState := getSavingsGenesisRewardState(ctx, k) savingsRewardState := getSavingsGenesisRewardState(ctx, k)
earnClaims := k.GetAllEarnClaims(ctx)
earnRewardState := getEarnGenesisRewardState(ctx, k)
return types.NewGenesisState( return types.NewGenesisState(
params, params,
usdxRewardState, hardSupplyRewardState, hardBorrowRewardState, delegatorRewardState, swapRewardState, // Reward states
savingsRewardState, usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, 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) 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 { func ValidateAccumulationTime(previousAccumulationTime, genesisTime time.Time) error {
if previousAccumulationTime.Before(genesisTime.Add(-1 * EarliestValidAccumulationTime)) { if previousAccumulationTime.Before(genesisTime.Add(-1 * EarliestValidAccumulationTime)) {
return fmt.Errorf( return fmt.Errorf(

View File

@ -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, "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, "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.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", suite.genesisTime.Add(-1*oneYear), suite.genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultipliersPerDenoms{ types.MultipliersPerDenoms{
{ {
Denom: "ukava", Denom: "ukava",
@ -100,11 +101,13 @@ func (suite *GenesisTestSuite) SetupTest() {
types.DefaultGenesisRewardState, types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState, types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState, types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
types.DefaultUSDXClaims, types.DefaultUSDXClaims,
types.DefaultHardClaims, types.DefaultHardClaims,
types.DefaultDelegatorClaims, types.DefaultDelegatorClaims,
types.DefaultSwapClaims, types.DefaultSwapClaims,
types.DefaultSavingsClaims, types.DefaultSavingsClaims,
types.DefaultEarnClaims,
) )
cdc := suite.app.AppCodec() 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, "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, "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.MultiRewardPeriods{types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354)))},
types.MultipliersPerDenoms{ types.MultipliersPerDenoms{
{ {
Denom: "ukava", Denom: "ukava",
@ -207,6 +211,14 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.NewMultiRewardIndex("ukava", types.RewardIndexes{{CollateralType: "ukava", RewardFactor: d("0.2")}}), 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.USDXMintingClaims{
types.NewUSDXMintingClaim( types.NewUSDXMintingClaim(
suite.addrs[0], 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.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() tApp := app.NewTestApp()

View File

@ -256,3 +256,51 @@ func (k Keeper) ClaimSavingsReward(ctx sdk.Context, owner, receiver sdk.AccAddre
) )
return nil 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
}

View File

@ -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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -70,7 +70,7 @@ func (suite *ClaimTests) TestCannotClaimAfterEndTime() {
ClaimEnd: endTime, 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)) suite.ctx = suite.ctx.WithBlockTime(endTime.Add(time.Nanosecond))

View File

@ -5,6 +5,7 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
cdptypes "github.com/kava-labs/kava/x/cdp/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" hardtypes "github.com/kava-labs/kava/x/hard/types"
savingstypes "github.com/kava-labs/kava/x/savings/types" savingstypes "github.com/kava-labs/kava/x/savings/types"
swaptypes "github.com/kava-labs/kava/x/swap/types" swaptypes "github.com/kava-labs/kava/x/swap/types"
@ -21,6 +22,7 @@ var (
_ stakingtypes.StakingHooks = Hooks{} _ stakingtypes.StakingHooks = Hooks{}
_ swaptypes.SwapHooks = Hooks{} _ swaptypes.SwapHooks = Hooks{}
_ savingstypes.SavingsHooks = Hooks{} _ savingstypes.SavingsHooks = Hooks{}
_ earntypes.EarnHooks = Hooks{}
) )
// Hooks create new incentive 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) { func (h Hooks) BeforeSavingsDepositModified(ctx sdk.Context, deposit savingstypes.Deposit, incomingDenoms []string) {
h.k.SynchronizeSavingsReward(ctx, deposit, incomingDenoms) 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)
}

View File

@ -22,13 +22,14 @@ type Keeper struct {
stakingKeeper types.StakingKeeper stakingKeeper types.StakingKeeper
swapKeeper types.SwapKeeper swapKeeper types.SwapKeeper
savingsKeeper types.SavingsKeeper savingsKeeper types.SavingsKeeper
earnKeeper types.EarnKeeper
} }
// NewKeeper creates a new keeper // NewKeeper creates a new keeper
func NewKeeper( func NewKeeper(
cdc codec.Codec, key sdk.StoreKey, paramstore types.ParamSubspace, bk types.BankKeeper, cdc codec.Codec, key sdk.StoreKey, paramstore types.ParamSubspace, bk types.BankKeeper,
cdpk types.CdpKeeper, hk types.HardKeeper, ak types.AccountKeeper, stk types.StakingKeeper, 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 { ) Keeper {
if !paramstore.HasKeyTable() { if !paramstore.HasKeyTable() {
paramstore = paramstore.WithKeyTable(types.ParamKeyTable()) paramstore = paramstore.WithKeyTable(types.ParamKeyTable())
@ -45,6 +46,7 @@ func NewKeeper(
stakingKeeper: stk, stakingKeeper: stk,
swapKeeper: swpk, swapKeeper: swpk,
savingsKeeper: svk, savingsKeeper: svk,
earnKeeper: ek,
} }
} }
@ -372,6 +374,55 @@ func (k Keeper) GetAllSavingsClaims(ctx sdk.Context) types.SavingsClaims {
return cs 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 // SetHardSupplyRewardIndexes sets the current reward indexes for an individual denom
func (k Keeper) SetHardSupplyRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) { func (k Keeper) SetHardSupplyRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix) 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
}
}
}

View File

@ -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 { type accrualtime struct {
denom string denom string
time time.Time time time.Time
@ -397,6 +606,24 @@ func (suite *KeeperTestSuite) TestIterateSwapRewardAccrualTimes() {
suite.Equal(expectedAccrualTimes, actualAccrualTimes) 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) { func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite)) suite.Run(t, new(KeeperTestSuite))
} }

View File

@ -108,3 +108,21 @@ func (k msgServer) ClaimSavingsReward(goCtx context.Context, msg *types.MsgClaim
return &types.MsgClaimSavingsRewardResponse{}, nil 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
}

View File

@ -29,6 +29,8 @@ func NewQuerier(k Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
return queryGetSavingsRewards(ctx, req, k, legacyQuerierCdc) return queryGetSavingsRewards(ctx, req, k, legacyQuerierCdc)
case types.QueryGetRewardFactors: case types.QueryGetRewardFactors:
return queryGetRewardFactors(ctx, req, k, legacyQuerierCdc) return queryGetRewardFactors(ctx, req, k, legacyQuerierCdc)
case types.QueryGetEarnRewards:
return queryGetEarnRewards(ctx, req, k, legacyQuerierCdc)
default: default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) 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 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, &params)
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) { func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper, legacyQuerierCdc *codec.LegacyAmino) ([]byte, error) {
var usdxFactors types.RewardIndexes var usdxFactors types.RewardIndexes
k.IterateUSDXMintingRewardFactors(ctx, func(collateralType string, factor sdk.Dec) (stop bool) { 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 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( response := types.NewQueryGetRewardFactorsResponse(
usdxFactors, usdxFactors,
supplyFactors, supplyFactors,
@ -305,6 +358,7 @@ func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper, leg
delegatorFactors, delegatorFactors,
swapFactors, swapFactors,
savingsFactors, savingsFactors,
earnFactors,
) )
bz, err := codec.MarshalJSONIndent(legacyQuerierCdc, response) bz, err := codec.MarshalJSONIndent(legacyQuerierCdc, response)

View File

@ -39,7 +39,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateUpdatedWhenBlockTimeHasIncre
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1")) 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{ suite.storeGlobalBorrowIndexes(types.MultiRewardIndexes{
{ {
@ -91,7 +91,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateUnchangedWhenBlockTimeHasNot
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1")) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -136,7 +136,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoAccumulationWhenSourceSharesAre
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper() // zero total borrows 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -182,7 +182,7 @@ func (suite *AccumulateBorrowRewardsTests) TestStateAddedWhenStateDoesNotExist()
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1")) 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( period := types.NewMultiRewardPeriod(
true, true,
@ -225,7 +225,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoPanicWhenStateDoesNotExist() {
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper() 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( period := types.NewMultiRewardPeriod(
true, true,
@ -253,7 +253,7 @@ func (suite *AccumulateBorrowRewardsTests) TestNoAccumulationWhenBeforeStartTime
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1")) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -299,7 +299,7 @@ func (suite *AccumulateBorrowRewardsTests) TestPanicWhenCurrentTimeLessThanPrevi
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalBorrow(c(denom, 1e6), d("1")) 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) previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, denom, previousAccrualTime) suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, denom, previousAccrualTime)

View File

@ -36,7 +36,7 @@ func TestAccumulateDelegatorRewards(t *testing.T) {
func (suite *AccumulateDelegatorRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreased() { func (suite *AccumulateDelegatorRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreased() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6) 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{ suite.storeGlobalDelegatorIndexes(types.MultiRewardIndexes{
{ {
@ -86,7 +86,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateUpdatedWhenBlockTimeHasIn
func (suite *AccumulateDelegatorRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() { func (suite *AccumulateDelegatorRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -129,7 +129,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateUnchangedWhenBlockTimeHas
func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenSourceSharesAreZero() { func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenSourceSharesAreZero() {
stakingKeeper := newFakeStakingKeeper() // zero total bonded 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -173,7 +173,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenSourceShares
func (suite *AccumulateDelegatorRewardsTests) TestStateAddedWhenStateDoesNotExist() { func (suite *AccumulateDelegatorRewardsTests) TestStateAddedWhenStateDoesNotExist() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6) 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( period := types.NewMultiRewardPeriod(
true, true,
@ -214,7 +214,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestStateAddedWhenStateDoesNotExis
func (suite *AccumulateDelegatorRewardsTests) TestNoPanicWhenStateDoesNotExist() { func (suite *AccumulateDelegatorRewardsTests) TestNoPanicWhenStateDoesNotExist() {
stakingKeeper := newFakeStakingKeeper() 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( period := types.NewMultiRewardPeriod(
true, true,
@ -240,7 +240,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoPanicWhenStateDoesNotExist()
func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenBeforeStartTime() { func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenBeforeStartTime() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -284,7 +284,7 @@ func (suite *AccumulateDelegatorRewardsTests) TestNoAccumulationWhenBeforeStartT
func (suite *AccumulateDelegatorRewardsTests) TestPanicWhenCurrentTimeLessThanPrevious() { func (suite *AccumulateDelegatorRewardsTests) TestPanicWhenCurrentTimeLessThanPrevious() {
stakingKeeper := newFakeStakingKeeper().addBondedTokens(1e6) 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) previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousDelegatorRewardAccrualTime(suite.ctx, types.BondDenom, previousAccrualTime) suite.keeper.SetPreviousDelegatorRewardAccrualTime(suite.ctx, types.BondDenom, previousAccrualTime)

View File

@ -58,7 +58,7 @@ func (suite *InitializeDelegatorRewardTests) TestClaimIsSyncedAndIndexesAreSetWh
DelegatorShares: d("1000"), 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{

View File

@ -37,7 +37,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGl
delegator := arbitraryAddress() delegator := arbitraryAddress()
stakingKeeper := &fakeStakingKeeper{} // use an empty staking keeper that returns no delegations 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -58,7 +58,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUnchangedWhenGl
func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUpdatedWhenGlobalFactorIncreased() { func (suite *SynchronizeDelegatorRewardTests) TestClaimIndexesAreUpdatedWhenGlobalFactorIncreased() {
delegator := arbitraryAddress() 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -97,7 +97,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsUnchangedWhenGlobalFac
unslashedBondedValidator(validatorAddress), 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -142,7 +142,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsIncreasedWhenNewReward
unslashedBondedValidator(validatorAddress), 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -192,7 +192,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestRewardIsIncreasedWhenGlobalFac
unslashedBondedValidator(validatorAddress), 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{ claim := types.DelegatorClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -299,7 +299,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenValAddrIsNil()
unslashedNotBondedValidator(validatorAddresses[3]), 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( suite.Equal(
d("11"), // delegation to bonded validators d("11"), // delegation to bonded validators
@ -343,7 +343,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenExcludingAVali
unslashedNotBondedValidator(validatorAddresses[3]), 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( suite.Equal(
d("10"), d("10"),
@ -387,7 +387,7 @@ func (suite *SynchronizeDelegatorRewardTests) TestGetDelegatedWhenIncludingAVali
unslashedNotBondedValidator(validatorAddresses[3]), 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( suite.Equal(
d("111"), d("111"),

View File

@ -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
}

View File

@ -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)
})
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -38,7 +38,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateUpdatedWhenBlockTimeHasIncre
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1")) 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{ suite.storeGlobalSupplyIndexes(types.MultiRewardIndexes{
{ {
@ -90,7 +90,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateUnchangedWhenBlockTimeHasNot
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1")) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -135,7 +135,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoAccumulationWhenSourceSharesAre
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper() // zero total supplys 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -181,7 +181,7 @@ func (suite *AccumulateSupplyRewardsTests) TestStateAddedWhenStateDoesNotExist()
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1")) 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( period := types.NewMultiRewardPeriod(
true, true,
@ -224,7 +224,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoPanicWhenStateDoesNotExist() {
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper() 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( period := types.NewMultiRewardPeriod(
true, true,
@ -252,7 +252,7 @@ func (suite *AccumulateSupplyRewardsTests) TestNoAccumulationWhenBeforeStartTime
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1")) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -298,7 +298,7 @@ func (suite *AccumulateSupplyRewardsTests) TestPanicWhenCurrentTimeLessThanPrevi
denom := "bnb" denom := "bnb"
hardKeeper := newFakeHardKeeper().addTotalSupply(c(denom, 1e6), d("1")) 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) previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, denom, previousAccrualTime) suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, denom, previousAccrualTime)

View File

@ -37,7 +37,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreas
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) 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{ suite.storeGlobalSwapIndexes(types.MultiRewardIndexes{
{ {
@ -89,7 +89,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIn
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -134,7 +134,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoAccumulationWhenSourceSharesAreZe
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper() // no pools, so no source shares 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -180,7 +180,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateAddedWhenStateDoesNotExist() {
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) 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( period := types.NewMultiRewardPeriod(
true, true,
@ -223,7 +223,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoPanicWhenStateDoesNotExist() {
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper() 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( period := types.NewMultiRewardPeriod(
true, true,
@ -251,7 +251,7 @@ func (suite *AccumulateSwapRewardsTests) TestNoAccumulationWhenBeforeStartTime()
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) 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{ previousIndexes := types.MultiRewardIndexes{
{ {
@ -297,7 +297,7 @@ func (suite *AccumulateSwapRewardsTests) TestPanicWhenCurrentTimeLessThanPreviou
pool := "btc:usdx" pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6)) 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) previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetSwapRewardAccrualTime(suite.ctx, pool, previousAccrualTime) suite.keeper.SetSwapRewardAccrualTime(suite.ctx, pool, previousAccrualTime)

View File

@ -323,7 +323,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUnchangedWhenNo
swapKeeper := newFakeSwapKeeper(). swapKeeper := newFakeSwapKeeper().
addDeposit(poolID_1, owner, i(1e9)) 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{ claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -356,7 +356,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMiss
owner := arbitraryAddress() owner := arbitraryAddress()
// owner has no shares in any pool // 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{ claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{
@ -416,7 +416,7 @@ func (suite *SynchronizeSwapRewardTests) TestGetSyncedClaim_ClaimUpdatedWhenMiss
swapKeeper := newFakeSwapKeeper(). swapKeeper := newFakeSwapKeeper().
addDeposit(poolID_1, owner, i(1e9)). addDeposit(poolID_1, owner, i(1e9)).
addDeposit(poolID_2, 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{ claim := types.SwapClaim{
BaseMultiClaim: types.BaseMultiClaim{ BaseMultiClaim: types.BaseMultiClaim{

View File

@ -34,7 +34,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreas
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1")) 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{ suite.storeGlobalUSDXIndexes(types.RewardIndexes{
{ {
@ -68,7 +68,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIn
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1")) 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{ previousIndexes := types.RewardIndexes{
{ {
@ -104,7 +104,7 @@ func (suite *AccumulateUSDXRewardsTests) TestNoAccumulationWhenSourceSharesAreZe
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper() // zero total borrows 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{ previousIndexes := types.RewardIndexes{
{ {
@ -141,7 +141,7 @@ func (suite *AccumulateUSDXRewardsTests) TestStateAddedWhenStateDoesNotExist() {
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1")) 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( period := types.NewRewardPeriod(
true, true,
@ -174,7 +174,7 @@ func (suite *AccumulateUSDXRewardsTests) TestNoAccumulationWhenBeforeStartTime()
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1")) 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{ previousIndexes := types.RewardIndexes{
{ {
@ -211,7 +211,7 @@ func (suite *AccumulateUSDXRewardsTests) TestPanicWhenCurrentTimeLessThanPreviou
cType := "bnb-a" cType := "bnb-a"
cdpKeeper := newFakeCDPKeeper().addTotalPrincipal(i(1e6)).addInterestFactor(d("1")) 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) previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.SetPreviousUSDXMintingAccrualTime(suite.ctx, cType, previousAccrualTime) suite.keeper.SetPreviousUSDXMintingAccrualTime(suite.ctx, cType, previousAccrualTime)

View File

@ -15,6 +15,7 @@ import (
"github.com/kava-labs/kava/app" "github.com/kava-labs/kava/app"
cdptypes "github.com/kava-labs/kava/x/cdp/types" 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" tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
hardtypes "github.com/kava-labs/kava/x/hard/types" hardtypes "github.com/kava-labs/kava/x/hard/types"
@ -58,7 +59,7 @@ func (suite *unitTester) SetupSuite() {
func (suite *unitTester) SetupTest() { func (suite *unitTester) SetupTest() {
suite.ctx = NewTestContext(suite.incentiveStoreKey) 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() { func (suite *unitTester) TearDownTest() {
@ -66,8 +67,8 @@ func (suite *unitTester) TearDownTest() {
suite.ctx = sdk.Context{} 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 { 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) return keeper.NewKeeper(suite.cdc, suite.incentiveStoreKey, paramSubspace, bk, cdpk, hk, ak, stk, swk, svk, ek)
} }
func (suite *unitTester) storeGlobalBorrowIndexes(indexes types.MultiRewardIndexes) { 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) { func (suite *unitTester) storeHardClaim(claim types.HardLiquidityProviderClaim) {
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim) suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim)
} }
@ -116,6 +123,10 @@ func (suite *unitTester) storeSavingsClaim(claim types.SavingsClaim) {
suite.keeper.SetSavingsClaim(suite.ctx, claim) 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. // fakeParamSubspace is a stub paramSpace to simplify keeper unit test setup.
type fakeParamSubspace struct { type fakeParamSubspace struct {
params types.Params params types.Params
@ -351,6 +362,56 @@ func (k *fakeCDPKeeper) GetCollateral(_ sdk.Context, collateralType string) (cdp
return cdptypes.CollateralParam{}, false 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 // Assorted Testing Data
// note: amino panics when encoding times ≥ the start of year 10000. // note: amino panics when encoding times ≥ the start of year 10000.

View File

View File

@ -14,6 +14,7 @@ const (
DelegatorClaimType = "delegator_claim" DelegatorClaimType = "delegator_claim"
SwapClaimType = "swap" SwapClaimType = "swap"
SavingsClaimType = "savings" SavingsClaimType = "savings"
EarnClaimType = "earn"
) )
// GetOwner is a getter for Claim Owner // GetOwner is a getter for Claim Owner
@ -339,6 +340,58 @@ func (cs SavingsClaims) Validate() error {
return nil 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 ---------------------- // ---------------------- Reward indexes are used internally in the store ----------------------
// NewRewardIndex returns a new RewardIndex // NewRewardIndex returns a new RewardIndex

View File

@ -454,6 +454,45 @@ func (m *SavingsClaim) XXX_DiscardUnknown() {
var xxx_messageInfo_SavingsClaim proto.InternalMessageInfo 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() { func init() {
proto.RegisterType((*BaseClaim)(nil), "kava.incentive.v1beta1.BaseClaim") proto.RegisterType((*BaseClaim)(nil), "kava.incentive.v1beta1.BaseClaim")
proto.RegisterType((*BaseMultiClaim)(nil), "kava.incentive.v1beta1.BaseMultiClaim") proto.RegisterType((*BaseMultiClaim)(nil), "kava.incentive.v1beta1.BaseMultiClaim")
@ -466,6 +505,7 @@ func init() {
proto.RegisterType((*DelegatorClaim)(nil), "kava.incentive.v1beta1.DelegatorClaim") proto.RegisterType((*DelegatorClaim)(nil), "kava.incentive.v1beta1.DelegatorClaim")
proto.RegisterType((*SwapClaim)(nil), "kava.incentive.v1beta1.SwapClaim") proto.RegisterType((*SwapClaim)(nil), "kava.incentive.v1beta1.SwapClaim")
proto.RegisterType((*SavingsClaim)(nil), "kava.incentive.v1beta1.SavingsClaim") proto.RegisterType((*SavingsClaim)(nil), "kava.incentive.v1beta1.SavingsClaim")
proto.RegisterType((*EarnClaim)(nil), "kava.incentive.v1beta1.EarnClaim")
} }
func init() { func init() {
@ -473,50 +513,51 @@ func init() {
} }
var fileDescriptor_5f7515029623a895 = []byte{ var fileDescriptor_5f7515029623a895 = []byte{
// 686 bytes of a gzipped FileDescriptorProto // 693 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0x4f, 0x4f, 0x13, 0x4f, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0x4f, 0x4f, 0x13, 0x4d,
0x18, 0xc7, 0x3b, 0xf0, 0x83, 0xfc, 0x3a, 0x94, 0x4a, 0x16, 0x50, 0xe8, 0x61, 0x8b, 0x25, 0xc1, 0x1c, 0xc7, 0x3b, 0xf0, 0x40, 0x9e, 0x0e, 0xa5, 0x0f, 0x59, 0xe0, 0x11, 0x7a, 0xd8, 0x62, 0x49,
0x26, 0xa6, 0xbb, 0x82, 0x07, 0x13, 0x6f, 0x2c, 0xc4, 0x80, 0x91, 0x48, 0xb6, 0x9a, 0x18, 0x0f, 0xb0, 0x89, 0xe9, 0xae, 0xe0, 0xc1, 0xc4, 0x1b, 0x0b, 0x1a, 0x30, 0x12, 0xc9, 0x56, 0x13, 0xe3,
0x36, 0xb3, 0xbb, 0x63, 0x9d, 0xb0, 0xdd, 0xa9, 0x3b, 0xd3, 0x96, 0xbe, 0x06, 0x2f, 0xfa, 0x06, 0xc1, 0x66, 0x76, 0x77, 0xac, 0x13, 0xb6, 0x3b, 0x75, 0x66, 0xdb, 0xd2, 0xd7, 0xe0, 0x45, 0xdf,
0x7c, 0x01, 0x5e, 0xbc, 0xf0, 0x22, 0x88, 0xf1, 0x40, 0x8c, 0x89, 0x7f, 0x0e, 0x15, 0xe1, 0xea, 0x80, 0x2f, 0xc0, 0x8b, 0x17, 0x5e, 0x04, 0x31, 0x1e, 0x88, 0x31, 0xf1, 0xcf, 0xa1, 0x22, 0x5c,
0x2b, 0xf0, 0x64, 0xe6, 0x0f, 0xb0, 0x40, 0x4b, 0x88, 0x29, 0x1e, 0x38, 0xb5, 0xf3, 0xcc, 0xb3, 0x7d, 0x05, 0x9e, 0xcc, 0xfc, 0x01, 0x16, 0x68, 0x09, 0x31, 0xc5, 0x03, 0xa7, 0xdd, 0xf9, 0xcd,
0xcf, 0xf7, 0xf3, 0x7c, 0xf7, 0xd9, 0xd9, 0x85, 0xb3, 0x1b, 0xa8, 0x89, 0x6c, 0x12, 0xf9, 0x38, 0x6f, 0x7f, 0xdf, 0xcf, 0xef, 0x3b, 0xb3, 0xb3, 0x0b, 0x67, 0x37, 0x50, 0x13, 0xd9, 0x24, 0xf2,
0xe2, 0xa4, 0x89, 0xed, 0xe6, 0xbc, 0x87, 0x39, 0x9a, 0xb7, 0xfd, 0x10, 0x91, 0x1a, 0xb3, 0xea, 0x71, 0x14, 0x93, 0x26, 0xb6, 0x9b, 0xf3, 0x1e, 0x8e, 0xd1, 0xbc, 0xed, 0x87, 0x88, 0xd4, 0xb8,
0x31, 0xe5, 0xd4, 0xb8, 0x2a, 0x92, 0xac, 0xc3, 0x24, 0x4b, 0x27, 0xe5, 0x26, 0xaa, 0xb4, 0x4a, 0x55, 0x67, 0x34, 0xa6, 0xc6, 0xff, 0x22, 0xc9, 0x3a, 0x4c, 0xb2, 0x74, 0x52, 0x6e, 0xa2, 0x4a,
0x65, 0x8a, 0x2d, 0xfe, 0xa9, 0xec, 0xdc, 0xb4, 0x4f, 0x59, 0x8d, 0xb2, 0x8a, 0xda, 0x50, 0x0b, 0xab, 0x54, 0xa6, 0xd8, 0xe2, 0x4e, 0x65, 0xe7, 0xa6, 0x7d, 0xca, 0x6b, 0x94, 0x57, 0xd4, 0x84,
0xbd, 0x65, 0xaa, 0x95, 0xed, 0x21, 0x96, 0x90, 0xa2, 0x24, 0x52, 0xfb, 0x85, 0xf7, 0x00, 0xa6, 0x1a, 0xe8, 0x29, 0x53, 0x8d, 0x6c, 0x0f, 0xf1, 0x84, 0x14, 0x25, 0x91, 0x9a, 0x2f, 0xbc, 0x03,
0x1d, 0xc4, 0xf0, 0x92, 0x50, 0x37, 0x9e, 0xc1, 0x21, 0xda, 0x8a, 0x70, 0x3c, 0x05, 0x66, 0x40, 0x30, 0xed, 0x20, 0x8e, 0x97, 0x84, 0xba, 0xf1, 0x14, 0x0e, 0xd1, 0x56, 0x84, 0xd9, 0x14, 0x98,
0x31, 0xe3, 0xac, 0xfc, 0xee, 0xe4, 0x4b, 0x55, 0xc2, 0x5f, 0x34, 0x3c, 0xcb, 0xa7, 0x35, 0x5d, 0x01, 0xc5, 0x8c, 0xb3, 0xf2, 0xab, 0x93, 0x2f, 0x55, 0x49, 0xfc, 0xbc, 0xe1, 0x59, 0x3e, 0xad,
0x59, 0xff, 0x94, 0x58, 0xb0, 0x61, 0xf3, 0x76, 0x1d, 0x33, 0x6b, 0xd1, 0xf7, 0x17, 0x83, 0x20, 0xe9, 0xca, 0xfa, 0x52, 0xe2, 0xc1, 0x86, 0x1d, 0xb7, 0xeb, 0x98, 0x5b, 0x8b, 0xbe, 0xbf, 0x18,
0xc6, 0x8c, 0x7d, 0xda, 0x2a, 0x8d, 0x6b, 0x7d, 0x1d, 0x71, 0xda, 0x1c, 0x33, 0x57, 0x95, 0x35, 0x04, 0x0c, 0x73, 0xfe, 0x71, 0xab, 0x34, 0xae, 0xf5, 0x75, 0xc4, 0x69, 0xc7, 0x98, 0xbb, 0xaa,
0xee, 0xc0, 0xe1, 0x18, 0xb7, 0x50, 0x1c, 0x4c, 0x0d, 0xcc, 0x80, 0xe2, 0xc8, 0xc2, 0xb4, 0xa5, 0xac, 0x71, 0x0b, 0x0e, 0x33, 0xdc, 0x42, 0x2c, 0x98, 0x1a, 0x98, 0x01, 0xc5, 0x91, 0x85, 0x69,
0x93, 0x05, 0xde, 0x41, 0x93, 0xd6, 0x12, 0x25, 0x91, 0xf3, 0xdf, 0x76, 0x27, 0x9f, 0x72, 0x75, 0x4b, 0x27, 0x0b, 0xbc, 0x83, 0x26, 0xad, 0x25, 0x4a, 0x22, 0xe7, 0x9f, 0xed, 0x4e, 0x3e, 0xe5,
0xfa, 0xdd, 0xf4, 0x87, 0xad, 0xd2, 0x90, 0x64, 0x2c, 0xec, 0x02, 0x98, 0x15, 0xc4, 0x6b, 0x8d, 0xea, 0xf4, 0xdb, 0xe9, 0xf7, 0x5b, 0xa5, 0x21, 0xc9, 0x58, 0xd8, 0x05, 0x30, 0x2b, 0x88, 0xd7,
0x90, 0x93, 0x7f, 0x83, 0xed, 0x27, 0xb0, 0x07, 0xcf, 0xc6, 0xbe, 0x25, 0xb0, 0xdf, 0xfd, 0xc8, 0x1a, 0x61, 0x4c, 0xfe, 0x0e, 0xb6, 0x9f, 0xc0, 0x1e, 0x3c, 0x1b, 0xfb, 0x86, 0xc0, 0x7e, 0xfb,
0x17, 0xcf, 0xa1, 0x2f, 0x2e, 0x60, 0xdd, 0x5a, 0x7c, 0x05, 0xe0, 0x88, 0x2b, 0xa3, 0xab, 0x51, 0x3d, 0x5f, 0x3c, 0x87, 0xbe, 0x78, 0x80, 0x77, 0x6b, 0xf1, 0x25, 0x80, 0x23, 0xae, 0x8c, 0xae,
0x80, 0x37, 0x8d, 0x1b, 0xf0, 0x8a, 0x4f, 0xc3, 0x10, 0x71, 0x1c, 0xa3, 0xb0, 0x22, 0x2e, 0x96, 0x46, 0x01, 0xde, 0x34, 0xae, 0xc1, 0xff, 0x7c, 0x1a, 0x86, 0x28, 0xc6, 0x0c, 0x85, 0x15, 0xf1,
0x9d, 0xa6, 0xdd, 0xec, 0x51, 0xf8, 0x51, 0xbb, 0x8e, 0x8d, 0x32, 0x1c, 0x55, 0xd5, 0x2a, 0xcf, 0xb0, 0xec, 0x34, 0xed, 0x66, 0x8f, 0xc2, 0x0f, 0xdb, 0x75, 0x6c, 0x94, 0xe1, 0xa8, 0xaa, 0x56,
0x91, 0xcf, 0x69, 0x2c, 0x6d, 0xce, 0x38, 0x96, 0x80, 0xfa, 0xde, 0xc9, 0xcf, 0x9d, 0x03, 0x6a, 0x79, 0x86, 0xfc, 0x98, 0x32, 0x69, 0x73, 0xc6, 0xb1, 0x04, 0xd4, 0xb7, 0x4e, 0x7e, 0xee, 0x1c,
0x19, 0xfb, 0x6e, 0x46, 0x15, 0xb9, 0x27, 0x6b, 0x14, 0x5a, 0xd0, 0x48, 0xc0, 0x60, 0xb6, 0x2e, 0x50, 0xcb, 0xd8, 0x77, 0x33, 0xaa, 0xc8, 0x5d, 0x59, 0xa3, 0xd0, 0x82, 0x46, 0x02, 0x06, 0xf3,
0x27, 0x14, 0xc1, 0xac, 0x96, 0x22, 0x2a, 0x3c, 0x05, 0xa4, 0x37, 0xb3, 0x56, 0xf7, 0xd1, 0xb5, 0x75, 0xb9, 0x43, 0x11, 0xcc, 0x6a, 0x29, 0xa2, 0xc2, 0x53, 0x40, 0x7a, 0x33, 0x6b, 0x75, 0xdf,
0x12, 0x35, 0x9c, 0x49, 0xed, 0xd2, 0xe8, 0xb1, 0xc2, 0xae, 0x86, 0xd7, 0xcb, 0xc2, 0x5b, 0x00, 0xba, 0x56, 0xa2, 0x86, 0x33, 0xa9, 0x5d, 0x1a, 0x3d, 0x56, 0xd8, 0xd5, 0xf0, 0x7a, 0x58, 0x78,
0xc7, 0xe4, 0x5d, 0xfe, 0x2b, 0x2f, 0x4e, 0x03, 0x0e, 0xf4, 0x1b, 0xf0, 0x0d, 0x80, 0xd7, 0x4e, 0x03, 0xe0, 0x98, 0x5c, 0xe5, 0x3f, 0xf2, 0xe2, 0x34, 0xe0, 0x40, 0xbf, 0x01, 0x5f, 0x03, 0x78,
0x02, 0x1e, 0xf8, 0xd3, 0x84, 0x13, 0x35, 0xb1, 0x55, 0xe9, 0xea, 0x52, 0xb1, 0x17, 0xc4, 0xc9, 0xe5, 0x24, 0xe0, 0x81, 0x3f, 0x4d, 0x38, 0x51, 0x13, 0x53, 0x95, 0xae, 0x2e, 0x15, 0x7b, 0x41,
0x72, 0x4e, 0x4e, 0x93, 0x18, 0xa7, 0x85, 0x5c, 0xa3, 0x76, 0x2a, 0x56, 0xf8, 0x08, 0xe0, 0xd8, 0x9c, 0x2c, 0xe7, 0xe4, 0x34, 0x89, 0x71, 0x5a, 0xc8, 0x35, 0x6a, 0xa7, 0x62, 0x85, 0x0f, 0x00,
0xe3, 0xf2, 0xf2, 0x93, 0x35, 0x12, 0x71, 0x12, 0x55, 0xd5, 0x03, 0x72, 0x1f, 0x42, 0x31, 0xaa, 0x8e, 0x3d, 0x2a, 0x2f, 0x3f, 0x5e, 0x23, 0x51, 0x4c, 0xa2, 0xaa, 0x7a, 0x41, 0xee, 0x41, 0x28,
0x15, 0x79, 0xc6, 0x48, 0xbf, 0x46, 0x16, 0xae, 0xf7, 0x42, 0x38, 0x3c, 0x0e, 0x9c, 0xff, 0x85, 0xb6, 0x6a, 0x45, 0x9e, 0x31, 0xd2, 0xaf, 0x91, 0x85, 0xab, 0xbd, 0x10, 0x0e, 0x8f, 0x03, 0xe7,
0xf6, 0x4e, 0x27, 0x0f, 0xdc, 0xb4, 0x77, 0x78, 0x46, 0x5c, 0xbc, 0xaf, 0xc9, 0x47, 0xe1, 0xd7, 0x5f, 0xa1, 0xbd, 0xd3, 0xc9, 0x03, 0x37, 0xed, 0x1d, 0x9e, 0x11, 0x17, 0xef, 0x6b, 0xf2, 0x55,
0x00, 0xcc, 0xad, 0xa0, 0x38, 0x78, 0x40, 0x5e, 0x36, 0x48, 0x40, 0x78, 0x7b, 0x3d, 0xa6, 0x4d, 0xf8, 0x39, 0x00, 0x73, 0x2b, 0x88, 0x05, 0xf7, 0xc9, 0x8b, 0x06, 0x09, 0x48, 0xdc, 0x5e, 0x67,
0x12, 0xe0, 0x58, 0xc1, 0x3c, 0xec, 0xd2, 0xd8, 0xdc, 0x59, 0x8d, 0x1d, 0x9d, 0x1a, 0xdd, 0xbb, 0xb4, 0x49, 0x02, 0xcc, 0x14, 0xcc, 0x83, 0x2e, 0x8d, 0xcd, 0x9d, 0xd5, 0xd8, 0xd1, 0xa9, 0xd1,
0xdb, 0x84, 0x93, 0xac, 0x51, 0xaf, 0x87, 0xed, 0x4a, 0xd7, 0x26, 0xfb, 0x73, 0xdf, 0xc6, 0x95, 0xbd, 0xbb, 0x4d, 0x38, 0xc9, 0x1b, 0xf5, 0x7a, 0xd8, 0xae, 0x74, 0x6d, 0xb2, 0x3f, 0xeb, 0x36,
0xc4, 0xb1, 0xa0, 0x50, 0xf6, 0x68, 0x1c, 0xd3, 0xd6, 0x49, 0xe5, 0xc1, 0x7e, 0x2a, 0x2b, 0x09, 0xae, 0x24, 0x8e, 0x05, 0x85, 0xb2, 0x47, 0x19, 0xa3, 0xad, 0x93, 0xca, 0x83, 0xfd, 0x54, 0x56,
0xb7, 0x97, 0xdd, 0xdf, 0x00, 0xcc, 0x2e, 0xe3, 0x10, 0x57, 0x11, 0xa7, 0x17, 0x65, 0xf1, 0x46, 0x12, 0x6e, 0x2f, 0xbb, 0xbf, 0x02, 0x98, 0x5d, 0xc6, 0x21, 0xae, 0xa2, 0x98, 0x5e, 0x94, 0xc5,
0x8f, 0x01, 0xea, 0x4f, 0x87, 0xbd, 0x47, 0xe9, 0x33, 0x80, 0xe9, 0x72, 0x0b, 0xd5, 0x2f, 0x59, 0x1b, 0x3d, 0x36, 0x50, 0x7f, 0x3a, 0xec, 0xbd, 0x95, 0x3e, 0x01, 0x98, 0x2e, 0xb7, 0x50, 0xfd,
0x5b, 0x5f, 0x00, 0xcc, 0x94, 0x51, 0x93, 0x44, 0x55, 0x76, 0xb9, 0x3a, 0x73, 0x56, 0xb7, 0x7f, 0x92, 0xb5, 0xf5, 0x19, 0xc0, 0x4c, 0x19, 0x35, 0x49, 0x54, 0xe5, 0x97, 0x70, 0xc1, 0xee, 0x20,
0x9a, 0xa9, 0xed, 0x3d, 0x13, 0xec, 0xec, 0x99, 0x60, 0x77, 0xcf, 0x04, 0xaf, 0xf7, 0xcd, 0xd4, 0x16, 0x5d, 0xae, 0xb6, 0x9c, 0xd5, 0xed, 0x1f, 0x66, 0x6a, 0x7b, 0xcf, 0x04, 0x3b, 0x7b, 0x26,
0xce, 0xbe, 0x99, 0xfa, 0xba, 0x6f, 0xa6, 0x9e, 0xde, 0x4c, 0xbc, 0xcc, 0x04, 0x47, 0x29, 0x44, 0xd8, 0xdd, 0x33, 0xc1, 0xab, 0x7d, 0x33, 0xb5, 0xb3, 0x6f, 0xa6, 0xbe, 0xec, 0x9b, 0xa9, 0x27,
0x1e, 0x93, 0xff, 0xec, 0xcd, 0xc4, 0xe7, 0x95, 0x7c, 0xab, 0x79, 0xc3, 0xf2, 0x6b, 0xe7, 0xf6, 0xd7, 0x13, 0xdf, 0x68, 0xc1, 0x51, 0x0a, 0x91, 0xc7, 0xe5, 0x9d, 0xbd, 0x99, 0xf8, 0x6b, 0x94,
0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x6c, 0x47, 0x50, 0x7d, 0x09, 0x00, 0x00, 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) { 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 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 { func encodeVarintClaims(dAtA []byte, offset int, v uint64) int {
offset -= sovClaims(v) offset -= sovClaims(v)
base := offset base := offset
@ -1210,6 +1298,23 @@ func (m *SavingsClaim) Size() (n int) {
return n 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) { func sovClaims(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7 return (math_bits.Len64(x|1) + 6) / 7
} }
@ -2469,6 +2574,123 @@ func (m *SavingsClaim) Unmarshal(dAtA []byte) error {
} }
return nil 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) { func skipClaims(dAtA []byte) (n int, err error) {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

View File

@ -17,6 +17,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgClaimDelegatorReward{}, "incentive/MsgClaimDelegatorReward", nil) cdc.RegisterConcrete(&MsgClaimDelegatorReward{}, "incentive/MsgClaimDelegatorReward", nil)
cdc.RegisterConcrete(&MsgClaimSwapReward{}, "incentive/MsgClaimSwapReward", nil) cdc.RegisterConcrete(&MsgClaimSwapReward{}, "incentive/MsgClaimSwapReward", nil)
cdc.RegisterConcrete(&MsgClaimSavingsReward{}, "incentive/MsgClaimSavingsReward", nil) cdc.RegisterConcrete(&MsgClaimSavingsReward{}, "incentive/MsgClaimSavingsReward", nil)
cdc.RegisterConcrete(&MsgClaimEarnReward{}, "incentive/MsgClaimEarnReward", nil)
} }
func RegisterInterfaces(registry types.InterfaceRegistry) { func RegisterInterfaces(registry types.InterfaceRegistry) {
@ -26,6 +27,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgClaimDelegatorReward{}, &MsgClaimDelegatorReward{},
&MsgClaimSwapReward{}, &MsgClaimSwapReward{},
&MsgClaimSavingsReward{}, &MsgClaimSavingsReward{},
&MsgClaimEarnReward{},
) )
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)

View File

@ -6,6 +6,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
cdptypes "github.com/kava-labs/kava/x/cdp/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" hardtypes "github.com/kava-labs/kava/x/hard/types"
savingstypes "github.com/kava-labs/kava/x/savings/types" savingstypes "github.com/kava-labs/kava/x/savings/types"
) )
@ -63,6 +64,12 @@ type SavingsKeeper interface {
GetSavingsModuleAccountBalances(ctx sdk.Context) sdk.Coins 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) // AccountKeeper expected interface for the account keeper (noalias)
type AccountKeeper interface { type AccountKeeper interface {
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI

View File

@ -15,13 +15,15 @@ var (
AccumulationTimes{}, AccumulationTimes{},
MultiRewardIndexes{}, MultiRewardIndexes{},
) )
DefaultEarnClaims = EarnClaims{}
) )
// NewGenesisState returns a new genesis state // NewGenesisState returns a new genesis state
func NewGenesisState( func NewGenesisState(
params Params, 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, c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims,
earnc EarnClaims,
) GenesisState { ) GenesisState {
return GenesisState{ return GenesisState{
Params: params, Params: params,
@ -32,12 +34,14 @@ func NewGenesisState(
DelegatorRewardState: delegatorState, DelegatorRewardState: delegatorState,
SwapRewardState: swapState, SwapRewardState: swapState,
SavingsRewardState: savingsState, SavingsRewardState: savingsState,
EarnRewardState: earnState,
USDXMintingClaims: c, USDXMintingClaims: c,
HardLiquidityProviderClaims: hc, HardLiquidityProviderClaims: hc,
DelegatorClaims: dc, DelegatorClaims: dc,
SwapClaims: sc, SwapClaims: sc,
SavingsClaims: savingsc, SavingsClaims: savingsc,
EarnClaims: earnc,
} }
} }
@ -51,11 +55,13 @@ func DefaultGenesisState() GenesisState {
DelegatorRewardState: DefaultGenesisRewardState, DelegatorRewardState: DefaultGenesisRewardState,
SwapRewardState: DefaultGenesisRewardState, SwapRewardState: DefaultGenesisRewardState,
SavingsRewardState: DefaultGenesisRewardState, SavingsRewardState: DefaultGenesisRewardState,
EarnRewardState: DefaultGenesisRewardState,
USDXMintingClaims: DefaultUSDXClaims, USDXMintingClaims: DefaultUSDXClaims,
HardLiquidityProviderClaims: DefaultHardClaims, HardLiquidityProviderClaims: DefaultHardClaims,
DelegatorClaims: DefaultDelegatorClaims, DelegatorClaims: DefaultDelegatorClaims,
SwapClaims: DefaultSwapClaims, SwapClaims: DefaultSwapClaims,
SavingsClaims: DefaultSavingsClaims, SavingsClaims: DefaultSavingsClaims,
EarnClaims: DefaultEarnClaims,
} }
} }
@ -84,6 +90,9 @@ func (gs GenesisState) Validate() error {
if err := gs.SavingsRewardState.Validate(); err != nil { if err := gs.SavingsRewardState.Validate(); err != nil {
return err return err
} }
if err := gs.EarnRewardState.Validate(); err != nil {
return err
}
if err := gs.USDXMintingClaims.Validate(); err != nil { if err := gs.USDXMintingClaims.Validate(); err != nil {
return err return err
@ -97,7 +106,12 @@ func (gs GenesisState) Validate() error {
if err := gs.SwapClaims.Validate(); err != nil { if err := gs.SwapClaims.Validate(); err != nil {
return err return err
} }
return gs.SavingsClaims.Validate()
if err := gs.SavingsClaims.Validate(); err != nil {
return err
}
return gs.EarnClaims.Validate()
} }
// NewGenesisRewardState returns a new GenesisRewardState // NewGenesisRewardState returns a new GenesisRewardState

View File

@ -119,6 +119,8 @@ type GenesisState struct {
SwapClaims SwapClaims `protobuf:"bytes,10,rep,name=swap_claims,json=swapClaims,proto3,castrepeated=SwapClaims" json:"swap_claims"` 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"` 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"` 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{} } func (m *GenesisState) Reset() { *m = GenesisState{} }
@ -165,54 +167,57 @@ func init() {
} }
var fileDescriptor_8b76737885d05afd = []byte{ var fileDescriptor_8b76737885d05afd = []byte{
// 744 bytes of a gzipped FileDescriptorProto // 785 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x4f, 0x13, 0x41, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x4f, 0xdb, 0x48,
0x14, 0xc7, 0xbb, 0x80, 0x08, 0x53, 0xa0, 0x74, 0x2c, 0x50, 0x4b, 0xb2, 0x45, 0x20, 0xda, 0x68, 0x14, 0xc7, 0x63, 0x60, 0x59, 0x98, 0x00, 0x21, 0xb3, 0x01, 0xb2, 0x41, 0x72, 0x58, 0x40, 0xbb,
0xdc, 0x0d, 0xf5, 0xea, 0xc5, 0x95, 0x44, 0x49, 0x24, 0x21, 0x5b, 0x34, 0xc6, 0x98, 0x34, 0xb3, 0xd1, 0x56, 0xb5, 0x45, 0x7a, 0xed, 0xa5, 0x2e, 0x55, 0x8b, 0x54, 0x24, 0xe4, 0x50, 0x54, 0x55,
0xdd, 0x61, 0x19, 0xdd, 0x5f, 0xee, 0xec, 0xb6, 0xf4, 0xe6, 0xd1, 0x9b, 0xfc, 0x01, 0x26, 0xde, 0x95, 0xa2, 0x71, 0x3c, 0x98, 0x69, 0xfd, 0xab, 0x1e, 0x3b, 0x21, 0xb7, 0x1e, 0x7b, 0xe4, 0x0f,
0xfd, 0x4b, 0x38, 0x72, 0xf4, 0x04, 0x5a, 0xfe, 0x11, 0x33, 0xb3, 0xb3, 0x65, 0xb7, 0x65, 0x31, 0xa8, 0xd4, 0x7b, 0xff, 0x8f, 0x4a, 0x1c, 0x39, 0xf6, 0x04, 0x6d, 0xf8, 0x47, 0xaa, 0x19, 0x8f,
0xe2, 0x6d, 0xfa, 0xe6, 0xbd, 0xef, 0xe7, 0x3b, 0xf3, 0xde, 0x76, 0xc0, 0xe6, 0x47, 0xd4, 0x45, 0x83, 0x9d, 0x60, 0xaa, 0xa6, 0xb7, 0xc9, 0x9b, 0x37, 0xdf, 0xcf, 0xf7, 0xcd, 0x7b, 0x13, 0x83,
0x2a, 0x71, 0x3b, 0xd8, 0x0d, 0x49, 0x17, 0xab, 0xdd, 0x2d, 0x03, 0x87, 0x68, 0x4b, 0xb5, 0xb0, 0xed, 0xb7, 0xa8, 0x8b, 0x54, 0xe2, 0x76, 0xb0, 0x1b, 0x92, 0x2e, 0x56, 0xbb, 0x3b, 0x06, 0x0e,
0x8b, 0x29, 0xa1, 0x8a, 0x1f, 0x78, 0xa1, 0x07, 0x97, 0x59, 0x96, 0x32, 0xcc, 0x52, 0x44, 0x56, 0xd1, 0x8e, 0x6a, 0x61, 0x17, 0x53, 0x42, 0x15, 0x3f, 0xf0, 0x42, 0x0f, 0xae, 0xb2, 0x2c, 0x65,
0xad, 0x62, 0x79, 0x96, 0xc7, 0x53, 0x54, 0xb6, 0x8a, 0xb3, 0x6b, 0x1b, 0x39, 0x9a, 0x1d, 0x1b, 0x98, 0xa5, 0x88, 0xac, 0x5a, 0xc5, 0xf2, 0x2c, 0x8f, 0xa7, 0xa8, 0x6c, 0x15, 0x67, 0xd7, 0xb6,
0x11, 0x87, 0xfe, 0x25, 0xc9, 0x47, 0x01, 0x1a, 0x26, 0xd5, 0x2d, 0xcf, 0xb3, 0x6c, 0xac, 0xf2, 0x72, 0x34, 0x3b, 0x36, 0x22, 0x0e, 0xfd, 0x49, 0x92, 0x8f, 0x02, 0x34, 0x4c, 0xaa, 0x5b, 0x9e,
0x5f, 0x46, 0x74, 0xa0, 0x86, 0xc4, 0xc1, 0x34, 0x44, 0x8e, 0x1f, 0x27, 0xac, 0x7f, 0x97, 0xc0, 0x67, 0xd9, 0x58, 0xe5, 0xbf, 0x8c, 0xe8, 0x58, 0x0d, 0x89, 0x83, 0x69, 0x88, 0x1c, 0x3f, 0x4e,
0xe2, 0xb3, 0x4e, 0x27, 0x72, 0x22, 0x1b, 0x85, 0xc4, 0x73, 0xf7, 0x89, 0x83, 0xe1, 0x03, 0x50, 0xd8, 0xfc, 0x24, 0x81, 0xe5, 0x47, 0x9d, 0x4e, 0xe4, 0x44, 0x36, 0x0a, 0x89, 0xe7, 0x1e, 0x12,
0xea, 0x78, 0xb6, 0x8d, 0x42, 0x1c, 0x20, 0xbb, 0x1d, 0xf6, 0x7d, 0x5c, 0x95, 0xd6, 0xa4, 0xc6, 0x07, 0xc3, 0xff, 0x40, 0xa9, 0xe3, 0xd9, 0x36, 0x0a, 0x71, 0x80, 0xec, 0x76, 0xd8, 0xf7, 0x71,
0xac, 0xbe, 0x70, 0x19, 0xde, 0xef, 0xfb, 0x18, 0x1a, 0xa0, 0xe6, 0x07, 0xb8, 0x4b, 0xbc, 0x88, 0x55, 0xda, 0x90, 0x1a, 0xf3, 0xfa, 0xd2, 0x4d, 0xf8, 0xb0, 0xef, 0x63, 0x68, 0x80, 0x9a, 0x1f,
0xb6, 0x51, 0x4a, 0xa5, 0xcd, 0x30, 0xd5, 0x89, 0x35, 0xa9, 0x51, 0x6c, 0xd6, 0x94, 0xd8, 0x83, 0xe0, 0x2e, 0xf1, 0x22, 0xda, 0x46, 0x29, 0x95, 0x36, 0xc3, 0x54, 0xa7, 0x36, 0xa4, 0x46, 0xb1,
0x92, 0x78, 0x50, 0xf6, 0x13, 0x0f, 0xda, 0xcc, 0xc9, 0x59, 0xbd, 0x70, 0x7c, 0x5e, 0x97, 0xf4, 0x59, 0x53, 0x62, 0x0f, 0x4a, 0xe2, 0x41, 0x39, 0x4c, 0x3c, 0x68, 0x73, 0xe7, 0x97, 0xf5, 0xc2,
0x6a, 0xa2, 0x33, 0x6a, 0x66, 0xfd, 0xf3, 0x04, 0x80, 0x2f, 0xe2, 0xcb, 0xd4, 0x71, 0x0f, 0x05, 0xd9, 0x55, 0x5d, 0xd2, 0xab, 0x89, 0xce, 0xa8, 0x99, 0xcd, 0xf7, 0x53, 0x00, 0x3e, 0x8d, 0x2f,
0x66, 0x2b, 0x44, 0x21, 0x86, 0x01, 0x80, 0x63, 0x44, 0x5a, 0x95, 0xd6, 0x26, 0x1b, 0xc5, 0x66, 0x53, 0xc7, 0x3d, 0x14, 0x98, 0xad, 0x10, 0x85, 0x18, 0x06, 0x00, 0x8e, 0x11, 0x69, 0x55, 0xda,
0x43, 0xb9, 0xfa, 0xba, 0x95, 0x51, 0x71, 0xed, 0x2e, 0x33, 0xf0, 0xe3, 0xbc, 0x5e, 0x1e, 0xdd, 0x98, 0x6e, 0x14, 0x9b, 0x0d, 0xe5, 0xf6, 0xeb, 0x56, 0x46, 0xc5, 0xb5, 0xbf, 0x99, 0x81, 0xcf,
0xa1, 0x7a, 0x19, 0x8d, 0x86, 0x60, 0x17, 0x54, 0x9c, 0xc8, 0x0e, 0x49, 0x3b, 0xe0, 0x46, 0xda, 0x57, 0xf5, 0xf2, 0xe8, 0x0e, 0xd5, 0xcb, 0x68, 0x34, 0x04, 0xbb, 0xa0, 0xe2, 0x44, 0x76, 0x48,
0xc4, 0x35, 0xf1, 0x11, 0xa6, 0xd5, 0x89, 0xeb, 0xa9, 0xbb, 0xac, 0x26, 0xf6, 0xbe, 0xc3, 0x2a, 0xda, 0x01, 0x37, 0xd2, 0x26, 0xae, 0x89, 0x4f, 0x31, 0xad, 0x4e, 0xdd, 0x4d, 0xdd, 0x67, 0x67,
0xb4, 0x9a, 0xa0, 0xc2, 0xd1, 0x1d, 0x4c, 0x75, 0xe8, 0x8c, 0xc5, 0xd6, 0xbf, 0x02, 0x30, 0x27, 0x62, 0xef, 0x7b, 0xec, 0x84, 0x56, 0x13, 0x54, 0x38, 0xba, 0x83, 0xa9, 0x0e, 0x9d, 0xb1, 0xd8,
0xae, 0x20, 0x3e, 0xfc, 0x53, 0x30, 0x1d, 0xb7, 0x99, 0xf7, 0xa5, 0xd8, 0x94, 0xf3, 0xd0, 0x7b, 0xe6, 0x97, 0x22, 0x58, 0x10, 0x57, 0x10, 0x17, 0xff, 0x10, 0xcc, 0xc6, 0x6d, 0xe6, 0x7d, 0x29,
0x3c, 0x4b, 0x9b, 0x62, 0x40, 0x5d, 0xd4, 0x40, 0x0f, 0x94, 0x23, 0x6a, 0x1e, 0x25, 0xa7, 0xa0, 0x36, 0xe5, 0x3c, 0xf4, 0x01, 0xcf, 0xd2, 0x66, 0x18, 0x50, 0x17, 0x67, 0xa0, 0x07, 0xca, 0x11,
0x4c, 0x52, 0x34, 0xeb, 0x61, 0x9e, 0xd0, 0x78, 0x07, 0xb4, 0x15, 0x26, 0x3a, 0x38, 0xab, 0x97, 0x35, 0x4f, 0x93, 0x2a, 0x28, 0x93, 0x14, 0xcd, 0xfa, 0x3f, 0x4f, 0x68, 0xbc, 0x03, 0xda, 0x1a,
0x5e, 0xb7, 0xb6, 0xdf, 0xa6, 0x36, 0xf4, 0x12, 0x53, 0x4f, 0xf7, 0x8a, 0x80, 0xea, 0x21, 0x27, 0x13, 0x1d, 0x5c, 0xd6, 0x4b, 0x2f, 0x5a, 0xbb, 0x2f, 0x53, 0x1b, 0x7a, 0x89, 0xa9, 0xa7, 0x7b,
0x45, 0xbe, 0x6f, 0xf7, 0xb3, 0xdc, 0xc9, 0x7f, 0xe6, 0xc6, 0x87, 0x59, 0x62, 0x8a, 0x2d, 0x2e, 0x45, 0x40, 0xf5, 0x84, 0x93, 0x22, 0xdf, 0xb7, 0xfb, 0x59, 0xee, 0xf4, 0x2f, 0x73, 0xe3, 0x62,
0x78, 0x15, 0xca, 0xf0, 0x82, 0xc0, 0xeb, 0x65, 0x51, 0x53, 0xff, 0x83, 0xd2, 0xb8, 0x60, 0x1a, 0x56, 0x98, 0x62, 0x8b, 0x0b, 0xde, 0x86, 0x32, 0xbc, 0x20, 0xf0, 0x7a, 0x59, 0xd4, 0xcc, 0xef,
0x75, 0x00, 0x96, 0x4d, 0x6c, 0x63, 0x0b, 0x85, 0x5e, 0x90, 0x05, 0xdd, 0xba, 0x21, 0xa8, 0x32, 0xa0, 0x34, 0x2e, 0x98, 0x46, 0x1d, 0x83, 0x55, 0x13, 0xdb, 0xd8, 0x42, 0xa1, 0x17, 0x64, 0x41,
0xd4, 0x4b, 0x73, 0xde, 0x83, 0x32, 0xed, 0x21, 0x3f, 0x8b, 0x98, 0xbe, 0x21, 0xa2, 0xc4, 0xa4, 0x7f, 0x4c, 0x08, 0xaa, 0x0c, 0xf5, 0xd2, 0x9c, 0xd7, 0xa0, 0x4c, 0x7b, 0xc8, 0xcf, 0x22, 0x66,
0xd2, 0xea, 0x5f, 0x24, 0x70, 0x87, 0x4f, 0x83, 0x43, 0xdc, 0x90, 0xb8, 0x56, 0x3b, 0xfe, 0x93, 0x27, 0x44, 0x94, 0x98, 0x54, 0x5a, 0xfd, 0x83, 0x04, 0xfe, 0xe2, 0xd3, 0xe0, 0x10, 0x37, 0x24,
0xa9, 0xde, 0xbe, 0x7e, 0xa6, 0x59, 0xcf, 0x77, 0xe3, 0x8a, 0xe7, 0xac, 0x40, 0x53, 0xc4, 0x34, 0xae, 0xd5, 0x8e, 0xff, 0x64, 0xaa, 0x7f, 0xde, 0x3d, 0xd3, 0xac, 0xe7, 0xfb, 0xf1, 0x89, 0xc7,
0x94, 0x47, 0x77, 0x28, 0xfb, 0xbc, 0xc6, 0x82, 0x3a, 0x1f, 0xc1, 0x4c, 0x08, 0x7e, 0x93, 0x80, 0xec, 0x80, 0xa6, 0x88, 0x69, 0x28, 0x8f, 0xee, 0x50, 0xf6, 0xbc, 0xc6, 0x82, 0x3a, 0x1f, 0xc1,
0xcc, 0x9b, 0x67, 0x93, 0x4f, 0x11, 0x31, 0x49, 0xd8, 0x6f, 0xfb, 0x81, 0xd7, 0x25, 0x26, 0x0e, 0x4c, 0x08, 0x7e, 0x94, 0x80, 0xcc, 0x9b, 0x67, 0x93, 0x77, 0x11, 0x31, 0x49, 0xd8, 0x6f, 0xfb,
0x12, 0x57, 0x33, 0xdc, 0x55, 0x33, 0xcf, 0xd5, 0x4b, 0x14, 0x98, 0xaf, 0x92, 0xe2, 0x3d, 0x51, 0x81, 0xd7, 0x25, 0x26, 0x0e, 0x12, 0x57, 0x73, 0xdc, 0x55, 0x33, 0xcf, 0xd5, 0x33, 0x14, 0x98,
0x1b, 0xfb, 0xdb, 0x10, 0xdf, 0xdc, 0x6a, 0x7e, 0x0e, 0xd5, 0x57, 0x0f, 0xf3, 0x37, 0xe1, 0x07, 0xcf, 0x93, 0xc3, 0x07, 0xe2, 0x6c, 0xec, 0x6f, 0x4b, 0xbc, 0xb9, 0xf5, 0xfc, 0x1c, 0xaa, 0xaf,
0xb0, 0x78, 0xd9, 0x6f, 0xe1, 0x67, 0x96, 0xfb, 0xb9, 0x9f, 0xe7, 0x67, 0x3b, 0xc9, 0x8f, 0x3d, 0x9f, 0xe4, 0x6f, 0xc2, 0x37, 0x60, 0xf9, 0xa6, 0xdf, 0xc2, 0xcf, 0x3c, 0xf7, 0xf3, 0x6f, 0x9e,
0xac, 0x08, 0x0f, 0xa5, 0x6c, 0x9c, 0xea, 0x25, 0x33, 0x1b, 0x80, 0x6f, 0x40, 0x91, 0xf7, 0x5c, 0x9f, 0xdd, 0x24, 0x3f, 0xf6, 0xb0, 0x26, 0x3c, 0x94, 0xb2, 0x71, 0xaa, 0x97, 0xcc, 0x6c, 0x00,
0x60, 0x00, 0xc7, 0xdc, 0xcb, 0xc3, 0xb4, 0x7a, 0xc8, 0x8f, 0x09, 0x50, 0x10, 0xc0, 0x30, 0x44, 0x1e, 0x81, 0x22, 0xef, 0xb9, 0xc0, 0x00, 0x8e, 0xf9, 0x27, 0x0f, 0xd3, 0xea, 0x21, 0x3f, 0x26,
0x75, 0x40, 0x87, 0x6b, 0x68, 0x80, 0x0a, 0x45, 0x5d, 0xe2, 0x5a, 0x34, 0x3b, 0x4e, 0xc5, 0x1b, 0x40, 0x41, 0x00, 0xc3, 0x10, 0xd5, 0x01, 0x1d, 0xae, 0xa1, 0x01, 0x2a, 0x14, 0x75, 0x89, 0x6b,
0x8e, 0x13, 0x14, 0x6a, 0xe9, 0x89, 0x32, 0xc0, 0x42, 0xc2, 0x10, 0xf6, 0xe7, 0xb8, 0xfd, 0xcd, 0xd1, 0xec, 0x38, 0x15, 0x27, 0x1c, 0x27, 0x28, 0xd4, 0xd2, 0x13, 0x65, 0x80, 0xa5, 0x84, 0x21,
0x5c, 0xfb, 0x71, 0x76, 0x7c, 0x82, 0x25, 0x71, 0x82, 0xf9, 0x74, 0x94, 0xea, 0xf3, 0x34, 0xfd, 0xec, 0x2f, 0x70, 0xfb, 0xdb, 0xb9, 0xf6, 0xe3, 0xec, 0xb8, 0x82, 0x15, 0x51, 0xc1, 0x62, 0x3a,
0x53, 0xdb, 0x39, 0xf9, 0x2d, 0x17, 0x4e, 0x06, 0xb2, 0x74, 0x3a, 0x90, 0xa5, 0x5f, 0x03, 0x59, 0x4a, 0xf5, 0x45, 0x9a, 0xfe, 0xc9, 0xde, 0x04, 0x46, 0x81, 0x9b, 0x2d, 0x62, 0x71, 0xd2, 0x37,
0x3a, 0xbe, 0x90, 0x0b, 0xa7, 0x17, 0x72, 0xe1, 0xe7, 0x85, 0x5c, 0x78, 0xf7, 0xc8, 0x22, 0xe1, 0xc1, 0xa4, 0xd2, 0x15, 0x1c, 0x81, 0x22, 0x57, 0x17, 0xf6, 0x97, 0xee, 0xbe, 0xfd, 0x27, 0x28,
0x61, 0x64, 0x28, 0x1d, 0xcf, 0x51, 0x19, 0xf3, 0xb1, 0x8d, 0x0c, 0xca, 0x57, 0xea, 0x51, 0xea, 0x70, 0x47, 0x6e, 0x7f, 0x18, 0xa2, 0x3a, 0xc0, 0xc3, 0xb5, 0xb6, 0x77, 0xfe, 0x5d, 0x2e, 0x9c,
0xc5, 0x64, 0x0f, 0x1b, 0x35, 0xa6, 0xf9, 0xbb, 0xf4, 0xe4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x64, 0xe9, 0x62, 0x20, 0x4b, 0xdf, 0x06, 0xb2, 0x74, 0x76, 0x2d, 0x17, 0x2e, 0xae, 0xe5,
0xfd, 0x2b, 0xb5, 0x5f, 0xc9, 0x07, 0x00, 0x00, 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) { func (m *AccumulationTime) Marshal() (dAtA []byte, err error) {
@ -324,6 +329,30 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = 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 { if len(m.SavingsClaims) > 0 {
for iNdEx := len(m.SavingsClaims) - 1; iNdEx >= 0; iNdEx-- { 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)) 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 return n
} }
@ -1236,6 +1273,73 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex 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: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:]) skippy, err := skipGenesis(dAtA[iNdEx:])

View File

@ -46,6 +46,7 @@ func TestGenesisState_Validate(t *testing.T) {
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
MultipliersPerDenoms{ MultipliersPerDenoms{
{ {
Denom: "ukava", Denom: "ukava",

View File

@ -36,4 +36,7 @@ var (
SavingsClaimKeyPrefix = []byte{0x15} // prefix for keys that store savings claims SavingsClaimKeyPrefix = []byte{0x15} // prefix for keys that store savings claims
SavingsRewardIndexesKeyPrefix = []byte{0x16} // prefix for key that stores savings reward indexes 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 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
) )

View File

@ -3,18 +3,35 @@ package types
import ( import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
) )
const MaxDenomsToClaim = 1000 const MaxDenomsToClaim = 1000
// ensure Msg interface compliance at compile time // ensure Msg interface compliance at compile time
var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
var ( var (
_ sdk.Msg = &MsgClaimUSDXMintingReward{}
_ sdk.Msg = &MsgClaimHardReward{} _ sdk.Msg = &MsgClaimHardReward{}
_ sdk.Msg = &MsgClaimDelegatorReward{} _ sdk.Msg = &MsgClaimDelegatorReward{}
_ sdk.Msg = &MsgClaimSwapReward{} _ sdk.Msg = &MsgClaimSwapReward{}
_ sdk.Msg = &MsgClaimSavingsReward{} _ 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. // NewMsgClaimUSDXMintingReward returns a new MsgClaimUSDXMintingReward.
@ -29,7 +46,7 @@ func NewMsgClaimUSDXMintingReward(sender string, multiplierName string) MsgClaim
func (msg MsgClaimUSDXMintingReward) Route() string { return RouterKey } func (msg MsgClaimUSDXMintingReward) Route() string { return RouterKey }
// Type returns a human-readable string for the message, intended for utilization within tags. // 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. // ValidateBasic does a simple validation check that doesn't require access to state.
func (msg MsgClaimUSDXMintingReward) ValidateBasic() error { 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. // Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimHardReward) Type() string { func (msg MsgClaimHardReward) Type() string {
return "claim_hard_reward" return TypeMsgClaimHardReward
} }
// ValidateBasic does a simple validation check that doesn't require access to state. // 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. // Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimDelegatorReward) Type() string { func (msg MsgClaimDelegatorReward) Type() string {
return "claim_delegator_reward" return TypeMsgClaimDelegatorReward
} }
// ValidateBasic does a simple validation check that doesn't require access to state. // 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. // Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimSwapReward) Type() string { func (msg MsgClaimSwapReward) Type() string {
return "claim_swap_reward" return TypeMsgClaimSwapReward
} }
// ValidateBasic does a simple validation check that doesn't require access to state. // 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. // Type returns a human-readable string for the message, intended for utilization within tags.
func (msg MsgClaimSavingsReward) Type() string { func (msg MsgClaimSavingsReward) Type() string {
return "claim_savings_reward" return TypeMsgClaimSavingsReward
} }
// ValidateBasic does a simple validation check that doesn't require access to state. // 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} 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}
}

View File

@ -21,6 +21,7 @@ var (
KeyDelegatorRewardPeriods = []byte("DelegatorRewardPeriods") KeyDelegatorRewardPeriods = []byte("DelegatorRewardPeriods")
KeySwapRewardPeriods = []byte("SwapRewardPeriods") KeySwapRewardPeriods = []byte("SwapRewardPeriods")
KeySavingsRewardPeriods = []byte("SavingsRewardPeriods") KeySavingsRewardPeriods = []byte("SavingsRewardPeriods")
KeyEarnRewardPeriods = []byte("EarnRewardPeriods")
KeyClaimEnd = []byte("ClaimEnd") KeyClaimEnd = []byte("ClaimEnd")
KeyMultipliers = []byte("ClaimMultipliers") KeyMultipliers = []byte("ClaimMultipliers")
@ -37,8 +38,12 @@ var (
) )
// NewParams returns a new params object // NewParams returns a new params object
func NewParams(usdxMinting RewardPeriods, hardSupply, hardBorrow, delegator, swap, func NewParams(
savings MultiRewardPeriods, multipliers MultipliersPerDenoms, claimEnd time.Time, usdxMinting RewardPeriods,
// MultiRewardPeriods
hardSupply, hardBorrow, delegator, swap, savings, earn MultiRewardPeriods,
multipliers MultipliersPerDenoms,
claimEnd time.Time,
) Params { ) Params {
return Params{ return Params{
USDXMintingRewardPeriods: usdxMinting, USDXMintingRewardPeriods: usdxMinting,
@ -61,6 +66,7 @@ func DefaultParams() Params {
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods, DefaultMultiRewardPeriods,
DefaultMultiRewardPeriods,
DefaultMultipliers, DefaultMultipliers,
DefaultClaimEnd, DefaultClaimEnd,
) )
@ -80,6 +86,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(KeyDelegatorRewardPeriods, &p.DelegatorRewardPeriods, validateMultiRewardPeriodsParam), paramtypes.NewParamSetPair(KeyDelegatorRewardPeriods, &p.DelegatorRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeySwapRewardPeriods, &p.SwapRewardPeriods, validateMultiRewardPeriodsParam), paramtypes.NewParamSetPair(KeySwapRewardPeriods, &p.SwapRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeySavingsRewardPeriods, &p.SavingsRewardPeriods, validateMultiRewardPeriodsParam), paramtypes.NewParamSetPair(KeySavingsRewardPeriods, &p.SavingsRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeyEarnRewardPeriods, &p.EarnRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersPerDenomParam), paramtypes.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersPerDenomParam),
paramtypes.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam), paramtypes.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
} }
@ -115,6 +122,10 @@ func (p Params) Validate() error {
return err return err
} }
if err := validateMultiRewardPeriodsParam(p.EarnRewardPeriods); err != nil {
return err
}
return nil return nil
} }

View File

@ -202,6 +202,7 @@ type Params struct {
ClaimMultipliers MultipliersPerDenoms `protobuf:"bytes,6,rep,name=claim_multipliers,json=claimMultipliers,proto3,castrepeated=MultipliersPerDenoms" json:"claim_multipliers"` 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"` 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"` 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{} } func (m *Params) Reset() { *m = Params{} }
@ -250,55 +251,56 @@ func init() {
} }
var fileDescriptor_bb8833f5d745eac9 = []byte{ var fileDescriptor_bb8833f5d745eac9 = []byte{
// 760 bytes of a gzipped FileDescriptorProto // 774 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x96, 0x4f, 0x4f, 0x13, 0x4f, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x96, 0xcf, 0x6e, 0xd3, 0x4a,
0x18, 0xc7, 0xbb, 0xfd, 0x47, 0x19, 0xe0, 0xf7, 0x83, 0xa1, 0xa9, 0x6b, 0x35, 0x5b, 0x52, 0x8c, 0x14, 0xc6, 0xe3, 0xfc, 0xbb, 0xc9, 0xb4, 0xbd, 0xb7, 0x9d, 0x46, 0xb9, 0xbe, 0xb9, 0xc8, 0xa9,
0xd6, 0x10, 0x76, 0x45, 0x13, 0x0f, 0xde, 0x5c, 0xd1, 0xc4, 0x44, 0x12, 0xb2, 0x60, 0xa2, 0x5e, 0x52, 0x04, 0x41, 0x55, 0x6d, 0x0a, 0x12, 0x0b, 0x76, 0x98, 0x82, 0x84, 0x44, 0xa5, 0xca, 0x2d,
0x9a, 0xe9, 0xee, 0xb0, 0x6c, 0xd8, 0xdd, 0xd9, 0xcc, 0x4c, 0x0b, 0x8d, 0x07, 0x13, 0x0f, 0xde, 0x12, 0xb0, 0x89, 0x26, 0xf6, 0xd4, 0xb5, 0x6a, 0x7b, 0xac, 0x99, 0x49, 0xda, 0x88, 0x05, 0x12,
0x4c, 0x88, 0x07, 0x5f, 0x04, 0x6f, 0xc3, 0x0b, 0x47, 0x8e, 0x46, 0x13, 0xd0, 0xf2, 0x46, 0xcc, 0x0b, 0x76, 0x48, 0x15, 0x0b, 0x1e, 0xa2, 0xaf, 0xc1, 0xa6, 0xcb, 0x8a, 0x15, 0x62, 0xd1, 0x42,
0xcc, 0x2e, 0x74, 0x5b, 0x0b, 0x4a, 0xd2, 0x8b, 0x27, 0x66, 0x9e, 0x79, 0x9e, 0xe7, 0xf3, 0x9d, 0xfa, 0x22, 0x68, 0xc6, 0x6e, 0xe3, 0xa4, 0x69, 0xa1, 0x52, 0x36, 0xac, 0x32, 0x3e, 0x73, 0xce,
0x2f, 0xfb, 0x4c, 0x0a, 0x16, 0x77, 0x50, 0x07, 0x19, 0x5e, 0x68, 0xe3, 0x90, 0x7b, 0x1d, 0x6c, 0xf9, 0x7d, 0xfe, 0xc6, 0x67, 0x14, 0xb0, 0xb8, 0x83, 0xba, 0xc8, 0xf0, 0x42, 0x1b, 0x87, 0xdc,
0x74, 0x56, 0x5a, 0x98, 0xa3, 0x15, 0x23, 0x42, 0x14, 0x05, 0x4c, 0x8f, 0x28, 0xe1, 0x04, 0x56, 0xeb, 0x62, 0xa3, 0xbb, 0xd2, 0xc6, 0x1c, 0xad, 0x18, 0x11, 0xa2, 0x28, 0x60, 0x7a, 0x44, 0x09,
0x44, 0x92, 0x7e, 0x9e, 0xa4, 0x27, 0x49, 0xd5, 0xb2, 0x4b, 0x5c, 0x22, 0x53, 0x0c, 0xb1, 0x8a, 0x27, 0xb0, 0x2a, 0x92, 0xf4, 0xf3, 0x24, 0x3d, 0x49, 0xaa, 0x55, 0x5c, 0xe2, 0x12, 0x99, 0x62,
0xb3, 0xab, 0x35, 0x97, 0x10, 0xd7, 0xc7, 0x86, 0xdc, 0xb5, 0xda, 0x5b, 0x06, 0xf7, 0x02, 0xcc, 0x88, 0x55, 0x9c, 0x5d, 0xab, 0xbb, 0x84, 0xb8, 0x3e, 0x36, 0xe4, 0x53, 0xbb, 0xb3, 0x65, 0x70,
0x38, 0x0a, 0xa2, 0x24, 0x41, 0xb3, 0x09, 0x0b, 0x08, 0x33, 0x5a, 0x88, 0xf5, 0x81, 0x36, 0xf1, 0x2f, 0xc0, 0x8c, 0xa3, 0x20, 0x4a, 0x12, 0x34, 0x9b, 0xb0, 0x80, 0x30, 0xa3, 0x8d, 0xd8, 0x00,
0xc2, 0xf8, 0xbc, 0xfe, 0x29, 0x0b, 0xa6, 0x2d, 0xbc, 0x8b, 0xa8, 0xb3, 0x8e, 0xa9, 0x47, 0x1c, 0x68, 0x13, 0x2f, 0x8c, 0xf7, 0x1b, 0x1f, 0xb3, 0x60, 0xda, 0xc2, 0xbb, 0x88, 0x3a, 0xeb, 0x98,
0x58, 0x01, 0x45, 0x64, 0x0b, 0xb2, 0xaa, 0x2c, 0x28, 0x8d, 0x92, 0x95, 0xec, 0xe0, 0x1d, 0xf0, 0x7a, 0xc4, 0x81, 0x55, 0x50, 0x44, 0xb6, 0x20, 0xab, 0xca, 0x82, 0xd2, 0x2c, 0x59, 0xc9, 0x13,
0xbf, 0x4d, 0x7c, 0x1f, 0x71, 0x4c, 0x91, 0xdf, 0xe4, 0xdd, 0x08, 0xab, 0xd9, 0x05, 0xa5, 0x31, 0xbc, 0x0d, 0xfe, 0xb1, 0x89, 0xef, 0x23, 0x8e, 0x29, 0xf2, 0x5b, 0xbc, 0x17, 0x61, 0x35, 0xbb,
0x69, 0xfd, 0xd7, 0x0f, 0x6f, 0x76, 0x23, 0x0c, 0x1f, 0x81, 0x02, 0xe3, 0x88, 0x72, 0x35, 0xb7, 0xa0, 0x34, 0xcb, 0xd6, 0xdf, 0x83, 0xf0, 0x66, 0x2f, 0xc2, 0xf0, 0x21, 0x28, 0x30, 0x8e, 0x28,
0xa0, 0x34, 0xa6, 0xee, 0x57, 0xf5, 0x58, 0xa2, 0x7e, 0x26, 0x51, 0xdf, 0x3c, 0x93, 0x68, 0x96, 0x57, 0x73, 0x0b, 0x4a, 0x73, 0xea, 0x5e, 0x4d, 0x8f, 0x25, 0xea, 0x67, 0x12, 0xf5, 0xcd, 0x33,
0x0e, 0x8f, 0x6b, 0x99, 0xfd, 0x93, 0x9a, 0x62, 0xc5, 0x25, 0xf0, 0x21, 0xc8, 0xe1, 0xd0, 0x51, 0x89, 0x66, 0xe9, 0xf0, 0xb8, 0x9e, 0xd9, 0x3f, 0xa9, 0x2b, 0x56, 0x5c, 0x02, 0x1f, 0x80, 0x1c,
0xf3, 0x57, 0xa8, 0x14, 0x05, 0x70, 0x0d, 0x40, 0x2a, 0x2f, 0xc1, 0x9a, 0x11, 0xa6, 0x4d, 0x86, 0x0e, 0x1d, 0x35, 0x7f, 0x8d, 0x4a, 0x51, 0x00, 0xd7, 0x00, 0xa4, 0xf2, 0x25, 0x58, 0x2b, 0xc2,
0x6d, 0x12, 0x3a, 0x6a, 0x41, 0xb6, 0xb9, 0xae, 0xc7, 0x16, 0xe8, 0xc2, 0x82, 0x33, 0x3b, 0xf5, 0xb4, 0xc5, 0xb0, 0x4d, 0x42, 0x47, 0x2d, 0xc8, 0x36, 0xff, 0xe9, 0xb1, 0x05, 0xba, 0xb0, 0xe0,
0x27, 0xc4, 0x0b, 0xcd, 0xbc, 0xe8, 0x62, 0xcd, 0x26, 0xa5, 0xeb, 0x98, 0x6e, 0xc8, 0xc2, 0xfa, 0xcc, 0x4e, 0xfd, 0x31, 0xf1, 0x42, 0x33, 0x2f, 0xba, 0x58, 0xb3, 0x49, 0xe9, 0x3a, 0xa6, 0x1b,
0x97, 0x2c, 0x98, 0x5b, 0x6b, 0xfb, 0xdc, 0xfb, 0xf7, 0x9d, 0xe9, 0x5e, 0xe0, 0x4c, 0xee, 0x72, 0xb2, 0xb0, 0xf1, 0x39, 0x0b, 0xe6, 0xd6, 0x3a, 0x3e, 0xf7, 0xfe, 0x7c, 0x67, 0x7a, 0x97, 0x38,
0x67, 0xee, 0x89, 0x2e, 0x07, 0x27, 0xb5, 0x86, 0xeb, 0xf1, 0xed, 0x76, 0x4b, 0xb7, 0x49, 0x60, 0x93, 0xbb, 0xda, 0x99, 0xbb, 0xa2, 0xcb, 0xc1, 0x49, 0xbd, 0xe9, 0x7a, 0x7c, 0xbb, 0xd3, 0xd6,
0x24, 0x5f, 0x52, 0xfc, 0x67, 0x99, 0x39, 0x3b, 0x86, 0xb8, 0x2b, 0x93, 0x05, 0x6c, 0x84, 0x8b, 0x6d, 0x12, 0x18, 0xc9, 0x97, 0x14, 0xff, 0x2c, 0x33, 0x67, 0xc7, 0x10, 0xef, 0xca, 0x64, 0x01,
0x1f, 0x15, 0x00, 0xa4, 0x8b, 0x91, 0xef, 0x61, 0x0a, 0x21, 0xc8, 0x87, 0x28, 0x88, 0xcd, 0x9b, 0x1b, 0xe3, 0xe2, 0x07, 0x05, 0x00, 0xe9, 0x62, 0xe4, 0x7b, 0x98, 0x42, 0x08, 0xf2, 0x21, 0x0a,
0xb4, 0xe4, 0x1a, 0x2e, 0x82, 0x99, 0x80, 0x84, 0x7c, 0x9b, 0x35, 0x7d, 0x62, 0xef, 0xb4, 0x23, 0x62, 0xf3, 0xca, 0x96, 0x5c, 0xc3, 0x45, 0x30, 0x13, 0x90, 0x90, 0x6f, 0xb3, 0x96, 0x4f, 0xec,
0x69, 0x5c, 0xce, 0x9a, 0x8e, 0x83, 0x2f, 0x64, 0x0c, 0x3e, 0x03, 0xc5, 0x2d, 0x64, 0x73, 0x42, 0x9d, 0x4e, 0x24, 0x8d, 0xcb, 0x59, 0xd3, 0x71, 0xf0, 0xb9, 0x8c, 0xc1, 0xa7, 0xa0, 0xb8, 0x85,
0xa5, 0x6f, 0xd3, 0xa6, 0x2e, 0xb4, 0x7d, 0x3b, 0xae, 0xdd, 0xfe, 0x0b, 0x6d, 0xab, 0xd8, 0xb6, 0x6c, 0x4e, 0xa8, 0xf4, 0x6d, 0xda, 0xd4, 0x85, 0xb6, 0x6f, 0xc7, 0xf5, 0x5b, 0xbf, 0xa1, 0x6d,
0x92, 0xea, 0xfa, 0x07, 0x05, 0xcc, 0xf7, 0xf5, 0x08, 0xa1, 0xab, 0x38, 0x24, 0x01, 0x2c, 0x83, 0x15, 0xdb, 0x56, 0x52, 0xdd, 0x78, 0xaf, 0x80, 0xf9, 0x81, 0x1e, 0x21, 0x74, 0x15, 0x87, 0x24,
0x82, 0x23, 0x16, 0x89, 0xb2, 0x78, 0x03, 0x5f, 0x83, 0xa9, 0xa0, 0x9f, 0xac, 0x66, 0xa5, 0x63, 0x80, 0x15, 0x50, 0x70, 0xc4, 0x22, 0x51, 0x16, 0x3f, 0xc0, 0x57, 0x60, 0x2a, 0x18, 0x24, 0xab,
0x75, 0x7d, 0xf4, 0x74, 0xea, 0xfd, 0xbe, 0xe6, 0x7c, 0x62, 0xdd, 0x54, 0x8a, 0x65, 0xa5, 0x7b, 0x59, 0xe9, 0x58, 0x43, 0x1f, 0x3f, 0x9d, 0xfa, 0xa0, 0xaf, 0x39, 0x9f, 0x58, 0x37, 0x95, 0x62,
0xd5, 0xbf, 0x4f, 0x80, 0xe2, 0xba, 0x9c, 0x79, 0xf8, 0x59, 0x01, 0x37, 0xda, 0xcc, 0xd9, 0x6b, 0x59, 0xe9, 0x5e, 0x8d, 0x2f, 0x25, 0x50, 0x5c, 0x97, 0x33, 0x0f, 0x3f, 0x29, 0xe0, 0xff, 0x0e,
0x06, 0x5e, 0xc8, 0xbd, 0xd0, 0x6d, 0xc6, 0x2e, 0x8a, 0xff, 0x95, 0x47, 0x1c, 0xa6, 0x2a, 0x12, 0x73, 0xf6, 0x5a, 0x81, 0x17, 0x72, 0x2f, 0x74, 0x5b, 0xb1, 0x8b, 0xe2, 0xac, 0x3c, 0xe2, 0x30,
0x7b, 0xeb, 0x22, 0x6c, 0xfa, 0xfb, 0x34, 0x57, 0x04, 0xb8, 0x77, 0x5c, 0x53, 0x5f, 0x6e, 0xac, 0x55, 0x91, 0xd8, 0x9b, 0x97, 0x61, 0xd3, 0xdf, 0xa7, 0xb9, 0x22, 0xc0, 0xfd, 0xe3, 0xba, 0xfa,
0xbe, 0x5a, 0x8b, 0xfb, 0xa5, 0x13, 0xd8, 0xc1, 0x49, 0x6d, 0x66, 0x20, 0x60, 0xa9, 0x82, 0x3d, 0x62, 0x63, 0xf5, 0xe5, 0x5a, 0xdc, 0x2f, 0x9d, 0xc0, 0x0e, 0x4e, 0xea, 0x33, 0x43, 0x01, 0x4b,
0x2a, 0x15, 0xbe, 0x57, 0x40, 0x75, 0x5b, 0x28, 0x61, 0xed, 0x28, 0xf2, 0xbb, 0xc3, 0xba, 0x62, 0x15, 0xec, 0x71, 0xa9, 0xf0, 0x9d, 0x02, 0x6a, 0xdb, 0x42, 0x09, 0xeb, 0x44, 0x91, 0xdf, 0x1b,
0x3b, 0xee, 0x5e, 0x6a, 0xc7, 0x80, 0xb8, 0x6a, 0xe2, 0x0a, 0xfc, 0xed, 0x88, 0x59, 0xd7, 0x04, 0xd5, 0x15, 0xdb, 0x71, 0xe7, 0x4a, 0x3b, 0x86, 0xc4, 0xd5, 0x12, 0x57, 0xe0, 0x85, 0x2d, 0x66,
0x68, 0x43, 0x72, 0x2e, 0x10, 0xd1, 0x22, 0x94, 0x92, 0xdd, 0x61, 0x11, 0xb9, 0xb1, 0x8b, 0x30, 0xfd, 0x2b, 0x40, 0x1b, 0x92, 0x73, 0x89, 0x88, 0x36, 0xa1, 0x94, 0xec, 0x8e, 0x8a, 0xc8, 0x4d,
0x25, 0x67, 0x50, 0xc4, 0x3b, 0xa0, 0x3a, 0xd8, 0xc7, 0x2e, 0xe2, 0x84, 0x0e, 0x2b, 0xc8, 0x8f, 0x5c, 0x84, 0x29, 0x39, 0xc3, 0x22, 0xde, 0x02, 0xd5, 0xc1, 0x3e, 0x76, 0x11, 0x27, 0x74, 0x54,
0x53, 0x41, 0xe5, 0x1c, 0x33, 0x28, 0xa0, 0x0d, 0xe6, 0xd9, 0x2e, 0x8a, 0x86, 0xd9, 0x85, 0x71, 0x41, 0x7e, 0x92, 0x0a, 0xaa, 0xe7, 0x98, 0x61, 0x01, 0x1d, 0x30, 0xcf, 0x76, 0x51, 0x34, 0xca,
0xb2, 0xe7, 0x04, 0x61, 0x10, 0xdb, 0x01, 0x73, 0xb6, 0x8f, 0xbc, 0xa0, 0x99, 0x1e, 0x83, 0xa2, 0x2e, 0x4c, 0x92, 0x3d, 0x27, 0x08, 0xc3, 0xd8, 0x2e, 0x98, 0xb3, 0x7d, 0xe4, 0x05, 0xad, 0xf4,
0x84, 0x2e, 0xfd, 0x79, 0x0c, 0xce, 0xc7, 0xcb, 0xbc, 0x99, 0x60, 0xcb, 0x23, 0x0e, 0x99, 0x35, 0x18, 0x14, 0x25, 0x74, 0xe9, 0xd7, 0x63, 0x70, 0x3e, 0x5e, 0xe6, 0x8d, 0x04, 0x5b, 0x19, 0xb3,
0x2b, 0x19, 0xa9, 0x23, 0xf8, 0x18, 0x4c, 0xc6, 0x5c, 0xf1, 0xde, 0x4d, 0x5c, 0xe1, 0xbd, 0x2b, 0xc9, 0xac, 0x59, 0xc9, 0x48, 0x6d, 0xc1, 0x47, 0xa0, 0x1c, 0x73, 0xc5, 0x7d, 0xf7, 0xd7, 0x35,
0xc9, 0xb2, 0xa7, 0xa1, 0x03, 0xdf, 0x82, 0x0a, 0x43, 0x1d, 0x2f, 0x74, 0xd9, 0xb0, 0x69, 0xa5, 0xee, 0xbb, 0x92, 0x2c, 0x7b, 0x12, 0x3a, 0xf0, 0x0d, 0xa8, 0x32, 0xd4, 0xf5, 0x42, 0x97, 0x8d,
0x71, 0x9a, 0x56, 0x4e, 0x20, 0x03, 0x51, 0xf3, 0xf9, 0xe1, 0x4f, 0x2d, 0x73, 0xd8, 0xd3, 0x94, 0x9a, 0x56, 0x9a, 0xa4, 0x69, 0x95, 0x04, 0x72, 0xe1, 0xb8, 0x30, 0xa2, 0xe1, 0x28, 0xb9, 0x3c,
0xa3, 0x9e, 0xa6, 0xfc, 0xe8, 0x69, 0xca, 0xfe, 0xa9, 0x96, 0x39, 0x3a, 0xd5, 0x32, 0x5f, 0x4f, 0xd1, 0xe3, 0x12, 0x84, 0xa1, 0x90, 0xf9, 0xec, 0xf0, 0x87, 0x96, 0x39, 0xec, 0x6b, 0xca, 0x51,
0xb5, 0xcc, 0x9b, 0xa5, 0xd4, 0xa3, 0x25, 0x44, 0x2c, 0xfb, 0xa8, 0xc5, 0xe4, 0xca, 0xd8, 0x4b, 0x5f, 0x53, 0xbe, 0xf7, 0x35, 0x65, 0xff, 0x54, 0xcb, 0x1c, 0x9d, 0x6a, 0x99, 0xaf, 0xa7, 0x5a,
0xfd, 0x34, 0x90, 0xaf, 0x57, 0xab, 0x28, 0xef, 0xfb, 0xe0, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xf5, 0x52, 0xea, 0xae, 0x14, 0x0a, 0x96, 0x7d, 0xd4, 0x66, 0x72, 0x65, 0xec, 0xa5, 0xfe,
0x8f, 0x22, 0xdc, 0x69, 0x39, 0x08, 0x00, 0x00, 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) { func (m *RewardPeriod) Marshal() (dAtA []byte, err error) {
@ -546,6 +548,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = 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 { if len(m.SavingsRewardPeriods) > 0 {
for iNdEx := len(m.SavingsRewardPeriods) - 1; iNdEx >= 0; iNdEx-- { 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)) 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 return n
} }
@ -1763,6 +1785,40 @@ func (m *Params) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex 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: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:]) skippy, err := skipParams(dAtA[iNdEx:])

View File

@ -11,6 +11,7 @@ const (
QueryGetDelegatorRewards = "delegator-rewards" QueryGetDelegatorRewards = "delegator-rewards"
QueryGetSwapRewards = "swap-rewards" QueryGetSwapRewards = "swap-rewards"
QueryGetSavingsRewards = "savings-rewards" QueryGetSavingsRewards = "savings-rewards"
QueryGetEarnRewards = "earn-rewards"
QueryGetRewardFactors = "reward-factors" QueryGetRewardFactors = "reward-factors"
QueryGetParams = "parameters" QueryGetParams = "parameters"
@ -46,11 +47,12 @@ type QueryGetRewardFactorsResponse struct {
DelegatorRewardFactors MultiRewardIndexes `json:"delegator_reward_factors" yaml:"delegator_reward_factors"` DelegatorRewardFactors MultiRewardIndexes `json:"delegator_reward_factors" yaml:"delegator_reward_factors"`
SwapRewardFactors MultiRewardIndexes `json:"swap_reward_factors" yaml:"swap_reward_factors"` SwapRewardFactors MultiRewardIndexes `json:"swap_reward_factors" yaml:"swap_reward_factors"`
SavingsRewardFactors MultiRewardIndexes `json:"savings_reward_factors" yaml:"savings_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 // NewQueryGetRewardFactorsResponse returns a new instance of QueryAllRewardFactorsResponse
func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFactors, func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFactors,
hardBorrowFactors, delegatorFactors, swapFactors, savingsFactors MultiRewardIndexes, hardBorrowFactors, delegatorFactors, swapFactors, savingsFactors, earnFactors MultiRewardIndexes,
) QueryGetRewardFactorsResponse { ) QueryGetRewardFactorsResponse {
return QueryGetRewardFactorsResponse{ return QueryGetRewardFactorsResponse{
USDXMintingRewardFactors: usdxMintingFactors, USDXMintingRewardFactors: usdxMintingFactors,
@ -59,5 +61,6 @@ func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFa
DelegatorRewardFactors: delegatorFactors, DelegatorRewardFactors: delegatorFactors,
SwapRewardFactors: swapFactors, SwapRewardFactors: swapFactors,
SavingsRewardFactors: savingsFactors, SavingsRewardFactors: savingsFactors,
EarnRewardFactors: earnFactors,
} }
} }

View File

@ -448,6 +448,82 @@ func (m *MsgClaimSavingsRewardResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_MsgClaimSavingsRewardResponse proto.InternalMessageInfo 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() { func init() {
proto.RegisterType((*Selection)(nil), "kava.incentive.v1beta1.Selection") proto.RegisterType((*Selection)(nil), "kava.incentive.v1beta1.Selection")
proto.RegisterType((*MsgClaimUSDXMintingReward)(nil), "kava.incentive.v1beta1.MsgClaimUSDXMintingReward") proto.RegisterType((*MsgClaimUSDXMintingReward)(nil), "kava.incentive.v1beta1.MsgClaimUSDXMintingReward")
@ -460,44 +536,47 @@ func init() {
proto.RegisterType((*MsgClaimSwapRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimSwapRewardResponse") proto.RegisterType((*MsgClaimSwapRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimSwapRewardResponse")
proto.RegisterType((*MsgClaimSavingsReward)(nil), "kava.incentive.v1beta1.MsgClaimSavingsReward") proto.RegisterType((*MsgClaimSavingsReward)(nil), "kava.incentive.v1beta1.MsgClaimSavingsReward")
proto.RegisterType((*MsgClaimSavingsRewardResponse)(nil), "kava.incentive.v1beta1.MsgClaimSavingsRewardResponse") 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) } func init() { proto.RegisterFile("kava/incentive/v1beta1/tx.proto", fileDescriptor_b1cec058e3ff75d5) }
var fileDescriptor_b1cec058e3ff75d5 = []byte{ 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, 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, 0x14, 0xc7, 0x7d, 0xad, 0x5a, 0xd1, 0x87, 0x20, 0xd2, 0x29, 0x84, 0x60, 0x81, 0xdd, 0x84, 0x81,
0x02, 0xd5, 0x56, 0x82, 0x10, 0x82, 0xb1, 0x14, 0x89, 0x25, 0x0c, 0x49, 0x91, 0x10, 0x12, 0x8a, 0x0a, 0x54, 0x5b, 0x09, 0x42, 0x08, 0xc6, 0xd2, 0x4a, 0x2c, 0x61, 0x48, 0x8a, 0x84, 0x90, 0x50,
0x2e, 0xc9, 0x71, 0x9c, 0xb0, 0xef, 0x8c, 0xef, 0x9a, 0x16, 0x26, 0x26, 0xc4, 0xc8, 0x82, 0x84, 0x74, 0x49, 0x0e, 0x73, 0xc2, 0xbe, 0x33, 0xbe, 0x6b, 0x5a, 0x98, 0x98, 0x10, 0x23, 0x0b, 0x12,
0x98, 0x3a, 0xf3, 0x49, 0x3a, 0x76, 0x64, 0x02, 0x94, 0x2c, 0xec, 0x7c, 0x01, 0x14, 0x27, 0x76, 0x62, 0xea, 0xcc, 0x27, 0xe9, 0xd8, 0x91, 0x09, 0x50, 0x22, 0x21, 0x3e, 0x06, 0x8a, 0x93, 0xd8,
0xa2, 0xc4, 0xc6, 0x84, 0x29, 0xdb, 0xdd, 0xbd, 0xff, 0x7b, 0xef, 0xf7, 0x9e, 0xde, 0xd3, 0x81, 0x56, 0x6d, 0x63, 0xd2, 0x29, 0x9b, 0xed, 0xf7, 0x7f, 0xef, 0xfd, 0xfe, 0x4f, 0x7e, 0x77, 0x60,
0xfd, 0x8a, 0xf4, 0x89, 0xcb, 0x45, 0x97, 0x0a, 0xcd, 0xfb, 0xd4, 0xed, 0xd7, 0x3a, 0x54, 0x93, 0xbe, 0x26, 0x43, 0x62, 0x33, 0xde, 0xa7, 0x5c, 0xb1, 0x21, 0xb5, 0x87, 0x8d, 0x1e, 0x55, 0xa4,
0x9a, 0xab, 0x8f, 0x9c, 0x20, 0x94, 0x5a, 0xe2, 0xd2, 0x48, 0xe0, 0x24, 0x02, 0x67, 0x22, 0x30, 0x61, 0xab, 0x23, 0xcb, 0x0f, 0x84, 0x12, 0xb8, 0x32, 0x11, 0x58, 0x91, 0xc0, 0x9a, 0x09, 0xf4,
0x8b, 0x4c, 0x32, 0x19, 0x49, 0xdc, 0xd1, 0x69, 0xac, 0xae, 0xee, 0xc3, 0x66, 0x8b, 0x7a, 0xb4, 0xb2, 0x23, 0x1c, 0x11, 0x4a, 0xec, 0xc9, 0xd3, 0x54, 0x5d, 0xdf, 0x87, 0x8d, 0x0e, 0x75, 0x69,
0xab, 0xb9, 0x14, 0xb8, 0x08, 0x67, 0x7b, 0x54, 0x48, 0xbf, 0x8c, 0xb6, 0xd0, 0xf6, 0x66, 0x73, 0x5f, 0x31, 0xc1, 0x71, 0x19, 0xd6, 0x06, 0x94, 0x0b, 0xaf, 0x8a, 0x36, 0xd1, 0xd6, 0x46, 0x7b,
0x7c, 0xc1, 0x37, 0xa0, 0xe0, 0x1f, 0x78, 0x9a, 0x07, 0x1e, 0xa7, 0x61, 0x5b, 0x10, 0x9f, 0x96, 0xfa, 0x82, 0x6f, 0x41, 0xc9, 0x3b, 0x70, 0x15, 0xf3, 0x5d, 0x46, 0x83, 0x2e, 0x27, 0x1e, 0xad,
0xd7, 0x22, 0xfb, 0xc5, 0xe9, 0xf3, 0x63, 0xe2, 0xd3, 0xfb, 0xe7, 0x3e, 0x1c, 0xdb, 0xc6, 0xaf, 0xae, 0x84, 0xf1, 0xcb, 0xf1, 0xe7, 0x27, 0xc4, 0xa3, 0x0f, 0x2f, 0x7c, 0x3c, 0x36, 0xb5, 0x3f,
0x63, 0xdb, 0xa8, 0xbe, 0x80, 0x2b, 0x0d, 0xc5, 0x1e, 0x78, 0x84, 0xfb, 0x4f, 0x5a, 0x7b, 0x4f, 0xc7, 0xa6, 0x56, 0x7f, 0x09, 0xd7, 0x5a, 0xd2, 0x79, 0xe4, 0x12, 0xe6, 0x3d, 0xed, 0xec, 0x3e,
0x1b, 0x5c, 0x68, 0x2e, 0x58, 0x93, 0x1e, 0x92, 0xb0, 0x87, 0x4b, 0xb0, 0xa1, 0xa8, 0xe8, 0xd1, 0x6b, 0x31, 0xae, 0x18, 0x77, 0xda, 0xf4, 0x90, 0x04, 0x03, 0x5c, 0x81, 0x75, 0x49, 0xf9, 0x80,
0x70, 0x92, 0x66, 0x72, 0xfb, 0x9f, 0x3c, 0xd7, 0xa1, 0x92, 0x99, 0xa7, 0x49, 0x55, 0x20, 0x85, 0x06, 0xb3, 0x36, 0xb3, 0xb7, 0xf3, 0xf4, 0xb9, 0x09, 0xb5, 0xdc, 0x3e, 0x6d, 0x2a, 0x7d, 0xc1,
0xa2, 0xd5, 0x4f, 0x08, 0x70, 0xac, 0x7a, 0x14, 0x19, 0xfe, 0x8a, 0xf1, 0x1c, 0x0a, 0x51, 0xdd, 0x25, 0xad, 0x7f, 0x46, 0x80, 0xe7, 0xaa, 0xc7, 0x61, 0xe0, 0x9f, 0x18, 0x2f, 0xa0, 0x14, 0xfa,
0xaa, 0xad, 0x65, 0xbb, 0x3b, 0x72, 0x2a, 0xaf, 0x6d, 0xad, 0x6f, 0x9f, 0xaf, 0x57, 0x9c, 0xf4, 0x96, 0x5d, 0x25, 0xba, 0xfd, 0x49, 0x52, 0x75, 0x65, 0x73, 0x75, 0xeb, 0x62, 0xb3, 0x66, 0x65,
0xce, 0x3a, 0x49, 0x03, 0x77, 0xf1, 0xc9, 0x77, 0xdb, 0xf8, 0xfa, 0xc3, 0x86, 0xe4, 0x49, 0x35, 0x4f, 0xd6, 0x8a, 0x06, 0xb8, 0x83, 0x4f, 0x7e, 0x98, 0xda, 0xb7, 0x9f, 0x26, 0x44, 0x9f, 0x64,
0x2f, 0x8c, 0xa3, 0xed, 0xcb, 0x08, 0x60, 0x06, 0xfe, 0x2a, 0x98, 0x8b, 0x58, 0x09, 0xf5, 0x17, 0xfb, 0xd2, 0xb4, 0xda, 0xbe, 0x08, 0x01, 0x12, 0xf0, 0xd7, 0x41, 0x4f, 0x63, 0x45, 0xd4, 0x5f,
0x04, 0x97, 0x63, 0xf3, 0x1e, 0xf5, 0x28, 0x23, 0x5a, 0x86, 0xab, 0x82, 0x5e, 0x01, 0x3b, 0x83, 0x11, 0x5c, 0x9d, 0x87, 0x77, 0xa9, 0x4b, 0x1d, 0xa2, 0x44, 0xb0, 0x2c, 0xe8, 0x35, 0x30, 0x73,
0x2d, 0xb5, 0xeb, 0xad, 0x43, 0x12, 0xac, 0x60, 0xd7, 0xa7, 0x58, 0x09, 0xf5, 0x67, 0x04, 0x97, 0xd8, 0x32, 0xa7, 0xde, 0x39, 0x24, 0xfe, 0x12, 0x4e, 0x3d, 0xc6, 0x8a, 0xa8, 0xbf, 0x20, 0xb8,
0x12, 0x33, 0xe9, 0x73, 0xc1, 0xd4, 0xaa, 0x80, 0xdb, 0x70, 0x2d, 0x95, 0x2c, 0x66, 0xaf, 0xff, 0x12, 0x85, 0xc9, 0x90, 0x71, 0x47, 0x2e, 0x0b, 0xb8, 0x09, 0x37, 0x32, 0xc9, 0x32, 0x27, 0xbe,
0x3e, 0x03, 0xeb, 0x0d, 0xc5, 0xf0, 0x7b, 0x04, 0xa5, 0x8c, 0xd5, 0xab, 0x65, 0x31, 0x65, 0x6e, 0x47, 0x02, 0xbe, 0x84, 0x13, 0x8f, 0xb1, 0xe6, 0xd4, 0xcd, 0xdf, 0x6b, 0xb0, 0xda, 0x92, 0x0e,
0x91, 0x79, 0x6f, 0x69, 0x97, 0x18, 0x08, 0xbf, 0x86, 0xc2, 0xfc, 0xd2, 0xdd, 0xcc, 0x8b, 0x36, 0xfe, 0x80, 0xa0, 0x92, 0x73, 0x60, 0x34, 0xf2, 0x80, 0x72, 0x77, 0x5f, 0x7f, 0xb0, 0x70, 0xca,
0xd5, 0x9a, 0xf5, 0x7f, 0xd7, 0x26, 0x29, 0xdf, 0x21, 0x28, 0xa6, 0xae, 0x8c, 0x9b, 0x17, 0x6c, 0x1c, 0x08, 0xbf, 0x81, 0xd2, 0xd9, 0xa3, 0xe2, 0x76, 0x51, 0xb5, 0x58, 0xab, 0x37, 0xff, 0x5f,
0xce, 0xc1, 0xbc, 0xbb, 0xa4, 0xc3, 0x42, 0xd5, 0x33, 0x43, 0x9f, 0x5b, 0xf5, 0x54, 0x9b, 0x5f, 0x1b, 0xb5, 0x7c, 0x8f, 0xa0, 0x9c, 0xb9, 0xe8, 0x76, 0x51, 0xb1, 0x33, 0x09, 0xfa, 0xfd, 0x05,
0xf5, 0xe2, 0xd4, 0xe2, 0xb7, 0x80, 0x53, 0x26, 0x76, 0x27, 0x37, 0xd2, 0xac, 0xdc, 0xbc, 0xb3, 0x13, 0x52, 0xae, 0x13, 0xab, 0x5a, 0xe8, 0x3a, 0xd6, 0x16, 0xbb, 0x4e, 0xef, 0x1a, 0x7e, 0x07,
0x94, 0x3c, 0xce, 0xbd, 0xfb, 0xf0, 0x64, 0x60, 0xa1, 0xd3, 0x81, 0x85, 0x7e, 0x0e, 0x2c, 0xf4, 0x38, 0x63, 0xcf, 0xb6, 0x0b, 0x2b, 0x25, 0xe5, 0xfa, 0xbd, 0x85, 0xe4, 0x29, 0xbb, 0x89, 0x3d,
0x71, 0x68, 0x19, 0xa7, 0x43, 0xcb, 0xf8, 0x36, 0xb4, 0x8c, 0x67, 0xb7, 0x18, 0xd7, 0x2f, 0x0f, 0x29, 0xb4, 0x1b, 0x6b, 0x8b, 0xed, 0xa6, 0x7f, 0xf4, 0x9d, 0xbd, 0x93, 0x91, 0x81, 0x4e, 0x47,
0x3a, 0x4e, 0x57, 0xfa, 0xee, 0x28, 0xf4, 0x8e, 0x47, 0x3a, 0x2a, 0x3a, 0xb9, 0x47, 0x33, 0x1f, 0x06, 0xfa, 0x35, 0x32, 0xd0, 0xa7, 0xb1, 0xa1, 0x9d, 0x8e, 0x0d, 0xed, 0xfb, 0xd8, 0xd0, 0x9e,
0x98, 0x7e, 0x13, 0x50, 0xd5, 0xd9, 0x88, 0xbe, 0xa3, 0xdb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x71, 0x98, 0x7a, 0x75, 0xd0, 0xb3, 0xfa, 0xc2, 0xb3, 0x27, 0x75, 0xb7, 0x5d, 0xd2, 0x93,
0x7e, 0x03, 0x15, 0xb3, 0xdf, 0x06, 0x00, 0x00, 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. // 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) ClaimHardReward(ctx context.Context, in *MsgClaimHardReward, opts ...grpc.CallOption) (*MsgClaimHardRewardResponse, error)
// ClaimDelegatorReward is a message type used to claim delegator rewards // ClaimDelegatorReward is a message type used to claim delegator rewards
ClaimDelegatorReward(ctx context.Context, in *MsgClaimDelegatorReward, opts ...grpc.CallOption) (*MsgClaimDelegatorRewardResponse, error) 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) ClaimSwapReward(ctx context.Context, in *MsgClaimSwapReward, opts ...grpc.CallOption) (*MsgClaimSwapRewardResponse, error)
// ClaimSavingsReward is a message type used to claim savings rewards // ClaimSavingsReward is a message type used to claim savings rewards
ClaimSavingsReward(ctx context.Context, in *MsgClaimSavingsReward, opts ...grpc.CallOption) (*MsgClaimSavingsRewardResponse, error) 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 { type msgClient struct {
@ -577,6 +658,15 @@ func (c *msgClient) ClaimSavingsReward(ctx context.Context, in *MsgClaimSavingsR
return out, nil 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. // MsgServer is the server API for Msg service.
type MsgServer interface { type MsgServer interface {
// ClaimUSDXMintingReward is a message type used to claim USDX minting rewards // ClaimUSDXMintingReward is a message type used to claim USDX minting rewards
@ -585,10 +675,12 @@ type MsgServer interface {
ClaimHardReward(context.Context, *MsgClaimHardReward) (*MsgClaimHardRewardResponse, error) ClaimHardReward(context.Context, *MsgClaimHardReward) (*MsgClaimHardRewardResponse, error)
// ClaimDelegatorReward is a message type used to claim delegator rewards // ClaimDelegatorReward is a message type used to claim delegator rewards
ClaimDelegatorReward(context.Context, *MsgClaimDelegatorReward) (*MsgClaimDelegatorRewardResponse, error) 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) ClaimSwapReward(context.Context, *MsgClaimSwapReward) (*MsgClaimSwapRewardResponse, error)
// ClaimSavingsReward is a message type used to claim savings rewards // ClaimSavingsReward is a message type used to claim savings rewards
ClaimSavingsReward(context.Context, *MsgClaimSavingsReward) (*MsgClaimSavingsRewardResponse, error) 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. // 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) { func (*UnimplementedMsgServer) ClaimSavingsReward(ctx context.Context, req *MsgClaimSavingsReward) (*MsgClaimSavingsRewardResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ClaimSavingsReward not implemented") 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) { func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
s.RegisterService(&_Msg_serviceDesc, srv) 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) 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{ var _Msg_serviceDesc = grpc.ServiceDesc{
ServiceName: "kava.incentive.v1beta1.Msg", ServiceName: "kava.incentive.v1beta1.Msg",
HandlerType: (*MsgServer)(nil), HandlerType: (*MsgServer)(nil),
@ -729,6 +842,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{
MethodName: "ClaimSavingsReward", MethodName: "ClaimSavingsReward",
Handler: _Msg_ClaimSavingsReward_Handler, Handler: _Msg_ClaimSavingsReward_Handler,
}, },
{
MethodName: "ClaimEarnReward",
Handler: _Msg_ClaimEarnReward_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "kava/incentive/v1beta1/tx.proto", Metadata: "kava/incentive/v1beta1/tx.proto",
@ -1099,6 +1216,73 @@ func (m *MsgClaimSavingsRewardResponse) MarshalToSizedBuffer(dAtA []byte) (int,
return len(dAtA) - i, nil 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 { func encodeVarintTx(dAtA []byte, offset int, v uint64) int {
offset -= sovTx(v) offset -= sovTx(v)
base := offset base := offset
@ -1265,6 +1449,34 @@ func (m *MsgClaimSavingsRewardResponse) Size() (n int) {
return n 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) { func sovTx(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7 return (math_bits.Len64(x|1) + 6) / 7
} }
@ -2213,6 +2425,172 @@ func (m *MsgClaimSavingsRewardResponse) Unmarshal(dAtA []byte) error {
} }
return nil 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) { func skipTx(dAtA []byte) (n int, err error) {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0