Revert incentive refactor commits (#1433)

* Revert "Add incentive migrations for earn rewards (#1406)"

This reverts commit 937e5f339f.

* Revert "Use different accumulator for earn (#1395)"

This reverts commit cf009647e6.

* Revert "Add base earn incentive accumulator (#1393)"

This reverts commit 44a90a8ef9.

* Revert "Add generic incentive `AccumulateRewards` method (#1392)"

This reverts commit dce631d3de.

* Revert "Add GetSynchronizedClaim and swap adapter (#1386)"

This reverts commit f52a581ea9.

* Revert "Add Initialize/Synchronize Claim methods (#1383)"

This reverts commit c2061f626e.

* Revert "Add source adapter interface definition (#1377)"

This reverts commit 2abb2ce606.

* Revert "Add incentive RewardIndexes types and state methods (#1381)"

This reverts commit 4a3002b09c.

* Revert "Add AccrualTime type and state methods (#1379)"

This reverts commit df1c2ffc34.

* Revert "Add incentive claim state methods (#1375)"

This reverts commit 90735e29ed.

* Revert "Add generic Claim type (#1371)"

This reverts commit 45fc1a7643.

* Regerate protos and minor revert fixes
This commit is contained in:
Ruaridh 2022-12-22 01:08:16 +00:00 committed by GitHub
parent e4b4a7c62e
commit 4b8e224f6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 254 additions and 7058 deletions

View File

@ -59,16 +59,13 @@ var (
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
// This file also contains test helpers. Ideally they would be in separate package.
// Basic Usage:
//
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
//
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
// Advanced Usage:
//
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
// and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
// Creating the genesis states can be cumbersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
// Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
type TestApp struct {
App
}
@ -122,10 +119,6 @@ func (tApp TestApp) GetRouterKeeper() routerkeeper.Keeper { return tApp.ro
func (tApp TestApp) GetKavamintKeeper() kavamintkeeper.Keeper { return tApp.kavamintKeeper }
func (tApp TestApp) GetCommunityKeeper() communitykeeper.Keeper { return tApp.communityKeeper }
func (tApp TestApp) GetKeys() map[string]*sdk.KVStoreKey {
return tApp.keys
}
// LegacyAmino returns the app's amino codec.
func (app *App) LegacyAmino() *codec.LegacyAmino {
return app.legacyAmino

View File

@ -327,7 +327,6 @@
- [kava/incentive/v1beta1/claims.proto](#kava/incentive/v1beta1/claims.proto)
- [BaseClaim](#kava.incentive.v1beta1.BaseClaim)
- [BaseMultiClaim](#kava.incentive.v1beta1.BaseMultiClaim)
- [Claim](#kava.incentive.v1beta1.Claim)
- [DelegatorClaim](#kava.incentive.v1beta1.DelegatorClaim)
- [EarnClaim](#kava.incentive.v1beta1.EarnClaim)
- [HardLiquidityProviderClaim](#kava.incentive.v1beta1.HardLiquidityProviderClaim)
@ -337,21 +336,16 @@
- [RewardIndexesProto](#kava.incentive.v1beta1.RewardIndexesProto)
- [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim)
- [SwapClaim](#kava.incentive.v1beta1.SwapClaim)
- [TypedRewardIndexes](#kava.incentive.v1beta1.TypedRewardIndexes)
- [USDXMintingClaim](#kava.incentive.v1beta1.USDXMintingClaim)
- [ClaimType](#kava.incentive.v1beta1.ClaimType)
- [kava/incentive/v1beta1/params.proto](#kava/incentive/v1beta1/params.proto)
- [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod)
- [Multiplier](#kava.incentive.v1beta1.Multiplier)
- [MultipliersPerDenom](#kava.incentive.v1beta1.MultipliersPerDenom)
- [Params](#kava.incentive.v1beta1.Params)
- [RewardPeriod](#kava.incentive.v1beta1.RewardPeriod)
- [TypedMultiRewardPeriod](#kava.incentive.v1beta1.TypedMultiRewardPeriod)
- [kava/incentive/v1beta1/genesis.proto](#kava/incentive/v1beta1/genesis.proto)
- [AccrualTime](#kava.incentive.v1beta1.AccrualTime)
- [AccumulationTime](#kava.incentive.v1beta1.AccumulationTime)
- [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState)
- [GenesisState](#kava.incentive.v1beta1.GenesisState)
@ -4705,24 +4699,6 @@ BaseMultiClaim is a claim with multiple reward coin types
<a name="kava.incentive.v1beta1.Claim"></a>
### Claim
Claim stores any generic rewards that can be claimed by owner
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) | | |
| `owner` | [bytes](#bytes) | | |
| `reward` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
| `reward_indexes` | [MultiRewardIndex](#kava.incentive.v1beta1.MultiRewardIndex) | repeated | |
<a name="kava.incentive.v1beta1.DelegatorClaim"></a>
### DelegatorClaim
@ -4866,24 +4842,6 @@ SwapClaim stores the swap rewards that can be claimed by owner
<a name="kava.incentive.v1beta1.TypedRewardIndexes"></a>
### TypedRewardIndexes
TypedRewardIndexes defines a RewardIndexes slice with its corresponding
claim and collateral type
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) | | |
| `collateral_type` | [string](#string) | | |
| `reward_indexes` | [RewardIndex](#kava.incentive.v1beta1.RewardIndex) | repeated | |
<a name="kava.incentive.v1beta1.USDXMintingClaim"></a>
### USDXMintingClaim
@ -4901,24 +4859,6 @@ USDXMintingClaim is for USDX minting rewards
<!-- end messages -->
<a name="kava.incentive.v1beta1.ClaimType"></a>
### ClaimType
ClaimType is the type of claim
| Name | Number | Description |
| ---- | ------ | ----------- |
| CLAIM_TYPE_UNSPECIFIED | 0 | indicates an invalid claim type |
| CLAIM_TYPE_HARD_BORROW | 1 | claim type for hard borrow rewards |
| CLAIM_TYPE_HARD_SUPPLY | 2 | claim type for hard supply rewards |
| CLAIM_TYPE_DELEGATOR | 3 | claim type for delegator rewards |
| CLAIM_TYPE_EARN | 4 | claim type for earn rewards |
| CLAIM_TYPE_SAVINGS | 5 | claim type for savings rewards |
| CLAIM_TYPE_SWAP | 6 | claim type for swap rewards |
| CLAIM_TYPE_USDX_MINTING | 7 | claim type for usdx minting rewards |
<!-- end enums -->
<!-- end HasExtensions -->
@ -4956,8 +4896,7 @@ MultiRewardPeriod supports multiple reward types
<a name="kava.incentive.v1beta1.Multiplier"></a>
### Multiplier
Multiplier amount the claim rewards get increased by, along with how long the
claim rewards are locked
Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
| Field | Type | Label | Description |
@ -5004,7 +4943,6 @@ Params
| `claim_end` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
| `savings_reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated | |
| `earn_reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated | |
| `reward_periods` | [TypedMultiRewardPeriod](#kava.incentive.v1beta1.TypedMultiRewardPeriod) | repeated | |
@ -5029,22 +4967,6 @@ RewardPeriod stores the state of an ongoing reward
<a name="kava.incentive.v1beta1.TypedMultiRewardPeriod"></a>
### TypedMultiRewardPeriod
TypedMultiRewardPeriod stores mutiple reward types of a claim type
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) | | |
| `reward_periods` | [MultiRewardPeriod](#kava.incentive.v1beta1.MultiRewardPeriod) | repeated | |
<!-- end messages -->
<!-- end enums -->
@ -5062,25 +4984,6 @@ TypedMultiRewardPeriod stores mutiple reward types of a claim type
<a name="kava.incentive.v1beta1.AccrualTime"></a>
### AccrualTime
AccrualTime stores the previous reward distribution time and its
corresponding collateral type and claim type. This is the new version of
AccumulationTime that is used for the new claim types.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `claim_type` | [ClaimType](#kava.incentive.v1beta1.ClaimType) | | |
| `collateral_type` | [string](#string) | | |
| `previous_accumulation_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
<a name="kava.incentive.v1beta1.AccumulationTime"></a>
### AccumulationTime
@ -5135,9 +5038,6 @@ GenesisState is the state that must be provided at genesis.
| `savings_claims` | [SavingsClaim](#kava.incentive.v1beta1.SavingsClaim) | repeated | |
| `earn_reward_state` | [GenesisRewardState](#kava.incentive.v1beta1.GenesisRewardState) | | |
| `earn_claims` | [EarnClaim](#kava.incentive.v1beta1.EarnClaim) | repeated | |
| `claims` | [Claim](#kava.incentive.v1beta1.Claim) | repeated | |
| `accrual_times` | [AccrualTime](#kava.incentive.v1beta1.AccrualTime) | repeated | |
| `reward_indexes` | [TypedRewardIndexes](#kava.incentive.v1beta1.TypedRewardIndexes) | repeated | |

View File

@ -12,6 +12,8 @@ option (gogoproto.goproto_getters_all) = false;
// BaseClaim is a claim with a single reward coin types
message BaseClaim {
option (cosmos_proto.implements_interface) = "Claim";
bytes owner = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
@ -22,6 +24,8 @@ message BaseClaim {
// BaseMultiClaim is a claim with multiple reward coin types
message BaseMultiClaim {
option (cosmos_proto.implements_interface) = "Claim";
bytes owner = 1 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
@ -51,17 +55,6 @@ message RewardIndexesProto {
];
}
// TypedRewardIndexes defines a RewardIndexes slice with its corresponding
// claim and collateral type
message TypedRewardIndexes {
ClaimType claim_type = 1;
string collateral_type = 2;
repeated RewardIndex reward_indexes = 3 [
(gogoproto.castrepeated) = "RewardIndexes",
(gogoproto.nullable) = false
];
}
// MultiRewardIndex stores reward accumulation information on multiple reward types
message MultiRewardIndex {
string collateral_type = 1;
@ -84,6 +77,8 @@ message MultiRewardIndexesProto {
// USDXMintingClaim is for USDX minting rewards
message USDXMintingClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -97,6 +92,8 @@ message USDXMintingClaim {
// HardLiquidityProviderClaim stores the hard liquidity provider rewards that can be claimed by owner
message HardLiquidityProviderClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -115,6 +112,8 @@ message HardLiquidityProviderClaim {
// DelegatorClaim stores delegation rewards that can be claimed by owner
message DelegatorClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -128,6 +127,8 @@ message DelegatorClaim {
// SwapClaim stores the swap rewards that can be claimed by owner
message SwapClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -141,6 +142,8 @@ message SwapClaim {
// SavingsClaim stores the savings rewards that can be claimed by owner
message SavingsClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -154,6 +157,8 @@ message SavingsClaim {
// EarnClaim stores the earn rewards that can be claimed by owner
message EarnClaim {
option (cosmos_proto.implements_interface) = "Claim";
BaseMultiClaim base_claim = 1 [
(gogoproto.embed) = true,
(gogoproto.nullable) = false
@ -164,45 +169,3 @@ message EarnClaim {
(gogoproto.nullable) = false
];
}
// ClaimType is the type of claim
enum ClaimType {
option (gogoproto.goproto_enum_prefix) = false;
// indicates an invalid claim type
CLAIM_TYPE_UNSPECIFIED = 0;
// claim type for hard borrow rewards
CLAIM_TYPE_HARD_BORROW = 1;
// claim type for hard supply rewards
CLAIM_TYPE_HARD_SUPPLY = 2;
// claim type for delegator rewards
CLAIM_TYPE_DELEGATOR = 3;
// claim type for earn rewards
CLAIM_TYPE_EARN = 4;
// claim type for savings rewards
CLAIM_TYPE_SAVINGS = 5;
// claim type for swap rewards
CLAIM_TYPE_SWAP = 6;
// claim type for usdx minting rewards
CLAIM_TYPE_USDX_MINTING = 7;
}
// Claim stores any generic rewards that can be claimed by owner
message Claim {
ClaimType type = 1;
bytes owner = 2 [
(cosmos_proto.scalar) = "cosmos.AddressBytes",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"
];
repeated cosmos.base.v1beta1.Coin reward = 3 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.nullable) = false
];
repeated MultiRewardIndex reward_indexes = 4 [
(gogoproto.castrepeated) = "MultiRewardIndexes",
(gogoproto.nullable) = false
];
}

View File

@ -14,8 +14,6 @@ option (gogoproto.goproto_getters_all) = false;
// AccumulationTime stores the previous reward distribution time and its corresponding collateral type
message AccumulationTime {
option deprecated = true;
string collateral_type = 1;
google.protobuf.Timestamp previous_accumulation_time = 2 [
@ -24,18 +22,6 @@ message AccumulationTime {
];
}
// AccrualTime stores the previous reward distribution time and its
// corresponding collateral type and claim type. This is the new version of
// AccumulationTime that is used for the new claim types.
message AccrualTime {
ClaimType claim_type = 1;
string collateral_type = 2;
google.protobuf.Timestamp previous_accumulation_time = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdtime) = true
];
}
// GenesisRewardState groups together the global state for a particular reward so it can be exported in genesis.
message GenesisRewardState {
repeated AccumulationTime accumulation_times = 1 [
@ -100,19 +86,4 @@ message GenesisState {
(gogoproto.castrepeated) = "EarnClaims",
(gogoproto.nullable) = false
];
repeated Claim claims = 15 [
(gogoproto.castrepeated) = "Claims",
(gogoproto.nullable) = false
];
repeated AccrualTime accrual_times = 16 [
(gogoproto.castrepeated) = "AccrualTimes",
(gogoproto.nullable) = false
];
repeated TypedRewardIndexes reward_indexes = 17 [
(gogoproto.castrepeated) = "TypedRewardIndexesList",
(gogoproto.nullable) = false
];
}

View File

@ -4,7 +4,6 @@ package kava.incentive.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "kava/incentive/v1beta1/claims.proto";
option go_package = "github.com/kava-labs/kava/x/incentive/types";
option (gogoproto.goproto_getters_all) = false;
@ -50,17 +49,7 @@ message MultiRewardPeriod {
];
}
// TypedMultiRewardPeriod stores mutiple reward types of a claim type
message TypedMultiRewardPeriod {
ClaimType claim_type = 1;
repeated MultiRewardPeriod reward_periods = 2 [
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
}
// Multiplier amount the claim rewards get increased by, along with how long the
// claim rewards are locked
// Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
message Multiplier {
string name = 1;
@ -129,9 +118,4 @@ message Params {
(gogoproto.castrepeated) = "MultiRewardPeriods",
(gogoproto.nullable) = false
];
repeated TypedMultiRewardPeriod reward_periods = 10 [
(gogoproto.castrepeated) = "TypedMultiRewardPeriods",
(gogoproto.nullable) = false
];
}

View File

@ -35,13 +35,4 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
panic(fmt.Sprintf("failed to accumulate earn rewards: %s", err))
}
}
// New generic RewardPeriods
for _, mrp := range params.RewardPeriods {
for _, rp := range mrp.RewardPeriods {
if err := k.AccumulateRewards(ctx, mrp.ClaimType, rp); err != nil {
panic(fmt.Errorf("failed to accumulate rewards for claim type %s: %w", mrp.ClaimType, err))
}
}
}
}

View File

@ -44,28 +44,6 @@ func InitGenesis(
k.SetParams(ctx, gs.Params)
// Set Claims of all types
for _, claim := range gs.Claims {
k.Store.SetClaim(ctx, claim)
}
// Set AccrualTimes of all types
for _, accrualTime := range gs.AccrualTimes {
k.Store.SetRewardAccrualTime(
ctx,
accrualTime.ClaimType,
accrualTime.CollateralType,
accrualTime.PreviousAccumulationTime,
)
}
// Set RewardIndexes of all types
for _, rewardIndex := range gs.RewardIndexes {
k.Store.SetRewardIndexes(ctx, rewardIndex.ClaimType, rewardIndex.CollateralType, rewardIndex.RewardIndexes)
}
// Legacy claims and indexes below
// USDX Minting
for _, claim := range gs.USDXMintingClaims {
k.SetUSDXMintingClaim(ctx, claim)
@ -168,10 +146,6 @@ func InitGenesis(
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
params := k.GetParams(ctx)
claims := k.Store.GetAllClaims(ctx)
accrualTimes := k.Store.GetAllRewardAccrualTimes(ctx)
rewardIndexes := k.Store.GetRewardIndexes(ctx)
usdxClaims := k.GetAllUSDXMintingClaims(ctx)
usdxRewardState := getUSDXMintingGenesisRewardState(ctx, k)
@ -196,9 +170,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
// Reward states
usdxRewardState, hardSupplyRewardState, hardBorrowRewardState, delegatorRewardState, swapRewardState, savingsRewardState, earnRewardState,
// Claims
claims, usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, earnClaims,
accrualTimes,
rewardIndexes,
usdxClaims, hardClaims, delegatorClaims, swapClaims, savingsClaims, earnClaims,
)
}

View File

@ -94,7 +94,6 @@ func (suite *GenesisTestSuite) SetupTest() {
},
},
suite.genesisTime.Add(5*oneYear),
types.DefaultTypedMultiRewardPeriods,
),
types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
@ -103,15 +102,12 @@ func (suite *GenesisTestSuite) SetupTest() {
types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
types.DefaultGenesisRewardState,
types.DefaultClaims,
types.DefaultUSDXClaims,
types.DefaultHardClaims,
types.DefaultDelegatorClaims,
types.DefaultSwapClaims,
types.DefaultSavingsClaims,
types.DefaultEarnClaims,
types.DefaultAccrualTimes,
types.DefaultTypedRewardIndexesList,
)
cdc := suite.app.AppCodec()
@ -166,14 +162,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
},
},
genesisTime.Add(5*oneYear),
types.TypedMultiRewardPeriods{
types.NewTypedMultiRewardPeriod(
types.CLAIM_TYPE_SWAP,
types.MultiRewardPeriods{
types.NewMultiRewardPeriod(true, "ukava", genesisTime.Add(-1*oneYear), genesisTime.Add(oneYear), cs(c("hard", 122354))),
},
),
},
),
types.NewGenesisRewardState(
types.AccumulationTimes{
@ -231,14 +219,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.NewMultiRewardIndex("usdx", types.RewardIndexes{{CollateralType: "usdx", RewardFactor: d("0.2")}}),
},
),
types.Claims{
types.NewClaim(
types.CLAIM_TYPE_USDX_MINTING,
suite.addrs[3],
nil,
types.MultiRewardIndexes{{CollateralType: "btcb/usdx", RewardIndexes: types.RewardIndexes{{CollateralType: "swap", RewardFactor: d("0.0")}}}},
),
},
types.USDXMintingClaims{
types.NewUSDXMintingClaim(
suite.addrs[0],
@ -293,14 +273,6 @@ func (suite *GenesisTestSuite) TestExportedGenesisMatchesImported() {
types.MultiRewardIndexes{{CollateralType: "usdx", RewardIndexes: types.RewardIndexes{{CollateralType: "earn", RewardFactor: d("0.0")}}}},
),
},
types.AccrualTimes{
types.NewAccrualTime(types.CLAIM_TYPE_USDX_MINTING, "usdx", genesisTime.Add(-2*time.Hour)),
},
types.TypedRewardIndexesList{
types.NewTypedRewardIndexes(types.CLAIM_TYPE_EARN, "ukava", types.RewardIndexes{
types.NewRewardIndex("ukava", d("0.1")),
}),
},
)
tApp := app.NewTestApp()

View File

@ -1,19 +0,0 @@
package accumulators_test
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var distantFuture = time.Date(9000, 1, 1, 0, 0, 0, 0, time.UTC)
func i(in int64) sdk.Int { return sdk.NewInt(in) }
func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str) }
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
func dc(denom string, amount string) sdk.DecCoin {
return sdk.NewDecCoinFromDec(denom, sdk.MustNewDecFromStr(amount))
}
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
func toDcs(coins ...sdk.Coin) sdk.DecCoins { return sdk.NewDecCoinsFromCoins(coins...) }
func dcs(coins ...sdk.DecCoin) sdk.DecCoins { return sdk.NewDecCoins(coins...) }

View File

@ -1,63 +0,0 @@
package accumulators
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper/adapters"
"github.com/kava-labs/kava/x/incentive/keeper/store"
"github.com/kava-labs/kava/x/incentive/types"
)
// BasicAccumulator is a default implementation of the RewardAccumulator
// interface. This applies to all claim types except for those with custom
// accumulator logic e.g. Earn.
type BasicAccumulator struct {
store store.IncentiveStore
adapters adapters.SourceAdapters
}
var _ types.RewardAccumulator = BasicAccumulator{}
// NewBasicAccumulator returns a new BasicAccumulator.
func NewBasicAccumulator(
store store.IncentiveStore,
adapters adapters.SourceAdapters,
) BasicAccumulator {
return BasicAccumulator{
store: store,
adapters: adapters,
}
}
// AccumulateRewards calculates new rewards to distribute this block and updates
// the global indexes to reflect this. The provided rewardPeriod must be valid
// to avoid panics in calculating time durations.
func (k BasicAccumulator) AccumulateRewards(
ctx sdk.Context,
claimType types.ClaimType,
rewardPeriod types.MultiRewardPeriod,
) error {
previousAccrualTime, found := k.store.GetRewardAccrualTime(ctx, claimType, rewardPeriod.CollateralType)
if !found {
previousAccrualTime = ctx.BlockTime()
}
indexes, found := k.store.GetRewardIndexesOfClaimType(ctx, claimType, rewardPeriod.CollateralType)
if !found {
indexes = types.RewardIndexes{}
}
acc := types.NewAccumulator(previousAccrualTime, indexes)
totalSource := k.adapters.TotalSharesBySource(ctx, claimType, rewardPeriod.CollateralType)
acc.Accumulate(rewardPeriod, totalSource, ctx.BlockTime())
k.store.SetRewardAccrualTime(ctx, claimType, rewardPeriod.CollateralType, acc.PreviousAccumulationTime)
if len(acc.Indexes) > 0 {
// the store panics when setting empty or nil indexes
k.store.SetRewardIndexes(ctx, claimType, rewardPeriod.CollateralType, acc.Indexes)
}
return nil
}

View File

@ -1,402 +0,0 @@
package accumulators_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/app"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/testutil"
"github.com/kava-labs/kava/x/incentive/types"
swaptypes "github.com/kava-labs/kava/x/swap/types"
)
type BasicAccumulatorTestSuite struct {
testutil.IntegrationTester
keeper testutil.TestKeeper
userAddrs []sdk.AccAddress
valAddrs []sdk.ValAddress
pool string
}
func TestBasicAccumulatorTestSuite(t *testing.T) {
suite.Run(t, new(BasicAccumulatorTestSuite))
}
func (suite *BasicAccumulatorTestSuite) SetupTest() {
suite.IntegrationTester.SetupTest()
suite.keeper = testutil.TestKeeper{
Keeper: suite.App.GetIncentiveKeeper(),
}
_, addrs := app.GeneratePrivKeyAddressPairs(5)
suite.userAddrs = addrs[0:2]
suite.valAddrs = []sdk.ValAddress{
sdk.ValAddress(addrs[2]),
sdk.ValAddress(addrs[3]),
}
poolDenomA := "btc"
poolDenomB := "usdx"
// Setup app with test state
authBuilder := app.NewAuthBankGenesisBuilder().
WithSimpleAccount(addrs[0], cs(
c("ukava", 1e12),
c(poolDenomA, 1e12),
c(poolDenomB, 1e12),
)).
WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[3], cs(c("ukava", 1e12)))
incentiveBuilder := testutil.NewIncentiveGenesisBuilder().
WithGenesisTime(suite.GenesisTime).
WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs())
savingsBuilder := testutil.NewSavingsGenesisBuilder().
WithSupportedDenoms("bkava")
earnBuilder := testutil.NewEarnGenesisBuilder().
WithAllowedVaults(earntypes.AllowedVault{
Denom: "bkava",
Strategies: earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
IsPrivateVault: false,
AllowedDepositors: nil,
})
stakingBuilder := testutil.NewStakingGenesisBuilder()
kavamintBuilder := testutil.NewKavamintGenesisBuilder().
WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")).
WithPreviousBlockTime(suite.GenesisTime)
suite.StartChainWithBuilders(
authBuilder,
incentiveBuilder,
savingsBuilder,
earnBuilder,
stakingBuilder,
kavamintBuilder,
)
suite.pool = swaptypes.PoolID(poolDenomA, poolDenomB)
swapKeeper := suite.App.GetSwapKeeper()
swapKeeper.SetParams(suite.Ctx, swaptypes.NewParams(
swaptypes.NewAllowedPools(
swaptypes.NewAllowedPool(poolDenomA, poolDenomB),
),
sdk.ZeroDec(),
))
}
func TestAccumulateSwapRewards(t *testing.T) {
suite.Run(t, new(BasicAccumulatorTestSuite))
}
func (suite *BasicAccumulatorTestSuite) TestStateUpdatedWhenBlockTimeHasIncreased() {
pool := "btc:usdx"
err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0"))
suite.Require().NoError(err)
suite.keeper.StoreGlobalIndexes(
suite.Ctx,
types.CLAIM_TYPE_SWAP,
types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
},
)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
newAccrualTime := previousAccrualTime.Add(1 * time.Hour)
suite.Ctx = suite.Ctx.WithBlockTime(newAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, newAccrualTime)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("7.22"),
},
{
CollateralType: "ukava",
RewardFactor: d("3.64"),
},
})
}
func (suite *BasicAccumulatorTestSuite) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
pool := "btc:usdx"
err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0"))
suite.Require().NoError(err)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(
suite.Ctx,
types.CLAIM_TYPE_SWAP,
previousIndexes,
)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
suite.Ctx = suite.Ctx.WithBlockTime(previousAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
expected, f := previousIndexes.Get(pool)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expected)
}
func (suite *BasicAccumulatorTestSuite) TestNoAccumulationWhenSourceSharesAreZero() {
pool := "btc:usdx"
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(
suite.Ctx,
types.CLAIM_TYPE_SWAP, previousIndexes)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
firstAccrualTime := previousAccrualTime.Add(7 * time.Second)
suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
err := suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime)
expected, f := previousIndexes.Get(pool)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expected)
}
func (suite *BasicAccumulatorTestSuite) TestStateAddedWhenStateDoesNotExist() {
pool := "btc:usdx"
err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0"))
suite.Require().NoError(err)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
firstAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime)
err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// After the first accumulation only the current block time should be stored.
// The indexes will be empty as no time has passed since the previous block because it didn't exist.
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, nil)
secondAccrualTime := firstAccrualTime.Add(10 * time.Second)
suite.Ctx = suite.Ctx.WithBlockTime(secondAccrualTime)
err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// After the second accumulation both current block time and indexes should be stored.
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, secondAccrualTime)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.01"),
},
})
}
func (suite *BasicAccumulatorTestSuite) TestNoPanicWhenStateDoesNotExist() {
pool := "btc:usdx"
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(),
)
accrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.Ctx = suite.Ctx.WithBlockTime(accrualTime)
// Accumulate with no swap shares and no rewards per second will result in no increment to the indexes.
// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
// Check there is no panic.
suite.NotPanics(func() {
err := suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
})
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, accrualTime)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, nil)
}
func (suite *BasicAccumulatorTestSuite) TestNoAccumulationWhenBeforeStartTime() {
pool := "btc:usdx"
err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0"))
suite.Require().NoError(err)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(
suite.Ctx,
types.CLAIM_TYPE_SWAP, previousIndexes)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
firstAccrualTime := previousAccrualTime.Add(10 * time.Second)
period := types.NewMultiRewardPeriod(
true,
pool,
firstAccrualTime.Add(time.Nanosecond), // start time after accrual time
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime)
err = suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
suite.Require().NoError(err)
// The accrual time should be updated, but the indexes unchanged
suite.StoredTimeEquals(types.CLAIM_TYPE_SWAP, pool, firstAccrualTime)
expectedIndexes, f := previousIndexes.Get(pool)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_SWAP, pool, expectedIndexes)
}
func (suite *BasicAccumulatorTestSuite) TestPanicWhenCurrentTimeLessThanPrevious() {
pool := "btc:usdx"
err := suite.DeliverSwapMsgDeposit(suite.userAddrs[0], c("btc", 1e6), c("usdx", 1e6), d("1.0"))
suite.Require().NoError(err)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_SWAP, pool, previousAccrualTime)
firstAccrualTime := time.Time{}
period := types.NewMultiRewardPeriod(
true,
pool,
time.Time{}, // start time after accrual time
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
suite.Ctx = suite.Ctx.WithBlockTime(firstAccrualTime)
suite.Panics(func() {
suite.keeper.AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_SWAP, period)
})
}

View File

@ -1,245 +0,0 @@
package accumulators
import (
"errors"
"fmt"
"sort"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/keeper/adapters"
"github.com/kava-labs/kava/x/incentive/keeper/store"
"github.com/kava-labs/kava/x/incentive/types"
)
// EarnAccumulator is an accumulator for Earn claim types. This includes
// claiming staking rewards and reward distribution for liquid kava.
type EarnAccumulator struct {
store store.IncentiveStore
liquidKeeper types.LiquidKeeper
earnKeeper types.EarnKeeper
adapters adapters.SourceAdapters
}
var _ types.RewardAccumulator = EarnAccumulator{}
// NewEarnAccumulator returns a new EarnAccumulator.
func NewEarnAccumulator(
store store.IncentiveStore,
liquidKeeper types.LiquidKeeper,
earnKeeper types.EarnKeeper,
adapters adapters.SourceAdapters,
) EarnAccumulator {
return EarnAccumulator{
store: store,
liquidKeeper: liquidKeeper,
earnKeeper: earnKeeper,
adapters: adapters,
}
}
// AccumulateRewards calculates new rewards to distribute this block and updates
// the global indexes to reflect this. The provided rewardPeriod must be valid
// to avoid panics in calculating time durations.
func (a EarnAccumulator) AccumulateRewards(
ctx sdk.Context,
claimType types.ClaimType,
rewardPeriod types.MultiRewardPeriod,
) error {
if claimType != types.CLAIM_TYPE_EARN {
panic(fmt.Sprintf(
"invalid claim type for earn accumulator, expected %s but got %s",
types.CLAIM_TYPE_EARN,
claimType,
))
}
if rewardPeriod.CollateralType == "bkava" {
return a.accumulateEarnBkavaRewards(ctx, rewardPeriod)
}
// Non bkava vaults use the basic accumulator.
return NewBasicAccumulator(a.store, a.adapters).AccumulateRewards(ctx, claimType, rewardPeriod)
}
// accumulateEarnBkavaRewards does the same as AccumulateEarnRewards but for
// *all* bkava vaults.
func (k EarnAccumulator) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error {
// All bkava vault denoms
bkavaVaultsDenoms := make(map[string]bool)
// bkava vault denoms from earn records (non-empty vaults)
k.earnKeeper.IterateVaultRecords(ctx, func(record earntypes.VaultRecord) (stop bool) {
if k.liquidKeeper.IsDerivativeDenom(ctx, record.TotalShares.Denom) {
bkavaVaultsDenoms[record.TotalShares.Denom] = true
}
return false
})
// bkava vault denoms from past incentive indexes, may include vaults
// that were fully withdrawn.
k.store.IterateRewardIndexesByClaimType(
ctx,
types.CLAIM_TYPE_EARN,
func(reward types.TypedRewardIndexes) (stop bool) {
if k.liquidKeeper.IsDerivativeDenom(ctx, reward.CollateralType) {
bkavaVaultsDenoms[reward.CollateralType] = true
}
return false
})
totalBkavaValue, err := k.liquidKeeper.GetTotalDerivativeValue(ctx)
if err != nil {
return err
}
i := 0
sortedBkavaVaultsDenoms := make([]string, len(bkavaVaultsDenoms))
for vaultDenom := range bkavaVaultsDenoms {
sortedBkavaVaultsDenoms[i] = vaultDenom
i++
}
// Sort the vault denoms to ensure deterministic iteration order.
sort.Strings(sortedBkavaVaultsDenoms)
// Accumulate rewards for each bkava vault.
for _, bkavaDenom := range sortedBkavaVaultsDenoms {
derivativeValue, err := k.liquidKeeper.GetDerivativeValue(ctx, bkavaDenom)
if err != nil {
return err
}
k.accumulateBkavaEarnRewards(
ctx,
bkavaDenom,
rewardPeriod.Start,
rewardPeriod.End,
GetProportionalRewardsPerSecond(
rewardPeriod,
totalBkavaValue.Amount,
derivativeValue.Amount,
),
)
}
return nil
}
func GetProportionalRewardsPerSecond(
rewardPeriod types.MultiRewardPeriod,
totalBkavaSupply sdk.Int,
singleBkavaSupply sdk.Int,
) sdk.DecCoins {
// Rate per bkava-xxx = rewardsPerSecond * % of bkava-xxx
// = rewardsPerSecond * (bkava-xxx / total bkava)
// = (rewardsPerSecond * bkava-xxx) / total bkava
newRate := sdk.NewDecCoins()
// Prevent division by zero, if there are no total shares then there are no
// rewards.
if totalBkavaSupply.IsZero() {
return newRate
}
for _, rewardCoin := range rewardPeriod.RewardsPerSecond {
scaledAmount := rewardCoin.Amount.ToDec().
Mul(singleBkavaSupply.ToDec()).
Quo(totalBkavaSupply.ToDec())
newRate = newRate.Add(sdk.NewDecCoinFromDec(rewardCoin.Denom, scaledAmount))
}
return newRate
}
func (k EarnAccumulator) accumulateBkavaEarnRewards(
ctx sdk.Context,
collateralType string,
periodStart time.Time,
periodEnd time.Time,
periodRewardsPerSecond sdk.DecCoins,
) {
// Collect staking rewards for this validator, does not have any start/end
// period time restrictions.
stakingRewards := k.collectDerivativeStakingRewards(ctx, collateralType)
// Collect incentive rewards
// **Total rewards** for vault per second, NOT per share
perSecondRewards := k.collectPerSecondRewards(
ctx,
collateralType,
periodStart,
periodEnd,
periodRewardsPerSecond,
)
// **Total rewards** for vault per second, NOT per share
rewards := stakingRewards.Add(perSecondRewards...)
// Distribute rewards by incrementing indexes
indexes, found := k.store.GetRewardIndexesOfClaimType(ctx, types.CLAIM_TYPE_EARN, collateralType)
if !found {
indexes = types.RewardIndexes{}
}
totalSourceShares := k.adapters.TotalSharesBySource(ctx, types.CLAIM_TYPE_EARN, collateralType)
var increment types.RewardIndexes
if totalSourceShares.GT(sdk.ZeroDec()) {
// Divide total rewards by total shares to get the reward **per share**
// Leave as nil if no source shares
increment = types.NewRewardIndexesFromCoins(rewards).Quo(totalSourceShares)
}
updatedIndexes := indexes.Add(increment)
if len(updatedIndexes) > 0 {
// the store panics when setting empty or nil indexes
k.store.SetRewardIndexes(ctx, types.CLAIM_TYPE_EARN, collateralType, updatedIndexes)
}
}
func (k EarnAccumulator) collectDerivativeStakingRewards(ctx sdk.Context, collateralType string) sdk.DecCoins {
rewards, err := k.liquidKeeper.CollectStakingRewardsByDenom(ctx, collateralType, types.IncentiveMacc)
if err != nil {
if !errors.Is(err, distrtypes.ErrNoValidatorDistInfo) &&
!errors.Is(err, distrtypes.ErrEmptyDelegationDistInfo) {
panic(fmt.Sprintf("failed to collect staking rewards for %s: %s", collateralType, err))
}
// otherwise there's no validator or delegation yet
rewards = nil
}
return sdk.NewDecCoinsFromCoins(rewards...)
}
func (k EarnAccumulator) collectPerSecondRewards(
ctx sdk.Context,
collateralType string,
periodStart time.Time,
periodEnd time.Time,
periodRewardsPerSecond sdk.DecCoins,
) sdk.DecCoins {
previousAccrualTime, found := k.store.GetRewardAccrualTime(ctx, types.CLAIM_TYPE_EARN, collateralType)
if !found {
previousAccrualTime = ctx.BlockTime()
}
rewards, accumulatedTo := types.CalculatePerSecondRewards(
periodStart,
periodEnd,
periodRewardsPerSecond,
previousAccrualTime,
ctx.BlockTime(),
)
k.store.SetRewardAccrualTime(ctx, types.CLAIM_TYPE_EARN, collateralType, accumulatedTo)
// Don't need to move funds as they're assumed to be in the IncentiveMacc module account already.
return rewards
}

View File

@ -1,665 +0,0 @@
package accumulators_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/kava-labs/kava/app"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/keeper/accumulators"
"github.com/kava-labs/kava/x/incentive/testutil"
"github.com/kava-labs/kava/x/incentive/types"
)
type AccumulateEarnRewardsIntegrationTests struct {
testutil.IntegrationTester
keeper testutil.TestKeeper
userAddrs []sdk.AccAddress
valAddrs []sdk.ValAddress
}
func TestAccumulateEarnRewardsIntegrationTests(t *testing.T) {
suite.Run(t, new(AccumulateEarnRewardsIntegrationTests))
}
func (suite *AccumulateEarnRewardsIntegrationTests) SetupTest() {
suite.IntegrationTester.SetupTest()
suite.keeper = testutil.TestKeeper{
Keeper: suite.App.GetIncentiveKeeper(),
}
_, addrs := app.GeneratePrivKeyAddressPairs(5)
suite.userAddrs = addrs[0:2]
suite.valAddrs = []sdk.ValAddress{
sdk.ValAddress(addrs[2]),
sdk.ValAddress(addrs[3]),
}
// Setup app with test state
authBuilder := app.NewAuthBankGenesisBuilder().
WithSimpleAccount(addrs[0], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[3], cs(c("ukava", 1e12)))
incentiveBuilder := testutil.NewIncentiveGenesisBuilder().
WithGenesisTime(suite.GenesisTime).
WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs())
savingsBuilder := testutil.NewSavingsGenesisBuilder().
WithSupportedDenoms("bkava")
earnBuilder := testutil.NewEarnGenesisBuilder().
WithAllowedVaults(earntypes.AllowedVault{
Denom: "bkava",
Strategies: earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
IsPrivateVault: false,
AllowedDepositors: nil,
})
stakingBuilder := testutil.NewStakingGenesisBuilder()
kavamintBuilder := testutil.NewKavamintGenesisBuilder().
WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")).
WithPreviousBlockTime(suite.GenesisTime)
suite.StartChainWithBuilders(
authBuilder,
incentiveBuilder,
savingsBuilder,
earnBuilder,
stakingBuilder,
kavamintBuilder,
)
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUpdatedWhenBlockTimeHasIncreased() {
suite.AddIncentiveMultiRewardPeriod(
types.CLAIM_TYPE_EARN,
types.NewMultiRewardPeriod(
true,
"bkava", // reward period is set for "bkava" to apply to all vaults
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
),
)
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 800000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 200000))
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: derivative0.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: derivative1.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
val0 := suite.GetAbciValidator(suite.valAddrs[0])
val1 := suite.GetAbciValidator(suite.valAddrs[1])
// Mint tokens, distribute to validators, claim staking rewards
// 1 hour later
_, resBeginBlock := suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{
{
Validator: val0,
SignedLastBlock: true,
},
{
Validator: val1,
SignedLastBlock: true,
},
},
},
},
)
validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock)
suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 0")
suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1")
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
stakingRewardIndexes0 := validatorRewards[suite.valAddrs[0].String()].
AmountOf("ukava").
ToDec().
Quo(derivative0.Amount.ToDec())
stakingRewardIndexes1 := validatorRewards[suite.valAddrs[1].String()].
AmountOf("ukava").
ToDec().
Quo(derivative1.Amount.ToDec())
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("7.22"),
},
{
CollateralType: "ukava",
RewardFactor: d("3.64").Add(stakingRewardIndexes0),
},
})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("7.22"),
},
{
CollateralType: "ukava",
RewardFactor: d("3.64").Add(stakingRewardIndexes1),
},
})
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUpdatedWhenBlockTimeHasIncreased_partialDeposit() {
suite.AddIncentiveMultiRewardPeriod(
types.CLAIM_TYPE_EARN,
types.NewMultiRewardPeriod(
true,
"bkava", // reward period is set for "bkava" to apply to all vaults
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
),
)
// 800000bkava0 minted, 700000 deposited
// 200000bkava1 minted, 100000 deposited
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 800000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 200000))
suite.NoError(err)
depositAmount0 := c(derivative0.Denom, 700000)
depositAmount1 := c(derivative1.Denom, 100000)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], depositAmount0, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], depositAmount1, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: derivative0.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: derivative1.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
val0 := suite.GetAbciValidator(suite.valAddrs[0])
val1 := suite.GetAbciValidator(suite.valAddrs[1])
// Mint tokens, distribute to validators, claim staking rewards
// 1 hour later
_, resBeginBlock := suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{
{
Validator: val0,
SignedLastBlock: true,
},
{
Validator: val1,
SignedLastBlock: true,
},
},
},
},
)
validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock)
suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 0")
suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1")
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
// Divided by deposit amounts, not bank supply amounts
stakingRewardIndexes0 := validatorRewards[suite.valAddrs[0].String()].
AmountOf("ukava").
ToDec().
Quo(depositAmount0.Amount.ToDec())
stakingRewardIndexes1 := validatorRewards[suite.valAddrs[1].String()].
AmountOf("ukava").
ToDec().
Quo(depositAmount1.Amount.ToDec())
// Slightly increased rewards due to less bkava deposited
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("8.248571428571428571"),
},
{
CollateralType: "ukava",
RewardFactor: d("4.154285714285714286").Add(stakingRewardIndexes0),
},
})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("14.42"),
},
{
CollateralType: "ukava",
RewardFactor: d("7.24").Add(stakingRewardIndexes1),
},
})
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000))
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: derivative0.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: derivative1.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, previousIndexes)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
period := types.NewMultiRewardPeriod(
true,
"bkava",
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
// Must manually accumulate rewards as BeginBlockers only run when the block time increases
// This does not run any x/mint or x/distribution BeginBlockers
earnKeeper := suite.App.GetEarnKeeper()
err = accumulators.
NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters).
AccumulateRewards(suite.Ctx, types.CLAIM_TYPE_EARN, period)
suite.NoError(err)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
expected, f := previousIndexes.Get(derivative0.Denom)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, expected)
expected, f = previousIndexes.Get(derivative1.Denom)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, expected)
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestNoAccumulationWhenSourceSharesAreZero() {
suite.AddIncentiveMultiRewardPeriod(
types.CLAIM_TYPE_EARN,
types.NewMultiRewardPeriod(
true,
"bkava", // reward period is set for "bkava" to apply to all vaults
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
),
)
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000))
suite.NoError(err)
// No earn deposits
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: derivative0.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: derivative1.Denom,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "earn",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, previousIndexes)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
val0 := suite.GetAbciValidator(suite.valAddrs[0])
val1 := suite.GetAbciValidator(suite.valAddrs[1])
// Mint tokens, distribute to validators, claim staking rewards
// 1 hour later
_, _ = suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{
{
Validator: val0,
SignedLastBlock: true,
},
{
Validator: val1,
SignedLastBlock: true,
},
},
},
},
)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
expected, f := previousIndexes.Get(derivative0.Denom)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, expected)
expected, f = previousIndexes.Get(derivative1.Denom)
suite.True(f)
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, expected)
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestStateAddedWhenStateDoesNotExist() {
suite.AddIncentiveMultiRewardPeriod(
types.CLAIM_TYPE_EARN,
types.NewMultiRewardPeriod(
true,
"bkava", // reward period is set for "bkava" to apply to all vaults
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
),
)
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000))
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], derivative0, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[1], derivative1, earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
val0 := suite.GetAbciValidator(suite.valAddrs[0])
val1 := suite.GetAbciValidator(suite.valAddrs[1])
_, resBeginBlock := suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{
{
Validator: val0,
SignedLastBlock: true,
},
{
Validator: val1,
SignedLastBlock: true,
},
},
},
},
)
// After the second accumulation both current block time and indexes should be stored.
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
validatorRewards0, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock)
firstStakingRewardIndexes0 := validatorRewards0[suite.valAddrs[0].String()].
AmountOf("ukava").
ToDec().
Quo(derivative0.Amount.ToDec())
firstStakingRewardIndexes1 := validatorRewards0[suite.valAddrs[1].String()].
AmountOf("ukava").
ToDec().
Quo(derivative1.Amount.ToDec())
// After the first accumulation only the current block time should be stored.
// The indexes will be empty as no time has passed since the previous block because it didn't exist.
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
// First accumulation can have staking rewards, but no other rewards
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: firstStakingRewardIndexes0,
},
})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: firstStakingRewardIndexes1,
},
})
_, resBeginBlock = suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{
{
Validator: val0,
SignedLastBlock: true,
},
{
Validator: val1,
SignedLastBlock: true,
},
},
},
},
)
// After the second accumulation both current block time and indexes should be stored.
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, suite.Ctx.BlockTime())
validatorRewards1, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock)
secondStakingRewardIndexes0 := validatorRewards1[suite.valAddrs[0].String()].
AmountOf("ukava").
ToDec().
Quo(derivative0.Amount.ToDec())
secondStakingRewardIndexes1 := validatorRewards1[suite.valAddrs[1].String()].
AmountOf("ukava").
ToDec().
Quo(derivative1.Amount.ToDec())
// Second accumulation has both staking rewards and incentive rewards
// ukava incentive rewards: 3600 * 1000 / (2 * 1000000) == 1.8
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, types.RewardIndexes{
{
CollateralType: "ukava",
// Incentive rewards + both staking rewards
RewardFactor: d("1.8").Add(firstStakingRewardIndexes0).Add(secondStakingRewardIndexes0),
},
{
CollateralType: "earn",
RewardFactor: d("3.6"),
},
})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, types.RewardIndexes{
{
CollateralType: "ukava",
// Incentive rewards + both staking rewards
RewardFactor: d("1.8").Add(firstStakingRewardIndexes1).Add(secondStakingRewardIndexes1),
},
{
CollateralType: "earn",
RewardFactor: d("3.6"),
},
})
}
func (suite *AccumulateEarnRewardsIntegrationTests) TestNoPanicWhenStateDoesNotExist() {
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], c("ukava", 1000000))
suite.NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[1], suite.valAddrs[1], c("ukava", 1000000))
suite.NoError(err)
period := types.NewMultiRewardPeriod(
true,
"bkava",
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(),
)
// Accumulate with no earn shares and no rewards per second will result in no increment to the indexes.
// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
// Check there is no panic.
suite.NotPanics(func() {
// This does not update any state, as there are no bkava vaults
// to iterate over, denoms are unknown
err := suite.keeper.AccumulateEarnRewards(suite.Ctx, period)
suite.NoError(err)
})
// Times are not stored for vaults with no state
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative0.Denom, time.Time{})
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, derivative1.Denom, time.Time{})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative0.Denom, nil)
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, derivative1.Denom, nil)
}

View File

@ -1,192 +0,0 @@
package accumulators_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/app"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/testutil"
"github.com/kava-labs/kava/x/incentive/types"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
)
type EarnAccumulatorStakingRewardsTestSuite struct {
testutil.IntegrationTester
keeper testutil.TestKeeper
userAddrs []sdk.AccAddress
valAddrs []sdk.ValAddress
}
func TestEarnStakingRewardsIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(EarnAccumulatorStakingRewardsTestSuite))
}
func (suite *EarnAccumulatorStakingRewardsTestSuite) SetupTest() {
suite.IntegrationTester.SetupTest()
suite.keeper = testutil.TestKeeper{
Keeper: suite.App.GetIncentiveKeeper(),
}
_, addrs := app.GeneratePrivKeyAddressPairs(5)
suite.userAddrs = addrs[0:2]
suite.valAddrs = []sdk.ValAddress{
sdk.ValAddress(addrs[2]),
sdk.ValAddress(addrs[3]),
}
// Setup app with test state
authBuilder := app.NewAuthBankGenesisBuilder().
WithSimpleAccount(addrs[0], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[1], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[2], cs(c("ukava", 1e12))).
WithSimpleAccount(addrs[3], cs(c("ukava", 1e12)))
incentiveBuilder := testutil.NewIncentiveGenesisBuilder().
WithGenesisTime(suite.GenesisTime).
WithSimpleRewardPeriod(types.CLAIM_TYPE_EARN, "bkava", cs())
savingsBuilder := testutil.NewSavingsGenesisBuilder().
WithSupportedDenoms("bkava")
earnBuilder := testutil.NewEarnGenesisBuilder().
WithAllowedVaults(earntypes.AllowedVault{
Denom: "bkava",
Strategies: earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
IsPrivateVault: false,
AllowedDepositors: nil,
})
stakingBuilder := testutil.NewStakingGenesisBuilder()
kavamintBuilder := testutil.NewKavamintGenesisBuilder().
WithStakingRewardsApy(sdk.MustNewDecFromStr("0.2")).
WithPreviousBlockTime(suite.GenesisTime)
suite.StartChainWithBuilders(
authBuilder,
incentiveBuilder,
savingsBuilder,
earnBuilder,
stakingBuilder,
kavamintBuilder,
)
}
func (suite *EarnAccumulatorStakingRewardsTestSuite) TestStakingRewardsDistributed() {
// derivative 1: 8 total staked, 7 to earn, 1 not in earn
// derivative 2: 2 total staked, 1 to earn, 1 not in earn
userMintAmount0 := c("ukava", 8e9)
userMintAmount1 := c("ukava", 2e9)
userDepositAmount0 := i(7e9)
userDepositAmount1 := i(1e9)
// Create two validators
derivative0, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[0], userMintAmount0)
suite.Require().NoError(err)
derivative1, err := suite.MintLiquidAnyValAddr(suite.userAddrs[0], suite.valAddrs[1], userMintAmount1)
suite.Require().NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], sdk.NewCoin(derivative0.Denom, userDepositAmount0), earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
err = suite.DeliverEarnMsgDeposit(suite.userAddrs[0], sdk.NewCoin(derivative1.Denom, userDepositAmount1), earntypes.STRATEGY_TYPE_SAVINGS)
suite.NoError(err)
// Get derivative denoms
lq := suite.App.GetLiquidKeeper()
vaultDenom1 := lq.GetLiquidStakingTokenDenom(suite.valAddrs[0])
vaultDenom2 := lq.GetLiquidStakingTokenDenom(suite.valAddrs[1])
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.Ctx = suite.Ctx.WithBlockTime(previousAccrualTime)
initialVault1RewardFactor := d("0.04")
initialVault2RewardFactor := d("0.04")
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: vaultDenom1,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: initialVault1RewardFactor,
},
},
},
{
CollateralType: vaultDenom2,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: initialVault2RewardFactor,
},
},
},
}
suite.keeper.StoreGlobalIndexes(suite.Ctx, types.CLAIM_TYPE_EARN, globalIndexes)
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1, suite.Ctx.BlockTime())
suite.keeper.Store.SetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2, suite.Ctx.BlockTime())
suite.App.GetKavamintKeeper().SetPreviousBlockTime(suite.Ctx, suite.Ctx.BlockTime())
val := suite.GetAbciValidator(suite.valAddrs[0])
// Mint tokens, distribute to validators, claim staking rewards
// 1 hour later
_, resBeginBlock := suite.NextBlockAfterWithReq(
1*time.Hour,
abci.RequestEndBlock{},
abci.RequestBeginBlock{
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: true,
}},
},
},
)
// check time and factors
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, vaultDenom1, suite.Ctx.BlockTime())
suite.StoredTimeEquals(types.CLAIM_TYPE_EARN, vaultDenom2, suite.Ctx.BlockTime())
validatorRewards, _ := suite.GetBeginBlockClaimedStakingRewards(resBeginBlock)
suite.Require().Contains(validatorRewards, suite.valAddrs[0].String(), "there should be claim events for validator 1")
suite.Require().Contains(validatorRewards, suite.valAddrs[1].String(), "there should be claim events for validator 2")
// Total staking rewards / total source shares (**deposited in earn** not total minted)
// types.RewardIndexes.Quo() uses Dec.Quo() which uses bankers rounding.
// So we need to use Dec.Quo() to also round vs Dec.QuoInt() which truncates
expectedIndexes1 := validatorRewards[suite.valAddrs[0].String()].
AmountOf("ukava").
ToDec().
Quo(userDepositAmount0.ToDec())
expectedIndexes2 := validatorRewards[suite.valAddrs[1].String()].
AmountOf("ukava").
ToDec().
Quo(userDepositAmount1.ToDec())
// Only contains staking rewards
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, vaultDenom1, types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: initialVault1RewardFactor.Add(expectedIndexes1),
},
})
suite.StoredIndexesEqual(types.CLAIM_TYPE_EARN, vaultDenom2, types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: initialVault2RewardFactor.Add(expectedIndexes2),
},
})
}

View File

@ -1,50 +0,0 @@
package accumulators_test
import (
"fmt"
"time"
"github.com/kava-labs/kava/x/incentive/keeper/accumulators"
"github.com/kava-labs/kava/x/incentive/types"
)
func (suite *AccumulateEarnRewardsIntegrationTests) TestEarnAccumulator_OnlyEarnClaimType() {
period := types.NewMultiRewardPeriod(
true,
"bkava",
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("earn", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
earnKeeper := suite.App.GetEarnKeeper()
for _, claimTypeValue := range types.ClaimType_value {
claimType := types.ClaimType(claimTypeValue)
if claimType == types.CLAIM_TYPE_EARN {
suite.NotPanics(func() {
err := accumulators.
NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters).
AccumulateRewards(suite.Ctx, claimType, period)
suite.NoError(err)
})
continue
}
suite.PanicsWithValue(
fmt.Sprintf(
"invalid claim type for earn accumulator, expected %s but got %s",
types.CLAIM_TYPE_EARN,
claimType,
),
func() {
err := accumulators.
NewEarnAccumulator(suite.keeper.Store, suite.App.GetLiquidKeeper(), &earnKeeper, suite.keeper.Adapters).
AccumulateRewards(suite.Ctx, claimType, period)
suite.NoError(err)
},
)
}
}

View File

@ -1,81 +0,0 @@
package adapters
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper/adapters/earn"
"github.com/kava-labs/kava/x/incentive/keeper/adapters/swap"
"github.com/kava-labs/kava/x/incentive/types"
)
// SourceAdapters is a collection of source adapters.
type SourceAdapters struct {
adapters map[types.ClaimType]types.SourceAdapter
}
// SourceShare is a single share from a source with it's corresponding ID.
type SourceShare struct {
ID string
Shares sdk.Dec
}
// NewSourceAdapters returns a new SourceAdapters instance with all available
// source adapters.
func NewSourceAdapters(
swapKeeper types.SwapKeeper,
earnKeeper types.EarnKeeper,
) SourceAdapters {
return SourceAdapters{
adapters: map[types.ClaimType]types.SourceAdapter{
types.CLAIM_TYPE_SWAP: swap.NewSourceAdapter(swapKeeper),
types.CLAIM_TYPE_EARN: earn.NewSourceAdapter(earnKeeper),
},
}
}
// OwnerSharesBySource returns a slice of SourceShares for each sourceID from a
// specified owner. The slice is sorted by sourceID.
func (a SourceAdapters) OwnerSharesBySource(
ctx sdk.Context,
claimType types.ClaimType,
owner sdk.AccAddress,
sourceIDs []string,
) []SourceShare {
adapter, found := a.adapters[claimType]
if !found {
panic(fmt.Sprintf("no source share fetcher for claim type %s", claimType))
}
ownerShares := adapter.OwnerSharesBySource(ctx, owner, sourceIDs)
var shares []SourceShare
for _, sourceID := range sourceIDs {
singleShares, found := ownerShares[sourceID]
if !found {
panic(fmt.Sprintf("no source shares for claimType %s and source %s", claimType, sourceID))
}
shares = append(shares, SourceShare{
ID: sourceID,
Shares: singleShares,
})
}
return shares
}
// TotalSharesBySource returns the total shares of a given claimType and sourceID.
func (a SourceAdapters) TotalSharesBySource(
ctx sdk.Context,
claimType types.ClaimType,
sourceID string,
) sdk.Dec {
adapter, found := a.adapters[claimType]
if !found {
panic(fmt.Sprintf("no source share fetcher for claim type %s", claimType))
}
return adapter.TotalSharesBySource(ctx, sourceID)
}

View File

@ -1,48 +0,0 @@
package earn
import (
sdk "github.com/cosmos/cosmos-sdk/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/types"
)
var _ types.SourceAdapter = SourceAdapter{}
type SourceAdapter struct {
keeper types.EarnKeeper
}
func NewSourceAdapter(keeper types.EarnKeeper) SourceAdapter {
return SourceAdapter{
keeper: keeper,
}
}
func (f SourceAdapter) TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec {
vaultShares, found := f.keeper.GetVaultTotalShares(ctx, sourceID)
if !found {
return sdk.ZeroDec()
}
return vaultShares.Amount
}
func (f SourceAdapter) OwnerSharesBySource(
ctx sdk.Context,
owner sdk.AccAddress,
sourceIDs []string,
) map[string]sdk.Dec {
accountShares, found := f.keeper.GetVaultAccountShares(ctx, owner)
if !found {
accountShares = earntypes.VaultShares{}
}
shares := make(map[string]sdk.Dec)
for _, id := range sourceIDs {
// Sets shares to zero if not found
shares[id] = accountShares.AmountOf(id)
}
return shares
}

View File

@ -1,298 +0,0 @@
package earn_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/kava-labs/kava/app"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/keeper/adapters/earn"
savingstypes "github.com/kava-labs/kava/x/savings/types"
"github.com/stretchr/testify/suite"
)
type EarnAdapterTestSuite struct {
suite.Suite
app app.TestApp
ctx sdk.Context
genesisTime time.Time
addrs []sdk.AccAddress
}
func TestEarnAdapterTestSuite(t *testing.T) {
suite.Run(t, new(EarnAdapterTestSuite))
}
func (suite *EarnAdapterTestSuite) SetupTest() {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
_, suite.addrs = app.GeneratePrivKeyAddressPairs(5)
suite.genesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC)
suite.app = app.NewTestApp()
suite.ctx = suite.app.NewContext(true, tmprototypes.Header{Time: suite.genesisTime})
}
func (suite *EarnAdapterTestSuite) TestEarnAdapter_OwnerSharesBySource_Empty() {
ek := suite.app.GetEarnKeeper()
adapter := earn.NewSourceAdapter(&ek)
tests := []struct {
name string
giveOwner sdk.AccAddress
giveSourceIDs []string
wantShares map[string]sdk.Dec
}{
{
"empty requests",
suite.addrs[0],
[]string{},
map[string]sdk.Dec{},
},
{
"empty vaults are zero",
suite.addrs[0],
[]string{
"vault1",
"vault2",
"vault3",
},
map[string]sdk.Dec{
"vault1": sdk.ZeroDec(),
"vault2": sdk.ZeroDec(),
"vault3": sdk.ZeroDec(),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *EarnAdapterTestSuite) TestEarnAdapter_OwnerSharesBySource() {
vaultDenomA := "ukava"
vaultDenomB := "usdx"
savingsKeeper := suite.app.GetSavingsKeeper()
savingsKeeper.SetParams(suite.ctx, savingstypes.NewParams([]string{vaultDenomA, vaultDenomB}))
earnKeeper := suite.app.GetEarnKeeper()
earnKeeper.SetParams(suite.ctx, earntypes.NewParams(
earntypes.AllowedVaults{
earntypes.NewAllowedVault(
"ukava",
earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
false,
nil,
),
},
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[0],
sdk.NewCoins(
sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)),
),
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[1],
sdk.NewCoins(
sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)),
),
))
err := earnKeeper.Deposit(
suite.ctx,
suite.addrs[0],
sdk.NewCoin(vaultDenomA, sdk.NewInt(100)),
earntypes.STRATEGY_TYPE_SAVINGS,
)
suite.NoError(err)
err = earnKeeper.Deposit(
suite.ctx,
suite.addrs[1],
sdk.NewCoin(vaultDenomA, sdk.NewInt(250)),
earntypes.STRATEGY_TYPE_SAVINGS,
)
suite.NoError(err)
ek := suite.app.GetEarnKeeper()
adapter := earn.NewSourceAdapter(&ek)
tests := []struct {
name string
giveOwner sdk.AccAddress
giveSourceIDs []string
wantShares map[string]sdk.Dec
}{
{
"depositor has shares",
suite.addrs[0],
[]string{
vaultDenomA,
},
map[string]sdk.Dec{
vaultDenomA: sdk.NewDecWithPrec(100, 0),
},
},
{
"depositor has shares - including empty deposits",
suite.addrs[1],
[]string{
vaultDenomA,
"vault2",
},
map[string]sdk.Dec{
vaultDenomA: sdk.NewDecWithPrec(250, 0),
"vault2": sdk.ZeroDec(),
},
},
{
"non-depositor has zero shares",
suite.addrs[2],
[]string{
vaultDenomA,
},
map[string]sdk.Dec{
vaultDenomA: sdk.ZeroDec(),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *EarnAdapterTestSuite) TestEarnAdapter_TotalSharesBySource_Empty() {
ek := suite.app.GetEarnKeeper()
adapter := earn.NewSourceAdapter(&ek)
tests := []struct {
name string
giveSourceID string
wantShares sdk.Dec
}{
{
"empty/invalid vaults are zero",
"vault1",
sdk.ZeroDec(),
},
{
"invalid request returns zero",
"",
sdk.ZeroDec(),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *EarnAdapterTestSuite) TestEarnAdapter_TotalSharesBySource() {
vaultDenomA := "ukava"
vaultDenomB := "usdx"
savingsKeeper := suite.app.GetSavingsKeeper()
savingsKeeper.SetParams(suite.ctx, savingstypes.NewParams([]string{vaultDenomA, vaultDenomB}))
earnKeeper := suite.app.GetEarnKeeper()
earnKeeper.SetParams(suite.ctx, earntypes.NewParams(
earntypes.AllowedVaults{
earntypes.NewAllowedVault(
vaultDenomA,
earntypes.StrategyTypes{earntypes.STRATEGY_TYPE_SAVINGS},
false,
nil,
),
},
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[0],
sdk.NewCoins(
sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)),
),
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[1],
sdk.NewCoins(
sdk.NewCoin(vaultDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(vaultDenomB, sdk.NewInt(1000000000000)),
),
))
err := earnKeeper.Deposit(
suite.ctx,
suite.addrs[0],
sdk.NewCoin(vaultDenomA, sdk.NewInt(100)),
earntypes.STRATEGY_TYPE_SAVINGS,
)
suite.NoError(err)
err = earnKeeper.Deposit(
suite.ctx,
suite.addrs[1],
sdk.NewCoin(vaultDenomA, sdk.NewInt(250)),
earntypes.STRATEGY_TYPE_SAVINGS,
)
suite.NoError(err)
ek := suite.app.GetEarnKeeper()
adapter := earn.NewSourceAdapter(&ek)
tests := []struct {
name string
giveSourceID string
wantShares sdk.Dec
}{
{
"total shares",
vaultDenomA,
sdk.NewDecWithPrec(350, 0),
},
{
"empty or invalid vault empty",
"vault2",
sdk.ZeroDec(),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID)
suite.Equal(tt.wantShares, shares)
})
}
}

View File

@ -1,46 +0,0 @@
package swap
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/types"
)
var _ types.SourceAdapter = SourceAdapter{}
type SourceAdapter struct {
keeper types.SwapKeeper
}
func NewSourceAdapter(keeper types.SwapKeeper) SourceAdapter {
return SourceAdapter{
keeper: keeper,
}
}
func (f SourceAdapter) TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec {
shares, found := f.keeper.GetPoolShares(ctx, sourceID)
if !found {
shares = sdk.ZeroInt()
}
return shares.ToDec()
}
func (f SourceAdapter) OwnerSharesBySource(
ctx sdk.Context,
owner sdk.AccAddress,
sourceIDs []string,
) map[string]sdk.Dec {
shares := make(map[string]sdk.Dec)
for _, id := range sourceIDs {
s, found := f.keeper.GetDepositorSharesAmount(ctx, owner, id)
if !found {
s = sdk.ZeroInt()
}
shares[id] = s.ToDec()
}
return shares
}

View File

@ -1,286 +0,0 @@
package swap_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/incentive/keeper/adapters/swap"
swaptypes "github.com/kava-labs/kava/x/swap/types"
"github.com/stretchr/testify/suite"
)
type SwapAdapterTestSuite struct {
suite.Suite
app app.TestApp
ctx sdk.Context
genesisTime time.Time
addrs []sdk.AccAddress
}
func TestSwapAdapterTestSuite(t *testing.T) {
suite.Run(t, new(SwapAdapterTestSuite))
}
func (suite *SwapAdapterTestSuite) SetupTest() {
config := sdk.GetConfig()
app.SetBech32AddressPrefixes(config)
_, suite.addrs = app.GeneratePrivKeyAddressPairs(5)
suite.genesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC)
suite.app = app.NewTestApp()
suite.ctx = suite.app.NewContext(true, tmprototypes.Header{Time: suite.genesisTime})
}
func (suite *SwapAdapterTestSuite) TestSwapAdapter_OwnerSharesBySource_Empty() {
adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper())
tests := []struct {
name string
giveOwner sdk.AccAddress
giveSourceIDs []string
wantShares map[string]sdk.Dec
}{
{
"empty requests",
suite.addrs[0],
[]string{},
map[string]sdk.Dec{},
},
{
"empty pools are zero",
suite.addrs[0],
[]string{
"pool1",
"pool2",
"pool3",
},
map[string]sdk.Dec{
"pool1": sdk.ZeroDec(),
"pool2": sdk.ZeroDec(),
"pool3": sdk.ZeroDec(),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *SwapAdapterTestSuite) TestSwapAdapter_OwnerSharesBySource() {
poolDenomA := "ukava"
poolDenomB := "usdx"
swapKeeper := suite.app.GetSwapKeeper()
swapKeeper.SetParams(suite.ctx, swaptypes.NewParams(
swaptypes.NewAllowedPools(
swaptypes.NewAllowedPool(poolDenomA, poolDenomB),
),
sdk.ZeroDec(),
))
err := suite.app.FundAccount(
suite.ctx,
suite.addrs[0],
sdk.NewCoins(
sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)),
),
)
suite.NoError(err)
err = suite.app.FundAccount(
suite.ctx,
suite.addrs[1],
sdk.NewCoins(
sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)),
),
)
suite.NoError(err)
err = swapKeeper.Deposit(
suite.ctx,
suite.addrs[0],
sdk.NewCoin(poolDenomA, sdk.NewInt(100)),
sdk.NewCoin(poolDenomB, sdk.NewInt(100)),
sdk.NewDecWithPrec(1, 1),
)
suite.NoError(err)
err = swapKeeper.Deposit(
suite.ctx,
suite.addrs[1],
sdk.NewCoin(poolDenomA, sdk.NewInt(250)),
sdk.NewCoin(poolDenomB, sdk.NewInt(250)),
sdk.NewDecWithPrec(1, 0),
)
suite.NoError(err)
adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper())
tests := []struct {
name string
giveOwner sdk.AccAddress
giveSourceIDs []string
wantShares map[string]sdk.Dec
}{
{
"depositor has shares",
suite.addrs[0],
[]string{
swaptypes.PoolID(poolDenomA, poolDenomB),
},
map[string]sdk.Dec{
swaptypes.PoolID(poolDenomA, poolDenomB): sdk.NewDecWithPrec(100, 0),
},
},
{
"depositor has shares - including empty deposits",
suite.addrs[1],
[]string{
swaptypes.PoolID(poolDenomA, poolDenomB),
"pool2",
},
map[string]sdk.Dec{
swaptypes.PoolID(poolDenomA, poolDenomB): sdk.NewDecWithPrec(250, 0),
"pool2": sdk.ZeroDec(),
},
},
{
"non-depositor has zero shares",
suite.addrs[2],
[]string{
swaptypes.PoolID(poolDenomA, poolDenomB),
},
map[string]sdk.Dec{
swaptypes.PoolID(poolDenomA, poolDenomB): sdk.ZeroDec(),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.OwnerSharesBySource(suite.ctx, tt.giveOwner, tt.giveSourceIDs)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *SwapAdapterTestSuite) TestSwapAdapter_TotalSharesBySource_Empty() {
adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper())
tests := []struct {
name string
giveSourceID string
wantShares sdk.Dec
}{
{
"empty/invalid pools are zero",
"pool1",
sdk.ZeroDec(),
},
{
"invalid request returns zero",
"",
sdk.ZeroDec(),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID)
suite.Equal(tt.wantShares, shares)
})
}
}
func (suite *SwapAdapterTestSuite) TestSwapAdapter_TotalSharesBySource() {
poolDenomA := "ukava"
poolDenomB := "usdx"
swapKeeper := suite.app.GetSwapKeeper()
swapKeeper.SetParams(suite.ctx, swaptypes.NewParams(
swaptypes.NewAllowedPools(
swaptypes.NewAllowedPool(poolDenomA, poolDenomB),
),
sdk.ZeroDec(),
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[0],
sdk.NewCoins(
sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)),
),
))
suite.NoError(suite.app.FundAccount(
suite.ctx,
suite.addrs[1],
sdk.NewCoins(
sdk.NewCoin(poolDenomA, sdk.NewInt(1000000000000)),
sdk.NewCoin(poolDenomB, sdk.NewInt(1000000000000)),
),
))
err := swapKeeper.Deposit(
suite.ctx,
suite.addrs[0],
sdk.NewCoin(poolDenomA, sdk.NewInt(100)),
sdk.NewCoin(poolDenomB, sdk.NewInt(100)),
sdk.NewDecWithPrec(1, 1),
)
suite.NoError(err)
err = swapKeeper.Deposit(
suite.ctx,
suite.addrs[1],
sdk.NewCoin(poolDenomA, sdk.NewInt(250)),
sdk.NewCoin(poolDenomB, sdk.NewInt(250)),
sdk.NewDecWithPrec(1, 0),
)
suite.NoError(err)
adapter := swap.NewSourceAdapter(suite.app.GetSwapKeeper())
tests := []struct {
name string
giveSourceID string
wantShares sdk.Dec
}{
{
"total shares",
swaptypes.PoolID(poolDenomA, poolDenomB),
sdk.NewDecWithPrec(350, 0),
},
{
"empty or invalid pool empty",
"pool2",
sdk.ZeroDec(),
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
shares := adapter.TotalSharesBySource(suite.ctx, tt.giveSourceID)
suite.Equal(tt.wantShares, shares)
})
}
}

View File

@ -7,8 +7,6 @@ import (
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper/adapters"
"github.com/kava-labs/kava/x/incentive/keeper/store"
"github.com/kava-labs/kava/x/incentive/types"
)
@ -27,9 +25,6 @@ type Keeper struct {
liquidKeeper types.LiquidKeeper
earnKeeper types.EarnKeeper
Adapters adapters.SourceAdapters
Store store.IncentiveStore
// Keepers used for APY queries
kavamintKeeper types.KavamintKeeper
distrKeeper types.DistrKeeper
@ -61,12 +56,6 @@ func NewKeeper(
liquidKeeper: lqk,
earnKeeper: ek,
Adapters: adapters.NewSourceAdapters(
swpk,
ek,
),
Store: store.NewIncentiveStore(cdc, key),
kavamintKeeper: kmk,
distrKeeper: dk,
pricefeedKeeper: pfk,

View File

@ -1,427 +0,0 @@
package keeper_test
import (
"time"
"github.com/kava-labs/kava/x/incentive/types"
)
func (suite *KeeperTestSuite) TestGetSetDeleteClaims() {
suite.SetupApp()
for claimTypeName, claimTypeValue := range types.ClaimType_value {
suite.Run(claimTypeName, func() {
claimType := types.ClaimType(claimTypeValue)
c := types.NewClaim(
claimType,
suite.addrs[0],
arbitraryCoins(),
nonEmptyMultiRewardIndexes,
)
_, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0])
suite.Require().False(found)
suite.Require().NotPanics(func() {
suite.keeper.Store.SetClaim(suite.ctx, c)
})
testC, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0])
suite.Require().True(found)
suite.Require().Equal(c, testC)
// Check that other claim types do not exist for the same address
for otherClaimTypeName, otherClaimTypeValue := range types.ClaimType_value {
// Skip the current claim type
if otherClaimTypeValue == claimTypeValue {
continue
}
otherClaimType := types.ClaimType(otherClaimTypeValue)
_, found := suite.keeper.Store.GetClaim(suite.ctx, otherClaimType, suite.addrs[0])
suite.Require().False(found, "claim type %s should not exist", otherClaimTypeName)
}
suite.Require().NotPanics(func() {
suite.keeper.Store.DeleteClaim(suite.ctx, claimType, suite.addrs[0])
})
_, found = suite.keeper.Store.GetClaim(suite.ctx, claimType, suite.addrs[0])
suite.Require().False(found)
})
}
}
func (suite *KeeperTestSuite) TestIterateClaims() {
suite.SetupApp()
var claims types.Claims
// Add 2 of each type of claim
for _, claimTypeValue := range types.ClaimType_value {
c := types.Claims{
types.NewClaim(types.ClaimType(claimTypeValue), suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes),
types.NewClaim(types.ClaimType(claimTypeValue), suite.addrs[1], nil, nil),
}
claims = append(claims, c...)
}
for _, claim := range claims {
suite.keeper.Store.SetClaim(suite.ctx, claim)
}
for _, claimTypeValue := range types.ClaimType_value {
claimType := types.ClaimType(claimTypeValue)
// Claims of specific claim type only should be returned
claims := suite.keeper.Store.GetClaims(suite.ctx, claimType)
suite.Require().Len(claims, 2)
suite.Require().Equalf(
claims, types.Claims{
types.NewClaim(claimType, suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes),
types.NewClaim(claimType, suite.addrs[1], nil, nil),
},
"GetClaims(%s) should only return claims of those type", claimType,
)
}
allClaims := suite.keeper.Store.GetAllClaims(suite.ctx)
suite.Require().Len(allClaims, len(claims))
suite.Require().ElementsMatch(allClaims, claims, "GetAllClaims() should return claims of all types")
}
func (suite *KeeperTestSuite) TestGetSetRewardAccrualTimes() {
testCases := []struct {
name string
subKey string
accrualTime time.Time
panics bool
}{
{
name: "normal time can be written and read",
subKey: "btc/usdx",
accrualTime: time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
name: "zero time can be written and read",
subKey: "btc/usdx",
accrualTime: time.Time{},
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupApp()
_, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey)
suite.False(found)
setFunc := func() {
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey, tc.accrualTime)
}
if tc.panics {
suite.Panics(setFunc)
return
} else {
suite.NotPanics(setFunc)
}
for _, claimTypeValue := range types.ClaimType_value {
claimType := types.ClaimType(claimTypeValue)
if claimType == types.CLAIM_TYPE_USDX_MINTING {
continue
}
_, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, claimType, tc.subKey)
suite.False(found, "reward accrual time for claim type %s should not exist", claimType)
}
storedTime, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, tc.subKey)
suite.True(found)
suite.Equal(tc.accrualTime, storedTime)
})
}
}
func (suite *KeeperTestSuite) TestGetSetRewardIndexes() {
testCases := []struct {
name string
collateralType string
indexes types.RewardIndexes
wantIndex types.RewardIndexes
panics bool
}{
{
name: "two factors can be written and read",
collateralType: "btc/usdx",
indexes: types.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
wantIndex: types.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
name: "indexes with empty pool name panics",
collateralType: "",
indexes: types.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
panics: true,
},
{
// this test is to detect any changes in behavior
name: "setting empty indexes does not panic",
collateralType: "btc/usdx",
// Marshalling empty slice results in [] bytes, unmarshalling the []
// empty bytes results in a nil slice instead of an empty slice
indexes: types.RewardIndexes{},
wantIndex: nil,
panics: false,
},
{
// this test is to detect any changes in behavior
name: "setting nil indexes does not panic",
collateralType: "btc/usdx",
indexes: nil,
wantIndex: nil,
panics: false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupApp()
_, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType)
suite.False(found)
setFunc := func() {
suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType, tc.indexes)
}
if tc.panics {
suite.Panics(setFunc)
return
} else {
suite.NotPanics(setFunc)
}
storedIndexes, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, tc.collateralType)
suite.True(found)
suite.Equal(tc.wantIndex, storedIndexes)
for _, otherClaimTypeValue := range types.ClaimType_value {
// Skip swap
if types.ClaimType(otherClaimTypeValue) == types.CLAIM_TYPE_SWAP {
continue
}
otherClaimType := types.ClaimType(otherClaimTypeValue)
// Other claim types should not be affected
_, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, otherClaimType, tc.collateralType)
suite.False(found)
}
})
}
}
func (suite *KeeperTestSuite) TestIterateRewardAccrualTimes() {
suite.SetupApp()
expectedAccrualTimes := nonEmptyAccrualTimes
for _, at := range expectedAccrualTimes {
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, at.denom, at.time)
}
var actualAccrualTimes []accrualtime
suite.keeper.Store.IterateRewardAccrualTimesByClaimType(suite.ctx, types.CLAIM_TYPE_USDX_MINTING, func(denom string, accrualTime time.Time) bool {
actualAccrualTimes = append(actualAccrualTimes, accrualtime{denom: denom, time: accrualTime})
return false
})
suite.ElementsMatch(expectedAccrualTimes, actualAccrualTimes)
}
func (suite *KeeperTestSuite) TestIterateAllRewardAccrualTimes() {
suite.SetupApp()
var expectedAccrualTimes types.AccrualTimes
for _, claimTypeValue := range types.ClaimType_value {
claimType := types.ClaimType(claimTypeValue)
// Skip invalid claim type
if claimType.Validate() != nil {
continue
}
for _, at := range nonEmptyAccrualTimes {
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, at.denom, at.time)
expectedAccrualTimes = append(expectedAccrualTimes, types.NewAccrualTime(
claimType,
at.denom,
at.time,
))
}
}
var actualAccrualTimes types.AccrualTimes
suite.keeper.Store.IterateRewardAccrualTimes(
suite.ctx,
func(accrualTime types.AccrualTime) bool {
actualAccrualTimes = append(actualAccrualTimes, accrualTime)
return false
},
)
suite.ElementsMatch(expectedAccrualTimes, actualAccrualTimes)
}
func (suite *KeeperTestSuite) TestIterateRewardIndexes() {
suite.SetupApp()
swapMultiIndexes := types.MultiRewardIndexes{
{
CollateralType: "bnb",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.0000002"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: "btcb",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: d("0.02"),
},
},
},
}
earnMultiIndexes := types.MultiRewardIndexes{
{
CollateralType: "usdc",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "usdc",
RewardFactor: d("0.0000002"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: "ukava",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: d("0.02"),
},
},
},
}
for _, mi := range swapMultiIndexes {
suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_SWAP, mi.CollateralType, mi.RewardIndexes)
}
for _, mi := range earnMultiIndexes {
// These should be excluded when iterating over swap indexes
suite.keeper.Store.SetRewardIndexes(suite.ctx, types.CLAIM_TYPE_EARN, mi.CollateralType, mi.RewardIndexes)
}
actualMultiIndexesMap := make(map[types.ClaimType]types.MultiRewardIndexes)
suite.keeper.Store.IterateRewardIndexesByClaimType(suite.ctx, types.CLAIM_TYPE_SWAP, func(rewardIndex types.TypedRewardIndexes) bool {
actualMultiIndexesMap[rewardIndex.ClaimType] = actualMultiIndexesMap[rewardIndex.ClaimType].With(rewardIndex.CollateralType, rewardIndex.RewardIndexes)
return false
})
suite.Require().Len(actualMultiIndexesMap, 1, "iteration should only include 1 claim type")
suite.Require().Equal(swapMultiIndexes, actualMultiIndexesMap[types.CLAIM_TYPE_SWAP])
}
func (suite *KeeperTestSuite) TestIterateAllRewardIndexes() {
suite.SetupApp()
multiIndexes := types.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.0000002"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
{
CollateralType: "usdc",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: d("0.02"),
},
},
},
}
for _, claimTypeValue := range types.ClaimType_value {
if types.ClaimType(claimTypeValue) == types.CLAIM_TYPE_UNSPECIFIED {
continue
}
claimType := types.ClaimType(claimTypeValue)
for _, mi := range multiIndexes {
suite.keeper.Store.SetRewardIndexes(suite.ctx, claimType, mi.CollateralType, mi.RewardIndexes)
}
}
actualMultiIndexesMap := make(map[types.ClaimType]types.MultiRewardIndexes)
suite.keeper.Store.IterateRewardIndexes(suite.ctx, func(rewardIndex types.TypedRewardIndexes) bool {
actualMultiIndexesMap[rewardIndex.ClaimType] = actualMultiIndexesMap[rewardIndex.ClaimType].With(rewardIndex.CollateralType, rewardIndex.RewardIndexes)
return false
})
// -1 to exclude the unspecified type
suite.Require().Len(actualMultiIndexesMap, len(types.ClaimType_value)-1)
for claimType, actualMultiIndexes := range actualMultiIndexesMap {
suite.Require().NoError(claimType.Validate())
suite.Require().Equal(multiIndexes, actualMultiIndexes)
}
}

View File

@ -1,137 +0,0 @@
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper/accumulators"
"github.com/kava-labs/kava/x/incentive/types"
)
// AccumulateRewards calculates new rewards to distribute this block and updates the global indexes to reflect this.
// The provided rewardPeriod must be valid to avoid panics in calculating time durations.
func (k Keeper) AccumulateRewards(
ctx sdk.Context,
claimType types.ClaimType,
rewardPeriod types.MultiRewardPeriod,
) error {
var accumulator types.RewardAccumulator
switch claimType {
case types.CLAIM_TYPE_EARN:
accumulator = accumulators.NewEarnAccumulator(k.Store, k.liquidKeeper, k.earnKeeper, k.Adapters)
default:
accumulator = accumulators.NewBasicAccumulator(k.Store, k.Adapters)
}
return accumulator.AccumulateRewards(ctx, claimType, rewardPeriod)
}
// InitializeClaim creates a new claim with zero rewards and indexes matching
// the global indexes. If the claim already exists it just updates the indexes.
func (k Keeper) InitializeClaim(
ctx sdk.Context,
claimType types.ClaimType,
sourceID string,
owner sdk.AccAddress,
) {
claim, found := k.Store.GetClaim(ctx, claimType, owner)
if !found {
claim = types.NewClaim(claimType, owner, sdk.Coins{}, nil)
}
globalRewardIndexes, found := k.Store.GetRewardIndexesOfClaimType(ctx, claimType, sourceID)
if !found {
globalRewardIndexes = types.RewardIndexes{}
}
claim.RewardIndexes = claim.RewardIndexes.With(sourceID, globalRewardIndexes)
k.Store.SetClaim(ctx, claim)
}
// SynchronizeClaim updates the claim object by adding any accumulated rewards
// and updating the reward index value.
func (k Keeper) SynchronizeClaim(
ctx sdk.Context,
claimType types.ClaimType,
sourceID string,
owner sdk.AccAddress,
shares sdk.Dec,
) {
claim, found := k.Store.GetClaim(ctx, claimType, owner)
if !found {
return
}
claim = k.synchronizeClaim(ctx, claim, sourceID, owner, shares)
k.Store.SetClaim(ctx, claim)
}
// synchronizeClaim updates the reward and indexes in a claim for one sourceID.
func (k *Keeper) synchronizeClaim(
ctx sdk.Context,
claim types.Claim,
sourceID string,
owner sdk.AccAddress,
shares sdk.Dec,
) types.Claim {
globalRewardIndexes, found := k.Store.GetRewardIndexesOfClaimType(ctx, claim.Type, sourceID)
if !found {
// The global factor is only not found if
// - the pool has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
// - OR it was wrongly deleted from state (factors should never be removed while unsynced claims exist)
// If not found we could either skip this sync, or assume the global factor is zero.
// Skipping will avoid storing unnecessary factors in the claim for non rewarded pools.
// And in the event a global factor is wrongly deleted, it will avoid this function panicking when calculating rewards.
return claim
}
userRewardIndexes, found := claim.RewardIndexes.Get(sourceID)
if !found {
// Normally the reward indexes should always be found.
// But if a pool was not rewarded then becomes rewarded (ie a reward period is added to params), then the indexes will be missing from claims for that pool.
// So given the reward period was just added, assume the starting value for any global reward indexes, which is an empty slice.
userRewardIndexes = types.RewardIndexes{}
}
newRewards, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, shares)
if err != nil {
// Global reward factors should never decrease, as it would lead to a negative update to claim.Rewards.
// This panics if a global reward factor decreases or disappears between the old and new indexes.
panic(fmt.Sprintf("corrupted global reward indexes found: %v", err))
}
claim.Reward = claim.Reward.Add(newRewards...)
claim.RewardIndexes = claim.RewardIndexes.With(sourceID, globalRewardIndexes)
return claim
}
// GetSynchronizedClaim fetches a claim from the store and syncs rewards for all
// rewarded sourceIDs.
func (k Keeper) GetSynchronizedClaim(
ctx sdk.Context,
claimType types.ClaimType,
owner sdk.AccAddress,
) (types.Claim, bool) {
claim, found := k.Store.GetClaim(ctx, claimType, owner)
if !found {
return types.Claim{}, false
}
// Fetch all source IDs from indexes
var sourceIDs []string
k.Store.IterateRewardIndexesByClaimType(ctx, claimType, func(rewardIndexes types.TypedRewardIndexes) bool {
sourceIDs = append(sourceIDs, rewardIndexes.CollateralType)
return false
})
accShares := k.Adapters.OwnerSharesBySource(ctx, claimType, owner, sourceIDs)
// Synchronize claim for each source ID
for _, share := range accShares {
claim = k.synchronizeClaim(ctx, claim, share.ID, owner, share.Shares)
}
return claim, true
}

View File

@ -1,334 +0,0 @@
package keeper_test
import (
"testing"
"time"
"github.com/kava-labs/kava/x/incentive/types"
"github.com/stretchr/testify/suite"
)
type AccumulateTestSuite struct {
unitTester
}
func TestAccumulateTestSuite(t *testing.T) {
suite.Run(t, new(AccumulateTestSuite))
}
func (suite *AccumulateTestSuite) storedTimeEquals(
claimType types.ClaimType,
poolID string,
expected time.Time,
) {
storedTime, found := suite.keeper.Store.GetRewardAccrualTime(suite.ctx, claimType, poolID)
suite.True(found)
suite.Equal(expected, storedTime)
}
func (suite *AccumulateTestSuite) storedIndexesEquals(
claimType types.ClaimType,
poolID string,
expected types.RewardIndexes,
) {
storedIndexes, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.ctx, claimType, poolID)
suite.Equal(found, expected != nil)
if found {
suite.Equal(expected, storedIndexes)
} else {
suite.Empty(storedIndexes)
}
}
func (suite *AccumulateTestSuite) TestStateUpdatedWhenBlockTimeHasIncreased() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
suite.storeGlobalIndexes(claimType, types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
})
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime)
newAccrualTime := previousAccrualTime.Add(1 * time.Hour)
suite.ctx = suite.ctx.WithBlockTime(newAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// check time and factors
suite.storedTimeEquals(claimType, pool, newAccrualTime)
suite.storedIndexesEquals(claimType, pool, types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("7.22"),
},
{
CollateralType: "ukava",
RewardFactor: d("3.64"),
},
})
}
func (suite *AccumulateTestSuite) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.storeGlobalIndexes(claimType, previousIndexes)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime)
suite.ctx = suite.ctx.WithBlockTime(previousAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// check time and factors
suite.storedTimeEquals(claimType, pool, previousAccrualTime)
expected, f := previousIndexes.Get(pool)
suite.True(f)
suite.storedIndexesEquals(claimType, pool, expected)
}
func (suite *AccumulateTestSuite) TestNoAccumulationWhenSourceSharesAreZero() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper() // no pools, so no source shares
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.storeGlobalIndexes(claimType, previousIndexes)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime)
firstAccrualTime := previousAccrualTime.Add(7 * time.Second)
suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)), // same denoms as in global indexes
)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// check time and factors
suite.storedTimeEquals(claimType, pool, firstAccrualTime)
expected, f := previousIndexes.Get(pool)
suite.True(f)
suite.storedIndexesEquals(claimType, pool, expected)
}
func (suite *AccumulateTestSuite) TestStateAddedWhenStateDoesNotExist() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
firstAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// After the first accumulation only the current block time should be stored.
// The indexes will be empty as no time has passed since the previous block because it didn't exist.
suite.storedTimeEquals(claimType, pool, firstAccrualTime)
suite.storedIndexesEquals(claimType, pool, nil)
secondAccrualTime := firstAccrualTime.Add(10 * time.Second)
suite.ctx = suite.ctx.WithBlockTime(secondAccrualTime)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// After the second accumulation both current block time and indexes should be stored.
suite.storedTimeEquals(claimType, pool, secondAccrualTime)
suite.storedIndexesEquals(claimType, pool, types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.01"),
},
})
}
func (suite *AccumulateTestSuite) TestNoPanicWhenStateDoesNotExist() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper()
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
period := types.NewMultiRewardPeriod(
true,
pool,
time.Unix(0, 0), // ensure the test is within start and end times
distantFuture,
cs(),
)
accrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.ctx = suite.ctx.WithBlockTime(accrualTime)
// Accumulate with no swap shares and no rewards per second will result in no increment to the indexes.
// No increment and no previous indexes stored, results in an updated of nil. Setting this in the state panics.
// Check there is no panic.
suite.NotPanics(func() {
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
})
suite.storedTimeEquals(claimType, pool, accrualTime)
suite.storedIndexesEquals(claimType, pool, nil)
}
func (suite *AccumulateTestSuite) TestNoAccumulationWhenBeforeStartTime() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
previousIndexes := types.MultiRewardIndexes{
{
CollateralType: pool,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "swap",
RewardFactor: d("0.02"),
},
{
CollateralType: "ukava",
RewardFactor: d("0.04"),
},
},
},
}
suite.storeGlobalIndexes(claimType, previousIndexes)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime)
firstAccrualTime := previousAccrualTime.Add(10 * time.Second)
period := types.NewMultiRewardPeriod(
true,
pool,
firstAccrualTime.Add(time.Nanosecond), // start time after accrual time
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
// The accrual time should be updated, but the indexes unchanged
suite.storedTimeEquals(claimType, pool, firstAccrualTime)
expectedIndexes, f := previousIndexes.Get(pool)
suite.True(f)
suite.storedIndexesEquals(claimType, pool, expectedIndexes)
}
func (suite *AccumulateTestSuite) TestPanicWhenCurrentTimeLessThanPrevious() {
claimType := types.CLAIM_TYPE_SWAP
pool := "btc:usdx"
swapKeeper := newFakeSwapKeeper().addPool(pool, i(1e6))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
previousAccrualTime := time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC)
suite.keeper.Store.SetRewardAccrualTime(suite.ctx, claimType, pool, previousAccrualTime)
firstAccrualTime := time.Time{}
period := types.NewMultiRewardPeriod(
true,
pool,
time.Time{}, // start time after accrual time
distantFuture,
cs(c("swap", 2000), c("ukava", 1000)),
)
suite.ctx = suite.ctx.WithBlockTime(firstAccrualTime)
suite.Panics(func() {
suite.keeper.AccumulateRewards(suite.ctx, claimType, period)
})
}

View File

@ -9,7 +9,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
earntypes "github.com/kava-labs/kava/x/earn/types"
"github.com/kava-labs/kava/x/incentive/keeper/accumulators"
"github.com/kava-labs/kava/x/incentive/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
@ -33,6 +32,34 @@ func (k Keeper) AccumulateEarnRewards(ctx sdk.Context, rewardPeriod types.MultiR
return nil
}
func GetProportionalRewardsPerSecond(
rewardPeriod types.MultiRewardPeriod,
totalBkavaSupply sdk.Int,
singleBkavaSupply sdk.Int,
) sdk.DecCoins {
// Rate per bkava-xxx = rewardsPerSecond * % of bkava-xxx
// = rewardsPerSecond * (bkava-xxx / total bkava)
// = (rewardsPerSecond * bkava-xxx) / total bkava
newRate := sdk.NewDecCoins()
// Prevent division by zero, if there are no total shares then there are no
// rewards.
if totalBkavaSupply.IsZero() {
return newRate
}
for _, rewardCoin := range rewardPeriod.RewardsPerSecond {
scaledAmount := rewardCoin.Amount.ToDec().
Mul(singleBkavaSupply.ToDec()).
Quo(totalBkavaSupply.ToDec())
newRate = newRate.Add(sdk.NewDecCoinFromDec(rewardCoin.Denom, scaledAmount))
}
return newRate
}
// accumulateEarnBkavaRewards does the same as AccumulateEarnRewards but for
// *all* bkava vaults.
func (k Keeper) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) error {
@ -85,7 +112,7 @@ func (k Keeper) accumulateEarnBkavaRewards(ctx sdk.Context, rewardPeriod types.M
bkavaDenom,
rewardPeriod.Start,
rewardPeriod.End,
accumulators.GetProportionalRewardsPerSecond(
GetProportionalRewardsPerSecond(
rewardPeriod,
totalBkavaValue.Amount,
derivativeValue.Amount,

View File

@ -381,8 +381,7 @@ func (suite *AccumulateEarnRewardsIntegrationTests) TestStateUnchangedWhenBlockT
// Must manually accumulate rewards as BeginBlockers only run when the block time increases
// This does not run any x/mint or x/distribution BeginBlockers
err = suite.keeper.AccumulateEarnRewards(suite.Ctx, period)
suite.NoError(err)
suite.keeper.AccumulateEarnRewards(suite.Ctx, period)
// check time and factors
@ -645,8 +644,7 @@ func (suite *AccumulateEarnRewardsIntegrationTests) TestNoPanicWhenStateDoesNotE
suite.NotPanics(func() {
// This does not update any state, as there are no bkava vaults
// to iterate over, denoms are unknown
err := suite.keeper.AccumulateEarnRewards(suite.Ctx, period)
suite.NoError(err)
suite.keeper.AccumulateEarnRewards(suite.Ctx, period)
})
// Times are not stored for vaults with no state

View File

@ -1,11 +1,11 @@
package accumulators_test
package keeper_test
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper/accumulators"
"github.com/kava-labs/kava/x/incentive/keeper"
"github.com/kava-labs/kava/x/incentive/types"
"github.com/stretchr/testify/require"
)
@ -74,7 +74,7 @@ func TestGetProportionalRewardPeriod(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rewardsPerSecond := accumulators.GetProportionalRewardsPerSecond(
rewardsPerSecond := keeper.GetProportionalRewardsPerSecond(
tt.giveRewardPeriod,
tt.giveTotalBkavaSupply,
tt.giveSingleBkavaSupply,

View File

@ -1,197 +0,0 @@
package keeper_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/x/incentive/types"
)
// InitializeClaimTests runs unit tests for the keeper.InitializeClaim method
//
// inputs
// - claim in store if it exists
// - global indexes in store
//
// outputs
// - sets or creates a claim
type InitializeClaimTests struct {
unitTester
}
func TestInitializeRewardTests(t *testing.T) {
suite.Run(t, new(InitializeClaimTests))
}
func (suite *InitializeClaimTests) TestClaimAddedWhenClaimDoesNotExistAndNoRewards() {
// When a claim doesn't exist, and a user deposits to a non-rewarded pool;
// then a claim is added with no rewards and no indexes
collateralType := "usdc"
claimType := types.CLAIM_TYPE_SWAP
owner := arbitraryAddress()
// no global indexes stored as this pool is not rewarded
suite.keeper.InitializeClaim(suite.ctx, claimType, collateralType, owner)
syncedClaim, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, owner)
suite.True(found)
// A new claim should have empty indexes. It doesn't strictly need the collateralType either.
expectedIndexes := types.MultiRewardIndexes{{
CollateralType: collateralType,
RewardIndexes: nil,
}}
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
// a new claim should start with 0 rewards
suite.Equal(sdk.Coins(nil), syncedClaim.Reward)
}
func (suite *InitializeClaimTests) TestClaimAddedWhenClaimDoesNotExistAndRewardsExist() {
// When a claim doesn't exist, and a user deposits to a rewarded pool;
// then a claim is added with no rewards and indexes matching the global indexes
collateralType := "usdc"
claimType := types.CLAIM_TYPE_SWAP
owner := arbitraryAddress()
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
suite.keeper.InitializeClaim(suite.ctx, claimType, collateralType, owner)
syncedClaim, found := suite.keeper.Store.GetClaim(suite.ctx, claimType, owner)
suite.True(found)
// a new claim should start with the current global indexes
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// a new claim should start with 0 rewards
suite.Equal(sdk.Coins(nil), syncedClaim.Reward)
}
func (suite *InitializeClaimTests) TestClaimUpdatedWhenClaimExistsAndNoRewards() {
// When a claim exists, and a user deposits to a new non-rewarded pool;
// then the claim's rewards don't change
preexistingCollateralType := "preexisting"
preexistingIndexes := types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
}
newCollateralType := "usdc"
claimType := types.CLAIM_TYPE_SWAP
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: arbitraryCoins(),
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: preexistingCollateralType,
RewardIndexes: preexistingIndexes,
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
// no global indexes stored as the new pool is not rewarded
suite.keeper.InitializeClaim(suite.ctx, claimType, newCollateralType, claim.Owner)
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// The preexisting indexes shouldn't be changed. It doesn't strictly need the new collateralType either.
expectedIndexes := types.MultiRewardIndexes{
{
CollateralType: preexistingCollateralType,
RewardIndexes: preexistingIndexes,
},
{
CollateralType: newCollateralType,
RewardIndexes: nil,
},
}
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
// init should never alter the rewards
suite.Equal(claim.Reward, syncedClaim.Reward)
}
func (suite *InitializeClaimTests) TestClaimUpdatedWhenClaimExistsAndRewardsExist() {
// When a claim exists, and a user deposits to a new rewarded pool;
// then the claim's rewards don't change and the indexes are updated to match the global indexes
preexistingCollateralType := "preexisting"
preexistingIndexes := types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
}
newCollateralType := "btcb:usdx"
newIndexes := types.RewardIndexes{
{
CollateralType: "otherrewarddenom",
RewardFactor: d("1000.001"),
},
}
claimType := types.CLAIM_TYPE_SWAP
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: arbitraryCoins(),
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: preexistingCollateralType,
RewardIndexes: preexistingIndexes,
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: preexistingCollateralType,
RewardIndexes: increaseRewardFactors(preexistingIndexes),
},
{
CollateralType: newCollateralType,
RewardIndexes: newIndexes,
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
suite.keeper.InitializeClaim(suite.ctx, claimType, newCollateralType, claim.Owner)
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// only the indexes for the new pool should be updated
expectedIndexes := types.MultiRewardIndexes{
{
CollateralType: preexistingCollateralType,
RewardIndexes: preexistingIndexes,
},
{
CollateralType: newCollateralType,
RewardIndexes: newIndexes,
},
}
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
// init should never alter the rewards
suite.Equal(claim.Reward, syncedClaim.Reward)
}

View File

@ -1,472 +0,0 @@
package keeper_test
import (
"testing"
"github.com/stretchr/testify/suite"
"github.com/kava-labs/kava/x/incentive/types"
)
// SynchronizeClaimTests runs unit tests for the keeper.SynchronizeClaim method
//
// inputs
// - claim in store (only claim.RewardIndexes, claim.Reward)
// - global indexes in store
// - shares function arg
//
// outputs
// - sets a claim
type SynchronizeClaimTests struct {
unitTester
}
func TestSynchronizeClaim(t *testing.T) {
suite.Run(t, new(SynchronizeClaimTests))
}
func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesHaveIncreased() {
// This is the normal case
// Given some time has passed (meaning the global indexes have increased)
// When the claim is synced
// The user earns rewards for the time passed, and the claim indexes are updated
originalReward := arbitraryCoins()
collateralType := "base:quote"
claimType := types.CLAIM_TYPE_USDX_MINTING
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: originalReward,
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("2000.002"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
userShares := i(1e9)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// indexes updated from global
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// new reward is (new index - old index) * user shares
suite.Equal(
cs(c("rewarddenom", 1_000_001_000_000)).Add(originalReward...),
syncedClaim.Reward,
)
}
func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenGlobalIndexesUnchanged() {
// It should be safe to call SynchronizeClaim multiple times
collateralType := "base:quote"
claimType := types.CLAIM_TYPE_USDX_MINTING
unchangingIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
},
},
}
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: arbitraryCoins(),
RewardIndexes: unchangingIndexes,
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
suite.storeGlobalIndexes(claimType, unchangingIndexes)
userShares := i(1e9)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// claim should have the same rewards and indexes as before
suite.Equal(claim, syncedClaim)
}
func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardAdded() {
// When a new reward is added (via gov) for a pool the user has already deposited to, and the claim is synced;
// Then the user earns rewards for the time since the reward was added, and the indexes are added to the claim.
originalReward := arbitraryCoins()
newlyRewardcollateralType := "newlyRewardedPool"
claimType := types.CLAIM_TYPE_USDX_MINTING
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: originalReward,
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: "currentlyRewardedPool",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "reward",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: "currentlyRewardedPool",
RewardIndexes: types.RewardIndexes{
{
CollateralType: "reward",
RewardFactor: d("2000.002"),
},
},
},
{
CollateralType: newlyRewardcollateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "otherreward",
// Indexes start at 0 when the reward is added by gov,
// so this represents the syncing happening some time later.
RewardFactor: d("1000.001"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
userShares := i(1e9)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, newlyRewardcollateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// the new indexes should be added to the claim, but the old ones should be unchanged
newlyRewrdedIndexes, _ := globalIndexes.Get(newlyRewardcollateralType)
expectedIndexes := claim.RewardIndexes.With(newlyRewardcollateralType, newlyRewrdedIndexes)
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
// new reward is (new index - old index) * shares for the synced pool
// The old index for `newlyrewarded` isn't in the claim, so it's added starting at 0 for calculating the reward.
suite.Equal(
cs(c("otherreward", 1_000_001_000_000)).Add(originalReward...),
syncedClaim.Reward,
)
}
func (suite *SynchronizeClaimTests) TestClaimUnchangedWhenNoReward() {
// When a pool is not rewarded but the user has deposited to that pool, and the claim is synced;
// Then the claim should be the same.
collateralType := "nonRewardPool"
claimType := types.CLAIM_TYPE_USDX_MINTING
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: arbitraryCoins(),
RewardIndexes: nonEmptyMultiRewardIndexes,
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
// No global indexes stored as this pool is not rewarded
userShares := i(1e9)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
suite.Equal(claim, syncedClaim)
}
func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenNewRewardDenomAdded() {
// When a new reward coin is added (via gov) to an already rewarded pool (that the user has already deposited to), and the claim is synced;
// Then the user earns rewards for the time since the reward was added, and the new indexes are added.
originalReward := arbitraryCoins()
collateralType := "base:quote"
claimType := types.CLAIM_TYPE_USDX_MINTING
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: originalReward,
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "reward",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "reward",
RewardFactor: d("2000.002"),
},
{
CollateralType: "otherreward",
// Indexes start at 0 when the reward is added by gov,
// so this represents the syncing happening some time later.
RewardFactor: d("1000.001"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
userShares := i(1e9)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// indexes should have the new reward denom added
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// new reward is (new index - old index) * shares
// The old index for `otherreward` isn't in the claim, so it's added starting at 0 for calculating the reward.
suite.Equal(
cs(c("reward", 1_000_001_000_000), c("otherreward", 1_000_001_000_000)).Add(originalReward...),
syncedClaim.Reward,
)
}
func (suite *SynchronizeClaimTests) TestClaimUpdatedWhenGlobalIndexesIncreasedAndSourceIsZero() {
// Given some time has passed (meaning the global indexes have increased)
// When the claim is synced, but the user has no shares
// The user earns no rewards for the time passed, but the claim indexes are updated
collateralType := "base:quote"
claimType := types.CLAIM_TYPE_USDX_MINTING
claim := types.Claim{
Type: claimType,
Owner: arbitraryAddress(),
Reward: arbitraryCoins(),
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom",
RewardFactor: d("2000.002"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
userShares := i(0)
suite.keeper.SynchronizeClaim(suite.ctx, claimType, collateralType, claim.Owner, userShares.ToDec())
syncedClaim, _ := suite.keeper.Store.GetClaim(suite.ctx, claimType, claim.Owner)
// indexes updated from global
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// reward is unchanged
suite.Equal(claim.Reward, syncedClaim.Reward)
}
func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUnchangedWhenNoGlobalIndexes() {
collateralType_1 := "btcb:usdx"
owner := arbitraryAddress()
claimType := types.CLAIM_TYPE_SWAP
swapKeeper := newFakeSwapKeeper().
addDeposit(collateralType_1, owner, i(1e9))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
claim := types.Claim{
Type: claimType,
Owner: owner,
Reward: nil,
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType_1,
RewardIndexes: nil, // this state only happens because Init stores empty indexes
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
// no global indexes for any pool
syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner)
suite.True(f)
// indexes are unchanged
suite.Equal(claim.RewardIndexes, syncedClaim.RewardIndexes)
// reward is unchanged
suite.Equal(claim.Reward, syncedClaim.Reward)
}
func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexAndHasNoSourceShares() {
collateralType_1 := "btcb:usdx"
collateralType_2 := "ukava:usdx"
owner := arbitraryAddress()
claimType := types.CLAIM_TYPE_SWAP
// owner has no shares in any pool
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, newFakeSwapKeeper(), nil, nil, nil)
claim := types.Claim{
Type: claimType,
Owner: owner,
Reward: arbitraryCoins(),
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType_1,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom1",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType_1,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom1",
RewardFactor: d("2000.002"),
},
},
},
{
CollateralType: collateralType_2,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom2",
RewardFactor: d("2000.002"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner)
suite.True(f)
// indexes updated from global
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// reward is unchanged
suite.Equal(claim.Reward, syncedClaim.Reward)
}
func (suite *SynchronizeClaimTests) TestGetSyncedClaim_ClaimUpdatedWhenMissingIndexButHasSourceShares() {
collateralType_1 := "btcb:usdx"
collateralType_2 := "ukava:usdx"
owner := arbitraryAddress()
claimType := types.CLAIM_TYPE_SWAP
swapKeeper := newFakeSwapKeeper().
addDeposit(collateralType_1, owner, i(1e9)).
addDeposit(collateralType_2, owner, i(1e9))
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper, nil, nil, nil)
claim := types.Claim{
Type: claimType,
Owner: owner,
Reward: arbitraryCoins(),
RewardIndexes: types.MultiRewardIndexes{
{
CollateralType: collateralType_1,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom1",
RewardFactor: d("1000.001"),
},
},
},
},
}
suite.keeper.Store.SetClaim(suite.ctx, claim)
globalIndexes := types.MultiRewardIndexes{
{
CollateralType: collateralType_1,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom1",
RewardFactor: d("2000.002"),
},
},
},
{
CollateralType: collateralType_2,
RewardIndexes: types.RewardIndexes{
{
CollateralType: "rewarddenom2",
RewardFactor: d("2000.002"),
},
},
},
}
suite.storeGlobalIndexes(claimType, globalIndexes)
syncedClaim, f := suite.keeper.GetSynchronizedClaim(suite.ctx, claimType, claim.Owner)
suite.True(f)
// indexes updated from global
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
// reward is incremented
expectedReward := cs(c("rewarddenom1", 1_000_001_000_000), c("rewarddenom2", 2_000_002_000_000))
suite.Equal(claim.Reward.Add(expectedReward...), syncedClaim.Reward)
}

View File

@ -1,95 +0,0 @@
package store
import (
"time"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/types"
)
// GetRewardAccrualTime fetches the last time rewards were accrued for the
// specified ClaimType and sourceID.
func (k IncentiveStore) GetRewardAccrualTime(
ctx sdk.Context,
claimType types.ClaimType,
sourceID string,
) (time.Time, bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType))
b := store.Get(types.GetKeyFromSourceID(sourceID))
if b == nil {
return time.Time{}, false
}
var accrualTime types.AccrualTime
k.cdc.MustUnmarshal(b, &accrualTime)
return accrualTime.PreviousAccumulationTime, true
}
// SetRewardAccrualTime stores the last time rewards were accrued for the
// specified ClaimType and sourceID.
func (k IncentiveStore) SetRewardAccrualTime(
ctx sdk.Context,
claimType types.ClaimType,
sourceID string,
blockTime time.Time,
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType))
at := types.NewAccrualTime(claimType, sourceID, blockTime)
bz := k.cdc.MustMarshal(&at)
store.Set(types.GetKeyFromSourceID(sourceID), bz)
}
// IterateRewardAccrualTimesByClaimType iterates over all reward accrual times of a given
// claimType and performs a callback function.
func (k IncentiveStore) IterateRewardAccrualTimesByClaimType(
ctx sdk.Context,
claimType types.ClaimType,
cb func(string, time.Time) (stop bool),
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetPreviousRewardAccrualTimeKeyPrefix(claimType))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var accrualTime types.AccrualTime
k.cdc.MustUnmarshal(iterator.Value(), &accrualTime)
if cb(accrualTime.CollateralType, accrualTime.PreviousAccumulationTime) {
break
}
}
}
// IterateRewardAccrualTimes iterates over all reward accrual times of any
// claimType and performs a callback function.
func (k IncentiveStore) IterateRewardAccrualTimes(
ctx sdk.Context,
cb func(types.AccrualTime) (stop bool),
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousRewardAccrualTimeKeyPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var accrualTime types.AccrualTime
k.cdc.MustUnmarshal(iterator.Value(), &accrualTime)
if cb(accrualTime) {
break
}
}
}
// GetAllRewardAccrualTimes returns all reward accrual times of any claimType.
func (k IncentiveStore) GetAllRewardAccrualTimes(ctx sdk.Context) types.AccrualTimes {
var ats types.AccrualTimes
k.IterateRewardAccrualTimes(
ctx,
func(accrualTime types.AccrualTime) bool {
ats = append(ats, accrualTime)
return false
},
)
return ats
}

View File

@ -1,105 +0,0 @@
package store
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
"github.com/kava-labs/kava/x/incentive/types"
)
// GetClaim returns the claim in the store corresponding the the owner and
// claimType, and a boolean for if the claim was found
func (k IncentiveStore) GetClaim(
ctx sdk.Context,
claimType types.ClaimType,
addr sdk.AccAddress,
) (types.Claim, bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType))
bz := store.Get(addr)
if bz == nil {
return types.Claim{}, false
}
var c types.Claim
k.cdc.MustUnmarshal(bz, &c)
return c, true
}
// SetClaim sets the claim in the store corresponding to the owner and claimType
func (k IncentiveStore) SetClaim(
ctx sdk.Context,
c types.Claim,
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(c.Type))
bz := k.cdc.MustMarshal(&c)
store.Set(c.Owner, bz)
}
// DeleteClaim deletes the claim in the store corresponding to the owner and claimType
func (k IncentiveStore) DeleteClaim(
ctx sdk.Context,
claimType types.ClaimType,
owner sdk.AccAddress,
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType))
store.Delete(owner)
}
// IterateClaimsByClaimType iterates over all claim objects in the store of a given
// claimType and preforms a callback function
func (k IncentiveStore) IterateClaimsByClaimType(
ctx sdk.Context,
claimType types.ClaimType,
cb func(c types.Claim) (stop bool),
) {
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.GetClaimKeyPrefix(claimType))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var c types.Claim
k.cdc.MustUnmarshal(iterator.Value(), &c)
if cb(c) {
break
}
}
}
// GetClaims returns all Claim objects in the store of a given claimType
func (k IncentiveStore) GetClaims(
ctx sdk.Context,
claimType types.ClaimType,
) types.Claims {
var cs types.Claims
k.IterateClaimsByClaimType(ctx, claimType, func(c types.Claim) (stop bool) {
cs = append(cs, c)
return false
})
return cs
}
// IterateClaims iterates over all claim objects of any claimType in the
// store and preforms a callback function
func (k IncentiveStore) IterateClaims(
ctx sdk.Context,
cb func(c types.Claim) (stop bool),
) {
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.key), types.ClaimKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var c types.Claim
k.cdc.MustUnmarshal(iterator.Value(), &c)
if cb(c) {
break
}
}
}
// GetAllClaims returns all Claim objects in the store of any claimType
func (k IncentiveStore) GetAllClaims(ctx sdk.Context) types.Claims {
var cs types.Claims
k.IterateClaims(ctx, func(c types.Claim) (stop bool) {
cs = append(cs, c)
return false
})
return cs
}

View File

@ -1,95 +0,0 @@
package store
import (
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/types"
)
// SetRewardIndexes stores the global reward indexes that track total rewards of
// a given claim type and collateralType.
func (k IncentiveStore) SetRewardIndexes(
ctx sdk.Context,
claimType types.ClaimType,
collateralType string,
indexes types.RewardIndexes,
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType))
bz := k.cdc.MustMarshal(&types.TypedRewardIndexes{
ClaimType: claimType,
CollateralType: collateralType,
RewardIndexes: indexes,
})
store.Set(types.GetKeyFromSourceID(collateralType), bz)
}
// GetRewardIndexesOfClaimType fetches the global reward indexes that track total rewards
// of a given claimType and collateralType.
func (k IncentiveStore) GetRewardIndexesOfClaimType(
ctx sdk.Context,
claimType types.ClaimType,
collateralType string,
) (types.RewardIndexes, bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType))
bz := store.Get(types.GetKeyFromSourceID(collateralType))
if bz == nil {
return types.RewardIndexes{}, false
}
var proto types.TypedRewardIndexes
k.cdc.MustUnmarshal(bz, &proto)
return proto.RewardIndexes, true
}
// IterateRewardIndexesByClaimType iterates over all reward index objects in the store of a
// given ClaimType and performs a callback function.
func (k IncentiveStore) IterateRewardIndexesByClaimType(
ctx sdk.Context,
claimType types.ClaimType,
cb func(types.TypedRewardIndexes) (stop bool),
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.GetRewardIndexesKeyPrefix(claimType))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var typedRewardIndexes types.TypedRewardIndexes
k.cdc.MustUnmarshal(iterator.Value(), &typedRewardIndexes)
if cb(typedRewardIndexes) {
break
}
}
}
// IterateRewardIndexes iterates over all reward index objects in the store
// of all ClaimTypes and performs a callback function.
func (k IncentiveStore) IterateRewardIndexes(
ctx sdk.Context,
cb func(types.TypedRewardIndexes) (stop bool),
) {
store := prefix.NewStore(ctx.KVStore(k.key), types.RewardIndexesKeyPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var typedRewardIndexes types.TypedRewardIndexes
k.cdc.MustUnmarshal(iterator.Value(), &typedRewardIndexes)
if cb(typedRewardIndexes) {
break
}
}
}
// GetRewardIndexes returns all reward indexes of any claimType.
func (k IncentiveStore) GetRewardIndexes(ctx sdk.Context) types.TypedRewardIndexesList {
var tril types.TypedRewardIndexesList
k.IterateRewardIndexes(
ctx,
func(typedRewardIndexes types.TypedRewardIndexes) bool {
tril = append(tril, typedRewardIndexes)
return false
},
)
return tril
}

View File

@ -1,20 +0,0 @@
package store
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// IncentiveStore provides methods for interacting with the incentive store.
type IncentiveStore struct {
cdc codec.Codec
key sdk.StoreKey
}
// NewIncentiveStore creates a new IncentiveStore
func NewIncentiveStore(cdc codec.Codec, key sdk.StoreKey) IncentiveStore {
return IncentiveStore{
cdc: cdc,
key: key,
}
}

View File

@ -118,12 +118,6 @@ func (suite *unitTester) storeGlobalEarnIndexes(indexes types.MultiRewardIndexes
}
}
func (suite *unitTester) storeGlobalIndexes(claimType types.ClaimType, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
suite.keeper.Store.SetRewardIndexes(suite.ctx, claimType, i.CollateralType, i.RewardIndexes)
}
}
func (suite *unitTester) storeHardClaim(claim types.HardLiquidityProviderClaim) {
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim)
}

View File

@ -1,52 +0,0 @@
package v3
import (
"fmt"
"github.com/kava-labs/kava/x/incentive/types"
)
// Legacy store key prefixes
var (
EarnClaimKeyPrefix = []byte{0x18} // prefix for keys that store earn claims
EarnRewardIndexesKeyPrefix = []byte{0x19} // prefix for key that stores earn reward indexes
PreviousEarnRewardAccrualTimeKeyPrefix = []byte{0x20} // prefix for key that stores the previous time earn rewards accrued
)
func LegacyAccrualTimeKeyFromClaimType(claimType types.ClaimType) []byte {
switch claimType {
case types.CLAIM_TYPE_HARD_BORROW:
panic("todo")
case types.CLAIM_TYPE_HARD_SUPPLY:
panic("todo")
case types.CLAIM_TYPE_EARN:
return PreviousEarnRewardAccrualTimeKeyPrefix
case types.CLAIM_TYPE_SAVINGS:
panic("todo")
case types.CLAIM_TYPE_SWAP:
panic("todo")
case types.CLAIM_TYPE_USDX_MINTING:
panic("todo")
default:
panic(fmt.Sprintf("unrecognized claim type: %s", claimType))
}
}
func LegacyRewardIndexesKeyFromClaimType(claimType types.ClaimType) []byte {
switch claimType {
case types.CLAIM_TYPE_HARD_BORROW:
panic("todo")
case types.CLAIM_TYPE_HARD_SUPPLY:
panic("todo")
case types.CLAIM_TYPE_EARN:
return EarnRewardIndexesKeyPrefix
case types.CLAIM_TYPE_SAVINGS:
panic("todo")
case types.CLAIM_TYPE_SWAP:
panic("todo")
case types.CLAIM_TYPE_USDX_MINTING:
panic("todo")
default:
panic(fmt.Sprintf("unrecognized claim type: %s", claimType))
}
}

View File

@ -1,142 +0,0 @@
package v3
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/types"
)
// MigrateStore performs in-place migrations from incentive ConsensusVersion 2 to 3.
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error {
store := ctx.KVStore(storeKey)
if err := MigrateEarnClaims(store, cdc); err != nil {
return err
}
if err := MigrateAccrualTimes(store, cdc, types.CLAIM_TYPE_EARN); err != nil {
return err
}
if err := MigrateRewardIndexes(store, cdc, types.CLAIM_TYPE_EARN); err != nil {
return err
}
return nil
}
// MigrateEarnClaims migrates earn claims from v2 to v3
func MigrateEarnClaims(store sdk.KVStore, cdc codec.BinaryCodec) error {
newStore := prefix.NewStore(store, types.GetClaimKeyPrefix(types.CLAIM_TYPE_EARN))
oldStore := prefix.NewStore(store, EarnClaimKeyPrefix)
iterator := sdk.KVStorePrefixIterator(oldStore, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var c types.EarnClaim
cdc.MustUnmarshal(iterator.Value(), &c)
if err := c.Validate(); err != nil {
return fmt.Errorf("invalid v2 EarnClaim: %w", err)
}
// Convert to the new Claim type
newClaim := types.NewClaim(
types.CLAIM_TYPE_EARN,
c.Owner,
c.Reward,
c.RewardIndexes,
)
if err := newClaim.Validate(); err != nil {
return fmt.Errorf("invalid v3 EarnClaim: %w", err)
}
// Set in the **newStore** for the new store prefix
newStore.Set(c.Owner, cdc.MustMarshal(&newClaim))
// Remove the old claim in the old store
oldStore.Delete(iterator.Key())
}
return nil
}
// MigrateAccrualTimes migrates accrual times from v2 to v3
func MigrateAccrualTimes(
store sdk.KVStore,
cdc codec.BinaryCodec,
claimType types.ClaimType,
) error {
newStore := prefix.NewStore(store, types.GetPreviousRewardAccrualTimeKeyPrefix(claimType))
// Need prefix.NewStore instead of using it directly in the iterator, as
// there would be an extra space in the key
legacyPrefix := LegacyAccrualTimeKeyFromClaimType(claimType)
oldStore := prefix.NewStore(store, legacyPrefix)
iterator := sdk.KVStorePrefixIterator(oldStore, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var blockTime time.Time
if err := blockTime.UnmarshalBinary(iterator.Value()); err != nil {
panic(err)
}
sourceID := string(iterator.Key())
at := types.NewAccrualTime(claimType, sourceID, blockTime)
if err := at.Validate(); err != nil {
return fmt.Errorf("invalid v3 accrual time for claim type %s: %w", claimType, err)
}
// Set in the **newStore** for the new store prefix
bz := cdc.MustMarshal(&at)
newStore.Set(types.GetKeyFromSourceID(sourceID), bz)
// Remove the old accrual time in the old store
oldStore.Delete(iterator.Key())
}
return nil
}
// MigrateRewardIndexes migrates reward indexes from v2 to v3
func MigrateRewardIndexes(
store sdk.KVStore,
cdc codec.BinaryCodec,
claimType types.ClaimType,
) error {
newStore := prefix.NewStore(store, types.GetRewardIndexesKeyPrefix(claimType))
legacyPrefix := LegacyRewardIndexesKeyFromClaimType(claimType)
oldStore := prefix.NewStore(store, legacyPrefix)
iterator := sdk.KVStorePrefixIterator(oldStore, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var proto types.RewardIndexesProto
cdc.MustUnmarshal(iterator.Value(), &proto)
sourceID := string(iterator.Key())
rewardIndex := types.NewTypedRewardIndexes(
claimType,
sourceID,
proto.RewardIndexes,
)
bz := cdc.MustMarshal(&rewardIndex)
newStore.Set(types.GetKeyFromSourceID(sourceID), bz)
// Remove the old reward indexes in the old store
oldStore.Delete(iterator.Key())
}
return nil
}

View File

@ -1,159 +0,0 @@
package v3_test
import (
"testing"
"time"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/app"
"github.com/kava-labs/kava/x/incentive/testutil"
"github.com/kava-labs/kava/x/incentive/types"
"github.com/stretchr/testify/suite"
v3 "github.com/kava-labs/kava/x/incentive/migrations/v3"
)
type StoreMigrateTestSuite struct {
testutil.IntegrationTester
Addrs []sdk.AccAddress
keeper testutil.TestKeeper
storeKey sdk.StoreKey
cdc codec.Codec
}
func TestStoreMigrateTestSuite(t *testing.T) {
suite.Run(t, new(StoreMigrateTestSuite))
}
func (suite *StoreMigrateTestSuite) SetupTest() {
suite.IntegrationTester.SetupTest()
suite.keeper = testutil.TestKeeper{
Keeper: suite.App.GetIncentiveKeeper(),
}
_, suite.Addrs = app.GeneratePrivKeyAddressPairs(5)
suite.cdc = suite.App.AppCodec()
suite.storeKey = suite.App.GetKeys()[types.StoreKey]
suite.StartChain()
}
func (suite *StoreMigrateTestSuite) TestMigrateEarnClaims() {
store := suite.Ctx.KVStore(suite.storeKey)
// Create v2 earn claims
claim1 := types.NewEarnClaim(
suite.Addrs[0],
sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))),
types.MultiRewardIndexes{
types.NewMultiRewardIndex("bnb-a", types.RewardIndexes{
types.NewRewardIndex("bnb", sdk.NewDec(1)),
}),
},
)
claim2 := types.NewEarnClaim(
suite.Addrs[1],
sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(100))),
types.MultiRewardIndexes{
types.NewMultiRewardIndex("ukava", types.RewardIndexes{
types.NewRewardIndex("ukava", sdk.NewDec(1)),
}),
},
)
suite.keeper.SetEarnClaim(suite.Ctx, claim1)
suite.keeper.SetEarnClaim(suite.Ctx, claim2)
// Run earn claim migrations
err := v3.MigrateEarnClaims(store, suite.cdc)
suite.Require().NoError(err)
// Check that the claim was migrated correctly
newClaim1, found := suite.keeper.Store.GetClaim(suite.Ctx, types.CLAIM_TYPE_EARN, claim1.Owner)
suite.Require().True(found)
suite.Require().Equal(claim1.Owner, newClaim1.Owner)
newClaim2, found := suite.keeper.Store.GetClaim(suite.Ctx, types.CLAIM_TYPE_EARN, claim2.Owner)
suite.Require().True(found)
suite.Require().Equal(claim2.Owner, newClaim2.Owner)
// Ensure removed from old store
_, found = suite.keeper.GetEarnClaim(suite.Ctx, claim1.Owner)
suite.Require().False(found)
_, found = suite.keeper.GetEarnClaim(suite.Ctx, claim2.Owner)
suite.Require().False(found)
}
func (suite *StoreMigrateTestSuite) TestMigrateAccrualTimes() {
store := suite.Ctx.KVStore(suite.storeKey)
vaultDenom1 := "ukava"
vaultDenom2 := "usdc"
// Create v2 accrual times
accrualTime1 := time.Now()
accrualTime2 := time.Now().Add(time.Hour * 24)
suite.keeper.SetEarnRewardAccrualTime(suite.Ctx, vaultDenom1, accrualTime1)
suite.keeper.SetEarnRewardAccrualTime(suite.Ctx, vaultDenom2, accrualTime2)
// Run accrual time migrations
err := v3.MigrateAccrualTimes(store, suite.cdc, types.CLAIM_TYPE_EARN)
suite.Require().NoError(err)
// Check that the accrual time was migrated correctly
newAccrualTime1, found := suite.keeper.Store.GetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1)
suite.Require().True(found)
suite.Require().Equal(accrualTime1.Unix(), newAccrualTime1.Unix())
newAccrualTime2, found := suite.keeper.Store.GetRewardAccrualTime(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2)
suite.Require().True(found)
suite.Require().Equal(accrualTime2.Unix(), newAccrualTime2.Unix())
// Ensure removed from old store
_, found = suite.keeper.GetEarnRewardAccrualTime(suite.Ctx, vaultDenom1)
suite.Require().False(found)
_, found = suite.keeper.GetEarnRewardAccrualTime(suite.Ctx, vaultDenom2)
suite.Require().False(found)
}
func (suite *StoreMigrateTestSuite) TestMigrateRewardIndexes() {
store := suite.Ctx.KVStore(suite.storeKey)
vaultDenom1 := "ukava"
vaultDenom2 := "usdc"
rewardIndexes1 := types.RewardIndexes{
types.NewRewardIndex("ukava", sdk.NewDec(1)),
types.NewRewardIndex("hard", sdk.NewDec(2)),
}
rewardIndexes2 := types.RewardIndexes{
types.NewRewardIndex("ukava", sdk.NewDec(4)),
types.NewRewardIndex("swp", sdk.NewDec(10)),
}
suite.keeper.SetEarnRewardIndexes(suite.Ctx, vaultDenom1, rewardIndexes1)
suite.keeper.SetEarnRewardIndexes(suite.Ctx, vaultDenom2, rewardIndexes2)
err := v3.MigrateRewardIndexes(store, suite.cdc, types.CLAIM_TYPE_EARN)
suite.Require().NoError(err)
newRewardIndexes1, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom1)
suite.Require().True(found)
suite.Require().Equal(rewardIndexes1, newRewardIndexes1)
newRewardIndexes2, found := suite.keeper.Store.GetRewardIndexesOfClaimType(suite.Ctx, types.CLAIM_TYPE_EARN, vaultDenom2)
suite.Require().True(found)
suite.Require().Equal(rewardIndexes2, newRewardIndexes2)
// Ensure removed from old store
_, found = suite.keeper.GetEarnRewardIndexes(suite.Ctx, vaultDenom1)
suite.Require().False(found)
_, found = suite.keeper.GetEarnRewardIndexes(suite.Ctx, vaultDenom2)
suite.Require().False(found)
}

View File

@ -21,9 +21,6 @@ import (
"github.com/kava-labs/kava/x/incentive/types"
)
// ConsensusVersion defines the current module consensus version.
const ConsensusVersion = 3
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
@ -84,7 +81,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 {
return ConsensusVersion
return 1
}
// GetTxCmd returns the root tx command for the incentive module.

View File

@ -1,7 +1,6 @@
package testutil
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/codec"
@ -192,48 +191,6 @@ func (builder IncentiveGenesisBuilder) WithSimpleEarnRewardPeriod(ctype string,
return builder.WithInitializedEarnRewardPeriod(builder.simpleRewardPeriod(ctype, rewardsPerSecond))
}
// WithInitializedRewardPeriod adds an initialized typed reward period.
func (builder IncentiveGenesisBuilder) WithInitializedRewardPeriod(
claimType types.ClaimType,
periods types.MultiRewardPeriods,
) IncentiveGenesisBuilder {
// Append to claim type if it exists -- claim types must be unique in RewardPeriods field
for _, rewardPeriod := range builder.Params.RewardPeriods {
if rewardPeriod.ClaimType == claimType {
rewardPeriod.RewardPeriods = append(rewardPeriod.RewardPeriods, periods...)
return builder
}
}
// Add new reward period for claim type
builder.Params.RewardPeriods = append(builder.Params.RewardPeriods, types.NewTypedMultiRewardPeriod(claimType, periods))
for _, period := range periods {
accumulationTimeForPeriod := types.NewAccrualTime(claimType, period.CollateralType, builder.genesisTime)
builder.AccrualTimes = append(
builder.AccrualTimes,
accumulationTimeForPeriod,
)
if err := builder.AccrualTimes.Validate(); err != nil {
panic(fmt.Errorf("invalid accrual times: %w", err))
}
}
return builder
}
func (builder IncentiveGenesisBuilder) WithSimpleRewardPeriod(
claimType types.ClaimType,
collateralType string,
rewardsPerSecond sdk.Coins,
) IncentiveGenesisBuilder {
return builder.WithInitializedRewardPeriod(
claimType,
types.MultiRewardPeriods{builder.simpleRewardPeriod(collateralType, rewardsPerSecond)},
)
}
func (builder IncentiveGenesisBuilder) WithMultipliers(multipliers types.MultipliersPerDenoms) IncentiveGenesisBuilder {
builder.Params.ClaimMultipliers = multipliers

View File

@ -442,8 +442,7 @@ func (suite *IntegrationTester) AddTestAddrsFromPubKeys(ctx sdk.Context, pubKeys
initCoins := sdk.NewCoins(sdk.NewCoin(suite.App.GetStakingKeeper().BondDenom(ctx), accAmt))
for _, pk := range pubKeys {
err := suite.App.FundAccount(ctx, sdk.AccAddress(pk.Address()), initCoins)
suite.Require().NoError(err)
suite.App.FundAccount(ctx, sdk.AccAddress(pk.Address()), initCoins)
}
}
@ -469,28 +468,6 @@ func (suite *IntegrationTester) StoredEarnIndexesEqual(denom string, expected ty
}
}
func (suite *IntegrationTester) StoredTimeEquals(claimType types.ClaimType, denom string, expected time.Time) {
storedTime, found := suite.App.GetIncentiveKeeper().Store.GetRewardAccrualTime(suite.Ctx, claimType, denom)
suite.Equal(found, expected != time.Time{}, "expected time is %v but time found = %v", expected, found)
if found {
suite.Equal(expected, storedTime)
} else {
suite.Empty(storedTime)
}
}
func (suite *IntegrationTester) StoredIndexesEqual(claimType types.ClaimType, denom string, expected types.RewardIndexes) {
storedIndexes, found := suite.App.GetIncentiveKeeper().Store.GetRewardIndexesOfClaimType(suite.Ctx, claimType, denom)
suite.Equal(found, expected != nil)
if found {
suite.Equal(expected, storedIndexes)
} else {
// Can't compare Equal for types.RewardIndexes(nil) vs types.RewardIndexes{}
suite.Empty(storedIndexes)
}
}
func (suite *IntegrationTester) AddIncentiveEarnMultiRewardPeriod(period types.MultiRewardPeriod) {
ik := suite.App.GetIncentiveKeeper()
params := ik.GetParams(suite.Ctx)
@ -512,44 +489,6 @@ func (suite *IntegrationTester) AddIncentiveEarnMultiRewardPeriod(period types.M
ik.SetParams(suite.Ctx, params)
}
func (suite *IntegrationTester) AddIncentiveMultiRewardPeriod(
claimType types.ClaimType,
period types.MultiRewardPeriod,
) {
ik := suite.App.GetIncentiveKeeper()
params := ik.GetParams(suite.Ctx)
for i, rewardPeriod := range params.RewardPeriods {
if claimType == rewardPeriod.ClaimType {
for j, reward := range rewardPeriod.RewardPeriods {
if reward.CollateralType == period.CollateralType {
// Replace existing reward period if the collateralType exists.
// Params are invalid if there are multiple reward periods for the
// same collateral type.
params.RewardPeriods[i].RewardPeriods[j] = period
ik.SetParams(suite.Ctx, params)
return
}
}
// Claim type period exists but not the specific collateral type
params.RewardPeriods[i].RewardPeriods = append(params.RewardPeriods[i].RewardPeriods, period)
return
}
}
// Claim type does not exist in params
params.RewardPeriods = append(params.RewardPeriods, types.NewTypedMultiRewardPeriod(
claimType,
types.MultiRewardPeriods{
period,
},
))
suite.NoError(params.Validate())
ik.SetParams(suite.Ctx, params)
}
// -----------------------------------------------------------------------------
// x/router

View File

@ -1,54 +0,0 @@
package testutil
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/keeper"
"github.com/kava-labs/kava/x/incentive/types"
)
// TestKeeper is a test wrapper for the keeper which contains useful methods for testing
type TestKeeper struct {
keeper.Keeper
}
func (keeper TestKeeper) StoreGlobalBorrowIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.SetHardBorrowRewardIndexes(ctx, i.CollateralType, i.RewardIndexes)
}
}
func (keeper TestKeeper) StoreGlobalSupplyIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.SetHardSupplyRewardIndexes(ctx, i.CollateralType, i.RewardIndexes)
}
}
func (keeper TestKeeper) StoreGlobalDelegatorIndexes(ctx sdk.Context, multiRewardIndexes types.MultiRewardIndexes) {
// Hardcoded to use bond denom
multiRewardIndex, _ := multiRewardIndexes.GetRewardIndex(types.BondDenom)
keeper.SetDelegatorRewardIndexes(ctx, types.BondDenom, multiRewardIndex.RewardIndexes)
}
func (keeper TestKeeper) StoreGlobalSwapIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.SetSwapRewardIndexes(ctx, i.CollateralType, i.RewardIndexes)
}
}
func (keeper TestKeeper) StoreGlobalSavingsIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.SetSavingsRewardIndexes(ctx, i.CollateralType, i.RewardIndexes)
}
}
func (keeper TestKeeper) StoreGlobalEarnIndexes(ctx sdk.Context, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.SetEarnRewardIndexes(ctx, i.CollateralType, i.RewardIndexes)
}
}
func (keeper TestKeeper) StoreGlobalIndexes(ctx sdk.Context, claimType types.ClaimType, indexes types.MultiRewardIndexes) {
for _, i := range indexes {
keeper.Store.SetRewardIndexes(ctx, claimType, i.CollateralType, i.RewardIndexes)
}
}

View File

@ -1,18 +0,0 @@
package types
import sdk "github.com/cosmos/cosmos-sdk/types"
// SourceAdapter queries source shares from an external module.
type SourceAdapter interface {
// OwnerSharesBySource returns source shares owned by one address.
//
// For example, the shares a user owns in the kava:usdx and bnb:usdx swap pools.
// It returns the shares for several sources at once, in a map of sourceIDs to shares. Specifying no sourceIDS will return no shares.
// Note the returned map does not have a deterministic order.
OwnerSharesBySource(ctx sdk.Context, owner sdk.AccAddress, sourceIDs []string) map[string]sdk.Dec
// TotalSharesBySource returns the sum of all shares for a source (across all users).
//
// For example, the total number of shares in the kava:usdx swap pool for all users.
TotalSharesBySource(ctx sdk.Context, sourceID string) sdk.Dec
}

View File

@ -57,58 +57,6 @@ func (c BaseMultiClaim) Validate() error {
return nil
}
// Validate checks if a ClaimType is valid
func (ct ClaimType) Validate() error {
switch ct {
case CLAIM_TYPE_HARD_BORROW,
CLAIM_TYPE_HARD_SUPPLY,
CLAIM_TYPE_DELEGATOR,
CLAIM_TYPE_EARN,
CLAIM_TYPE_SAVINGS,
CLAIM_TYPE_SWAP,
CLAIM_TYPE_USDX_MINTING:
return nil
default:
return fmt.Errorf("invalid claim type: %v", ct)
}
}
// NewClaim returns a new Claim
func NewClaim(
claimType ClaimType,
owner sdk.AccAddress,
reward sdk.Coins,
rewardIndexes MultiRewardIndexes,
) Claim {
return Claim{
Type: claimType,
Owner: owner,
Reward: reward,
RewardIndexes: rewardIndexes,
}
}
// Validate performs a basic check of a Claim
func (c Claim) Validate() error {
if err := c.Type.Validate(); err != nil {
return err
}
if c.Owner.Empty() {
return errors.New("claim owner cannot be empty")
}
if err := c.Reward.Validate(); err != nil {
return fmt.Errorf("invalid reward amount %v: %w", c.Reward, err)
}
if err := c.RewardIndexes.Validate(); err != nil {
return fmt.Errorf("invalid reward indexes: %w", err)
}
return nil
}
// NewUSDXMintingClaim returns a new USDXMintingClaim
func NewUSDXMintingClaim(owner sdk.AccAddress, reward sdk.Coin, rewardIndexes RewardIndexes) USDXMintingClaim {
return USDXMintingClaim{
@ -163,20 +111,6 @@ func (cs USDXMintingClaims) Validate() error {
return nil
}
// Claims defines a slice of Claims
type Claims []Claim
// Validate checks if all the claims are valid.
func (cs Claims) Validate() error {
for _, c := range cs {
if err := c.Validate(); err != nil {
return err
}
}
return nil
}
// NewHardLiquidityProviderClaim returns a new HardLiquidityProviderClaim
func NewHardLiquidityProviderClaim(owner sdk.AccAddress, rewards sdk.Coins,
supplyRewardIndexes, borrowRewardIndexes MultiRewardIndexes,
@ -700,51 +634,3 @@ func (mris MultiRewardIndexes) copy() MultiRewardIndexes {
copy(newIndexes, mris)
return newIndexes
}
// NewTypedRewardIndexes returns a new TypedRewardIndexes
func NewTypedRewardIndexes(
claimType ClaimType,
collateralType string,
rewardIndexes RewardIndexes,
) TypedRewardIndexes {
return TypedRewardIndexes{
ClaimType: claimType,
CollateralType: collateralType,
RewardIndexes: rewardIndexes,
}
}
// Validate performs a basic check of a TypedRewardIndexes fields
func (tril TypedRewardIndexes) Validate() error {
if err := tril.ClaimType.Validate(); err != nil {
return err
}
if tril.CollateralType == "" {
return errors.New("collateral type cannot be empty")
}
return tril.RewardIndexes.Validate()
}
// TypedRewardIndexesList is a list of TypedRewardIndexes
type TypedRewardIndexesList []TypedRewardIndexes
// Validate validates a slice of TypedRewardIndexesList
func (tril TypedRewardIndexesList) Validate() error {
seen := make(map[string]bool)
for _, tri := range tril {
if err := tri.Validate(); err != nil {
return err
}
// Composite key of claim type and collateral type
key := fmt.Sprintf("%s/%s", tri.ClaimType, tri.CollateralType)
if seen[key] {
return fmt.Errorf("duplicate TypedRewardIndexes found: %s", key)
}
seen[key] = true
}
return nil
}

View File

@ -26,58 +26,6 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// ClaimType is the type of claim
type ClaimType int32
const (
// indicates an invalid claim type
CLAIM_TYPE_UNSPECIFIED ClaimType = 0
// claim type for hard borrow rewards
CLAIM_TYPE_HARD_BORROW ClaimType = 1
// claim type for hard supply rewards
CLAIM_TYPE_HARD_SUPPLY ClaimType = 2
// claim type for delegator rewards
CLAIM_TYPE_DELEGATOR ClaimType = 3
// claim type for earn rewards
CLAIM_TYPE_EARN ClaimType = 4
// claim type for savings rewards
CLAIM_TYPE_SAVINGS ClaimType = 5
// claim type for swap rewards
CLAIM_TYPE_SWAP ClaimType = 6
// claim type for usdx minting rewards
CLAIM_TYPE_USDX_MINTING ClaimType = 7
)
var ClaimType_name = map[int32]string{
0: "CLAIM_TYPE_UNSPECIFIED",
1: "CLAIM_TYPE_HARD_BORROW",
2: "CLAIM_TYPE_HARD_SUPPLY",
3: "CLAIM_TYPE_DELEGATOR",
4: "CLAIM_TYPE_EARN",
5: "CLAIM_TYPE_SAVINGS",
6: "CLAIM_TYPE_SWAP",
7: "CLAIM_TYPE_USDX_MINTING",
}
var ClaimType_value = map[string]int32{
"CLAIM_TYPE_UNSPECIFIED": 0,
"CLAIM_TYPE_HARD_BORROW": 1,
"CLAIM_TYPE_HARD_SUPPLY": 2,
"CLAIM_TYPE_DELEGATOR": 3,
"CLAIM_TYPE_EARN": 4,
"CLAIM_TYPE_SAVINGS": 5,
"CLAIM_TYPE_SWAP": 6,
"CLAIM_TYPE_USDX_MINTING": 7,
}
func (x ClaimType) String() string {
return proto.EnumName(ClaimType_name, int32(x))
}
func (ClaimType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{0}
}
// BaseClaim is a claim with a single reward coin types
type BaseClaim struct {
Owner github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=owner,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"owner,omitempty"`
@ -233,47 +181,6 @@ func (m *RewardIndexesProto) XXX_DiscardUnknown() {
var xxx_messageInfo_RewardIndexesProto proto.InternalMessageInfo
// TypedRewardIndexes defines a RewardIndexes slice with its corresponding
// claim and collateral type
type TypedRewardIndexes struct {
ClaimType ClaimType `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"`
CollateralType string `protobuf:"bytes,2,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"`
RewardIndexes RewardIndexes `protobuf:"bytes,3,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=RewardIndexes" json:"reward_indexes"`
}
func (m *TypedRewardIndexes) Reset() { *m = TypedRewardIndexes{} }
func (m *TypedRewardIndexes) String() string { return proto.CompactTextString(m) }
func (*TypedRewardIndexes) ProtoMessage() {}
func (*TypedRewardIndexes) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{4}
}
func (m *TypedRewardIndexes) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TypedRewardIndexes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TypedRewardIndexes.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TypedRewardIndexes) XXX_Merge(src proto.Message) {
xxx_messageInfo_TypedRewardIndexes.Merge(m, src)
}
func (m *TypedRewardIndexes) XXX_Size() int {
return m.Size()
}
func (m *TypedRewardIndexes) XXX_DiscardUnknown() {
xxx_messageInfo_TypedRewardIndexes.DiscardUnknown(m)
}
var xxx_messageInfo_TypedRewardIndexes proto.InternalMessageInfo
// MultiRewardIndex stores reward accumulation information on multiple reward types
type MultiRewardIndex struct {
CollateralType string `protobuf:"bytes,1,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"`
@ -284,7 +191,7 @@ func (m *MultiRewardIndex) Reset() { *m = MultiRewardIndex{} }
func (m *MultiRewardIndex) String() string { return proto.CompactTextString(m) }
func (*MultiRewardIndex) ProtoMessage() {}
func (*MultiRewardIndex) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{5}
return fileDescriptor_5f7515029623a895, []int{4}
}
func (m *MultiRewardIndex) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -322,7 +229,7 @@ func (m *MultiRewardIndexesProto) Reset() { *m = MultiRewardIndexesProto
func (m *MultiRewardIndexesProto) String() string { return proto.CompactTextString(m) }
func (*MultiRewardIndexesProto) ProtoMessage() {}
func (*MultiRewardIndexesProto) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{6}
return fileDescriptor_5f7515029623a895, []int{5}
}
func (m *MultiRewardIndexesProto) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -361,7 +268,7 @@ func (m *USDXMintingClaim) Reset() { *m = USDXMintingClaim{} }
func (m *USDXMintingClaim) String() string { return proto.CompactTextString(m) }
func (*USDXMintingClaim) ProtoMessage() {}
func (*USDXMintingClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{7}
return fileDescriptor_5f7515029623a895, []int{6}
}
func (m *USDXMintingClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -401,7 +308,7 @@ func (m *HardLiquidityProviderClaim) Reset() { *m = HardLiquidityProvide
func (m *HardLiquidityProviderClaim) String() string { return proto.CompactTextString(m) }
func (*HardLiquidityProviderClaim) ProtoMessage() {}
func (*HardLiquidityProviderClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{8}
return fileDescriptor_5f7515029623a895, []int{7}
}
func (m *HardLiquidityProviderClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -440,7 +347,7 @@ func (m *DelegatorClaim) Reset() { *m = DelegatorClaim{} }
func (m *DelegatorClaim) String() string { return proto.CompactTextString(m) }
func (*DelegatorClaim) ProtoMessage() {}
func (*DelegatorClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{9}
return fileDescriptor_5f7515029623a895, []int{8}
}
func (m *DelegatorClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -479,7 +386,7 @@ func (m *SwapClaim) Reset() { *m = SwapClaim{} }
func (m *SwapClaim) String() string { return proto.CompactTextString(m) }
func (*SwapClaim) ProtoMessage() {}
func (*SwapClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{10}
return fileDescriptor_5f7515029623a895, []int{9}
}
func (m *SwapClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -518,7 +425,7 @@ func (m *SavingsClaim) Reset() { *m = SavingsClaim{} }
func (m *SavingsClaim) String() string { return proto.CompactTextString(m) }
func (*SavingsClaim) ProtoMessage() {}
func (*SavingsClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{11}
return fileDescriptor_5f7515029623a895, []int{10}
}
func (m *SavingsClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -557,7 +464,7 @@ func (m *EarnClaim) Reset() { *m = EarnClaim{} }
func (m *EarnClaim) String() string { return proto.CompactTextString(m) }
func (*EarnClaim) ProtoMessage() {}
func (*EarnClaim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{12}
return fileDescriptor_5f7515029623a895, []int{11}
}
func (m *EarnClaim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -586,54 +493,11 @@ func (m *EarnClaim) XXX_DiscardUnknown() {
var xxx_messageInfo_EarnClaim proto.InternalMessageInfo
// Claim stores any generic rewards that can be claimed by owner
type Claim struct {
Type ClaimType `protobuf:"varint,1,opt,name=type,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"type,omitempty"`
Owner github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,2,opt,name=owner,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"owner,omitempty"`
Reward github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=reward,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"reward"`
RewardIndexes MultiRewardIndexes `protobuf:"bytes,4,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=MultiRewardIndexes" json:"reward_indexes"`
}
func (m *Claim) Reset() { *m = Claim{} }
func (m *Claim) String() string { return proto.CompactTextString(m) }
func (*Claim) ProtoMessage() {}
func (*Claim) Descriptor() ([]byte, []int) {
return fileDescriptor_5f7515029623a895, []int{13}
}
func (m *Claim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Claim) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Claim.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Claim) XXX_Merge(src proto.Message) {
xxx_messageInfo_Claim.Merge(m, src)
}
func (m *Claim) XXX_Size() int {
return m.Size()
}
func (m *Claim) XXX_DiscardUnknown() {
xxx_messageInfo_Claim.DiscardUnknown(m)
}
var xxx_messageInfo_Claim proto.InternalMessageInfo
func init() {
proto.RegisterEnum("kava.incentive.v1beta1.ClaimType", ClaimType_name, ClaimType_value)
proto.RegisterType((*BaseClaim)(nil), "kava.incentive.v1beta1.BaseClaim")
proto.RegisterType((*BaseMultiClaim)(nil), "kava.incentive.v1beta1.BaseMultiClaim")
proto.RegisterType((*RewardIndex)(nil), "kava.incentive.v1beta1.RewardIndex")
proto.RegisterType((*RewardIndexesProto)(nil), "kava.incentive.v1beta1.RewardIndexesProto")
proto.RegisterType((*TypedRewardIndexes)(nil), "kava.incentive.v1beta1.TypedRewardIndexes")
proto.RegisterType((*MultiRewardIndex)(nil), "kava.incentive.v1beta1.MultiRewardIndex")
proto.RegisterType((*MultiRewardIndexesProto)(nil), "kava.incentive.v1beta1.MultiRewardIndexesProto")
proto.RegisterType((*USDXMintingClaim)(nil), "kava.incentive.v1beta1.USDXMintingClaim")
@ -642,7 +506,6 @@ func init() {
proto.RegisterType((*SwapClaim)(nil), "kava.incentive.v1beta1.SwapClaim")
proto.RegisterType((*SavingsClaim)(nil), "kava.incentive.v1beta1.SavingsClaim")
proto.RegisterType((*EarnClaim)(nil), "kava.incentive.v1beta1.EarnClaim")
proto.RegisterType((*Claim)(nil), "kava.incentive.v1beta1.Claim")
}
func init() {
@ -650,63 +513,51 @@ func init() {
}
var fileDescriptor_5f7515029623a895 = []byte{
// 887 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0x4f, 0x6f, 0xe3, 0x44,
0x14, 0xcf, 0xa4, 0x69, 0x21, 0xaf, 0xdd, 0xac, 0x35, 0xfd, 0xb3, 0xdd, 0x20, 0x39, 0x4b, 0x56,
0x5a, 0x2a, 0x50, 0x1d, 0x76, 0x11, 0xe2, 0x8a, 0xdd, 0x64, 0x5b, 0xa3, 0x36, 0x8d, 0xec, 0x96,
0xdd, 0xe5, 0x80, 0x35, 0xb1, 0x87, 0x60, 0xd5, 0xf1, 0x04, 0xdb, 0x4d, 0x9a, 0x6f, 0x80, 0xc4,
0x05, 0xbe, 0x00, 0x17, 0x38, 0x71, 0xe6, 0x0b, 0x70, 0x2b, 0x12, 0x42, 0x15, 0x12, 0x12, 0xe2,
0x10, 0xd8, 0xf6, 0x0b, 0x70, 0xe6, 0x84, 0x3c, 0x76, 0x53, 0x37, 0x75, 0x56, 0xcb, 0x2a, 0xe9,
0xa1, 0xa7, 0x8c, 0xdf, 0x7b, 0xf3, 0xde, 0xef, 0xf7, 0x7b, 0x6f, 0x9c, 0x31, 0xdc, 0x3f, 0x20,
0x5d, 0x52, 0xb1, 0x5d, 0x93, 0xba, 0x81, 0xdd, 0xa5, 0x95, 0xee, 0xc3, 0x26, 0x0d, 0xc8, 0xc3,
0x8a, 0xe9, 0x10, 0xbb, 0xed, 0x4b, 0x1d, 0x8f, 0x05, 0x0c, 0xaf, 0x84, 0x41, 0xd2, 0x30, 0x48,
0x8a, 0x83, 0x8a, 0xa2, 0xc9, 0xfc, 0x36, 0xf3, 0x2b, 0x4d, 0xe2, 0x27, 0x76, 0x32, 0xdb, 0x8d,
0xf6, 0x15, 0xef, 0x46, 0x7e, 0x83, 0x3f, 0x55, 0xa2, 0x87, 0xd8, 0xb5, 0xd4, 0x62, 0x2d, 0x16,
0xd9, 0xc3, 0x55, 0x64, 0x2d, 0x7f, 0x8f, 0x20, 0xaf, 0x10, 0x9f, 0x6e, 0x84, 0xd5, 0xf1, 0xa7,
0x30, 0xcb, 0x7a, 0x2e, 0xf5, 0x56, 0xd1, 0x3d, 0xb4, 0xb6, 0xa0, 0x6c, 0xfd, 0x3b, 0x28, 0xad,
0xb7, 0xec, 0xe0, 0xf3, 0xc3, 0xa6, 0x64, 0xb2, 0x76, 0x9c, 0x2f, 0xfe, 0x59, 0xf7, 0xad, 0x83,
0x4a, 0xd0, 0xef, 0x50, 0x5f, 0x92, 0x4d, 0x53, 0xb6, 0x2c, 0x8f, 0xfa, 0xfe, 0x6f, 0x3f, 0xae,
0x2f, 0xc6, 0x55, 0x63, 0x8b, 0xd2, 0x0f, 0xa8, 0xaf, 0x45, 0x69, 0xf1, 0x07, 0x30, 0xe7, 0xd1,
0x1e, 0xf1, 0xac, 0xd5, 0xec, 0x3d, 0xb4, 0x36, 0xff, 0xe8, 0xae, 0x14, 0x07, 0x87, 0x7c, 0xce,
0x49, 0x4a, 0x1b, 0xcc, 0x76, 0x95, 0xdc, 0xf1, 0xa0, 0x94, 0xd1, 0xe2, 0xf0, 0xf2, 0xef, 0x08,
0x0a, 0x21, 0xcc, 0x9d, 0x43, 0x27, 0xb0, 0xaf, 0x07, 0xab, 0x99, 0xc0, 0x3a, 0xf3, 0x62, 0xac,
0xef, 0x86, 0x58, 0x7f, 0xf8, 0xab, 0xb4, 0xf6, 0x12, 0xf5, 0xc3, 0x0d, 0xfe, 0x90, 0xd7, 0x57,
0x08, 0xe6, 0x35, 0xbe, 0x54, 0x5d, 0x8b, 0x1e, 0xe1, 0xb7, 0xe0, 0xb6, 0xc9, 0x1c, 0x87, 0x04,
0xd4, 0x23, 0x8e, 0x11, 0xee, 0xe0, 0xf4, 0xf2, 0x5a, 0xe1, 0xc2, 0xbc, 0xd7, 0xef, 0x50, 0xac,
0xc3, 0xad, 0x28, 0x85, 0xf1, 0x19, 0x31, 0x03, 0xe6, 0x71, 0x41, 0x17, 0x14, 0x29, 0x44, 0xf2,
0xe7, 0xa0, 0xf4, 0xe0, 0x25, 0x90, 0x54, 0xa9, 0xa9, 0x2d, 0x44, 0x49, 0x1e, 0xf3, 0x1c, 0xe5,
0x1e, 0xe0, 0x04, 0x18, 0xea, 0x37, 0xf8, 0x2c, 0x12, 0x28, 0xc4, 0xa5, 0xec, 0xc8, 0xbc, 0x8a,
0xb8, 0x20, 0xf7, 0xa5, 0xf4, 0x21, 0x95, 0x12, 0x39, 0x94, 0xe5, 0x58, 0x9a, 0x5b, 0x97, 0x12,
0x6b, 0x31, 0xf8, 0xf8, 0xb1, 0x7c, 0x8a, 0x00, 0x87, 0xb4, 0xac, 0x4b, 0x51, 0xf8, 0x43, 0x00,
0x7e, 0x2a, 0x2e, 0x84, 0x28, 0x3c, 0x7a, 0x73, 0x5c, 0x55, 0x3e, 0x15, 0x61, 0x12, 0x2d, 0x6f,
0x9e, 0x2f, 0xd3, 0xf4, 0xcc, 0xa6, 0xea, 0x79, 0x95, 0xe4, 0xcc, 0xa4, 0x49, 0x7e, 0x8b, 0x40,
0xe0, 0xf3, 0xfb, 0x4a, 0x0d, 0xbf, 0x0a, 0x30, 0x3b, 0x69, 0x80, 0xdf, 0x20, 0xb8, 0x33, 0x0a,
0xf0, 0x7c, 0x08, 0xba, 0xb0, 0xd4, 0x0e, 0x5d, 0x46, 0xea, 0x28, 0xac, 0x8d, 0x03, 0x31, 0x9a,
0x4e, 0x29, 0xc6, 0x48, 0xf0, 0xd5, 0x42, 0x1a, 0x6e, 0x5f, 0xb1, 0x95, 0x7f, 0x42, 0x20, 0xec,
0xeb, 0xd5, 0xa7, 0x3b, 0xb6, 0x1b, 0xd8, 0x6e, 0x2b, 0x3a, 0xfa, 0x1f, 0x01, 0x84, 0x87, 0xd0,
0xe0, 0x7d, 0xe6, 0x7a, 0xcd, 0x8f, 0x9f, 0x8b, 0xe1, 0xdb, 0x4d, 0x79, 0x3d, 0xac, 0x7d, 0x32,
0x28, 0x21, 0x2d, 0xdf, 0x1c, 0xbe, 0xf2, 0xae, 0x41, 0xd7, 0xe7, 0x59, 0x28, 0x6e, 0x11, 0xcf,
0xda, 0xb6, 0xbf, 0x38, 0xb4, 0x2d, 0x3b, 0xe8, 0x37, 0x3c, 0xd6, 0xb5, 0x2d, 0xea, 0x45, 0x08,
0x76, 0x53, 0xd8, 0x3c, 0x78, 0x11, 0x9b, 0x8b, 0x97, 0x60, 0x3a, 0xa5, 0x23, 0x58, 0xf6, 0x0f,
0x3b, 0x1d, 0xa7, 0x6f, 0xa4, 0x32, 0x9b, 0x4c, 0xb3, 0x16, 0xa3, 0x12, 0x97, 0x0f, 0xec, 0x11,
0x2c, 0x37, 0x99, 0xe7, 0xb1, 0x9e, 0x91, 0x7a, 0x98, 0x26, 0x54, 0x39, 0x2a, 0x71, 0x79, 0x4e,
0x7e, 0x45, 0x50, 0xa8, 0x52, 0x87, 0xb6, 0x48, 0xc0, 0xa6, 0xa5, 0xeb, 0xc1, 0x98, 0x51, 0x99,
0x0c, 0xad, 0x91, 0xa1, 0xf9, 0x19, 0x41, 0x5e, 0xef, 0x91, 0xce, 0x4d, 0xe0, 0xf2, 0x0b, 0x82,
0x05, 0x9d, 0x74, 0x6d, 0xb7, 0xe5, 0xdf, 0x94, 0xd6, 0xd4, 0x88, 0xe7, 0xde, 0x04, 0x2e, 0xff,
0x64, 0x61, 0x36, 0x2a, 0xfb, 0x3e, 0xe4, 0xfe, 0xdf, 0xdf, 0x2c, 0x0f, 0xbf, 0xb8, 0x86, 0x65,
0xa7, 0x7d, 0x0d, 0x9b, 0x99, 0xda, 0x35, 0x2c, 0x45, 0xf2, 0xdc, 0xd4, 0x24, 0x7f, 0x7b, 0x80,
0x20, 0x3f, 0x54, 0x11, 0x17, 0x61, 0x65, 0x63, 0x5b, 0x56, 0x77, 0x8c, 0xbd, 0x67, 0x8d, 0x9a,
0xb1, 0x5f, 0xd7, 0x1b, 0xb5, 0x0d, 0xf5, 0xb1, 0x5a, 0xab, 0x0a, 0x99, 0x11, 0xdf, 0x96, 0xac,
0x55, 0x0d, 0x65, 0x57, 0xd3, 0x76, 0x9f, 0x08, 0x28, 0xcd, 0xa7, 0xef, 0x37, 0x1a, 0xdb, 0xcf,
0x84, 0x2c, 0x5e, 0x85, 0xa5, 0x84, 0xaf, 0x5a, 0xdb, 0xae, 0x6d, 0xca, 0x7b, 0xbb, 0x9a, 0x30,
0x83, 0x17, 0xe1, 0x76, 0xc2, 0x53, 0x93, 0xb5, 0xba, 0x90, 0xc3, 0x2b, 0x80, 0x13, 0x46, 0x5d,
0xfe, 0x58, 0xad, 0x6f, 0xea, 0xc2, 0xec, 0x48, 0xb0, 0xfe, 0x44, 0x6e, 0x08, 0x73, 0xf8, 0x0d,
0xb8, 0x93, 0xc4, 0xab, 0x57, 0x9f, 0x1a, 0x3b, 0x6a, 0x7d, 0x4f, 0xad, 0x6f, 0x0a, 0xaf, 0x15,
0x73, 0x5f, 0x7e, 0x27, 0x66, 0x14, 0xf5, 0xf8, 0xb9, 0x98, 0x39, 0x3e, 0x15, 0xd1, 0xc9, 0xa9,
0x88, 0xfe, 0x3e, 0x15, 0xd1, 0xd7, 0x67, 0x62, 0xe6, 0xe4, 0x4c, 0xcc, 0xfc, 0x71, 0x26, 0x66,
0x3e, 0x79, 0x27, 0xd1, 0x9d, 0x50, 0xdd, 0x75, 0x87, 0x34, 0x7d, 0xbe, 0xaa, 0x1c, 0x25, 0x3e,
0x8b, 0x78, 0x9b, 0x9a, 0x73, 0xfc, 0x2b, 0xe5, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcf,
0x23, 0x97, 0x53, 0x35, 0x0d, 0x00, 0x00,
// 691 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x4f, 0x4f, 0x13, 0x4d,
0x18, 0xef, 0xc0, 0x0b, 0x79, 0x3b, 0x94, 0xbe, 0x64, 0x81, 0x57, 0xe8, 0x61, 0x8b, 0x25, 0xc1,
0x26, 0xa6, 0xbb, 0x82, 0x07, 0x13, 0x6f, 0x2c, 0x68, 0xc0, 0x48, 0x24, 0x5b, 0x4d, 0x8c, 0x07,
0x9b, 0xd9, 0xdd, 0xb1, 0x4e, 0xd8, 0xee, 0xd4, 0x99, 0x6d, 0x4b, 0x3f, 0x83, 0x17, 0xfd, 0x02,
0x7e, 0x00, 0x2f, 0x5e, 0xf8, 0x10, 0xc4, 0x78, 0x20, 0xc6, 0xc4, 0x3f, 0x87, 0x8a, 0x70, 0xf5,
0x13, 0x78, 0x32, 0xf3, 0x07, 0x58, 0xa0, 0x25, 0xc4, 0x14, 0x0f, 0x9c, 0x76, 0xe7, 0x99, 0x67,
0x9e, 0xdf, 0x9f, 0x79, 0x76, 0x76, 0xe0, 0xec, 0x06, 0x6a, 0x22, 0x9b, 0x44, 0x3e, 0x8e, 0x62,
0xd2, 0xc4, 0x76, 0x73, 0xde, 0xc3, 0x31, 0x9a, 0xb7, 0xfd, 0x10, 0x91, 0x1a, 0xb7, 0xea, 0x8c,
0xc6, 0xd4, 0xf8, 0x5f, 0x24, 0x59, 0x87, 0x49, 0x96, 0x4e, 0xca, 0x99, 0x3e, 0xe5, 0x35, 0xca,
0x6d, 0x0f, 0xf1, 0xc4, 0x4a, 0x4a, 0x22, 0xb5, 0x2e, 0x37, 0xad, 0xe6, 0x2b, 0x72, 0x64, 0xab,
0x81, 0x9e, 0x9a, 0xa8, 0xd2, 0x2a, 0x55, 0x71, 0xf1, 0xa6, 0xa2, 0x85, 0x77, 0x00, 0xa6, 0x1d,
0xc4, 0xf1, 0x92, 0x40, 0x37, 0x9e, 0xc2, 0x21, 0xda, 0x8a, 0x30, 0x9b, 0x02, 0x33, 0xa0, 0x98,
0x71, 0x56, 0x7e, 0x75, 0xf2, 0xa5, 0x2a, 0x89, 0x9f, 0x37, 0x3c, 0xcb, 0xa7, 0x35, 0x5d, 0x4f,
0x3f, 0x4a, 0x3c, 0xd8, 0xb0, 0xe3, 0x76, 0x1d, 0x73, 0x6b, 0xd1, 0xf7, 0x17, 0x83, 0x80, 0x61,
0xce, 0x3f, 0x6e, 0x95, 0xc6, 0x35, 0xaa, 0x8e, 0x38, 0xed, 0x18, 0x73, 0x57, 0x95, 0x35, 0x6e,
0xc1, 0x61, 0x86, 0x5b, 0x88, 0x05, 0x53, 0x03, 0x33, 0xa0, 0x38, 0xb2, 0x30, 0x6d, 0xe9, 0x64,
0xa1, 0xe7, 0x40, 0xa4, 0xb5, 0x44, 0x49, 0xe4, 0xfc, 0xb3, 0xdd, 0xc9, 0xa7, 0x5c, 0x9d, 0x7e,
0x3b, 0xfd, 0x7e, 0xab, 0x34, 0x24, 0x39, 0x16, 0x76, 0x01, 0xcc, 0x0a, 0xc6, 0x6b, 0x8d, 0x30,
0x26, 0x7f, 0x87, 0xb6, 0x9f, 0xa0, 0x3d, 0x78, 0x36, 0xed, 0x1b, 0x82, 0xf6, 0xdb, 0xef, 0xf9,
0xe2, 0x39, 0xf0, 0xc5, 0x02, 0xde, 0x4d, 0xe2, 0x4b, 0x00, 0x47, 0x5c, 0x19, 0x5d, 0x8d, 0x02,
0xbc, 0x69, 0x5c, 0x83, 0xff, 0xf9, 0x34, 0x0c, 0x51, 0x8c, 0x19, 0x0a, 0x2b, 0x62, 0xb1, 0x54,
0x9a, 0x76, 0xb3, 0x47, 0xe1, 0x87, 0xed, 0x3a, 0x36, 0xca, 0x70, 0x54, 0x55, 0xab, 0x3c, 0x43,
0x7e, 0x4c, 0x99, 0xb4, 0x39, 0xe3, 0x58, 0x82, 0xd4, 0xb7, 0x4e, 0x7e, 0xee, 0x1c, 0xa4, 0x96,
0xb1, 0xef, 0x66, 0x54, 0x91, 0xbb, 0xb2, 0x46, 0xa1, 0x05, 0x8d, 0x04, 0x19, 0xcc, 0xd7, 0x65,
0x87, 0x22, 0x98, 0xd5, 0x50, 0x44, 0x85, 0xa7, 0x80, 0xf4, 0x66, 0xd6, 0xea, 0xde, 0xba, 0x56,
0xa2, 0x86, 0x33, 0xa9, 0x5d, 0x1a, 0x3d, 0x56, 0xd8, 0xd5, 0xe4, 0xf5, 0xb0, 0xf0, 0x06, 0xc0,
0x31, 0xb9, 0xcb, 0x7f, 0xe4, 0xc5, 0x69, 0x82, 0x03, 0xfd, 0x26, 0xf8, 0x1a, 0xc0, 0x2b, 0x27,
0x09, 0x1e, 0xf8, 0xd3, 0x84, 0x13, 0x35, 0x31, 0x55, 0xe9, 0xea, 0x52, 0xb1, 0x17, 0x89, 0x93,
0xe5, 0x9c, 0x9c, 0x66, 0x62, 0x9c, 0x06, 0x72, 0x8d, 0xda, 0xa9, 0x58, 0xe1, 0x03, 0x80, 0x63,
0x8f, 0xca, 0xcb, 0x8f, 0xd7, 0x48, 0x14, 0x93, 0xa8, 0xaa, 0x3e, 0x90, 0x7b, 0x10, 0x8a, 0x56,
0xad, 0xc8, 0x33, 0x46, 0xfa, 0x35, 0xb2, 0x70, 0xb5, 0x17, 0x85, 0xc3, 0xe3, 0xc0, 0xf9, 0x57,
0x60, 0xef, 0x74, 0xf2, 0xc0, 0x4d, 0x7b, 0x87, 0x67, 0xc4, 0xc5, 0xfb, 0x9a, 0xfc, 0x14, 0x7e,
0x0e, 0xc0, 0xdc, 0x0a, 0x62, 0xc1, 0x7d, 0xf2, 0xa2, 0x41, 0x02, 0x12, 0xb7, 0xd7, 0x19, 0x6d,
0x92, 0x00, 0x33, 0x45, 0xe6, 0x41, 0x17, 0x61, 0x73, 0x67, 0x09, 0x3b, 0x3a, 0x35, 0xba, 0xab,
0xdb, 0x84, 0x93, 0xbc, 0x51, 0xaf, 0x87, 0xed, 0x4a, 0x57, 0x91, 0xfd, 0xd9, 0xb7, 0x71, 0x05,
0x71, 0x2c, 0x28, 0x90, 0x3d, 0xca, 0x18, 0x6d, 0x9d, 0x44, 0x1e, 0xec, 0x27, 0xb2, 0x82, 0x70,
0x7b, 0xd9, 0xfd, 0x15, 0xc0, 0xec, 0x32, 0x0e, 0x71, 0x15, 0xc5, 0xf4, 0xa2, 0x2c, 0xde, 0xe8,
0xd1, 0x40, 0xfd, 0x51, 0xd8, 0xbb, 0x95, 0x3e, 0x01, 0x98, 0x2e, 0xb7, 0x50, 0xfd, 0x92, 0xc9,
0xfa, 0x0c, 0x60, 0xa6, 0x8c, 0x9a, 0x24, 0xaa, 0xf2, 0x4b, 0xb8, 0x61, 0x77, 0x10, 0x8b, 0x2e,
0x97, 0x2c, 0x67, 0x75, 0xfb, 0x87, 0x99, 0xda, 0xde, 0x33, 0xc1, 0xce, 0x9e, 0x09, 0x76, 0xf7,
0x4c, 0xf0, 0x6a, 0xdf, 0x4c, 0xed, 0xec, 0x9b, 0xa9, 0x2f, 0xfb, 0x66, 0xea, 0xc9, 0xf5, 0xc4,
0x3f, 0x5a, 0xf0, 0x28, 0x85, 0xc8, 0xe3, 0xf2, 0xcd, 0xde, 0x4c, 0xdc, 0x1a, 0xe5, 0xcf, 0xda,
0x1b, 0x96, 0x97, 0xb8, 0x9b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x88, 0xd7, 0x8a, 0x4f, 0x54,
0x0a, 0x00, 0x00,
}
func (m *BaseClaim) Marshal() (dAtA []byte, err error) {
@ -870,55 +721,6 @@ func (m *RewardIndexesProto) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *TypedRewardIndexes) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TypedRewardIndexes) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TypedRewardIndexes) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.RewardIndexes) > 0 {
for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintClaims(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.CollateralType) > 0 {
i -= len(m.CollateralType)
copy(dAtA[i:], m.CollateralType)
i = encodeVarintClaims(dAtA, i, uint64(len(m.CollateralType)))
i--
dAtA[i] = 0x12
}
if m.ClaimType != 0 {
i = encodeVarintClaims(dAtA, i, uint64(m.ClaimType))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *MultiRewardIndex) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1296,69 +1098,6 @@ func (m *EarnClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *Claim) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Claim) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Claim) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.RewardIndexes) > 0 {
for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintClaims(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
}
}
if len(m.Reward) > 0 {
for iNdEx := len(m.Reward) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Reward[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintClaims(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.Owner) > 0 {
i -= len(m.Owner)
copy(dAtA[i:], m.Owner)
i = encodeVarintClaims(dAtA, i, uint64(len(m.Owner)))
i--
dAtA[i] = 0x12
}
if m.Type != 0 {
i = encodeVarintClaims(dAtA, i, uint64(m.Type))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintClaims(dAtA []byte, offset int, v uint64) int {
offset -= sovClaims(v)
base := offset
@ -1434,28 +1173,6 @@ func (m *RewardIndexesProto) Size() (n int) {
return n
}
func (m *TypedRewardIndexes) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ClaimType != 0 {
n += 1 + sovClaims(uint64(m.ClaimType))
}
l = len(m.CollateralType)
if l > 0 {
n += 1 + l + sovClaims(uint64(l))
}
if len(m.RewardIndexes) > 0 {
for _, e := range m.RewardIndexes {
l = e.Size()
n += 1 + l + sovClaims(uint64(l))
}
}
return n
}
func (m *MultiRewardIndex) Size() (n int) {
if m == nil {
return 0
@ -1598,34 +1315,6 @@ func (m *EarnClaim) Size() (n int) {
return n
}
func (m *Claim) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Type != 0 {
n += 1 + sovClaims(uint64(m.Type))
}
l = len(m.Owner)
if l > 0 {
n += 1 + l + sovClaims(uint64(l))
}
if len(m.Reward) > 0 {
for _, e := range m.Reward {
l = e.Size()
n += 1 + l + sovClaims(uint64(l))
}
}
if len(m.RewardIndexes) > 0 {
for _, e := range m.RewardIndexes {
l = e.Size()
n += 1 + l + sovClaims(uint64(l))
}
}
return n
}
func sovClaims(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@ -2066,141 +1755,6 @@ func (m *RewardIndexesProto) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *TypedRewardIndexes) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TypedRewardIndexes: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TypedRewardIndexes: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType)
}
m.ClaimType = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClaimType |= ClaimType(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CollateralType", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthClaims
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthClaims
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.CollateralType = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthClaims
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthClaims
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RewardIndexes = append(m.RewardIndexes, RewardIndex{})
if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipClaims(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthClaims
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MultiRewardIndex) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -3137,177 +2691,6 @@ func (m *EarnClaim) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *Claim) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Claim: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Claim: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= ClaimType(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthClaims
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthClaims
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Owner = append(m.Owner[:0], dAtA[iNdEx:postIndex]...)
if m.Owner == nil {
m.Owner = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Reward", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthClaims
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthClaims
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Reward = append(m.Reward, types.Coin{})
if err := m.Reward[len(m.Reward)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClaims
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthClaims
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthClaims
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RewardIndexes = append(m.RewardIndexes, MultiRewardIndex{})
if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipClaims(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthClaims
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipClaims(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

View File

@ -21,59 +21,6 @@ func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
func TestClaims_Validate(t *testing.T) {
owner := sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
t.Run("Claims", func(t *testing.T) {
validRewardIndexes := RewardIndexes{}.With("ukava", d("0.002"))
validMultiRewardIndexes := MultiRewardIndexes{}.With("ukava", validRewardIndexes)
invalidRewardIndexes := RewardIndexes{}.With("ukava", d("-0.002"))
invalidMultiRewardIndexes := MultiRewardIndexes{}.With("ukava", invalidRewardIndexes)
testCases := []struct {
name string
claims Claims
expPass bool
}{
{
name: "valid",
claims: Claims{
NewClaim(CLAIM_TYPE_USDX_MINTING, owner, cs(c("bnb", 1)), validMultiRewardIndexes),
},
expPass: true,
},
{
name: "invalid owner",
claims: Claims{
NewClaim(CLAIM_TYPE_USDX_MINTING, nil, cs(c("bnb", 1)), validMultiRewardIndexes),
},
expPass: false,
},
{
name: "invalid reward",
claims: Claims{
NewClaim(CLAIM_TYPE_USDX_MINTING, owner, sdk.Coins{sdk.Coin{Denom: "invalid😫"}}, validMultiRewardIndexes),
},
expPass: false,
},
{
name: "invalid indexes",
claims: Claims{
NewClaim(CLAIM_TYPE_USDX_MINTING, nil, cs(c("bnb", 1)), invalidMultiRewardIndexes),
},
expPass: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.claims.Validate()
if tc.expPass {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
})
t.Run("USDXMintingClaims", func(t *testing.T) {
testCases := []struct {
name string

View File

@ -16,22 +16,14 @@ var (
MultiRewardIndexes{},
)
DefaultEarnClaims = EarnClaims{}
// New fields
DefaultClaims = Claims{}
DefaultAccrualTimes = AccrualTimes{}
DefaultTypedRewardIndexesList = TypedRewardIndexesList{}
)
// NewGenesisState returns a new genesis state
func NewGenesisState(
params Params,
usdxState, hardSupplyState, hardBorrowState, delegatorState, swapState, savingsState, earnState GenesisRewardState,
c Claims,
uc USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims,
c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims, savingsc SavingsClaims,
earnc EarnClaims,
accrualTimes AccrualTimes,
rewardIndexes TypedRewardIndexesList,
) GenesisState {
return GenesisState{
Params: params,
@ -44,18 +36,12 @@ func NewGenesisState(
SavingsRewardState: savingsState,
EarnRewardState: earnState,
USDXMintingClaims: uc,
USDXMintingClaims: c,
HardLiquidityProviderClaims: hc,
DelegatorClaims: dc,
SwapClaims: sc,
SavingsClaims: savingsc,
EarnClaims: earnc,
// New fields
// Claims of all types
Claims: c,
AccrualTimes: accrualTimes,
RewardIndexes: rewardIndexes,
}
}
@ -70,15 +56,12 @@ func DefaultGenesisState() GenesisState {
SwapRewardState: DefaultGenesisRewardState,
SavingsRewardState: DefaultGenesisRewardState,
EarnRewardState: DefaultGenesisRewardState,
Claims: DefaultClaims,
USDXMintingClaims: DefaultUSDXClaims,
HardLiquidityProviderClaims: DefaultHardClaims,
DelegatorClaims: DefaultDelegatorClaims,
SwapClaims: DefaultSwapClaims,
SavingsClaims: DefaultSavingsClaims,
EarnClaims: DefaultEarnClaims,
AccrualTimes: DefaultAccrualTimes,
RewardIndexes: DefaultTypedRewardIndexesList,
}
}
@ -128,20 +111,7 @@ func (gs GenesisState) Validate() error {
return err
}
if err := gs.EarnClaims.Validate(); err != nil {
return err
}
// Refactored methods -- these will eventually replace the claim and state methods above
if err := gs.Claims.Validate(); err != nil {
return err
}
if err := gs.AccrualTimes.Validate(); err != nil {
return err
}
return gs.RewardIndexes.Validate()
return gs.EarnClaims.Validate()
}
// NewGenesisRewardState returns a new GenesisRewardState
@ -188,50 +158,3 @@ func (gats AccumulationTimes) Validate() error {
}
return nil
}
// NewAccrualTime returns a new AccrualTime
func NewAccrualTime(claimType ClaimType, collateralType string, prevTime time.Time) AccrualTime {
return AccrualTime{
ClaimType: claimType,
CollateralType: collateralType,
PreviousAccumulationTime: prevTime,
}
}
// Validate performs validation of AccrualTime
func (at AccrualTime) Validate() error {
if at.PreviousAccumulationTime.IsZero() {
return fmt.Errorf("previous accumulation time cannot be zero")
}
if err := at.ClaimType.Validate(); err != nil {
return err
}
if len(at.CollateralType) == 0 {
return fmt.Errorf("collateral type cannot be empty")
}
return nil
}
// AccrualTimes slice of AccrualTime
type AccrualTimes []AccrualTime
// Validate performs validation of AccrualTimes
func (gats AccrualTimes) Validate() error {
seenAccrualTimes := make(map[string]bool)
for _, gat := range gats {
if err := gat.Validate(); err != nil {
return err
}
key := fmt.Sprintf("%s-%s", gat.ClaimType, gat.CollateralType)
if seenAccrualTimes[key] {
return fmt.Errorf("duplicate accrual time found for %s", key)
}
seenAccrualTimes[key] = true
}
return nil
}

View File

@ -28,8 +28,6 @@ var _ = time.Kitchen
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// AccumulationTime stores the previous reward distribution time and its corresponding collateral type
//
// Deprecated: Do not use.
type AccumulationTime struct {
CollateralType string `protobuf:"bytes,1,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"`
PreviousAccumulationTime time.Time `protobuf:"bytes,2,opt,name=previous_accumulation_time,json=previousAccumulationTime,proto3,stdtime" json:"previous_accumulation_time"`
@ -68,48 +66,6 @@ func (m *AccumulationTime) XXX_DiscardUnknown() {
var xxx_messageInfo_AccumulationTime proto.InternalMessageInfo
// AccrualTime stores the previous reward distribution time and its
// corresponding collateral type and claim type. This is the new version of
// AccumulationTime that is used for the new claim types.
type AccrualTime struct {
ClaimType ClaimType `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"`
CollateralType string `protobuf:"bytes,2,opt,name=collateral_type,json=collateralType,proto3" json:"collateral_type,omitempty"`
PreviousAccumulationTime time.Time `protobuf:"bytes,3,opt,name=previous_accumulation_time,json=previousAccumulationTime,proto3,stdtime" json:"previous_accumulation_time"`
}
func (m *AccrualTime) Reset() { *m = AccrualTime{} }
func (m *AccrualTime) String() string { return proto.CompactTextString(m) }
func (*AccrualTime) ProtoMessage() {}
func (*AccrualTime) Descriptor() ([]byte, []int) {
return fileDescriptor_8b76737885d05afd, []int{1}
}
func (m *AccrualTime) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *AccrualTime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_AccrualTime.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *AccrualTime) XXX_Merge(src proto.Message) {
xxx_messageInfo_AccrualTime.Merge(m, src)
}
func (m *AccrualTime) XXX_Size() int {
return m.Size()
}
func (m *AccrualTime) XXX_DiscardUnknown() {
xxx_messageInfo_AccrualTime.DiscardUnknown(m)
}
var xxx_messageInfo_AccrualTime proto.InternalMessageInfo
// GenesisRewardState groups together the global state for a particular reward so it can be exported in genesis.
type GenesisRewardState struct {
AccumulationTimes AccumulationTimes `protobuf:"bytes,1,rep,name=accumulation_times,json=accumulationTimes,proto3,castrepeated=AccumulationTimes" json:"accumulation_times"`
@ -120,7 +76,7 @@ func (m *GenesisRewardState) Reset() { *m = GenesisRewardState{} }
func (m *GenesisRewardState) String() string { return proto.CompactTextString(m) }
func (*GenesisRewardState) ProtoMessage() {}
func (*GenesisRewardState) Descriptor() ([]byte, []int) {
return fileDescriptor_8b76737885d05afd, []int{2}
return fileDescriptor_8b76737885d05afd, []int{1}
}
func (m *GenesisRewardState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -165,16 +121,13 @@ type GenesisState struct {
SavingsClaims SavingsClaims `protobuf:"bytes,12,rep,name=savings_claims,json=savingsClaims,proto3,castrepeated=SavingsClaims" json:"savings_claims"`
EarnRewardState GenesisRewardState `protobuf:"bytes,13,opt,name=earn_reward_state,json=earnRewardState,proto3" json:"earn_reward_state"`
EarnClaims EarnClaims `protobuf:"bytes,14,rep,name=earn_claims,json=earnClaims,proto3,castrepeated=EarnClaims" json:"earn_claims"`
Claims Claims `protobuf:"bytes,15,rep,name=claims,proto3,castrepeated=Claims" json:"claims"`
AccrualTimes AccrualTimes `protobuf:"bytes,16,rep,name=accrual_times,json=accrualTimes,proto3,castrepeated=AccrualTimes" json:"accrual_times"`
RewardIndexes TypedRewardIndexesList `protobuf:"bytes,17,rep,name=reward_indexes,json=rewardIndexes,proto3,castrepeated=TypedRewardIndexesList" json:"reward_indexes"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_8b76737885d05afd, []int{3}
return fileDescriptor_8b76737885d05afd, []int{2}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -205,7 +158,6 @@ var xxx_messageInfo_GenesisState proto.InternalMessageInfo
func init() {
proto.RegisterType((*AccumulationTime)(nil), "kava.incentive.v1beta1.AccumulationTime")
proto.RegisterType((*AccrualTime)(nil), "kava.incentive.v1beta1.AccrualTime")
proto.RegisterType((*GenesisRewardState)(nil), "kava.incentive.v1beta1.GenesisRewardState")
proto.RegisterType((*GenesisState)(nil), "kava.incentive.v1beta1.GenesisState")
}
@ -215,64 +167,57 @@ func init() {
}
var fileDescriptor_8b76737885d05afd = []byte{
// 911 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xf7, 0x3a, 0xc5, 0x34, 0xe3, 0xd8, 0x8e, 0x07, 0x37, 0x35, 0xae, 0x58, 0x87, 0xa4, 0x82,
0x08, 0xc4, 0x5a, 0x35, 0x37, 0xc4, 0x81, 0x2e, 0xad, 0xa0, 0x52, 0x2b, 0x55, 0x93, 0x50, 0x21,
0x84, 0xb0, 0x66, 0x77, 0xa7, 0x9b, 0x81, 0xfd, 0xd7, 0x99, 0x59, 0x27, 0xb9, 0x71, 0xe4, 0xd8,
0x0f, 0xc0, 0x8d, 0x1b, 0x9f, 0x24, 0xc7, 0x1e, 0x39, 0xa0, 0x06, 0x9c, 0x2f, 0x82, 0x66, 0x76,
0xd6, 0xd9, 0xb5, 0xb3, 0x46, 0x98, 0xde, 0x66, 0xdf, 0xbc, 0xf9, 0xfd, 0x99, 0xf7, 0x66, 0x67,
0xc0, 0xdd, 0x9f, 0xf0, 0x14, 0x8f, 0x68, 0xe4, 0x92, 0x48, 0xd0, 0x29, 0x19, 0x4d, 0xef, 0x39,
0x44, 0xe0, 0x7b, 0x23, 0x9f, 0x44, 0x84, 0x53, 0x6e, 0x25, 0x2c, 0x16, 0x31, 0xdc, 0x91, 0x59,
0xd6, 0x3c, 0xcb, 0xd2, 0x59, 0x83, 0x9e, 0x1f, 0xfb, 0xb1, 0x4a, 0x19, 0xc9, 0x51, 0x96, 0x3d,
0x18, 0xfa, 0x71, 0xec, 0x07, 0x64, 0xa4, 0xbe, 0x9c, 0xf4, 0xf9, 0x48, 0xd0, 0x90, 0x70, 0x81,
0xc3, 0x44, 0x27, 0xec, 0x57, 0x90, 0xba, 0x01, 0xa6, 0x21, 0xff, 0x97, 0xa4, 0x04, 0x33, 0x9c,
0x27, 0xed, 0xfd, 0x66, 0x80, 0xed, 0xfb, 0xae, 0x9b, 0x86, 0x69, 0x80, 0x05, 0x8d, 0xa3, 0x23,
0x1a, 0x12, 0xf8, 0x21, 0xe8, 0xb8, 0x71, 0x10, 0x60, 0x41, 0x18, 0x0e, 0x26, 0xe2, 0x2c, 0x21,
0x7d, 0x63, 0xd7, 0x38, 0xd8, 0x44, 0xed, 0xab, 0xf0, 0xd1, 0x59, 0x42, 0xa0, 0x03, 0x06, 0x09,
0x23, 0x53, 0x1a, 0xa7, 0x7c, 0x82, 0x0b, 0x28, 0x13, 0x29, 0xb8, 0x5f, 0xdf, 0x35, 0x0e, 0x9a,
0xe3, 0x81, 0x95, 0xb9, 0xb1, 0x72, 0x37, 0xd6, 0x51, 0xee, 0xc6, 0xbe, 0x79, 0xfe, 0x7a, 0x58,
0x7b, 0x79, 0x31, 0x34, 0x50, 0x3f, 0xc7, 0x59, 0x14, 0xf3, 0x59, 0xbd, 0x6f, 0xec, 0xfd, 0x69,
0x80, 0xe6, 0x7d, 0xd7, 0x65, 0x29, 0x0e, 0x94, 0xc0, 0x2f, 0x00, 0x50, 0x56, 0xaf, 0xb4, 0xb5,
0xc7, 0xef, 0x5b, 0xd7, 0xef, 0xb1, 0xf5, 0xa5, 0xcc, 0x94, 0x72, 0xd1, 0xa6, 0x9b, 0x0f, 0xaf,
0xb3, 0x58, 0x5f, 0xc3, 0xe2, 0xc6, 0x9b, 0xb0, 0xb8, 0xf7, 0x73, 0x1d, 0xc0, 0xaf, 0xb2, 0x7e,
0x41, 0xe4, 0x04, 0x33, 0xef, 0x50, 0x60, 0x41, 0x20, 0x03, 0x70, 0x89, 0x91, 0xf7, 0x8d, 0xdd,
0x8d, 0x83, 0xe6, 0xf8, 0xa0, 0xca, 0xed, 0x22, 0xb8, 0xfd, 0xae, 0x14, 0xf0, 0xfb, 0xc5, 0xb0,
0xbb, 0x38, 0xc3, 0x51, 0x17, 0x2f, 0x86, 0xe0, 0x14, 0xf4, 0xc2, 0x34, 0x10, 0x74, 0xc2, 0x94,
0x90, 0x09, 0x8d, 0x3c, 0x72, 0x4a, 0x78, 0xbf, 0xbe, 0x9a, 0xf5, 0x89, 0x5c, 0x93, 0x69, 0x7f,
0x24, 0x57, 0xd8, 0x03, 0xcd, 0x0a, 0x17, 0x67, 0x08, 0x47, 0x30, 0x5c, 0x8a, 0xed, 0x5d, 0xb4,
0xc0, 0x96, 0xde, 0x82, 0xcc, 0xfc, 0xe7, 0xa0, 0x91, 0x35, 0xaa, 0x2a, 0x6f, 0x73, 0x6c, 0x56,
0x51, 0x3f, 0x55, 0x59, 0xf6, 0x0d, 0x49, 0x88, 0xf4, 0x1a, 0x18, 0x83, 0x6e, 0xca, 0xbd, 0xd3,
0xdc, 0x05, 0x97, 0x90, 0xba, 0x1f, 0x3f, 0xaa, 0x02, 0x5a, 0xae, 0x80, 0x7d, 0x5b, 0x82, 0xce,
0x5e, 0x0f, 0x3b, 0xdf, 0x1c, 0x3e, 0xf8, 0xb6, 0x30, 0x81, 0x3a, 0x12, 0xbd, 0x58, 0x2b, 0x0a,
0xfa, 0xc7, 0x8a, 0x29, 0x4d, 0x92, 0xe0, 0xac, 0xcc, 0xbb, 0xf1, 0x9f, 0x79, 0x33, 0x33, 0xb7,
0x24, 0xe2, 0xa1, 0x02, 0xbc, 0x8e, 0xca, 0x89, 0x19, 0x8b, 0x4f, 0xca, 0x54, 0x37, 0xfe, 0x0f,
0x95, 0xad, 0x00, 0x8b, 0x54, 0xcf, 0xc1, 0x8e, 0x47, 0x02, 0xe2, 0x63, 0x11, 0xb3, 0x32, 0xd1,
0x5b, 0x6b, 0x12, 0xf5, 0xe6, 0x78, 0x45, 0x9e, 0xef, 0x41, 0x97, 0x9f, 0xe0, 0xa4, 0x4c, 0xd1,
0x58, 0x93, 0xa2, 0x23, 0xa1, 0x8a, 0xe8, 0xbf, 0x18, 0xe0, 0x1d, 0xd5, 0x0d, 0x21, 0x8d, 0x04,
0x8d, 0xfc, 0x49, 0xf6, 0x9b, 0xec, 0xbf, 0xbd, 0xba, 0xa7, 0x65, 0xcd, 0x9f, 0x64, 0x2b, 0xd4,
0x2f, 0xc4, 0xb6, 0x74, 0x37, 0x74, 0x17, 0x67, 0xb8, 0x3c, 0x5e, 0x4b, 0x41, 0xa4, 0x5a, 0xb0,
0x14, 0x82, 0xbf, 0x1a, 0xc0, 0x54, 0xc5, 0x0b, 0xe8, 0x8b, 0x94, 0x7a, 0x54, 0x9c, 0x4d, 0x12,
0x16, 0x4f, 0xa9, 0x47, 0x58, 0xae, 0xea, 0xa6, 0x52, 0x35, 0xae, 0x52, 0xf5, 0x35, 0x66, 0xde,
0xe3, 0x7c, 0xf1, 0x53, 0xbd, 0x36, 0xd3, 0xb7, 0xaf, 0xcf, 0xdc, 0x9d, 0xea, 0x1c, 0x8e, 0xee,
0x1c, 0x57, 0x4f, 0xc2, 0x1f, 0xc1, 0xf6, 0x55, 0xbd, 0xb5, 0x9e, 0x4d, 0xa5, 0xe7, 0x83, 0x2a,
0x3d, 0x0f, 0xf2, 0xfc, 0x4c, 0xc3, 0x6d, 0xad, 0xa1, 0x53, 0x8e, 0x73, 0xd4, 0xf1, 0xca, 0x01,
0xf8, 0x0c, 0x34, 0x55, 0xcd, 0x35, 0x0d, 0x50, 0x34, 0x95, 0x3f, 0xf1, 0xc3, 0x13, 0x9c, 0x64,
0x0c, 0x50, 0x33, 0x80, 0x79, 0x88, 0x23, 0xc0, 0xe7, 0x63, 0xe8, 0x80, 0x1e, 0xc7, 0x53, 0x1a,
0xf9, 0xbc, 0xdc, 0x4e, 0xcd, 0x35, 0xdb, 0x09, 0x6a, 0xb4, 0x62, 0x47, 0x39, 0xa0, 0x9d, 0x73,
0x68, 0xf9, 0x5b, 0x4a, 0xfe, 0xdd, 0x4a, 0xf9, 0x59, 0x76, 0xe6, 0xe0, 0x96, 0x76, 0xd0, 0x2a,
0x46, 0x39, 0x6a, 0xf1, 0xe2, 0xa7, 0x3c, 0x13, 0x04, 0xb3, 0xa8, 0x6c, 0xa2, 0xb5, 0xee, 0x99,
0x90, 0x50, 0x45, 0x07, 0xcf, 0x40, 0x53, 0xa1, 0x6b, 0xf9, 0xed, 0xd5, 0xbb, 0xff, 0x10, 0xb3,
0x68, 0x61, 0xf7, 0xe7, 0x21, 0x8e, 0x00, 0x99, 0x8f, 0xe1, 0x43, 0xd0, 0xd0, 0x90, 0x1d, 0x05,
0xf9, 0xde, 0xca, 0x5b, 0xd9, 0x6e, 0x6b, 0xb8, 0x86, 0x86, 0xd2, 0x8b, 0xe1, 0x0f, 0xa0, 0x85,
0xb3, 0xfb, 0x5e, 0xdf, 0x7a, 0xdb, 0x0a, 0x6d, 0x7f, 0xc5, 0xad, 0x97, 0x3f, 0x0e, 0xec, 0x9e,
0xc6, 0xdc, 0x2a, 0x04, 0x39, 0xda, 0xc2, 0x85, 0x2f, 0xf8, 0x02, 0xb4, 0x17, 0x2e, 0xb8, 0xae,
0x22, 0xa8, 0xdc, 0x59, 0xf9, 0x16, 0xf0, 0x4a, 0x57, 0x96, 0x6d, 0x6a, 0x9e, 0x9d, 0xe5, 0xb9,
0xc7, 0x94, 0x0b, 0xd4, 0x62, 0xa5, 0xf4, 0x47, 0xe7, 0x7f, 0x9b, 0xb5, 0xf3, 0x99, 0x69, 0xbc,
0x9a, 0x99, 0xc6, 0x5f, 0x33, 0xd3, 0x78, 0x79, 0x69, 0xd6, 0x5e, 0x5d, 0x9a, 0xb5, 0x3f, 0x2e,
0xcd, 0xda, 0x77, 0x1f, 0xfb, 0x54, 0x1c, 0xa7, 0x8e, 0xe5, 0xc6, 0xe1, 0x48, 0x4a, 0xf8, 0x24,
0xc0, 0x0e, 0x57, 0xa3, 0xd1, 0x69, 0xe1, 0x0d, 0x27, 0x1f, 0x2a, 0xdc, 0x69, 0xa8, 0x77, 0xc6,
0xa7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x85, 0x46, 0xc8, 0xc0, 0x7c, 0x0a, 0x00, 0x00,
// 785 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x4f, 0xdb, 0x48,
0x14, 0xc7, 0x63, 0x60, 0x59, 0x98, 0x00, 0x21, 0xb3, 0x01, 0xb2, 0x41, 0x72, 0x58, 0x40, 0xbb,
0xd1, 0x56, 0xb5, 0x45, 0x7a, 0xed, 0xa5, 0x2e, 0x55, 0x8b, 0x54, 0x24, 0xe4, 0x50, 0x54, 0x55,
0x95, 0xa2, 0x71, 0x3c, 0x98, 0x69, 0xfd, 0xab, 0x1e, 0x3b, 0x21, 0xb7, 0x1e, 0x7b, 0xe4, 0x0f,
0xa8, 0xd4, 0x7b, 0xff, 0x8f, 0x4a, 0x1c, 0x39, 0xf6, 0x04, 0x6d, 0xf8, 0x47, 0xaa, 0x19, 0x8f,
0x83, 0x9d, 0x60, 0xaa, 0xa6, 0xb7, 0xc9, 0x9b, 0x37, 0xdf, 0xcf, 0xf7, 0xcd, 0x7b, 0x13, 0x83,
0xed, 0xb7, 0xa8, 0x8b, 0x54, 0xe2, 0x76, 0xb0, 0x1b, 0x92, 0x2e, 0x56, 0xbb, 0x3b, 0x06, 0x0e,
0xd1, 0x8e, 0x6a, 0x61, 0x17, 0x53, 0x42, 0x15, 0x3f, 0xf0, 0x42, 0x0f, 0xae, 0xb2, 0x2c, 0x65,
0x98, 0xa5, 0x88, 0xac, 0x5a, 0xc5, 0xf2, 0x2c, 0x8f, 0xa7, 0xa8, 0x6c, 0x15, 0x67, 0xd7, 0xea,
0x96, 0xe7, 0x59, 0x36, 0x56, 0xf9, 0x2f, 0x23, 0x3a, 0x56, 0x43, 0xe2, 0x60, 0x1a, 0x22, 0xc7,
0x17, 0x09, 0x5b, 0x39, 0xd0, 0x8e, 0x8d, 0x88, 0x43, 0x7f, 0x92, 0xe4, 0xa3, 0x00, 0x25, 0x49,
0x9b, 0x9f, 0x24, 0xb0, 0xfc, 0xa8, 0xd3, 0x89, 0x9c, 0xc8, 0x46, 0x21, 0xf1, 0xdc, 0x43, 0xe2,
0x60, 0xf8, 0x1f, 0x28, 0x75, 0x3c, 0xdb, 0x46, 0x21, 0x0e, 0x90, 0xdd, 0x0e, 0xfb, 0x3e, 0xae,
0x4a, 0x1b, 0x52, 0x63, 0x5e, 0x5f, 0xba, 0x09, 0x1f, 0xf6, 0x7d, 0x0c, 0x0d, 0x50, 0xf3, 0x03,
0xdc, 0x25, 0x5e, 0x44, 0xdb, 0x28, 0xa5, 0xd2, 0x66, 0x86, 0xab, 0x53, 0x1b, 0x52, 0xa3, 0xd8,
0xac, 0x29, 0x71, 0x35, 0x4a, 0x52, 0x8d, 0x72, 0x98, 0x54, 0xa3, 0xcd, 0x9d, 0x5f, 0xd6, 0x0b,
0x67, 0x57, 0x75, 0x49, 0xaf, 0x26, 0x3a, 0xa3, 0x66, 0x36, 0xdf, 0x4f, 0x01, 0xf8, 0x34, 0xbe,
0x4c, 0x1d, 0xf7, 0x50, 0x60, 0xb6, 0x42, 0x14, 0x62, 0x18, 0x00, 0x38, 0x46, 0xa4, 0x55, 0x69,
0x63, 0xba, 0x51, 0x6c, 0x36, 0x94, 0xdb, 0xaf, 0x5b, 0x19, 0x15, 0xd7, 0xfe, 0x66, 0x06, 0x3e,
0x5f, 0xd5, 0xcb, 0xa3, 0x3b, 0x54, 0x2f, 0xa3, 0xd1, 0x10, 0xec, 0x82, 0x8a, 0x13, 0xd9, 0x21,
0x69, 0x07, 0xdc, 0x48, 0x9b, 0xb8, 0x26, 0x3e, 0xc5, 0xb4, 0x3a, 0x75, 0x37, 0x75, 0x9f, 0x9d,
0x89, 0xbd, 0xef, 0xb1, 0x13, 0x5a, 0x4d, 0x50, 0xe1, 0xe8, 0x0e, 0xa6, 0x3a, 0x74, 0xc6, 0x62,
0x9b, 0x5f, 0x8a, 0x60, 0x41, 0x5c, 0x41, 0x5c, 0xfc, 0x43, 0x30, 0x1b, 0x77, 0x91, 0xf7, 0xa5,
0xd8, 0x94, 0xf3, 0xd0, 0x07, 0x3c, 0x4b, 0x9b, 0x61, 0x40, 0x5d, 0x9c, 0x81, 0x1e, 0x28, 0x47,
0xd4, 0x3c, 0x4d, 0xaa, 0xa0, 0x4c, 0x52, 0x34, 0xeb, 0xff, 0x3c, 0xa1, 0xf1, 0x0e, 0x68, 0x6b,
0x4c, 0x74, 0x70, 0x59, 0x2f, 0xbd, 0x68, 0xed, 0xbe, 0x4c, 0x6d, 0xe8, 0x25, 0xa6, 0x9e, 0xee,
0x15, 0x01, 0xd5, 0x13, 0x4e, 0x8a, 0x7c, 0xdf, 0xee, 0x67, 0xb9, 0xd3, 0xbf, 0xcc, 0x8d, 0x8b,
0x59, 0x61, 0x8a, 0x2d, 0x2e, 0x78, 0x1b, 0xca, 0xf0, 0x82, 0xc0, 0xeb, 0x65, 0x51, 0x33, 0xbf,
0x83, 0xd2, 0xb8, 0x60, 0x1a, 0x75, 0x0c, 0x56, 0x4d, 0x6c, 0x63, 0x0b, 0x85, 0x5e, 0x90, 0x05,
0xfd, 0x31, 0x21, 0xa8, 0x32, 0xd4, 0x4b, 0x73, 0x5e, 0x83, 0x32, 0xed, 0x21, 0x3f, 0x8b, 0x98,
0x9d, 0x10, 0x51, 0x62, 0x52, 0x69, 0xf5, 0x0f, 0x12, 0xf8, 0x8b, 0x4f, 0x83, 0x43, 0xdc, 0x90,
0xb8, 0x56, 0x3b, 0xfe, 0x0f, 0xa9, 0xfe, 0x79, 0xf7, 0x4c, 0xb3, 0x9e, 0xef, 0xc7, 0x27, 0x1e,
0xb3, 0x03, 0x9a, 0x22, 0xa6, 0xa1, 0x3c, 0xba, 0x43, 0xd9, 0xf3, 0x1a, 0x0b, 0xea, 0x7c, 0x04,
0x33, 0x21, 0xf8, 0x51, 0x02, 0x32, 0x6f, 0x9e, 0x4d, 0xde, 0x45, 0xc4, 0x24, 0x61, 0xbf, 0xed,
0x07, 0x5e, 0x97, 0x98, 0x38, 0x48, 0x5c, 0xcd, 0x71, 0x57, 0xcd, 0x3c, 0x57, 0xcf, 0x50, 0x60,
0x3e, 0x4f, 0x0e, 0x1f, 0x88, 0xb3, 0xb1, 0xbf, 0x2d, 0xf1, 0xe6, 0xd6, 0xf3, 0x73, 0xa8, 0xbe,
0x7e, 0x92, 0xbf, 0x09, 0xdf, 0x80, 0xe5, 0x9b, 0x7e, 0x0b, 0x3f, 0xf3, 0xdc, 0xcf, 0xbf, 0x79,
0x7e, 0x76, 0x93, 0xfc, 0xd8, 0xc3, 0x9a, 0xf0, 0x50, 0xca, 0xc6, 0xa9, 0x5e, 0x32, 0xb3, 0x01,
0x78, 0x04, 0x8a, 0xbc, 0xe7, 0x02, 0x03, 0x38, 0xe6, 0x9f, 0x3c, 0x4c, 0xab, 0x87, 0xfc, 0x98,
0x00, 0x05, 0x01, 0x0c, 0x43, 0x54, 0x07, 0x74, 0xb8, 0x86, 0x06, 0xa8, 0x50, 0xd4, 0x25, 0xae,
0x45, 0xb3, 0xe3, 0x54, 0x9c, 0x70, 0x9c, 0xa0, 0x50, 0x4b, 0x4f, 0x94, 0x01, 0x96, 0x12, 0x86,
0xb0, 0xbf, 0xc0, 0xed, 0x6f, 0xe7, 0xda, 0x8f, 0xb3, 0xe3, 0x0a, 0x56, 0x44, 0x05, 0x8b, 0xe9,
0x28, 0xd5, 0x17, 0x69, 0xfa, 0x27, 0x7b, 0x13, 0x18, 0x05, 0x6e, 0xb6, 0x88, 0xc5, 0x49, 0xdf,
0x04, 0x93, 0x4a, 0x57, 0x70, 0x04, 0x8a, 0x5c, 0x5d, 0xd8, 0x5f, 0xba, 0xfb, 0xf6, 0x9f, 0xa0,
0xc0, 0x1d, 0xb9, 0xfd, 0x61, 0x88, 0xea, 0x00, 0x0f, 0xd7, 0xda, 0xde, 0xf9, 0x77, 0xb9, 0x70,
0x3e, 0x90, 0xa5, 0x8b, 0x81, 0x2c, 0x7d, 0x1b, 0xc8, 0xd2, 0xd9, 0xb5, 0x5c, 0xb8, 0xb8, 0x96,
0x0b, 0x5f, 0xaf, 0xe5, 0xc2, 0xab, 0x7b, 0x16, 0x09, 0x4f, 0x22, 0x43, 0xe9, 0x78, 0x8e, 0xca,
0x50, 0xf7, 0x6d, 0x64, 0x50, 0xbe, 0x52, 0x4f, 0x53, 0x9f, 0x71, 0xf6, 0x39, 0xa6, 0xc6, 0x2c,
0xff, 0x9a, 0x3e, 0xf8, 0x11, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xa8, 0x1c, 0xb0, 0x7f, 0x08, 0x00,
0x00,
}
func (m *AccumulationTime) Marshal() (dAtA []byte, err error) {
@ -313,49 +258,6 @@ func (m *AccumulationTime) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *AccrualTime) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *AccrualTime) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *AccrualTime) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousAccumulationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousAccumulationTime):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintGenesis(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x1a
if len(m.CollateralType) > 0 {
i -= len(m.CollateralType)
copy(dAtA[i:], m.CollateralType)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.CollateralType)))
i--
dAtA[i] = 0x12
}
if m.ClaimType != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.ClaimType))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *GenesisRewardState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -427,52 +329,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.RewardIndexes) > 0 {
for iNdEx := len(m.RewardIndexes) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.RewardIndexes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x8a
}
}
if len(m.AccrualTimes) > 0 {
for iNdEx := len(m.AccrualTimes) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.AccrualTimes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x82
}
}
if len(m.Claims) > 0 {
for iNdEx := len(m.Claims) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Claims[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x7a
}
}
if len(m.EarnClaims) > 0 {
for iNdEx := len(m.EarnClaims) - 1; iNdEx >= 0; iNdEx-- {
{
@ -666,24 +522,6 @@ func (m *AccumulationTime) Size() (n int) {
return n
}
func (m *AccrualTime) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ClaimType != 0 {
n += 1 + sovGenesis(uint64(m.ClaimType))
}
l = len(m.CollateralType)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousAccumulationTime)
n += 1 + l + sovGenesis(uint64(l))
return n
}
func (m *GenesisRewardState) Size() (n int) {
if m == nil {
return 0
@ -763,24 +601,6 @@ func (m *GenesisState) Size() (n int) {
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.Claims) > 0 {
for _, e := range m.Claims {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.AccrualTimes) > 0 {
for _, e := range m.AccrualTimes {
l = e.Size()
n += 2 + l + sovGenesis(uint64(l))
}
}
if len(m.RewardIndexes) > 0 {
for _, e := range m.RewardIndexes {
l = e.Size()
n += 2 + l + sovGenesis(uint64(l))
}
}
return n
}
@ -905,140 +725,6 @@ func (m *AccumulationTime) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *AccrualTime) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: AccrualTime: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: AccrualTime: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType)
}
m.ClaimType = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClaimType |= ClaimType(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CollateralType", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.CollateralType = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PreviousAccumulationTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.PreviousAccumulationTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GenesisRewardState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -1654,108 +1340,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 15:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Claims", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Claims = append(m.Claims, Claim{})
if err := m.Claims[len(m.Claims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 16:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AccrualTimes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AccrualTimes = append(m.AccrualTimes, AccrualTime{})
if err := m.AccrualTimes[len(m.AccrualTimes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 17:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RewardIndexes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RewardIndexes = append(m.RewardIndexes, TypedRewardIndexes{})
if err := m.RewardIndexes[len(m.RewardIndexes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])

View File

@ -1,6 +1,7 @@
package types
import (
"strings"
"testing"
"time"
@ -56,7 +57,6 @@ func TestGenesisState_Validate(t *testing.T) {
},
},
time.Date(2025, 10, 15, 14, 0, 0, 0, time.UTC),
DefaultTypedMultiRewardPeriods,
),
USDXRewardState: GenesisRewardState{
AccumulationTimes: AccumulationTimes{{
@ -68,17 +68,16 @@ func TestGenesisState_Validate(t *testing.T) {
RewardIndexes: normalRewardIndexes,
}},
},
Claims: Claims{
USDXMintingClaims: USDXMintingClaims{
{
Type: CLAIM_TYPE_USDX_MINTING,
Owner: sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))),
Reward: cs(c("ukava", 100000000)),
RewardIndexes: []MultiRewardIndex{
BaseClaim: BaseClaim{
Owner: sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1"))),
Reward: sdk.NewCoin("ukava", sdk.NewInt(100000000)),
},
RewardIndexes: []RewardIndex{
{
CollateralType: "bnb-a",
RewardIndexes: RewardIndexes{
NewRewardIndex(USDXMintingRewardDenom, sdk.ZeroDec()),
},
RewardFactor: sdk.ZeroDec(),
},
},
},
@ -102,7 +101,7 @@ func TestGenesisState_Validate(t *testing.T) {
RewardIndexes: normalRewardIndexes,
}},
},
Claims: DefaultClaims,
USDXMintingClaims: DefaultUSDXClaims,
},
errArgs: errArgs{
expectPass: false,
@ -114,17 +113,16 @@ func TestGenesisState_Validate(t *testing.T) {
genesis: GenesisState{
Params: DefaultParams(),
USDXRewardState: DefaultGenesisRewardState,
Claims: Claims{
USDXMintingClaims: USDXMintingClaims{
{
Type: CLAIM_TYPE_USDX_MINTING,
Owner: nil, // invalid address
Reward: cs(c("ukava", 100000000)),
RewardIndexes: []MultiRewardIndex{
BaseClaim: BaseClaim{
Owner: nil, // invalid address
Reward: sdk.NewCoin("ukava", sdk.NewInt(100000000)),
},
RewardIndexes: []RewardIndex{
{
CollateralType: "bnb-a",
RewardIndexes: RewardIndexes{
NewRewardIndex(USDXMintingRewardDenom, sdk.ZeroDec()),
},
RewardFactor: sdk.ZeroDec(),
},
},
},
@ -135,20 +133,6 @@ func TestGenesisState_Validate(t *testing.T) {
contains: "claim owner cannot be empty",
},
},
{
name: "invalid accrual time",
genesis: GenesisState{
Params: DefaultParams(),
Claims: DefaultClaims,
AccrualTimes: AccrualTimes{
NewAccrualTime(CLAIM_TYPE_USDX_MINTING, "", time.Date(2020, 10, 15, 14, 0, 0, 0, time.UTC)),
},
},
errArgs: errArgs{
expectPass: false,
contains: "collateral type cannot be empty",
},
},
}
for _, tc := range testCases {
@ -158,7 +142,7 @@ func TestGenesisState_Validate(t *testing.T) {
require.NoError(t, err, tc.name)
} else {
require.Error(t, err, tc.name)
require.Contains(t, err.Error(), tc.errArgs.contains)
require.True(t, strings.Contains(err.Error(), tc.errArgs.contains))
}
})
}
@ -203,76 +187,4 @@ func TestGenesisAccumulationTimes_Validate(t *testing.T) {
}
}
func TestAccrualTimes_Validate(t *testing.T) {
testCases := []struct {
name string
gats AccrualTimes
wantErr bool
}{
{
name: "normal",
gats: AccrualTimes{
{
ClaimType: CLAIM_TYPE_USDX_MINTING,
CollateralType: "btcb",
PreviousAccumulationTime: normalAccumulationtime,
},
{
ClaimType: CLAIM_TYPE_USDX_MINTING,
CollateralType: "bnb",
PreviousAccumulationTime: normalAccumulationtime,
},
},
wantErr: false,
},
{
name: "empty",
gats: nil,
wantErr: false,
},
{
name: "empty collateral type",
gats: AccrualTimes{
{
ClaimType: CLAIM_TYPE_USDX_MINTING,
PreviousAccumulationTime: normalAccumulationtime,
},
},
wantErr: true,
},
{
name: "invalid claim type",
gats: AccrualTimes{
{
ClaimType: 10000000,
CollateralType: "btcb",
PreviousAccumulationTime: normalAccumulationtime,
},
},
wantErr: true,
},
{
name: "unspecified claim type",
gats: AccrualTimes{
{
ClaimType: CLAIM_TYPE_UNSPECIFIED,
CollateralType: "btcb",
PreviousAccumulationTime: normalAccumulationtime,
},
},
wantErr: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.gats.Validate()
if tc.wantErr {
require.NotNil(t, err)
} else {
require.Nil(t, err)
}
})
}
}
var normalAccumulationtime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)

View File

@ -1,9 +1,5 @@
package types
import (
"encoding/binary"
)
const (
// ModuleName The name that will be used throughout the module
ModuleName = "incentive"
@ -44,47 +40,3 @@ var (
EarnRewardIndexesKeyPrefix = []byte{0x19} // prefix for key that stores earn reward indexes
PreviousEarnRewardAccrualTimeKeyPrefix = []byte{0x20} // prefix for key that stores the previous time earn rewards accrued
)
var (
ClaimKeyPrefix = []byte{0x21}
RewardIndexesKeyPrefix = []byte{0x22}
PreviousRewardAccrualTimeKeyPrefix = []byte{0x23}
)
var sep = []byte("|")
func createKey(bytes ...[]byte) (r []byte) {
for _, b := range bytes {
r = append(r, b...)
}
return
}
func getKeyPrefix(dataTypePrefix []byte, claimType ClaimType) []byte {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, uint32(claimType))
return createKey(dataTypePrefix, sep, b)
}
// GetClaimKeyPrefix returns the claim store key prefix for the given ClaimType.
func GetClaimKeyPrefix(claimType ClaimType) []byte {
return getKeyPrefix(ClaimKeyPrefix, claimType)
}
// GetRewardIndexesKeyPrefix returns the reward indexes key prefix for the given
// ClaimType.
func GetRewardIndexesKeyPrefix(claimType ClaimType) []byte {
return getKeyPrefix(RewardIndexesKeyPrefix, claimType)
}
// GetPreviousRewardAccrualTimeKeyPrefix returns the previous reward accrual time
// key prefix for the given ClaimType.
func GetPreviousRewardAccrualTimeKeyPrefix(claimType ClaimType) []byte {
return getKeyPrefix(PreviousRewardAccrualTimeKeyPrefix, claimType)
}
// GetKeyFromSourceID returns the store key for the given source ID.
func GetKeyFromSourceID(sourceID string) []byte {
return []byte(sourceID)
}

View File

@ -24,14 +24,12 @@ var (
KeyEarnRewardPeriods = []byte("EarnRewardPeriods")
KeyClaimEnd = []byte("ClaimEnd")
KeyMultipliers = []byte("ClaimMultipliers")
KeyTypedMultiRewardPeriods = []byte("TypedMultiRewardPeriods")
DefaultActive = false
DefaultRewardPeriods = RewardPeriods{}
DefaultMultiRewardPeriods = MultiRewardPeriods{}
DefaultMultipliers = MultipliersPerDenoms{}
DefaultTypedMultiRewardPeriods = TypedMultiRewardPeriods{}
DefaultClaimEnd = tmtime.Canonical(time.Unix(1, 0))
DefaultActive = false
DefaultRewardPeriods = RewardPeriods{}
DefaultMultiRewardPeriods = MultiRewardPeriods{}
DefaultMultipliers = MultipliersPerDenoms{}
DefaultClaimEnd = tmtime.Canonical(time.Unix(1, 0))
BondDenom = "ukava"
USDXMintingRewardDenom = "ukava"
@ -46,7 +44,6 @@ func NewParams(
hardSupply, hardBorrow, delegator, swap, savings, earn MultiRewardPeriods,
multipliers MultipliersPerDenoms,
claimEnd time.Time,
rewardPeriods TypedMultiRewardPeriods,
) Params {
return Params{
USDXMintingRewardPeriods: usdxMinting,
@ -55,10 +52,8 @@ func NewParams(
DelegatorRewardPeriods: delegator,
SwapRewardPeriods: swap,
SavingsRewardPeriods: savings,
EarnRewardPeriods: earn,
ClaimMultipliers: multipliers,
ClaimEnd: claimEnd,
RewardPeriods: rewardPeriods,
}
}
@ -74,7 +69,6 @@ func DefaultParams() Params {
DefaultMultiRewardPeriods,
DefaultMultipliers,
DefaultClaimEnd,
DefaultTypedMultiRewardPeriods,
)
}
@ -95,7 +89,6 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(KeyEarnRewardPeriods, &p.EarnRewardPeriods, validateMultiRewardPeriodsParam),
paramtypes.NewParamSetPair(KeyMultipliers, &p.ClaimMultipliers, validateMultipliersPerDenomParam),
paramtypes.NewParamSetPair(KeyClaimEnd, &p.ClaimEnd, validateClaimEndParam),
paramtypes.NewParamSetPair(KeyTypedMultiRewardPeriods, &p.RewardPeriods, validatedRewardPeriodsParam),
}
}
@ -133,10 +126,6 @@ func (p Params) Validate() error {
return err
}
if err := validatedRewardPeriodsParam(p.RewardPeriods); err != nil {
return err
}
return nil
}
@ -177,15 +166,6 @@ func validateClaimEndParam(i interface{}) error {
return nil
}
func validatedRewardPeriodsParam(i interface{}) error {
periods, ok := i.(TypedMultiRewardPeriods)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return periods.Validate()
}
// NewRewardPeriod returns a new RewardPeriod
func NewRewardPeriod(active bool, collateralType string, start time.Time, end time.Time, reward sdk.Coin) RewardPeriod {
return RewardPeriod{
@ -326,45 +306,3 @@ func (mrps MultiRewardPeriods) Validate() error {
return nil
}
// NewTypedMultiRewardPeriod returns a new TypedMultiRewardPeriod
func NewTypedMultiRewardPeriod(claimType ClaimType, rewardPeriods MultiRewardPeriods) TypedMultiRewardPeriod {
return TypedMultiRewardPeriod{
ClaimType: claimType,
RewardPeriods: rewardPeriods,
}
}
// Validate performs a basic check of a TypedMultiRewardPeriod fields.
func (mrp TypedMultiRewardPeriod) Validate() error {
if err := mrp.ClaimType.Validate(); err != nil {
return fmt.Errorf("invalid claim type: %w", err)
}
if err := mrp.RewardPeriods.Validate(); err != nil {
return fmt.Errorf("invalid reward periods: %w", err)
}
return nil
}
// TypedMultiRewardPeriods array of TypedMultiRewardPeriod
type TypedMultiRewardPeriods []TypedMultiRewardPeriod
// Validate checks if all the TypedMultiRewardPeriods are valid and there
// are no duplicated entries.
func (mrps TypedMultiRewardPeriods) Validate() error {
seenClaimTypes := make(map[ClaimType]bool)
for _, mrp := range mrps {
if seenClaimTypes[mrp.ClaimType] {
return fmt.Errorf("duplicated reward period with claim type %s", mrp.ClaimType)
}
if err := mrp.Validate(); err != nil {
return fmt.Errorf("invalid reward period for claimType %s: %w", mrp.ClaimType, err)
}
seenClaimTypes[mrp.ClaimType] = true
}
return nil
}

View File

@ -113,47 +113,7 @@ func (m *MultiRewardPeriod) XXX_DiscardUnknown() {
var xxx_messageInfo_MultiRewardPeriod proto.InternalMessageInfo
// TypedMultiRewardPeriod stores mutiple reward types of a claim type
type TypedMultiRewardPeriod struct {
ClaimType ClaimType `protobuf:"varint,1,opt,name=claim_type,json=claimType,proto3,enum=kava.incentive.v1beta1.ClaimType" json:"claim_type,omitempty"`
RewardPeriods MultiRewardPeriods `protobuf:"bytes,2,rep,name=reward_periods,json=rewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"reward_periods"`
}
func (m *TypedMultiRewardPeriod) Reset() { *m = TypedMultiRewardPeriod{} }
func (m *TypedMultiRewardPeriod) String() string { return proto.CompactTextString(m) }
func (*TypedMultiRewardPeriod) ProtoMessage() {}
func (*TypedMultiRewardPeriod) Descriptor() ([]byte, []int) {
return fileDescriptor_bb8833f5d745eac9, []int{2}
}
func (m *TypedMultiRewardPeriod) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TypedMultiRewardPeriod) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TypedMultiRewardPeriod.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TypedMultiRewardPeriod) XXX_Merge(src proto.Message) {
xxx_messageInfo_TypedMultiRewardPeriod.Merge(m, src)
}
func (m *TypedMultiRewardPeriod) XXX_Size() int {
return m.Size()
}
func (m *TypedMultiRewardPeriod) XXX_DiscardUnknown() {
xxx_messageInfo_TypedMultiRewardPeriod.DiscardUnknown(m)
}
var xxx_messageInfo_TypedMultiRewardPeriod proto.InternalMessageInfo
// Multiplier amount the claim rewards get increased by, along with how long the
// claim rewards are locked
// Multiplier amount the claim rewards get increased by, along with how long the claim rewards are locked
type Multiplier struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
MonthsLockup int64 `protobuf:"varint,2,opt,name=months_lockup,json=monthsLockup,proto3" json:"months_lockup,omitempty"`
@ -164,7 +124,7 @@ func (m *Multiplier) Reset() { *m = Multiplier{} }
func (m *Multiplier) String() string { return proto.CompactTextString(m) }
func (*Multiplier) ProtoMessage() {}
func (*Multiplier) Descriptor() ([]byte, []int) {
return fileDescriptor_bb8833f5d745eac9, []int{3}
return fileDescriptor_bb8833f5d745eac9, []int{2}
}
func (m *Multiplier) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -203,7 +163,7 @@ func (m *MultipliersPerDenom) Reset() { *m = MultipliersPerDenom{} }
func (m *MultipliersPerDenom) String() string { return proto.CompactTextString(m) }
func (*MultipliersPerDenom) ProtoMessage() {}
func (*MultipliersPerDenom) Descriptor() ([]byte, []int) {
return fileDescriptor_bb8833f5d745eac9, []int{4}
return fileDescriptor_bb8833f5d745eac9, []int{3}
}
func (m *MultipliersPerDenom) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -234,23 +194,22 @@ var xxx_messageInfo_MultipliersPerDenom proto.InternalMessageInfo
// Params
type Params struct {
USDXMintingRewardPeriods RewardPeriods `protobuf:"bytes,1,rep,name=usdx_minting_reward_periods,json=usdxMintingRewardPeriods,proto3,castrepeated=RewardPeriods" json:"usdx_minting_reward_periods"`
HardSupplyRewardPeriods MultiRewardPeriods `protobuf:"bytes,2,rep,name=hard_supply_reward_periods,json=hardSupplyRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"hard_supply_reward_periods"`
HardBorrowRewardPeriods MultiRewardPeriods `protobuf:"bytes,3,rep,name=hard_borrow_reward_periods,json=hardBorrowRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"hard_borrow_reward_periods"`
DelegatorRewardPeriods MultiRewardPeriods `protobuf:"bytes,4,rep,name=delegator_reward_periods,json=delegatorRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"delegator_reward_periods"`
SwapRewardPeriods MultiRewardPeriods `protobuf:"bytes,5,rep,name=swap_reward_periods,json=swapRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"swap_reward_periods"`
ClaimMultipliers MultipliersPerDenoms `protobuf:"bytes,6,rep,name=claim_multipliers,json=claimMultipliers,proto3,castrepeated=MultipliersPerDenoms" json:"claim_multipliers"`
ClaimEnd time.Time `protobuf:"bytes,7,opt,name=claim_end,json=claimEnd,proto3,stdtime" json:"claim_end"`
SavingsRewardPeriods MultiRewardPeriods `protobuf:"bytes,8,rep,name=savings_reward_periods,json=savingsRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"savings_reward_periods"`
EarnRewardPeriods MultiRewardPeriods `protobuf:"bytes,9,rep,name=earn_reward_periods,json=earnRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"earn_reward_periods"`
RewardPeriods TypedMultiRewardPeriods `protobuf:"bytes,10,rep,name=reward_periods,json=rewardPeriods,proto3,castrepeated=TypedMultiRewardPeriods" json:"reward_periods"`
USDXMintingRewardPeriods RewardPeriods `protobuf:"bytes,1,rep,name=usdx_minting_reward_periods,json=usdxMintingRewardPeriods,proto3,castrepeated=RewardPeriods" json:"usdx_minting_reward_periods"`
HardSupplyRewardPeriods MultiRewardPeriods `protobuf:"bytes,2,rep,name=hard_supply_reward_periods,json=hardSupplyRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"hard_supply_reward_periods"`
HardBorrowRewardPeriods MultiRewardPeriods `protobuf:"bytes,3,rep,name=hard_borrow_reward_periods,json=hardBorrowRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"hard_borrow_reward_periods"`
DelegatorRewardPeriods MultiRewardPeriods `protobuf:"bytes,4,rep,name=delegator_reward_periods,json=delegatorRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"delegator_reward_periods"`
SwapRewardPeriods MultiRewardPeriods `protobuf:"bytes,5,rep,name=swap_reward_periods,json=swapRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"swap_reward_periods"`
ClaimMultipliers MultipliersPerDenoms `protobuf:"bytes,6,rep,name=claim_multipliers,json=claimMultipliers,proto3,castrepeated=MultipliersPerDenoms" json:"claim_multipliers"`
ClaimEnd time.Time `protobuf:"bytes,7,opt,name=claim_end,json=claimEnd,proto3,stdtime" json:"claim_end"`
SavingsRewardPeriods MultiRewardPeriods `protobuf:"bytes,8,rep,name=savings_reward_periods,json=savingsRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"savings_reward_periods"`
EarnRewardPeriods MultiRewardPeriods `protobuf:"bytes,9,rep,name=earn_reward_periods,json=earnRewardPeriods,proto3,castrepeated=MultiRewardPeriods" json:"earn_reward_periods"`
}
func (m *Params) Reset() { *m = Params{} }
func (m *Params) String() string { return proto.CompactTextString(m) }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_bb8833f5d745eac9, []int{5}
return fileDescriptor_bb8833f5d745eac9, []int{4}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -282,7 +241,6 @@ var xxx_messageInfo_Params proto.InternalMessageInfo
func init() {
proto.RegisterType((*RewardPeriod)(nil), "kava.incentive.v1beta1.RewardPeriod")
proto.RegisterType((*MultiRewardPeriod)(nil), "kava.incentive.v1beta1.MultiRewardPeriod")
proto.RegisterType((*TypedMultiRewardPeriod)(nil), "kava.incentive.v1beta1.TypedMultiRewardPeriod")
proto.RegisterType((*Multiplier)(nil), "kava.incentive.v1beta1.Multiplier")
proto.RegisterType((*MultipliersPerDenom)(nil), "kava.incentive.v1beta1.MultipliersPerDenom")
proto.RegisterType((*Params)(nil), "kava.incentive.v1beta1.Params")
@ -293,60 +251,56 @@ func init() {
}
var fileDescriptor_bb8833f5d745eac9 = []byte{
// 844 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0xeb, 0x44,
0x14, 0x8e, 0xf3, 0x47, 0x32, 0xfd, 0xa1, 0x9d, 0x46, 0xa9, 0x09, 0xc8, 0x2e, 0x29, 0x82, 0xa0,
0xaa, 0x36, 0x2d, 0x12, 0x0b, 0x56, 0xe0, 0x16, 0x24, 0x24, 0x2a, 0x55, 0x6e, 0x91, 0x80, 0x8d,
0x35, 0xb1, 0xa7, 0xae, 0x55, 0xdb, 0x63, 0xcd, 0x38, 0x69, 0x23, 0x16, 0x48, 0x2c, 0xd8, 0x21,
0x55, 0x2c, 0x78, 0x88, 0xbe, 0x06, 0x9b, 0x88, 0x55, 0x97, 0x88, 0x45, 0xcb, 0x4d, 0x5f, 0xe4,
0x6a, 0xc6, 0x4e, 0x93, 0x38, 0x49, 0xef, 0xad, 0x94, 0xbb, 0xb8, 0xab, 0x9c, 0x99, 0x39, 0xe7,
0x7c, 0xdf, 0xf9, 0xce, 0xcc, 0x89, 0xc1, 0xf6, 0x05, 0xea, 0x22, 0xdd, 0x0b, 0x6d, 0x1c, 0xc6,
0x5e, 0x17, 0xeb, 0xdd, 0xbd, 0x36, 0x8e, 0xd1, 0x9e, 0x1e, 0x21, 0x8a, 0x02, 0xa6, 0x45, 0x94,
0xc4, 0x04, 0xd6, 0xb9, 0x93, 0xf6, 0xe8, 0xa4, 0xa5, 0x4e, 0x0d, 0xc5, 0x26, 0x2c, 0x20, 0x4c,
0x6f, 0x23, 0x36, 0x8a, 0xb4, 0x89, 0x17, 0x26, 0x71, 0x8d, 0x9a, 0x4b, 0x5c, 0x22, 0x4c, 0x9d,
0x5b, 0xe9, 0xae, 0xea, 0x12, 0xe2, 0xfa, 0x58, 0x17, 0xab, 0x76, 0xe7, 0x4c, 0x8f, 0xbd, 0x00,
0xb3, 0x18, 0x05, 0x51, 0xea, 0x30, 0x8f, 0x93, 0xed, 0x23, 0x6f, 0xc8, 0xa9, 0xf9, 0x67, 0x1e,
0x2c, 0x9b, 0xf8, 0x12, 0x51, 0xe7, 0x18, 0x53, 0x8f, 0x38, 0xb0, 0x0e, 0xca, 0xc8, 0xe6, 0xfe,
0xb2, 0xb4, 0x25, 0xb5, 0x2a, 0x66, 0xba, 0x82, 0x9f, 0x80, 0x77, 0x6d, 0xe2, 0xfb, 0x28, 0xc6,
0x14, 0xf9, 0x56, 0xdc, 0x8b, 0xb0, 0x9c, 0xdf, 0x92, 0x5a, 0x55, 0x73, 0x75, 0xb4, 0x7d, 0xda,
0x8b, 0x30, 0xfc, 0x12, 0x94, 0x58, 0x8c, 0x68, 0x2c, 0x17, 0xb6, 0xa4, 0xd6, 0xd2, 0x7e, 0x43,
0x4b, 0x78, 0x6a, 0x43, 0x9e, 0xda, 0xe9, 0x90, 0xa7, 0x51, 0xe9, 0xdf, 0xa9, 0xb9, 0xeb, 0x7b,
0x55, 0x32, 0x93, 0x10, 0xf8, 0x05, 0x28, 0xe0, 0xd0, 0x91, 0x8b, 0xcf, 0x88, 0xe4, 0x01, 0xf0,
0x08, 0x40, 0x2a, 0x8a, 0x60, 0x56, 0x84, 0xa9, 0xc5, 0xb0, 0x4d, 0x42, 0x47, 0x2e, 0x89, 0x34,
0xef, 0x69, 0x89, 0xbc, 0x1a, 0x97, 0x77, 0xa8, 0xb9, 0x76, 0x40, 0xbc, 0xd0, 0x28, 0xf2, 0x2c,
0xe6, 0x5a, 0x1a, 0x7a, 0x8c, 0xe9, 0x89, 0x08, 0x6c, 0xfe, 0x9d, 0x07, 0xeb, 0x47, 0x1d, 0x3f,
0xf6, 0xde, 0x7e, 0x65, 0x7a, 0x73, 0x94, 0x29, 0x3c, 0xad, 0xcc, 0x67, 0x3c, 0xcb, 0xcd, 0xbd,
0xda, 0x72, 0xbd, 0xf8, 0xbc, 0xd3, 0xd6, 0x6c, 0x12, 0xe8, 0xe9, 0x2d, 0x4d, 0x7e, 0x76, 0x99,
0x73, 0xa1, 0xf3, 0x5a, 0x99, 0x08, 0x60, 0x33, 0x54, 0xec, 0x4b, 0xa0, 0xce, 0xeb, 0x76, 0xa6,
0xa5, 0xfc, 0x0a, 0x00, 0x71, 0x0b, 0x13, 0xb5, 0xb8, 0x9c, 0xab, 0xfb, 0x1f, 0x6a, 0xb3, 0x9f,
0x87, 0x76, 0xc0, 0x3d, 0x79, 0x22, 0xb3, 0x6a, 0x0f, 0x4d, 0xe8, 0x83, 0xd5, 0x04, 0x90, 0x97,
0xe5, 0x11, 0x87, 0xc9, 0x79, 0x51, 0xd3, 0xa7, 0xf3, 0xb2, 0x4c, 0x91, 0x30, 0x1a, 0x69, 0x8d,
0x70, 0xea, 0x88, 0x99, 0x2b, 0x74, 0x7c, 0xd9, 0xfc, 0x43, 0x02, 0x40, 0x78, 0x45, 0xbe, 0x87,
0x29, 0x84, 0xa0, 0x18, 0xa2, 0x20, 0x21, 0x5e, 0x35, 0x85, 0x0d, 0xb7, 0xc1, 0x4a, 0x40, 0xc2,
0xf8, 0x9c, 0x59, 0x3e, 0xb1, 0x2f, 0x3a, 0x91, 0xb8, 0x03, 0x05, 0x73, 0x39, 0xd9, 0xfc, 0x5e,
0xec, 0xc1, 0x6f, 0x41, 0xf9, 0x0c, 0xd9, 0x31, 0xa1, 0xe2, 0x0a, 0x2c, 0x1b, 0x1a, 0xa7, 0xf0,
0xdf, 0x9d, 0xfa, 0xf1, 0x6b, 0xc8, 0x7c, 0x88, 0x6d, 0x33, 0x8d, 0x6e, 0xfe, 0x2e, 0x81, 0x8d,
0x11, 0x1f, 0xae, 0xf9, 0x21, 0x0e, 0x49, 0x00, 0x6b, 0xa0, 0xe4, 0x70, 0x23, 0x65, 0x96, 0x2c,
0xe0, 0x4f, 0x60, 0x29, 0x18, 0x39, 0xa7, 0x42, 0x35, 0x9f, 0x14, 0x4a, 0xb8, 0x1a, 0x1b, 0xa9,
0x42, 0x4b, 0x63, 0x58, 0xe6, 0x78, 0xae, 0xe6, 0x3f, 0x55, 0x50, 0x3e, 0x16, 0x33, 0x0e, 0xfe,
0x25, 0x81, 0xf7, 0x3b, 0xcc, 0xb9, 0xb2, 0x02, 0x2f, 0x8c, 0xbd, 0xd0, 0xb5, 0x32, 0xfd, 0x91,
0x04, 0xec, 0x47, 0xf3, 0x60, 0x27, 0x5a, 0xb3, 0xc7, 0x81, 0x07, 0x77, 0xaa, 0xfc, 0xc3, 0xc9,
0xe1, 0x8f, 0x47, 0x49, 0xbe, 0x89, 0x06, 0xdd, 0xdc, 0xab, 0x2b, 0x93, 0x1d, 0x93, 0x39, 0xf6,
0x2c, 0x57, 0xf8, 0x9b, 0x04, 0x1a, 0xe7, 0x9c, 0x09, 0xeb, 0x44, 0x91, 0xdf, 0xb3, 0xde, 0xe4,
0xbd, 0xd9, 0xe4, 0x40, 0x27, 0x02, 0x67, 0x0e, 0x89, 0x36, 0xa1, 0x94, 0x5c, 0x66, 0x49, 0x14,
0x16, 0x4e, 0xc2, 0x10, 0x38, 0x93, 0x24, 0x7e, 0x05, 0xb2, 0x83, 0x7d, 0xec, 0xa2, 0x98, 0xd0,
0x2c, 0x83, 0xe2, 0x22, 0x19, 0xd4, 0x1f, 0x61, 0x26, 0x09, 0x74, 0xc0, 0x06, 0xbb, 0x44, 0x51,
0x16, 0xbb, 0xb4, 0x48, 0xec, 0x75, 0x8e, 0x30, 0x09, 0xdb, 0x05, 0xeb, 0xc9, 0xb8, 0x19, 0x7f,
0x06, 0x65, 0x01, 0xba, 0xf3, 0xea, 0x67, 0xf0, 0xf8, 0xbc, 0x8c, 0x0f, 0x52, 0xd8, 0xda, 0x8c,
0x43, 0x66, 0xae, 0x09, 0x8c, 0xb1, 0x23, 0xf8, 0x35, 0x48, 0x26, 0x96, 0xc5, 0x47, 0xf7, 0x3b,
0xcf, 0x18, 0xdd, 0x15, 0x11, 0xf6, 0x4d, 0xe8, 0xc0, 0x5f, 0x40, 0x9d, 0xa1, 0xae, 0x17, 0xba,
0x2c, 0x2b, 0x5a, 0x65, 0x91, 0xa2, 0xd5, 0x52, 0x90, 0xa9, 0x76, 0x61, 0x44, 0xc3, 0x2c, 0x72,
0x75, 0xa1, 0xed, 0xe2, 0x08, 0xd9, 0x76, 0x65, 0x67, 0x3b, 0x10, 0x88, 0xda, 0x3c, 0xc4, 0xd9,
0xff, 0x32, 0x86, 0x9a, 0xc2, 0x6e, 0xce, 0x3e, 0xcf, 0x4e, 0x79, 0xe3, 0xbb, 0xfe, 0x0b, 0x25,
0xd7, 0x1f, 0x28, 0xd2, 0xed, 0x40, 0x91, 0xfe, 0x1f, 0x28, 0xd2, 0xf5, 0x83, 0x92, 0xbb, 0x7d,
0x50, 0x72, 0xff, 0x3e, 0x28, 0xb9, 0x9f, 0x77, 0xc6, 0x66, 0x34, 0xe7, 0xb1, 0xeb, 0xa3, 0x36,
0x13, 0x96, 0x7e, 0x35, 0xf6, 0x95, 0x25, 0x86, 0x75, 0xbb, 0x2c, 0xda, 0xfb, 0xf9, 0xcb, 0x00,
0x00, 0x00, 0xff, 0xff, 0x4c, 0xba, 0x2a, 0x08, 0x18, 0x0a, 0x00, 0x00,
// 774 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x96, 0xcf, 0x6e, 0xd3, 0x4a,
0x14, 0xc6, 0xe3, 0xfc, 0xbb, 0xc9, 0xb4, 0xbd, 0xb7, 0x9d, 0x46, 0xb9, 0xbe, 0xb9, 0xc8, 0xa9,
0x52, 0x04, 0x41, 0x55, 0x6d, 0x0a, 0x12, 0x0b, 0x76, 0x98, 0x82, 0x84, 0x44, 0xa5, 0xca, 0x2d,
0x12, 0xb0, 0x89, 0x26, 0xf6, 0xd4, 0xb5, 0x6a, 0x7b, 0xac, 0x99, 0x49, 0xda, 0x88, 0x05, 0x12,
0x0b, 0x76, 0x48, 0x15, 0x0b, 0x1e, 0xa2, 0xaf, 0xc1, 0xa6, 0xcb, 0x8a, 0x15, 0x62, 0xd1, 0x42,
0xfa, 0x22, 0x68, 0xc6, 0x6e, 0xe3, 0xa4, 0x69, 0xa1, 0x52, 0x36, 0xac, 0x32, 0x3e, 0x73, 0xce,
0xf9, 0x7d, 0xfe, 0xc6, 0x67, 0x14, 0xb0, 0xb8, 0x83, 0xba, 0xc8, 0xf0, 0x42, 0x1b, 0x87, 0xdc,
0xeb, 0x62, 0xa3, 0xbb, 0xd2, 0xc6, 0x1c, 0xad, 0x18, 0x11, 0xa2, 0x28, 0x60, 0x7a, 0x44, 0x09,
0x27, 0xb0, 0x2a, 0x92, 0xf4, 0xf3, 0x24, 0x3d, 0x49, 0xaa, 0x69, 0x36, 0x61, 0x01, 0x61, 0x46,
0x1b, 0xb1, 0x41, 0xa5, 0x4d, 0xbc, 0x30, 0xae, 0xab, 0x55, 0x5c, 0xe2, 0x12, 0xb9, 0x34, 0xc4,
0x2a, 0x89, 0xd6, 0x5d, 0x42, 0x5c, 0x1f, 0x1b, 0xf2, 0xa9, 0xdd, 0xd9, 0x32, 0xb8, 0x17, 0x60,
0xc6, 0x51, 0x10, 0xc5, 0x09, 0x8d, 0x8f, 0x59, 0x30, 0x6d, 0xe1, 0x5d, 0x44, 0x9d, 0x75, 0x4c,
0x3d, 0xe2, 0xc0, 0x2a, 0x28, 0x22, 0x5b, 0x90, 0x55, 0x65, 0x41, 0x69, 0x96, 0xac, 0xe4, 0x09,
0xde, 0x06, 0xff, 0xd8, 0xc4, 0xf7, 0x11, 0xc7, 0x14, 0xf9, 0x2d, 0xde, 0x8b, 0xb0, 0x9a, 0x5d,
0x50, 0x9a, 0x65, 0xeb, 0xef, 0x41, 0x78, 0xb3, 0x17, 0x61, 0xf8, 0x10, 0x14, 0x18, 0x47, 0x94,
0xab, 0xb9, 0x05, 0xa5, 0x39, 0x75, 0xaf, 0xa6, 0xc7, 0x12, 0xf4, 0x33, 0x09, 0xfa, 0xe6, 0x99,
0x04, 0xb3, 0x74, 0x78, 0x5c, 0xcf, 0xec, 0x9f, 0xd4, 0x15, 0x2b, 0x2e, 0x81, 0x0f, 0x40, 0x0e,
0x87, 0x8e, 0x9a, 0xbf, 0x46, 0xa5, 0x28, 0x80, 0x6b, 0x00, 0x52, 0xf9, 0x12, 0xac, 0x15, 0x61,
0xda, 0x62, 0xd8, 0x26, 0xa1, 0xa3, 0x16, 0x64, 0x9b, 0xff, 0xf4, 0xd8, 0x39, 0x5d, 0x38, 0x77,
0x66, 0xa7, 0xfe, 0x98, 0x78, 0xa1, 0x99, 0x17, 0x5d, 0xac, 0xd9, 0xa4, 0x74, 0x1d, 0xd3, 0x0d,
0x59, 0xd8, 0xf8, 0x9c, 0x05, 0x73, 0x6b, 0x1d, 0x9f, 0x7b, 0x7f, 0xbe, 0x33, 0xbd, 0x4b, 0x9c,
0xc9, 0x5d, 0xed, 0xcc, 0x5d, 0xd1, 0xe5, 0xe0, 0xa4, 0xde, 0x74, 0x3d, 0xbe, 0xdd, 0x69, 0xeb,
0x36, 0x09, 0x8c, 0xe4, 0x03, 0x8c, 0x7f, 0x96, 0x99, 0xb3, 0x63, 0x88, 0x77, 0x65, 0xb2, 0x80,
0x8d, 0x71, 0xf1, 0x83, 0x02, 0x80, 0x74, 0x31, 0xf2, 0x3d, 0x4c, 0x21, 0x04, 0xf9, 0x10, 0x05,
0xb1, 0x79, 0x65, 0x4b, 0xae, 0xe1, 0x22, 0x98, 0x09, 0x48, 0xc8, 0xb7, 0x59, 0xcb, 0x27, 0xf6,
0x4e, 0x27, 0x92, 0xc6, 0xe5, 0xac, 0xe9, 0x38, 0xf8, 0x5c, 0xc6, 0xe0, 0x53, 0x50, 0xdc, 0x42,
0x36, 0x27, 0x54, 0xfa, 0x36, 0x6d, 0xea, 0x42, 0xdb, 0xb7, 0xe3, 0xfa, 0xad, 0xdf, 0xd0, 0xb6,
0x8a, 0x6d, 0x2b, 0xa9, 0x6e, 0xbc, 0x57, 0xc0, 0xfc, 0x40, 0x8f, 0x10, 0xba, 0x8a, 0x43, 0x12,
0xc0, 0x0a, 0x28, 0x38, 0x62, 0x91, 0x28, 0x8b, 0x1f, 0xe0, 0x2b, 0x30, 0x15, 0x0c, 0x92, 0xd5,
0xac, 0x74, 0xac, 0xa1, 0x8f, 0x9f, 0x4e, 0x7d, 0xd0, 0xd7, 0x9c, 0x4f, 0xac, 0x9b, 0x4a, 0xb1,
0xac, 0x74, 0xaf, 0xc6, 0x97, 0x12, 0x28, 0xae, 0xcb, 0x99, 0x87, 0x9f, 0x14, 0xf0, 0x7f, 0x87,
0x39, 0x7b, 0xad, 0xc0, 0x0b, 0xb9, 0x17, 0xba, 0xad, 0xd8, 0x45, 0x71, 0x56, 0x1e, 0x71, 0x98,
0xaa, 0x48, 0xec, 0xcd, 0xcb, 0xb0, 0xe9, 0xef, 0xd3, 0x5c, 0x11, 0xe0, 0xfe, 0x71, 0x5d, 0x7d,
0xb1, 0xb1, 0xfa, 0x72, 0x2d, 0xee, 0x97, 0x4e, 0x60, 0x07, 0x27, 0xf5, 0x99, 0xa1, 0x80, 0xa5,
0x0a, 0xf6, 0xb8, 0x54, 0xf8, 0x4e, 0x01, 0xb5, 0x6d, 0xa1, 0x84, 0x75, 0xa2, 0xc8, 0xef, 0x8d,
0xea, 0x8a, 0xed, 0xb8, 0x73, 0xa5, 0x1d, 0x43, 0xe2, 0x6a, 0x89, 0x2b, 0xf0, 0xc2, 0x16, 0xb3,
0xfe, 0x15, 0xa0, 0x0d, 0xc9, 0xb9, 0x44, 0x44, 0x9b, 0x50, 0x4a, 0x76, 0x47, 0x45, 0xe4, 0x26,
0x2e, 0xc2, 0x94, 0x9c, 0x61, 0x11, 0x6f, 0x81, 0xea, 0x60, 0x1f, 0xbb, 0x88, 0x13, 0x3a, 0xaa,
0x20, 0x3f, 0x49, 0x05, 0xd5, 0x73, 0xcc, 0xb0, 0x80, 0x0e, 0x98, 0x67, 0xbb, 0x28, 0x1a, 0x65,
0x17, 0x26, 0xc9, 0x9e, 0x13, 0x84, 0x61, 0x6c, 0x17, 0xcc, 0xd9, 0x3e, 0xf2, 0x82, 0x56, 0x7a,
0x0c, 0x8a, 0x12, 0xba, 0xf4, 0xeb, 0x31, 0x38, 0x1f, 0x2f, 0xf3, 0x46, 0x82, 0xad, 0x8c, 0xd9,
0x64, 0xd6, 0xac, 0x64, 0xa4, 0xb6, 0xe0, 0x23, 0x50, 0x8e, 0xb9, 0xe2, 0xbe, 0xfb, 0xeb, 0x1a,
0xf7, 0x5d, 0x49, 0x96, 0x3d, 0x09, 0x1d, 0xf8, 0x06, 0x54, 0x19, 0xea, 0x7a, 0xa1, 0xcb, 0x46,
0x4d, 0x2b, 0x4d, 0xd2, 0xb4, 0x4a, 0x02, 0xb9, 0x70, 0x5c, 0x18, 0xd1, 0x70, 0x94, 0x5c, 0x9e,
0xe8, 0x71, 0x09, 0xc2, 0x50, 0xc8, 0x7c, 0x76, 0xf8, 0x43, 0xcb, 0x1c, 0xf6, 0x35, 0xe5, 0xa8,
0xaf, 0x29, 0xdf, 0xfb, 0x9a, 0xb2, 0x7f, 0xaa, 0x65, 0x8e, 0x4e, 0xb5, 0xcc, 0xd7, 0x53, 0x2d,
0xf3, 0x7a, 0x29, 0x75, 0x57, 0x0a, 0x05, 0xcb, 0x3e, 0x6a, 0x33, 0xb9, 0x32, 0xf6, 0x52, 0xff,
0x48, 0xe4, 0xa5, 0xd9, 0x2e, 0x4a, 0x9b, 0xef, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xca, 0x77,
0xf8, 0x09, 0xb0, 0x08, 0x00, 0x00,
}
func (m *RewardPeriod) Marshal() (dAtA []byte, err error) {
@ -485,48 +439,6 @@ func (m *MultiRewardPeriod) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *TypedMultiRewardPeriod) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TypedMultiRewardPeriod) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TypedMultiRewardPeriod) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.RewardPeriods) > 0 {
for iNdEx := len(m.RewardPeriods) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.RewardPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintParams(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
if m.ClaimType != 0 {
i = encodeVarintParams(dAtA, i, uint64(m.ClaimType))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *Multiplier) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -636,20 +548,6 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.RewardPeriods) > 0 {
for iNdEx := len(m.RewardPeriods) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.RewardPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintParams(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x52
}
}
if len(m.EarnRewardPeriods) > 0 {
for iNdEx := len(m.EarnRewardPeriods) - 1; iNdEx >= 0; iNdEx-- {
{
@ -832,24 +730,6 @@ func (m *MultiRewardPeriod) Size() (n int) {
return n
}
func (m *TypedMultiRewardPeriod) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ClaimType != 0 {
n += 1 + sovParams(uint64(m.ClaimType))
}
if len(m.RewardPeriods) > 0 {
for _, e := range m.RewardPeriods {
l = e.Size()
n += 1 + l + sovParams(uint64(l))
}
}
return n
}
func (m *Multiplier) Size() (n int) {
if m == nil {
return 0
@ -943,12 +823,6 @@ func (m *Params) Size() (n int) {
n += 1 + l + sovParams(uint64(l))
}
}
if len(m.RewardPeriods) > 0 {
for _, e := range m.RewardPeriods {
l = e.Size()
n += 1 + l + sovParams(uint64(l))
}
}
return n
}
@ -1361,109 +1235,6 @@ func (m *MultiRewardPeriod) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *TypedMultiRewardPeriod) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TypedMultiRewardPeriod: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TypedMultiRewardPeriod: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimType", wireType)
}
m.ClaimType = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClaimType |= ClaimType(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RewardPeriods", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthParams
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthParams
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RewardPeriods = append(m.RewardPeriods, MultiRewardPeriod{})
if err := m.RewardPeriods[len(m.RewardPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthParams
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Multiplier) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -2048,40 +1819,6 @@ func (m *Params) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RewardPeriods", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthParams
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthParams
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RewardPeriods = append(m.RewardPeriods, TypedMultiRewardPeriod{})
if err := m.RewardPeriods[len(m.RewardPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])

View File

@ -1,11 +0,0 @@
package types
import sdk "github.com/cosmos/cosmos-sdk/types"
type RewardAccumulator interface {
AccumulateRewards(
ctx sdk.Context,
claimType ClaimType,
rewardPeriod MultiRewardPeriod,
) error
}