Update Earn requests and responses to use multiple strategies (#1284)

* Add multiple strategies to params, queries, txs

* Check deposit/withdraw strategy if supported by vault

* Add note for deposit strategy

* Add strategy type to messages

* Update swagger docs, ignore ethermint proto linting errors

* Update strategy test, move single strategy support to strategytype

* Simplify NewStrategyTypeFromString
This commit is contained in:
Derrick Lee 2022-09-12 09:43:59 -07:00 committed by GitHub
parent b5e162a930
commit b38cd850df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 999 additions and 459 deletions

View File

@ -6978,22 +6978,48 @@ paths:
depositor:
type: string
description: depositor represents the owner of the deposit.
shares:
type: array
items:
type: object
properties:
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
amount:
type: string
description: >-
AccountSupplied represents the amount of denom supplied
to the vault.
account_value:
VaultShare defines shares of a vault owned by a
depositor.
description: >-
Shares represent the issued shares from their
corresponding vaults.
value:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: >-
AccountValue represents the coin value of the
depositor's share of the vault.
Coin defines a token with a denomination and an
amount.
NOTE: The amount field is an Int which implements the
custom method
signatures required by gogoproto.
description: >-
DepositResponse defines a single deposit query response
type.
Value represents the total accumulated value of denom
coins supplied to
vaults. This may be greater than or equal to
amount_supplied depending on
the strategy.
description: DepositResponse defines a deposit query response type.
title: >-
deposits returns the deposits matching the requested
parameters
@ -7135,14 +7161,25 @@ paths:
description: >-
Denom is the only supported denomination of the
vault for deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
StrategyType is the type of strategy that a vault
uses to optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
description: >-
AllowedVault is a vault that is allowed to be created.
These can be
@ -7176,69 +7213,7 @@ paths:
format: byte
tags:
- Earn
/kava/earn/v1beta1/total-deposited/{denom}:
get:
summary: TotalDeposited queries total deposited amount for each vault.
operationId: EarnTotalDeposited
responses:
'200':
description: A successful response.
schema:
type: object
properties:
supplied_coins:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: >-
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom
method
signatures required by gogoproto.
description: >-
QueryTotalDepositedResponse is the response type for the
Query/TotalDeposited RPC method.
default:
description: An unexpected error response
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
parameters:
- name: denom
description: >-
denom represents the vault denom to query total deposited amount
for.
in: path
required: true
type: string
tags:
- Earn
/kava/earn/v1beta1/vaults:
/kava/earn/v1beta1/vaults/{denom}:
get:
summary: Vaults queries vaults based on vault denom
operationId: EarnVaults
@ -7256,19 +7231,30 @@ paths:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
description: >-
StrategyType is the type of strategy that a vault uses
to optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
total_shares:
type: string
description: >-
TotalSupplied is the total amount of denom coins
supplied to the vault.
TotalShares is the total amount of shares issued to
depositors.
total_value:
type: string
description: >-
@ -7305,9 +7291,9 @@ paths:
format: byte
parameters:
- name: denom
description: vault filters vault by denom.
in: query
required: false
description: vault filters vault by denom
in: path
required: true
type: string
tags:
- Earn
@ -54207,14 +54193,25 @@ definitions:
description: >-
Denom is the only supported denomination of the vault for deposits and
withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
StrategyType is the type of strategy that a vault uses to optimize
yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
description: |-
AllowedVault is a vault that is allowed to be created. These can be
modified via parameter governance.
@ -54224,18 +54221,40 @@ definitions:
depositor:
type: string
description: depositor represents the owner of the deposit.
shares:
type: array
items:
type: object
properties:
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
amount:
type: string
description: AccountSupplied represents the amount of denom supplied to the vault.
account_value:
description: VaultShare defines shares of a vault owned by a depositor.
description: Shares represent the issued shares from their corresponding vaults.
value:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: |-
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
description: >-
AccountValue represents the coin value of the depositor's share of the
vault.
description: DepositResponse defines a single deposit query response type.
Value represents the total accumulated value of denom coins supplied
to
vaults. This may be greater than or equal to amount_supplied depending
on
the strategy.
description: DepositResponse defines a deposit query response type.
kava.earn.v1beta1.Params:
type: object
properties:
@ -54249,14 +54268,25 @@ definitions:
description: >-
Denom is the only supported denomination of the vault for
deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
StrategyType is the type of strategy that a vault uses to
optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
description: |-
AllowedVault is a vault that is allowed to be created. These can be
modified via parameter governance.
@ -54272,20 +54302,45 @@ definitions:
depositor:
type: string
description: depositor represents the owner of the deposit.
shares:
type: array
items:
type: object
properties:
denom:
type: string
description: denom represents the vault denom the deposit is for.
account_supplied:
amount:
type: string
description: VaultShare defines shares of a vault owned by a depositor.
description: >-
Shares represent the issued shares from their corresponding
vaults.
value:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: >-
AccountSupplied represents the amount of denom supplied to the
vault.
account_value:
type: string
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom
method
signatures required by gogoproto.
description: >-
AccountValue represents the coin value of the depositor's share
of the vault.
description: DepositResponse defines a single deposit query response type.
Value represents the total accumulated value of denom coins
supplied to
vaults. This may be greater than or equal to amount_supplied
depending on
the strategy.
description: DepositResponse defines a deposit query response type.
title: deposits returns the deposits matching the requested parameters
pagination:
description: pagination defines the pagination in the response.
@ -54325,14 +54380,25 @@ definitions:
description: >-
Denom is the only supported denomination of the vault for
deposits and withdrawals.
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
description: >-
StrategyType is the type of strategy that a vault uses to
optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
description: >-
AllowedVault is a vault that is allowed to be created. These can
be
@ -54342,26 +54408,6 @@ definitions:
description: >-
QueryParamsResponse defines the response type for querying x/earn
parameters.
kava.earn.v1beta1.QueryTotalDepositedResponse:
type: object
properties:
supplied_coins:
type: array
items:
type: object
properties:
denom:
type: string
amount:
type: string
description: |-
Coin defines a token with a denomination and an amount.
NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
description: >-
QueryTotalDepositedResponse is the response type for the
Query/TotalDeposited RPC method.
kava.earn.v1beta1.QueryVaultsResponse:
type: object
properties:
@ -54373,19 +54419,28 @@ definitions:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
type: string
description: >-
TotalSupplied is the total amount of denom coins supplied to the
vault.
StrategyType is the type of strategy that a vault uses to
optimize yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
total_shares:
type: string
description: TotalShares is the total amount of shares issued to depositors.
total_value:
type: string
description: >-
@ -54417,19 +54472,28 @@ definitions:
denom:
type: string
title: denom represents the denom of the vault
vault_strategy:
description: VaultStrategy is the strategy used for this vault.
strategies:
type: array
items:
type: string
enum:
- STRATEGY_TYPE_UNSPECIFIED
- STRATEGY_TYPE_HARD
- STRATEGY_TYPE_SAVINGS
default: STRATEGY_TYPE_UNSPECIFIED
total_supplied:
type: string
description: >-
TotalSupplied is the total amount of denom coins supplied to the
vault.
StrategyType is the type of strategy that a vault uses to optimize
yields.
- STRATEGY_TYPE_UNSPECIFIED: STRATEGY_TYPE_UNSPECIFIED represents an unspecified or invalid strategy type.
- STRATEGY_TYPE_HARD: STRATEGY_TYPE_HARD represents the strategy that deposits assets in the Hard
module.
- STRATEGY_TYPE_SAVINGS: STRATEGY_TYPE_SAVINGS represents the strategy that deposits assets in the
Savings module.
description: VaultStrategy is the strategy used for this vault.
total_shares:
type: string
description: TotalShares is the total amount of shares issued to depositors.
total_value:
type: string
description: >-
@ -54438,6 +54502,14 @@ definitions:
vault were to be liquidated.
description: VaultResponse is the response type for a vault.
kava.earn.v1beta1.VaultShare:
type: object
properties:
denom:
type: string
amount:
type: string
description: VaultShare defines shares of a vault owned by a depositor.
kava.hard.v1beta1.BorrowInterestFactorResponse:
type: object
properties:

View File

@ -2806,7 +2806,7 @@ modified via parameter governance.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | Denom is the only supported denomination of the vault for deposits and withdrawals. |
| `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | VaultStrategy is the strategy used for this vault. |
| `strategies` | [StrategyType](#kava.earn.v1beta1.StrategyType) | repeated | VaultStrategy is the strategy used for this vault. |
@ -3054,7 +3054,7 @@ VaultResponse is the response type for a vault.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | denom represents the denom of the vault |
| `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | VaultStrategy is the strategy used for this vault. |
| `strategies` | [StrategyType](#kava.earn.v1beta1.StrategyType) | repeated | VaultStrategy is the strategy used for this vault. |
| `total_shares` | [string](#string) | | TotalShares is the total amount of shares issued to depositors. |
| `total_value` | [string](#string) | | TotalValue is the total value of denom coins supplied to the vault if the vault were to be liquidated. |
@ -3101,6 +3101,7 @@ MsgDeposit represents a message for depositing assedts into a vault
| ----- | ---- | ----- | ----------- |
| `depositor` | [string](#string) | | depositor represents the address to deposit funds from |
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | Amount represents the token to deposit. The vault corresponds to the denom of the amount coin. |
| `strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | Strategy is the vault strategy to use. |
@ -3132,6 +3133,7 @@ MsgWithdraw represents a message for withdrawing liquidity from a vault
| ----- | ---- | ----- | ----------- |
| `from` | [string](#string) | | from represents the address we are withdrawing for |
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | Amount represents the token to withdraw. The vault corresponds to the denom of the amount coin. |
| `strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) | | Strategy is the vault strategy to use. |

View File

@ -58,7 +58,7 @@ message VaultResponse {
string denom = 1;
// VaultStrategy is the strategy used for this vault.
StrategyType vault_strategy = 2;
repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"];
// TotalShares is the total amount of shares issued to depositors.
string total_shares = 3;

View File

@ -4,6 +4,7 @@ package kava.earn.v1beta1;
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/strategy.proto";
import "kava/earn/v1beta1/vault.proto";
option go_package = "github.com/kava-labs/kava/x/earn/types";
@ -25,6 +26,9 @@ message MsgDeposit {
// Amount represents the token to deposit. The vault corresponds to the denom
// of the amount coin.
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
// Strategy is the vault strategy to use.
StrategyType strategy = 3;
}
// MsgDepositResponse defines the Msg/Deposit response type.
@ -42,6 +46,9 @@ message MsgWithdraw {
// Amount represents the token to withdraw. The vault corresponds to the denom
// of the amount coin.
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false];
// Strategy is the vault strategy to use.
StrategyType strategy = 3;
}
// MsgWithdrawResponse defines the Msg/Withdraw response type.

View File

@ -4,7 +4,6 @@ package kava.earn.v1beta1;
option go_package = "github.com/kava-labs/kava/x/earn/types";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "kava/earn/v1beta1/strategy.proto";
@ -15,7 +14,7 @@ message AllowedVault {
string denom = 1;
// VaultStrategy is the strategy used for this vault.
StrategyType vault_strategy = 2;
repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"];
}
// VaultRecord is the state of a vault.

View File

@ -4,6 +4,7 @@ lint:
ignore:
- cosmos
- cosmos_proto
- ethermint
- gogoproto
- google
- ibc

View File

@ -40,13 +40,13 @@ func GetTxCmd() *cobra.Command {
func getCmdDeposit() *cobra.Command {
return &cobra.Command{
Use: "deposit [amount]",
Use: "deposit [amount] [strategy]",
Short: "deposit coins to an earn vault",
Example: fmt.Sprintf(
`%s tx %s deposit 10000000ukava --from <key>`,
`%s tx %s deposit 10000000ukava hard --from <key>`,
version.AppName, types.ModuleName,
),
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
@ -58,8 +58,13 @@ func getCmdDeposit() *cobra.Command {
return err
}
strategy := types.NewStrategyTypeFromString(args[1])
if !strategy.IsValid() {
return fmt.Errorf("invalid strategy type: %s", args[1])
}
signer := clientCtx.GetFromAddress()
msg := types.NewMsgDeposit(signer.String(), amount)
msg := types.NewMsgDeposit(signer.String(), amount, strategy)
if err := msg.ValidateBasic(); err != nil {
return err
}
@ -71,13 +76,13 @@ func getCmdDeposit() *cobra.Command {
func getCmdWithdraw() *cobra.Command {
return &cobra.Command{
Use: "withdraw [amount]",
Use: "withdraw [amount] [strategy]",
Short: "withdraw coins from an earn vault",
Example: fmt.Sprintf(
`%s tx %s withdraw 10000000ukava --from <key>`,
`%s tx %s withdraw 10000000ukava hard --from <key>`,
version.AppName, types.ModuleName,
),
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
@ -89,8 +94,13 @@ func getCmdWithdraw() *cobra.Command {
return err
}
strategy := types.NewStrategyTypeFromString(args[1])
if !strategy.IsValid() {
return fmt.Errorf("invalid strategy type: %s", args[1])
}
fromAddr := clientCtx.GetFromAddress()
msg := types.NewMsgWithdraw(fromAddr.String(), amount)
msg := types.NewMsgWithdraw(fromAddr.String(), amount, strategy)
if err := msg.ValidateBasic(); err != nil {
return err
}

View File

@ -9,7 +9,12 @@ import (
// Deposit adds the provided amount from a depositor to a vault. The vault is
// specified by the denom in the amount.
func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.Coin) error {
func (k *Keeper) Deposit(
ctx sdk.Context,
depositor sdk.AccAddress,
amount sdk.Coin,
depositStrategy types.StrategyType,
) error {
// Get AllowedVault, if not found (not a valid vault), return error
allowedVault, found := k.GetAllowedVault(ctx, amount.Denom)
if !found {
@ -20,6 +25,11 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
return types.ErrInsufficientAmount
}
// Check if deposit strategy is supported by vault
if !allowedVault.IsStrategyAllowed(depositStrategy) {
return types.ErrInvalidVaultStrategy
}
// Check if VaultRecord exists, create if not exist
vaultRecord, found := k.GetVaultRecord(ctx, amount.Denom)
if !found {
@ -28,7 +38,11 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
}
// Get the strategy for the vault
strategy, err := k.GetStrategy(allowedVault.VaultStrategy)
// NOTE: Currently always uses the first one, AllowedVaults are currently
// only valid with 1 and only 1 strategy so this is safe.
// If/When multiple strategies are supported and users can specify specific
// strategies, shares should be issued per-strategy instead of per-vault.
strategy, err := k.GetStrategy(allowedVault.Strategies[0])
if err != nil {
return err
}

View File

@ -42,7 +42,7 @@ func (suite *depositTestSuite) TestDeposit_Balances() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.AccountBalanceEqual(
@ -65,7 +65,7 @@ func (suite *depositTestSuite) TestDeposit_Exceed() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, sdkerrors.ErrInsufficientFunds)
@ -90,7 +90,7 @@ func (suite *depositTestSuite) TestDeposit_Zero() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInsufficientAmount)
@ -115,7 +115,7 @@ func (suite *depositTestSuite) TestDeposit_InvalidVault() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInvalidVaultDenom)
@ -130,3 +130,17 @@ func (suite *depositTestSuite) TestDeposit_InvalidVault() {
sdk.NewCoins(),
)
}
func (suite *depositTestSuite) TestDeposit_InvalidStrategy() {
vaultDenom := "usdx"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
depositAmount := sdk.NewInt64Coin(vaultDenom, 1001)
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_SAVINGS)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInvalidVaultStrategy)
}

View File

@ -82,7 +82,7 @@ func (s queryServer) Vaults(
vaults = append(vaults, types.VaultResponse{
Denom: allowedVault.Denom,
VaultStrategy: allowedVault.VaultStrategy,
Strategies: allowedVault.Strategies,
TotalShares: vaultTotalShares.Amount.String(),
TotalValue: totalValue.Amount,
})

View File

@ -69,7 +69,7 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() {
suite.Require().Equal(
types.VaultResponse{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
TotalShares: sdk.NewDec(0).String(),
TotalValue: sdk.NewInt(0),
},
@ -85,13 +85,13 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() {
[]types.VaultResponse{
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
TotalShares: sdk.NewDec(0).String(),
TotalValue: sdk.NewInt(0),
},
{
Denom: "busd",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
TotalShares: sdk.NewDec(0).String(),
TotalValue: sdk.NewInt(0),
},
@ -111,7 +111,7 @@ func (suite *grpcQueryTestSuite) TestVaults_WithSupply() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
res, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest("usdx"))
@ -120,7 +120,7 @@ func (suite *grpcQueryTestSuite) TestVaults_WithSupply() {
suite.Require().Equal(
types.VaultResponse{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
TotalShares: depositAmount.Amount.ToDec().String(),
TotalValue: depositAmount.Amount,
},
@ -160,14 +160,14 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
// Deposit into each vault from each account - 4 total deposits
// Acc 1: usdx + busd
// Acc 2: usdx + usdc
err := suite.Keeper.Deposit(suite.Ctx, acc1, deposit1Amount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, deposit1Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc1, deposit2Amount)
err = suite.Keeper.Deposit(suite.Ctx, acc1, deposit2Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit1Amount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit1Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit3Amount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, deposit3Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.Run("1) 1 vault for 1 account", func() {

View File

@ -29,7 +29,7 @@ func (m msgServer) Deposit(goCtx context.Context, msg *types.MsgDeposit) (*types
return nil, err
}
if err := m.keeper.Deposit(ctx, depositor, msg.Amount); err != nil {
if err := m.keeper.Deposit(ctx, depositor, msg.Amount, msg.Strategy); err != nil {
return nil, err
}
@ -53,7 +53,7 @@ func (m msgServer) Withdraw(goCtx context.Context, msg *types.MsgWithdraw) (*typ
return nil, err
}
if err := m.keeper.Withdraw(ctx, from, msg.Amount); err != nil {
if err := m.keeper.Withdraw(ctx, from, msg.Amount, msg.Strategy); err != nil {
return nil, err
}

View File

@ -41,7 +41,7 @@ func (suite *msgServerTestSuite) TestDeposit() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
msg := types.NewMsgDeposit(acc.GetAddress().String(), depositAmount)
msg := types.NewMsgDeposit(acc.GetAddress().String(), depositAmount, types.STRATEGY_TYPE_HARD)
_, err := suite.msgServer.Deposit(sdk.WrapSDKContext(suite.Ctx), msg)
suite.Require().NoError(err)
@ -94,12 +94,12 @@ func (suite *msgServerTestSuite) TestWithdraw() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
msgDeposit := types.NewMsgDeposit(acc.GetAddress().String(), depositAmount)
msgDeposit := types.NewMsgDeposit(acc.GetAddress().String(), depositAmount, types.STRATEGY_TYPE_HARD)
_, err := suite.msgServer.Deposit(sdk.WrapSDKContext(suite.Ctx), msgDeposit)
suite.Require().NoError(err)
// Withdraw all
msgWithdraw := types.NewMsgWithdraw(acc.GetAddress().String(), depositAmount)
msgWithdraw := types.NewMsgWithdraw(acc.GetAddress().String(), depositAmount, types.STRATEGY_TYPE_HARD)
_, err = suite.msgServer.Withdraw(sdk.WrapSDKContext(suite.Ctx), msgWithdraw)
suite.Require().NoError(err)

View File

@ -40,7 +40,7 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.HardDepositAmountEqual(sdk.NewCoins(depositAmount))
@ -65,11 +65,11 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc_MultipleDeposits() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Second deposit
err = suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
expectedVaultBalance := depositAmount.Add(depositAmount)
@ -101,11 +101,11 @@ func (suite *strategyHardTestSuite) TestDeposit_MultipleAcc_MultipleDeposits() {
// 2 deposits each account
for i := 0; i < 2; i++ {
// Deposit from acc1
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Deposit from acc2
err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
}
@ -150,7 +150,7 @@ func (suite *strategyHardTestSuite) TestGetVaultTotalValue_NoDenomDeposit() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
// Deposit vault1
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Query vault total, hard deposit exists for account, but amount in busd does not
@ -173,7 +173,7 @@ func (suite *strategyHardTestSuite) TestWithdraw() {
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.HardDepositAmountEqual(sdk.NewCoins(depositAmount))
@ -184,7 +184,7 @@ func (suite *strategyHardTestSuite) TestWithdraw() {
suite.Equal(depositAmount, totalValue)
// Withdraw
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.HardDepositAmountEqual(sdk.NewCoins())
@ -196,7 +196,7 @@ func (suite *strategyHardTestSuite) TestWithdraw() {
suite.Equal(sdk.NewInt64Coin(vaultDenom, 0), totalValue)
// Withdraw again
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound, "vault should be deleted when no more supply")
}
@ -211,18 +211,18 @@ func (suite *strategyHardTestSuite) TestWithdraw_OnlyWithdrawOwnSupply() {
// Deposits from 2 accounts
acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Withdraw
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Withdraw again
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(
err,
@ -242,11 +242,11 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
err := suite.Keeper.Deposit(suite.Ctx, acc, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Deposit from acc2 so the vault doesn't get deleted when withdrawing
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Direct hard deposit from module account to increase vault value
@ -260,11 +260,11 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() {
suite.Equal(depositAmount.AddAmount(sdk.NewInt(10)), accValue)
// Withdraw 100, 10 remaining
err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Withdraw 100 again -- too much
err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(
err,
@ -273,11 +273,11 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() {
)
// Half of remaining 10, 5 remaining
err = suite.Keeper.Withdraw(suite.Ctx, acc, sdk.NewCoin(vaultDenom, sdk.NewInt(5)))
err = suite.Keeper.Withdraw(suite.Ctx, acc, sdk.NewCoin(vaultDenom, sdk.NewInt(5)), types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Withdraw all
err = suite.Keeper.Withdraw(suite.Ctx, acc, sdk.NewCoin(vaultDenom, sdk.NewInt(5)))
err = suite.Keeper.Withdraw(suite.Ctx, acc, sdk.NewCoin(vaultDenom, sdk.NewInt(5)), types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
accValue, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc)
@ -302,7 +302,7 @@ func (suite *strategyHardTestSuite) TestAccountShares() {
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
// 1. acc1 deposit 100
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -318,7 +318,7 @@ func (suite *strategyHardTestSuite) TestAccountShares() {
// 2. acc2 deposit 100
// share price is 10% more expensive now
// hard 110 -> 210
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// 100 * 100 / 210 = 47.619047619 shares
@ -347,7 +347,7 @@ func (suite *strategyHardTestSuite) TestAccountShares() {
suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 90)))
// Deposit again from acc1
err = suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -377,11 +377,11 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedAmount() {
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
// 1. acc1 deposit 100
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// acc2 deposit 100, just to make sure other deposits do not affect acc1
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -395,7 +395,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedAmount() {
suite.Require().NoError(err)
// 3. Withdraw all from acc1 - including accumulated amount
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount.AddAmount(sdk.NewInt(10)))
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount.AddAmount(sdk.NewInt(10)), types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
_, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -415,11 +415,11 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedTruncated() {
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
// 1. acc1 deposit 100
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// acc2 deposit 100, just to make sure other deposits do not affect acc1
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -437,7 +437,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedTruncated() {
suite.Equal(depositAmount.AddAmount(sdk.NewInt(5)), accBal, "acc1 should have 105 usdx")
// 3. Withdraw all from acc1 - including accumulated amount
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount.AddAmount(sdk.NewInt(5)))
err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount.AddAmount(sdk.NewInt(5)), types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -459,7 +459,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_ExpensiveShares() {
acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
// 1. acc1 deposit 100
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
@ -477,7 +477,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_ExpensiveShares() {
suite.Equal(sdk.NewInt(2000), accBal.Amount, "acc1 should have 2000 usdx")
// 3. Withdraw all from acc1 - including accumulated amount
err = suite.Keeper.Withdraw(suite.Ctx, acc1, sdk.NewInt64Coin(vaultDenom, 2000))
err = suite.Keeper.Withdraw(suite.Ctx, acc1, sdk.NewInt64Coin(vaultDenom, 2000), types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)

View File

@ -38,7 +38,7 @@ func (k *Keeper) GetVaultTotalValue(
return sdk.Coin{}, types.ErrVaultRecordNotFound
}
strategy, err := k.GetStrategy(enabledVault.VaultStrategy)
strategy, err := k.GetStrategy(enabledVault.Strategies[0])
if err != nil {
return sdk.Coin{}, types.ErrInvalidVaultStrategy
}

View File

@ -32,7 +32,7 @@ func (suite *vaultTestSuite) TestGetVaultTotalShares() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
vaultTotalShares, found := suite.Keeper.GetVaultTotalShares(suite.Ctx, vaultDenom)
@ -66,13 +66,12 @@ func (suite *vaultTestSuite) TestGetVaultTotalValue_NotFound() {
suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound)
}
func (suite *vaultTestSuite) TestGetVaultTotalValue_InvalidStrategy() {
func (suite *vaultTestSuite) TestInvalidVaultStrategy() {
vaultDenom := "usdx"
suite.CreateVault(vaultDenom, 99999) // not valid strategy type
_, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInvalidVaultStrategy)
suite.PanicsWithValue("value from ParamSetPair is invalid: invalid strategy 99999", func() {
suite.CreateVault(vaultDenom, 99999) // not valid strategy type
})
}
func (suite *vaultTestSuite) TestGetVaultAccountSupplied() {
@ -95,10 +94,10 @@ func (suite *vaultTestSuite) TestGetVaultAccountSupplied() {
suite.Require().False(found)
// Deposits from both accounts
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), deposit1Amount)
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), deposit1Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), deposit2Amount)
err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), deposit2Amount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Check balances
@ -123,7 +122,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue() {
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
accValue, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc.GetAddress())
@ -151,7 +150,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue_ShareNotFound() {
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
// Deposit from acc1 so that vault record exists
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// Query from acc2 with no share record

View File

@ -11,7 +11,12 @@ import (
// Withdraw removes the amount of supplied tokens from a vault and transfers it
// back to the account.
func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.Coin) error {
func (k *Keeper) Withdraw(
ctx sdk.Context,
from sdk.AccAddress,
wantAmount sdk.Coin,
withdrawStrategy types.StrategyType,
) error {
// Get AllowedVault, if not found (not a valid vault), return error
allowedVault, found := k.GetAllowedVault(ctx, wantAmount.Denom)
if !found {
@ -22,6 +27,11 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
return types.ErrInsufficientAmount
}
// Check if withdraw strategy is supported by vault
if !allowedVault.IsStrategyAllowed(withdrawStrategy) {
return types.ErrInvalidVaultStrategy
}
// Check if VaultRecord exists
vaultRecord, found := k.GetVaultRecord(ctx, wantAmount.Denom)
if !found {
@ -74,7 +84,7 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
}
// Get the strategy for the vault
strategy, err := k.GetStrategy(allowedVault.VaultStrategy)
strategy, err := k.GetStrategy(allowedVault.Strategies[0])
if err != nil {
return err
}

View File

@ -33,7 +33,7 @@ func (suite *withdrawTestSuite) TestWithdraw_NoVaultRecord() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
// Withdraw without having any prior deposits
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound)
@ -59,13 +59,13 @@ func (suite *withdrawTestSuite) TestWithdraw_NoVaultShareRecord() {
// Create deposit from acc1 so the VaultRecord exists in state
acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), acc1DepositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), acc1DepositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1)
// Withdraw from acc2 without having any prior deposits
err = suite.Keeper.Withdraw(suite.Ctx, acc2.GetAddress(), acc2WithdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc2.GetAddress(), acc2WithdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrVaultShareRecordNotFound)
@ -91,10 +91,10 @@ func (suite *withdrawTestSuite) TestWithdraw_ExceedBalance() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInsufficientValue)
@ -119,7 +119,7 @@ func (suite *withdrawTestSuite) TestWithdraw_Zero() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInsufficientAmount)
@ -144,7 +144,7 @@ func (suite *withdrawTestSuite) TestWithdraw_InvalidVault() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInvalidVaultDenom)
@ -160,6 +160,20 @@ func (suite *withdrawTestSuite) TestWithdraw_InvalidVault() {
)
}
func (suite *withdrawTestSuite) TestWithdraw_InvalidStrategy() {
vaultDenom := "usdx"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
withdrawAmount := sdk.NewInt64Coin(vaultDenom, 1001)
suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_SAVINGS)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrInvalidVaultStrategy)
}
func (suite *withdrawTestSuite) TestWithdraw_FullBalance() {
vaultDenom := "usdx"
startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
@ -170,10 +184,10 @@ func (suite *withdrawTestSuite) TestWithdraw_FullBalance() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), withdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// No net changes in balances
@ -197,10 +211,10 @@ func (suite *withdrawTestSuite) TestWithdraw_Partial() {
acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
suite.AccountBalanceEqual(
@ -209,11 +223,11 @@ func (suite *withdrawTestSuite) TestWithdraw_Partial() {
)
// Second withdraw for remaining 50
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().NoError(err)
// No more balance to withdraw
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount)
err = suite.Keeper.Withdraw(suite.Ctx, acc.GetAddress(), partialWithdrawAmount, types.STRATEGY_TYPE_HARD)
suite.Require().Error(err)
suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound, "vault record should be deleted after no more supplied")

View File

@ -216,13 +216,11 @@ func (suite *Suite) NewAccountFromAddr(addr sdk.AccAddress, balance sdk.Coins) a
// CreateVault adds a new vault to the keeper parameters
func (suite *Suite) CreateVault(vaultDenom string, vaultStrategy types.StrategyType) {
vault := types.NewAllowedVault(vaultDenom, vaultStrategy)
suite.Require().NoError(vault.Validate())
allowedVaults := suite.Keeper.GetAllowedVaults(suite.Ctx)
allowedVaults = append(allowedVaults, vault)
params := types.NewParams(allowedVaults)
suite.Require().NoError(params.Validate())
suite.Keeper.SetParams(
suite.Ctx,

View File

@ -20,10 +20,11 @@ const (
)
// NewMsgDeposit returns a new MsgDeposit.
func NewMsgDeposit(depositor string, amount sdk.Coin) *MsgDeposit {
func NewMsgDeposit(depositor string, amount sdk.Coin, strategy StrategyType) *MsgDeposit {
return &MsgDeposit{
Depositor: depositor,
Amount: amount,
Strategy: strategy,
}
}
@ -37,6 +38,10 @@ func (msg MsgDeposit) ValidateBasic() error {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, err.Error())
}
if err := msg.Strategy.Validate(); err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
return nil
}
@ -67,10 +72,11 @@ func (msg MsgDeposit) Type() string {
}
// NewMsgWithdraw returns a new MsgWithdraw.
func NewMsgWithdraw(from string, amount sdk.Coin) *MsgWithdraw {
func NewMsgWithdraw(from string, amount sdk.Coin, strategy StrategyType) *MsgWithdraw {
return &MsgWithdraw{
From: from,
Amount: amount,
Strategy: strategy,
}
}
@ -84,6 +90,10 @@ func (msg MsgWithdraw) ValidateBasic() error {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, err.Error())
}
if err := msg.Strategy.Validate(); err != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
return nil
}

View File

@ -192,7 +192,7 @@ type VaultResponse struct {
// denom represents the denom of the vault
Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
// VaultStrategy is the strategy used for this vault.
VaultStrategy StrategyType `protobuf:"varint,2,opt,name=vault_strategy,json=vaultStrategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"vault_strategy,omitempty"`
Strategies StrategyTypes `protobuf:"varint,2,rep,packed,name=strategies,proto3,enum=kava.earn.v1beta1.StrategyType,castrepeated=StrategyTypes" json:"strategies,omitempty"`
// TotalShares is the total amount of shares issued to depositors.
TotalShares string `protobuf:"bytes,3,opt,name=total_shares,json=totalShares,proto3" json:"total_shares,omitempty"`
// TotalValue is the total value of denom coins supplied to the vault if the
@ -376,55 +376,56 @@ func init() {
func init() { proto.RegisterFile("kava/earn/v1beta1/query.proto", fileDescriptor_63f8dee2f3192a6b) }
var fileDescriptor_63f8dee2f3192a6b = []byte{
// 762 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcf, 0x4f, 0x13, 0x4f,
0x14, 0xef, 0xb6, 0xb4, 0x81, 0xe9, 0x17, 0xbe, 0x71, 0xa8, 0x49, 0x5b, 0x64, 0x5b, 0x96, 0x08,
0x95, 0xa4, 0xbb, 0x52, 0x13, 0xbd, 0x18, 0x13, 0x2b, 0xd1, 0xe0, 0xc1, 0xe8, 0xa2, 0x1c, 0x4c,
0x4c, 0x33, 0xa5, 0x93, 0x65, 0x43, 0xbb, 0xb3, 0xec, 0x4c, 0xab, 0x68, 0xbc, 0x70, 0x37, 0x31,
0xf1, 0x5f, 0x30, 0x1e, 0x3c, 0xf3, 0x47, 0x70, 0x24, 0x78, 0x31, 0x1e, 0x50, 0xc1, 0xbb, 0x57,
0x8f, 0x66, 0x7e, 0x2c, 0x65, 0xdb, 0x6d, 0xea, 0xa9, 0x9d, 0xf7, 0xe3, 0xf3, 0xf9, 0xbc, 0x37,
0x6f, 0xde, 0x82, 0xf9, 0x1d, 0xd4, 0x43, 0x16, 0x46, 0x81, 0x67, 0xf5, 0x56, 0x9b, 0x98, 0xa1,
0x55, 0x6b, 0xb7, 0x8b, 0x83, 0x3d, 0xd3, 0x0f, 0x08, 0x23, 0xf0, 0x12, 0x77, 0x9b, 0xdc, 0x6d,
0x2a, 0x77, 0xb1, 0xb0, 0x45, 0x68, 0x87, 0xd0, 0x86, 0x08, 0xb0, 0xe4, 0x41, 0x46, 0x17, 0x57,
0xe4, 0xc9, 0x6a, 0x22, 0x8a, 0x25, 0xcc, 0x39, 0xa8, 0x8f, 0x1c, 0xd7, 0x43, 0xcc, 0x25, 0x9e,
0x8a, 0xd5, 0x2f, 0xc6, 0x86, 0x51, 0x5b, 0xc4, 0x0d, 0xfd, 0x39, 0x87, 0x38, 0x44, 0x72, 0xf0,
0x7f, 0xca, 0x7a, 0xc5, 0x21, 0xc4, 0x69, 0x63, 0x0b, 0xf9, 0xae, 0x85, 0x3c, 0x8f, 0x30, 0x01,
0x19, 0xf2, 0xeb, 0xc3, 0xc5, 0xf8, 0x28, 0x40, 0x9d, 0xd0, 0x5f, 0x1e, 0xf6, 0x53, 0x16, 0x20,
0x86, 0x1d, 0x55, 0x6f, 0x31, 0xa6, 0x1d, 0x3d, 0xd4, 0x6d, 0x33, 0xe9, 0x36, 0x72, 0x00, 0x3e,
0xe1, 0x65, 0x3d, 0x16, 0xa8, 0x36, 0xde, 0xed, 0x62, 0xca, 0x8c, 0x47, 0x60, 0x36, 0x62, 0xa5,
0x3e, 0xf1, 0x28, 0x86, 0xb7, 0x40, 0x46, 0xb2, 0xe7, 0xb5, 0xb2, 0x56, 0xc9, 0xd6, 0x0a, 0xe6,
0x50, 0x33, 0x4d, 0x99, 0x52, 0x9f, 0x38, 0x3c, 0x29, 0x25, 0x6c, 0x15, 0x6e, 0xac, 0x28, 0x96,
0x4d, 0xce, 0x1c, 0xb2, 0xc0, 0x1c, 0x48, 0xb7, 0xb0, 0x47, 0x3a, 0x02, 0x6d, 0xca, 0x96, 0x07,
0xe3, 0x99, 0xe2, 0x0e, 0x63, 0x15, 0xf7, 0x1d, 0x90, 0x11, 0xba, 0x39, 0x77, 0xaa, 0x92, 0xad,
0x95, 0x63, 0xb8, 0x45, 0x4a, 0x98, 0x11, 0x4a, 0x90, 0x59, 0xc6, 0x6f, 0x0d, 0x4c, 0x47, 0xfc,
0xf1, 0xf4, 0xf0, 0x3e, 0x98, 0x11, 0x19, 0x8d, 0xb0, 0x8f, 0xf9, 0x64, 0x59, 0xab, 0xcc, 0xd4,
0x4a, 0x31, 0x7c, 0x1b, 0x2a, 0xe4, 0xe9, 0x9e, 0x8f, 0xed, 0x69, 0x91, 0x16, 0x9a, 0xe0, 0x02,
0xf8, 0x8f, 0x11, 0x86, 0xda, 0x0d, 0xba, 0x8d, 0x02, 0x4c, 0xf3, 0x29, 0x41, 0x92, 0x15, 0xb6,
0x0d, 0x61, 0x82, 0x2f, 0x80, 0x3c, 0x36, 0x7a, 0xa8, 0xdd, 0xc5, 0xf9, 0x09, 0x1e, 0x51, 0xbf,
0xcd, 0x55, 0x7f, 0x3b, 0x29, 0x2d, 0x39, 0x2e, 0xdb, 0xee, 0x36, 0xcd, 0x2d, 0xd2, 0x51, 0x23,
0xa9, 0x7e, 0xaa, 0xb4, 0xb5, 0x63, 0xb1, 0x3d, 0x1f, 0x53, 0x73, 0xdd, 0x63, 0xc7, 0x07, 0x55,
0xa0, 0x26, 0x76, 0xdd, 0x63, 0x36, 0x10, 0x80, 0x9b, 0x1c, 0xcf, 0xf8, 0xa8, 0x81, 0x9c, 0xe8,
0xe4, 0x1a, 0xf6, 0x09, 0x75, 0xfb, 0x7d, 0x37, 0x41, 0x9a, 0xbc, 0xf4, 0x70, 0x20, 0x0b, 0xaf,
0xe7, 0x8f, 0x0f, 0xaa, 0x39, 0x85, 0x71, 0xb7, 0xd5, 0x0a, 0x30, 0xa5, 0x1b, 0x2c, 0x70, 0x3d,
0xc7, 0x96, 0x61, 0xfd, 0x46, 0x25, 0xa3, 0x8d, 0x02, 0xfd, 0x27, 0x20, 0xca, 0xcb, 0xd6, 0x96,
0x4c, 0x85, 0xc3, 0xdf, 0x80, 0x29, 0x9f, 0x5d, 0x7f, 0x30, 0x1c, 0xac, 0x14, 0xd8, 0x17, 0x32,
0x8d, 0x4f, 0x1a, 0xb8, 0x3c, 0x20, 0x53, 0x5d, 0xd0, 0x1a, 0x98, 0x6c, 0x29, 0x9b, 0xba, 0x74,
0x23, 0xe6, 0x12, 0x54, 0xda, 0xc0, 0xb5, 0x9f, 0x67, 0xc2, 0x07, 0x11, 0x9d, 0x49, 0xa1, 0x73,
0x79, 0xac, 0x4e, 0x09, 0x16, 0x11, 0xfa, 0x47, 0x03, 0xff, 0x0f, 0x90, 0xc1, 0x9b, 0x60, 0x4a,
0x11, 0x91, 0xf1, 0xed, 0xec, 0x87, 0xc2, 0x87, 0x20, 0xa3, 0xe6, 0x22, 0x29, 0x0a, 0x9b, 0x1f,
0x35, 0xcd, 0x62, 0x54, 0xea, 0xb3, 0xbc, 0xa6, 0xcf, 0xdf, 0x4b, 0xd9, 0xbe, 0x8d, 0xda, 0x0a,
0x01, 0x22, 0x90, 0x96, 0x03, 0x94, 0x12, 0x50, 0x85, 0x48, 0x6d, 0x21, 0xd8, 0x3d, 0xe2, 0x7a,
0xf5, 0xeb, 0x0a, 0xa6, 0xf2, 0x0f, 0xb3, 0xc5, 0x13, 0xa8, 0x2d, 0x91, 0x6b, 0xef, 0x52, 0x20,
0x2d, 0xee, 0x08, 0xbe, 0x06, 0x19, 0xf9, 0xc2, 0xe1, 0xd5, 0x18, 0xc9, 0xc3, 0xab, 0xa4, 0xb8,
0x34, 0x2e, 0x4c, 0x76, 0xd2, 0x58, 0xd8, 0xff, 0xf2, 0xeb, 0x43, 0x72, 0x0e, 0x16, 0xac, 0x51,
0x2b, 0x0f, 0xee, 0x6b, 0x20, 0x23, 0xb7, 0xc2, 0x68, 0xf2, 0xc8, 0x86, 0x19, 0x4d, 0x1e, 0x5d,
0x2e, 0xc6, 0x35, 0x41, 0xbe, 0x08, 0x17, 0xac, 0x11, 0xdb, 0x92, 0x5a, 0x6f, 0xc4, 0xd4, 0xbf,
0xe5, 0x22, 0x26, 0xc3, 0x49, 0x85, 0xcb, 0xa3, 0xf0, 0x07, 0x9e, 0x5c, 0xb1, 0x32, 0x3e, 0x50,
0x49, 0x59, 0x14, 0x52, 0xe6, 0xe1, 0x5c, 0x8c, 0x94, 0x70, 0xa6, 0xeb, 0x6b, 0x87, 0x3f, 0xf5,
0xc4, 0xe1, 0xa9, 0xae, 0x1d, 0x9d, 0xea, 0xda, 0x8f, 0x53, 0x5d, 0x7b, 0x7f, 0xa6, 0x27, 0x8e,
0xce, 0xf4, 0xc4, 0xd7, 0x33, 0x3d, 0xf1, 0xfc, 0xe2, 0xea, 0xe0, 0x20, 0xd5, 0x36, 0x6a, 0x52,
0x09, 0xf7, 0x4a, 0x02, 0x8a, 0x2b, 0x6e, 0x66, 0xc4, 0x27, 0xe0, 0xc6, 0xdf, 0x00, 0x00, 0x00,
0xff, 0xff, 0x27, 0x75, 0x39, 0xf4, 0x32, 0x07, 0x00, 0x00,
// 771 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x4f, 0x13, 0x4d,
0x18, 0xef, 0xb6, 0xb4, 0x81, 0xe9, 0xcb, 0xfb, 0x86, 0xa1, 0x6f, 0xd2, 0x96, 0x97, 0x6d, 0x59,
0xf2, 0x42, 0x25, 0xe9, 0xae, 0xd4, 0x44, 0x2f, 0xc6, 0xc4, 0x4a, 0x34, 0x78, 0x30, 0xba, 0x28,
0x07, 0x13, 0x43, 0xa6, 0x74, 0xb2, 0x6c, 0x68, 0x77, 0x96, 0x9d, 0x69, 0x15, 0x8d, 0x17, 0xee,
0x26, 0x26, 0x7e, 0x05, 0xe3, 0x81, 0x33, 0x1f, 0x82, 0x23, 0xc1, 0x8b, 0xf1, 0x00, 0x0a, 0x7e,
0x08, 0x13, 0x2f, 0x66, 0xfe, 0x2c, 0xed, 0xb6, 0xdb, 0xd4, 0x53, 0x3b, 0xcf, 0x9f, 0xdf, 0xef,
0x79, 0x9e, 0xf9, 0xcd, 0xb3, 0x60, 0x7e, 0x17, 0x75, 0x91, 0x85, 0x51, 0xe0, 0x59, 0xdd, 0xd5,
0x06, 0x66, 0x68, 0xd5, 0xda, 0xeb, 0xe0, 0x60, 0xdf, 0xf4, 0x03, 0xc2, 0x08, 0x9c, 0xe1, 0x6e,
0x93, 0xbb, 0x4d, 0xe5, 0x2e, 0x16, 0xb6, 0x09, 0x6d, 0x13, 0xba, 0x25, 0x02, 0x2c, 0x79, 0x90,
0xd1, 0xc5, 0x15, 0x79, 0xb2, 0x1a, 0x88, 0x62, 0x09, 0x73, 0x05, 0xea, 0x23, 0xc7, 0xf5, 0x10,
0x73, 0x89, 0xa7, 0x62, 0xf5, 0xfe, 0xd8, 0x30, 0x6a, 0x9b, 0xb8, 0xa1, 0x3f, 0xe7, 0x10, 0x87,
0x48, 0x0e, 0xfe, 0x4f, 0x59, 0xff, 0x73, 0x08, 0x71, 0x5a, 0xd8, 0x42, 0xbe, 0x6b, 0x21, 0xcf,
0x23, 0x4c, 0x40, 0x86, 0xfc, 0xfa, 0x70, 0x33, 0x3e, 0x0a, 0x50, 0x3b, 0xf4, 0x97, 0x87, 0xfd,
0x94, 0x05, 0x88, 0x61, 0x47, 0xf5, 0x5b, 0x8c, 0x19, 0x47, 0x17, 0x75, 0x5a, 0x4c, 0xba, 0x8d,
0x1c, 0x80, 0x4f, 0x78, 0x5b, 0x8f, 0x05, 0xaa, 0x8d, 0xf7, 0x3a, 0x98, 0x32, 0xe3, 0x11, 0x98,
0x8d, 0x58, 0xa9, 0x4f, 0x3c, 0x8a, 0xe1, 0x2d, 0x90, 0x91, 0xec, 0x79, 0xad, 0xac, 0x55, 0xb2,
0xb5, 0x82, 0x39, 0x34, 0x4c, 0x53, 0xa6, 0xd4, 0x27, 0x8e, 0xcf, 0x4a, 0x09, 0x5b, 0x85, 0x1b,
0x2b, 0x8a, 0x65, 0x93, 0x33, 0x87, 0x2c, 0x30, 0x07, 0xd2, 0x4d, 0xec, 0x91, 0xb6, 0x40, 0x9b,
0xb2, 0xe5, 0xc1, 0x78, 0xa6, 0xb8, 0xc3, 0x58, 0xc5, 0x7d, 0x07, 0x64, 0x44, 0xdd, 0x9c, 0x3b,
0x55, 0xc9, 0xd6, 0xca, 0x31, 0xdc, 0x22, 0x25, 0xcc, 0x08, 0x4b, 0x90, 0x59, 0xc6, 0x2f, 0x0d,
0x4c, 0x47, 0xfc, 0xf1, 0xf4, 0xd0, 0x06, 0x40, 0x4d, 0xd0, 0xc5, 0x34, 0x9f, 0x2c, 0xa7, 0x2a,
0x7f, 0xd7, 0x4a, 0x31, 0x5c, 0x1b, 0x6a, 0xcc, 0x4f, 0xf7, 0x7d, 0x5c, 0x9f, 0x39, 0x3c, 0x2f,
0x4d, 0xf7, 0x5b, 0xa8, 0xdd, 0x87, 0x02, 0x17, 0xc0, 0x5f, 0x8c, 0x30, 0xd4, 0xda, 0xa2, 0x3b,
0x28, 0xc0, 0x34, 0x9f, 0x12, 0x84, 0x59, 0x61, 0xdb, 0x10, 0x26, 0xf8, 0x02, 0xc8, 0xe3, 0x56,
0x17, 0xb5, 0x3a, 0x38, 0x3f, 0xc1, 0x23, 0xea, 0xb7, 0x79, 0x07, 0x5f, 0xcf, 0x4a, 0x4b, 0x8e,
0xcb, 0x76, 0x3a, 0x0d, 0x73, 0x9b, 0xb4, 0x95, 0x3c, 0xd5, 0x4f, 0x95, 0x36, 0x77, 0x2d, 0xc6,
0xf9, 0xcc, 0x75, 0x8f, 0x9d, 0x1e, 0x55, 0x81, 0x52, 0xef, 0xba, 0xc7, 0x6c, 0x20, 0x00, 0x37,
0x39, 0x9e, 0xf1, 0x51, 0x03, 0x39, 0x31, 0xd5, 0x35, 0xec, 0x13, 0xea, 0xf6, 0xee, 0xc0, 0x04,
0x69, 0xf2, 0xd2, 0xc3, 0x81, 0x1c, 0x42, 0x3d, 0x7f, 0x7a, 0x54, 0xcd, 0x29, 0x8c, 0xbb, 0xcd,
0x66, 0x80, 0x29, 0xdd, 0x60, 0x81, 0xeb, 0x39, 0xb6, 0x0c, 0xeb, 0x0d, 0x2d, 0xd9, 0x3f, 0xb4,
0xfb, 0x00, 0xf4, 0x9e, 0x83, 0x68, 0x2f, 0x5b, 0x5b, 0x32, 0x15, 0x0e, 0x7f, 0x0f, 0xa6, 0x7c,
0x82, 0x3d, 0x91, 0x38, 0x58, 0x55, 0x60, 0xf7, 0x65, 0x1a, 0x9f, 0x34, 0xf0, 0xef, 0x40, 0x99,
0xea, 0xb2, 0xd6, 0xc0, 0x64, 0x53, 0xd9, 0x94, 0x00, 0x8c, 0x98, 0x4b, 0x51, 0x69, 0x03, 0x12,
0xb8, 0xca, 0x84, 0x0f, 0x22, 0x75, 0x26, 0x45, 0x9d, 0xcb, 0x63, 0xeb, 0x94, 0x60, 0x91, 0x42,
0x7f, 0x6a, 0xe0, 0x9f, 0x01, 0x32, 0x78, 0x13, 0x4c, 0x29, 0x22, 0x32, 0x7e, 0x9c, 0xbd, 0x50,
0xf8, 0x10, 0x64, 0x94, 0x2e, 0x92, 0xa2, 0xb1, 0xf9, 0x51, 0xca, 0x16, 0x52, 0xa9, 0xcf, 0xf2,
0x9e, 0x0e, 0xcf, 0x4b, 0xd9, 0x9e, 0x8d, 0xda, 0x0a, 0x01, 0x22, 0x90, 0x96, 0x02, 0x4a, 0x09,
0xa8, 0x42, 0xa4, 0xb7, 0x10, 0xec, 0x1e, 0x71, 0xbd, 0xfa, 0x75, 0x05, 0x53, 0xf9, 0x03, 0x6d,
0xf1, 0x04, 0x6a, 0x4b, 0xe4, 0xda, 0xbb, 0x14, 0x48, 0x8b, 0x3b, 0x82, 0xaf, 0x41, 0x46, 0xbe,
0x76, 0xf8, 0x7f, 0x4c, 0xc9, 0xc3, 0x6b, 0xa5, 0xb8, 0x34, 0x2e, 0x4c, 0x4e, 0xd2, 0x58, 0x38,
0xf8, 0xfc, 0xe3, 0x43, 0x72, 0x0e, 0x16, 0xac, 0x51, 0xeb, 0x0f, 0x1e, 0x68, 0x20, 0x23, 0x37,
0xc4, 0x68, 0xf2, 0xc8, 0xb6, 0x19, 0x4d, 0x1e, 0x5d, 0x34, 0xc6, 0x35, 0x41, 0xbe, 0x08, 0x17,
0xac, 0x11, 0x9b, 0x93, 0x5a, 0x6f, 0x84, 0xea, 0xdf, 0xf2, 0x22, 0x26, 0x43, 0xa5, 0xc2, 0xe5,
0x51, 0xf8, 0x03, 0x4f, 0xae, 0x58, 0x19, 0x1f, 0xa8, 0x4a, 0x59, 0x14, 0xa5, 0xcc, 0xc3, 0xb9,
0x98, 0x52, 0x42, 0x4d, 0xd7, 0xd7, 0x8e, 0xbf, 0xeb, 0x89, 0xe3, 0x0b, 0x5d, 0x3b, 0xb9, 0xd0,
0xb5, 0x6f, 0x17, 0xba, 0xf6, 0xfe, 0x52, 0x4f, 0x9c, 0x5c, 0xea, 0x89, 0x2f, 0x97, 0x7a, 0xe2,
0x79, 0xff, 0xea, 0xe0, 0x20, 0xd5, 0x16, 0x6a, 0x50, 0x09, 0xf7, 0x4a, 0x02, 0x8a, 0x2b, 0x6e,
0x64, 0xc4, 0xe7, 0xe0, 0xc6, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x53, 0xed, 0x53, 0xe2, 0x3e,
0x07, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -745,10 +746,23 @@ func (m *VaultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x1a
}
if m.VaultStrategy != 0 {
i = encodeVarintQuery(dAtA, i, uint64(m.VaultStrategy))
if len(m.Strategies) > 0 {
dAtA3 := make([]byte, len(m.Strategies)*10)
var j2 int
for _, num := range m.Strategies {
for num >= 1<<7 {
dAtA3[j2] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j2++
}
dAtA3[j2] = uint8(num)
j2++
}
i -= j2
copy(dAtA[i:], dAtA3[:j2])
i = encodeVarintQuery(dAtA, i, uint64(j2))
i--
dAtA[i] = 0x10
dAtA[i] = 0x12
}
if len(m.Denom) > 0 {
i -= len(m.Denom)
@ -985,8 +999,12 @@ func (m *VaultResponse) Size() (n int) {
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
if m.VaultStrategy != 0 {
n += 1 + sovQuery(uint64(m.VaultStrategy))
if len(m.Strategies) > 0 {
l = 0
for _, e := range m.Strategies {
l += sovQuery(uint64(e))
}
n += 1 + sovQuery(uint64(l)) + l
}
l = len(m.TotalShares)
if l > 0 {
@ -1429,10 +1447,8 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error {
m.Denom = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field VaultStrategy", wireType)
}
m.VaultStrategy = 0
if wireType == 0 {
var v StrategyType
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
@ -1442,11 +1458,63 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.VaultStrategy |= StrategyType(b&0x7F) << shift
v |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Strategies = append(m.Strategies, v)
} else if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if packedLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + packedLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
var elementCount int
if elementCount != 0 && len(m.Strategies) == 0 {
m.Strategies = make([]StrategyType, 0, elementCount)
}
for iNdEx < postIndex {
var v StrategyType
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Strategies = append(m.Strategies, v)
}
} else {
return fmt.Errorf("proto: wrong wireType = %d for field Strategies", wireType)
}
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType)

62
x/earn/types/strategy.go Normal file
View File

@ -0,0 +1,62 @@
package types
import (
"fmt"
"strings"
)
// IsValid returns true if the StrategyType status is valid and false otherwise.
func (s StrategyType) IsValid() bool {
return s == STRATEGY_TYPE_HARD || s == STRATEGY_TYPE_SAVINGS
}
// Validate returns an error if the StrategyType is invalid.
func (s StrategyType) Validate() error {
if !s.IsValid() {
return fmt.Errorf("invalid strategy %s", s)
}
return nil
}
// NewStrategyTypeFromString converts string to StrategyType type
func NewStrategyTypeFromString(str string) StrategyType {
switch strings.ToLower(str) {
case "hard":
return STRATEGY_TYPE_HARD
case "savings":
return STRATEGY_TYPE_SAVINGS
default:
return STRATEGY_TYPE_UNSPECIFIED
}
}
// StrategyTypes defines a slice of StrategyType
type StrategyTypes []StrategyType
// Validate returns an error if StrategyTypes are invalid.
func (strategies StrategyTypes) Validate() error {
if len(strategies) == 0 {
return fmt.Errorf("empty StrategyTypes")
}
if len(strategies) != 1 {
return fmt.Errorf("must have exactly one strategy type, multiple strategies are not supported")
}
uniqueStrategies := make(map[StrategyType]bool)
for _, strategy := range strategies {
if err := strategy.Validate(); err != nil {
return err
}
if _, found := uniqueStrategies[strategy]; found {
return fmt.Errorf("duplicate strategy %s", strategy)
}
uniqueStrategies[strategy] = true
}
return nil
}

View File

@ -0,0 +1,120 @@
package types_test
import (
"testing"
"github.com/kava-labs/kava/x/earn/types"
"github.com/stretchr/testify/require"
)
func TestNewStrategyTypeFromString(t *testing.T) {
tests := []struct {
name string
strategy string
expected types.StrategyType
}{
{
name: "hard",
strategy: "hard",
expected: types.STRATEGY_TYPE_HARD,
},
{
name: "savings",
strategy: "savings",
expected: types.STRATEGY_TYPE_SAVINGS,
},
{
name: "unspecified",
strategy: "not a valid strategy name",
expected: types.STRATEGY_TYPE_UNSPECIFIED,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
actual := types.NewStrategyTypeFromString(tc.strategy)
if actual != tc.expected {
t.Errorf("expected %s, got %s", tc.expected, actual)
}
})
}
}
func TestValidateStrategyTypes(t *testing.T) {
type errArgs struct {
expectPass bool
contains string
}
tests := []struct {
name string
strategies types.StrategyTypes
errArgs errArgs
}{
{
name: "valid - hard",
strategies: types.StrategyTypes{types.STRATEGY_TYPE_HARD},
errArgs: errArgs{
expectPass: true,
},
},
{
name: "valid - savings",
strategies: types.StrategyTypes{types.STRATEGY_TYPE_SAVINGS},
errArgs: errArgs{
expectPass: true,
},
},
{
name: "invalid - duplicate",
strategies: types.StrategyTypes{
types.STRATEGY_TYPE_SAVINGS,
types.STRATEGY_TYPE_SAVINGS,
},
errArgs: errArgs{
expectPass: false,
// This will change to duplicate error if multiple strategies are supported
contains: "must have exactly one strategy type, multiple strategies are not supported",
},
},
{
name: "invalid - unspecified",
strategies: types.StrategyTypes{types.STRATEGY_TYPE_UNSPECIFIED},
errArgs: errArgs{
expectPass: false,
contains: "invalid strategy",
},
},
{
name: "invalid - zero",
strategies: types.StrategyTypes{},
errArgs: errArgs{
expectPass: false,
contains: "empty StrategyTypes",
},
},
{
name: "invalid - more than 1",
strategies: types.StrategyTypes{
types.STRATEGY_TYPE_HARD,
types.STRATEGY_TYPE_SAVINGS,
},
errArgs: errArgs{
expectPass: false,
contains: "must have exactly one strategy type, multiple strategies are not supported",
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.strategies.Validate()
if tc.errArgs.expectPass {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errArgs.contains)
}
})
}
}

View File

@ -37,6 +37,8 @@ type MsgDeposit struct {
// Amount represents the token to deposit. The vault corresponds to the denom
// of the amount coin.
Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount"`
// Strategy is the vault strategy to use.
Strategy StrategyType `protobuf:"varint,3,opt,name=strategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"strategy,omitempty"`
}
func (m *MsgDeposit) Reset() { *m = MsgDeposit{} }
@ -124,6 +126,8 @@ type MsgWithdraw struct {
// Amount represents the token to withdraw. The vault corresponds to the denom
// of the amount coin.
Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount"`
// Strategy is the vault strategy to use.
Strategy StrategyType `protobuf:"varint,3,opt,name=strategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"strategy,omitempty"`
}
func (m *MsgWithdraw) Reset() { *m = MsgWithdraw{} }
@ -214,33 +218,35 @@ func init() {
func init() { proto.RegisterFile("kava/earn/v1beta1/tx.proto", fileDescriptor_2e9dcf48a3fa0009) }
var fileDescriptor_2e9dcf48a3fa0009 = []byte{
// 404 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x4e, 0x2c, 0x4b,
0xd4, 0x4f, 0x4d, 0x2c, 0xca, 0xd3, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0xa9,
0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0xc9, 0xe9, 0x81, 0xe4, 0xf4, 0xa0, 0x72,
0x52, 0x92, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0x60, 0x05, 0xfa, 0x10, 0x0e, 0x44, 0xb5,
0x94, 0x1c, 0x84, 0xa7, 0x9f, 0x94, 0x58, 0x9c, 0x0a, 0x37, 0x2b, 0x39, 0x3f, 0x33, 0x0f, 0x2a,
0x2f, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0xd1, 0x07, 0x62, 0x41, 0x45, 0x65, 0x31, 0xed, 0x2f, 0x4b,
0x2c, 0xcd, 0x29, 0x81, 0x48, 0x2b, 0x35, 0x33, 0x72, 0x71, 0xf9, 0x16, 0xa7, 0xbb, 0xa4, 0x16,
0xe4, 0x17, 0x67, 0x96, 0x08, 0x99, 0x71, 0x71, 0xa6, 0x40, 0x98, 0xf9, 0x45, 0x12, 0x8c, 0x0a,
0x8c, 0x1a, 0x9c, 0x4e, 0x12, 0x97, 0xb6, 0xe8, 0x8a, 0x40, 0x1d, 0xe2, 0x98, 0x92, 0x52, 0x94,
0x5a, 0x5c, 0x1c, 0x5c, 0x52, 0x94, 0x99, 0x97, 0x1e, 0x84, 0x50, 0x2a, 0x64, 0xce, 0xc5, 0x96,
0x98, 0x9b, 0x5f, 0x9a, 0x57, 0x22, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa9, 0x07, 0xd5,
0x01, 0x72, 0x2c, 0xcc, 0x73, 0x7a, 0xce, 0xf9, 0x99, 0x79, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33,
0x04, 0x41, 0x95, 0x5b, 0xb1, 0x74, 0x2c, 0x90, 0x67, 0x50, 0x0a, 0xe4, 0x12, 0x42, 0x38, 0x22,
0x28, 0xb5, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, 0x9a, 0x8b, 0xad, 0x38, 0x23, 0xb1, 0x28,
0xb5, 0x18, 0xec, 0x12, 0x6e, 0x23, 0x59, 0x3d, 0x8c, 0xf0, 0xd2, 0x0b, 0x03, 0xf9, 0x25, 0x18,
0xa4, 0x0a, 0x66, 0x30, 0x44, 0x8b, 0x52, 0x15, 0x17, 0xb7, 0x6f, 0x71, 0x7a, 0x78, 0x66, 0x49,
0x46, 0x4a, 0x51, 0x62, 0xb9, 0x90, 0x0e, 0x17, 0x4b, 0x5a, 0x51, 0x7e, 0x2e, 0x41, 0x3f, 0x81,
0x55, 0x51, 0xea, 0x9d, 0x20, 0x2e, 0x61, 0x24, 0xbb, 0xa9, 0xe2, 0x1f, 0xa3, 0x55, 0x8c, 0x5c,
0xcc, 0xbe, 0xc5, 0xe9, 0x42, 0xfe, 0x5c, 0xec, 0xb0, 0xc8, 0xc2, 0xa6, 0x1f, 0x11, 0x8c, 0x52,
0xaa, 0x78, 0xa5, 0xe1, 0xae, 0x0a, 0xe2, 0xe2, 0x80, 0x87, 0x92, 0x1c, 0x76, 0x2d, 0x30, 0x79,
0x29, 0x35, 0xfc, 0xf2, 0x30, 0x33, 0x9d, 0x1c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e,
0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58,
0x8e, 0x21, 0x4a, 0x2d, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x64,
0x96, 0x6e, 0x4e, 0x62, 0x52, 0x31, 0x98, 0xa5, 0x5f, 0x01, 0x49, 0xa5, 0x25, 0x95, 0x05, 0xa9,
0xc5, 0x49, 0x6c, 0xe0, 0xe4, 0x69, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xb4, 0xb0, 0x19, 0x18,
0x3f, 0x03, 0x00, 0x00,
// 443 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x41, 0x8b, 0xd3, 0x40,
0x14, 0xc7, 0x33, 0x6e, 0xa9, 0xbb, 0x53, 0x10, 0x1c, 0xf7, 0xd0, 0x0d, 0xec, 0xb4, 0x14, 0x5c,
0x7a, 0x70, 0x27, 0x6c, 0x05, 0x05, 0xf7, 0xa2, 0xd5, 0x6b, 0x11, 0x53, 0x51, 0xf0, 0x22, 0x93,
0x66, 0x9c, 0x06, 0x37, 0x99, 0x30, 0x6f, 0x5a, 0xb7, 0xdf, 0xc0, 0xa3, 0x1f, 0xc1, 0xb3, 0x67,
0xc1, 0xab, 0xc7, 0x3d, 0x2e, 0x9e, 0x3c, 0x89, 0xb4, 0x5f, 0x44, 0x92, 0x99, 0xa4, 0x42, 0xcb,
0x7a, 0x11, 0xf6, 0xf6, 0x26, 0xff, 0xdf, 0xff, 0xe5, 0xbd, 0x7f, 0x32, 0xd8, 0x7f, 0xcf, 0xe7,
0x3c, 0x10, 0x5c, 0x67, 0xc1, 0xfc, 0x24, 0x12, 0x86, 0x9f, 0x04, 0xe6, 0x9c, 0xe5, 0x5a, 0x19,
0x45, 0x6e, 0x17, 0x1a, 0x2b, 0x34, 0xe6, 0x34, 0xff, 0x60, 0xa2, 0x20, 0x55, 0xf0, 0xb6, 0x04,
0x02, 0x7b, 0xb0, 0xb4, 0x4f, 0xed, 0x29, 0x88, 0x38, 0x88, 0xba, 0xd7, 0x44, 0x25, 0x99, 0xd3,
0xf7, 0xa5, 0x92, 0xca, 0xfa, 0x8a, 0xca, 0x3d, 0xed, 0x6e, 0xbe, 0x1f, 0x8c, 0xe6, 0x46, 0xc8,
0x85, 0x23, 0x0e, 0x37, 0x89, 0x39, 0x9f, 0x9d, 0x19, 0x2b, 0xf7, 0xbe, 0x23, 0x8c, 0x47, 0x20,
0x9f, 0x89, 0x5c, 0x41, 0x62, 0xc8, 0x03, 0xbc, 0x17, 0xdb, 0x52, 0xe9, 0x36, 0xea, 0xa2, 0xfe,
0xde, 0xb0, 0xfd, 0xe3, 0xeb, 0xf1, 0xbe, 0x1b, 0xf5, 0x49, 0x1c, 0x6b, 0x01, 0x30, 0x36, 0x3a,
0xc9, 0x64, 0xb8, 0x46, 0xc9, 0x43, 0xdc, 0xe4, 0xa9, 0x9a, 0x65, 0xa6, 0x7d, 0xa3, 0x8b, 0xfa,
0xad, 0xc1, 0x01, 0x73, 0x8e, 0x62, 0x9d, 0x6a, 0x7d, 0xf6, 0x54, 0x25, 0xd9, 0xb0, 0x71, 0xf1,
0xab, 0xe3, 0x85, 0x0e, 0x27, 0xa7, 0x78, 0xb7, 0x1a, 0xb8, 0xbd, 0xd3, 0x45, 0xfd, 0x5b, 0x83,
0x0e, 0xdb, 0xc8, 0x8d, 0x8d, 0x1d, 0xf2, 0x72, 0x91, 0x8b, 0xb0, 0x36, 0x3c, 0x6a, 0x7c, 0xfc,
0xdc, 0xf1, 0x7a, 0x2f, 0x30, 0x59, 0x6f, 0x10, 0x0a, 0xc8, 0x55, 0x06, 0x82, 0x9c, 0xe2, 0x26,
0x4c, 0xb9, 0x16, 0x50, 0xae, 0xd1, 0x1a, 0x1c, 0x6e, 0x69, 0xfb, 0xaa, 0x08, 0x62, 0x5c, 0x50,
0xd5, 0x54, 0xd6, 0xd2, 0xfb, 0x86, 0x70, 0x6b, 0x04, 0xf2, 0x75, 0x62, 0xa6, 0xb1, 0xe6, 0x1f,
0xc8, 0x3d, 0xdc, 0x78, 0xa7, 0x55, 0xfa, 0xcf, 0x44, 0x4a, 0xea, 0x5a, 0xc3, 0x08, 0xf1, 0x9d,
0xbf, 0x06, 0xff, 0x2f, 0x69, 0x0c, 0xbe, 0x20, 0xbc, 0x33, 0x02, 0x49, 0x9e, 0xe3, 0x9b, 0xd5,
0x7f, 0xb2, 0xcd, 0xbf, 0xfe, 0x08, 0xfe, 0xdd, 0x2b, 0xe5, 0x7a, 0xaa, 0x10, 0xef, 0xd6, 0x11,
0xd3, 0xed, 0x96, 0x4a, 0xf7, 0x8f, 0xae, 0xd6, 0xab, 0x9e, 0xc3, 0xc7, 0x17, 0x4b, 0x8a, 0x2e,
0x97, 0x14, 0xfd, 0x5e, 0x52, 0xf4, 0x69, 0x45, 0xbd, 0xcb, 0x15, 0xf5, 0x7e, 0xae, 0xa8, 0xf7,
0xe6, 0x48, 0x26, 0x66, 0x3a, 0x8b, 0xd8, 0x44, 0xa5, 0x41, 0xd1, 0xeb, 0xf8, 0x8c, 0x47, 0x50,
0x56, 0xc1, 0xb9, 0xbd, 0x20, 0x66, 0x91, 0x0b, 0x88, 0x9a, 0xe5, 0xcd, 0xb8, 0xff, 0x27, 0x00,
0x00, 0xff, 0xff, 0x23, 0xf1, 0x3e, 0x54, 0xdc, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -383,6 +389,11 @@ func (m *MsgDeposit) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.Strategy != 0 {
i = encodeVarintTx(dAtA, i, uint64(m.Strategy))
i--
dAtA[i] = 0x18
}
{
size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@ -456,6 +467,11 @@ func (m *MsgWithdraw) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.Strategy != 0 {
i = encodeVarintTx(dAtA, i, uint64(m.Strategy))
i--
dAtA[i] = 0x18
}
{
size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@ -532,6 +548,9 @@ func (m *MsgDeposit) Size() (n int) {
}
l = m.Amount.Size()
n += 1 + l + sovTx(uint64(l))
if m.Strategy != 0 {
n += 1 + sovTx(uint64(m.Strategy))
}
return n
}
@ -558,6 +577,9 @@ func (m *MsgWithdraw) Size() (n int) {
}
l = m.Amount.Size()
n += 1 + l + sovTx(uint64(l))
if m.Strategy != 0 {
n += 1 + sovTx(uint64(m.Strategy))
}
return n
}
@ -672,6 +694,25 @@ func (m *MsgDeposit) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType)
}
m.Strategy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Strategy |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTx(dAtA[iNdEx:])
@ -870,6 +911,25 @@ func (m *MsgWithdraw) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType)
}
m.Strategy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Strategy |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTx(dAtA[iNdEx:])

View File

@ -86,15 +86,17 @@ func (vsrs VaultShareRecords) Validate() error {
}
// NewAllowedVaults returns a new AllowedVaults with the given denom and strategy type.
func NewAllowedVault(denom string, strategyType StrategyType) AllowedVault {
func NewAllowedVault(denom string, strategyTypes ...StrategyType) AllowedVault {
return AllowedVault{
Denom: denom,
VaultStrategy: strategyType,
Strategies: strategyTypes,
}
}
// AllowedVaults is a slice of AllowedVault.
type AllowedVaults []AllowedVault
// Validate returns an error if the AllowedVaults is invalid.
func (a AllowedVaults) Validate() error {
denoms := make(map[string]bool)
@ -109,17 +111,27 @@ func (a AllowedVaults) Validate() error {
denoms[v.Denom] = true
}
return nil
}
// Validate returns an error if the AllowedVault is invalid
func (a *AllowedVault) Validate() error {
if err := sdk.ValidateDenom(a.Denom); err != nil {
return sdkerrors.Wrap(ErrInvalidVaultDenom, err.Error())
}
if a.VaultStrategy == STRATEGY_TYPE_UNSPECIFIED {
return ErrInvalidVaultStrategy
return a.Strategies.Validate()
}
return nil
// IsStrategyAllowed returns true if the given strategy type is allowed for the
// vault.
func (a *AllowedVault) IsStrategyAllowed(strategy StrategyType) bool {
for _, s := range a.Strategies {
if s == strategy {
return true
}
}
return false
}

View File

@ -32,7 +32,7 @@ type AllowedVault struct {
// Denom is the only supported denomination of the vault for deposits and withdrawals.
Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
// VaultStrategy is the strategy used for this vault.
VaultStrategy StrategyType `protobuf:"varint,2,opt,name=vault_strategy,json=vaultStrategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"vault_strategy,omitempty"`
Strategies StrategyTypes `protobuf:"varint,2,rep,packed,name=strategies,proto3,enum=kava.earn.v1beta1.StrategyType,castrepeated=StrategyTypes" json:"strategies,omitempty"`
}
func (m *AllowedVault) Reset() { *m = AllowedVault{} }
@ -75,11 +75,11 @@ func (m *AllowedVault) GetDenom() string {
return ""
}
func (m *AllowedVault) GetVaultStrategy() StrategyType {
func (m *AllowedVault) GetStrategies() StrategyTypes {
if m != nil {
return m.VaultStrategy
return m.Strategies
}
return STRATEGY_TYPE_UNSPECIFIED
return nil
}
// VaultRecord is the state of a vault.
@ -238,35 +238,36 @@ func init() {
func init() { proto.RegisterFile("kava/earn/v1beta1/vault.proto", fileDescriptor_884eb89509fbdc04) }
var fileDescriptor_884eb89509fbdc04 = []byte{
// 445 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x31, 0x8f, 0xd3, 0x30,
0x18, 0x4d, 0x8e, 0xa3, 0x52, 0x9d, 0x72, 0x82, 0xdc, 0x0d, 0xc7, 0x49, 0x4d, 0xa2, 0x0c, 0xa8,
0x4b, 0x12, 0xb5, 0x6c, 0x88, 0x81, 0x46, 0x55, 0x85, 0x18, 0xd3, 0xc2, 0xc0, 0x52, 0x39, 0x8e,
0x49, 0xab, 0x26, 0x71, 0x14, 0xbb, 0x85, 0x2c, 0xfc, 0x06, 0x46, 0x46, 0x66, 0xe6, 0xfe, 0x06,
0xd4, 0xb1, 0xea, 0x84, 0x18, 0x0a, 0x6a, 0xff, 0x05, 0x13, 0xb2, 0xe3, 0x12, 0xa4, 0x82, 0xb8,
0x29, 0xf6, 0xfb, 0xde, 0x7b, 0xdf, 0xfb, 0xf2, 0x19, 0xb4, 0xe7, 0x70, 0x09, 0x3d, 0x0c, 0x8b,
0xcc, 0x5b, 0x76, 0x43, 0xcc, 0x60, 0xd7, 0x5b, 0xc2, 0x45, 0xc2, 0xdc, 0xbc, 0x20, 0x8c, 0xe8,
0x0f, 0x78, 0xd9, 0xe5, 0x65, 0x57, 0x96, 0x6f, 0x1e, 0x22, 0x42, 0x53, 0x42, 0x27, 0x82, 0xe0,
0x55, 0x97, 0x8a, 0x7d, 0x63, 0x54, 0x37, 0x2f, 0x84, 0x14, 0xff, 0xb6, 0x43, 0x64, 0x96, 0xc9,
0xfa, 0x55, 0x4c, 0x62, 0x52, 0xe9, 0xf8, 0x49, 0xa2, 0xd6, 0x69, 0x04, 0xca, 0x0a, 0xc8, 0x70,
0x5c, 0x56, 0x0c, 0x3b, 0x01, 0xad, 0x7e, 0x92, 0x90, 0xb7, 0x38, 0x7a, 0xc5, 0xb3, 0xe9, 0x57,
0xe0, 0x6e, 0x84, 0x33, 0x92, 0x5e, 0xab, 0x96, 0xda, 0x69, 0x06, 0xd5, 0x45, 0x1f, 0x82, 0x0b,
0x11, 0x7d, 0x72, 0x54, 0x5f, 0x9f, 0x59, 0x6a, 0xe7, 0xa2, 0x67, 0xba, 0x27, 0x43, 0xb8, 0x23,
0x49, 0x19, 0x97, 0x39, 0x0e, 0xee, 0x09, 0xd9, 0x11, 0xb2, 0x5f, 0x02, 0x4d, 0xb4, 0x09, 0x30,
0x22, 0x45, 0xa4, 0x0f, 0x41, 0x8b, 0x11, 0x06, 0x93, 0x09, 0x9d, 0xc2, 0x02, 0x53, 0xd1, 0x53,
0xeb, 0xb5, 0xff, 0x62, 0x2a, 0x54, 0x23, 0xce, 0xf2, 0xcf, 0xd7, 0x3b, 0x53, 0x09, 0x34, 0x21,
0x14, 0x08, 0xb5, 0xbf, 0xa8, 0xe0, 0x7e, 0xcd, 0x90, 0xe6, 0x6f, 0x40, 0x33, 0xc2, 0x39, 0xa1,
0x33, 0x46, 0x0a, 0xe1, 0xdc, 0xf2, 0x9f, 0xff, 0xdc, 0x99, 0x4e, 0x3c, 0x63, 0xd3, 0x45, 0xe8,
0x22, 0x92, 0xca, 0x3f, 0x2c, 0x3f, 0x0e, 0x8d, 0xe6, 0x1e, 0x2b, 0x73, 0x4c, 0xdd, 0x3e, 0x42,
0xfd, 0x28, 0x2a, 0x30, 0xa5, 0xdb, 0x95, 0x73, 0x29, 0xf7, 0x20, 0x11, 0xbf, 0x64, 0x98, 0x06,
0xb5, 0xb5, 0xfe, 0x02, 0x34, 0x64, 0xfc, 0x33, 0xeb, 0xce, 0xff, 0xe3, 0x5f, 0xf2, 0xf8, 0x9f,
0xbf, 0x9b, 0x5a, 0x8d, 0xd1, 0x40, 0x3a, 0xd8, 0xef, 0x01, 0xa8, 0xe1, 0x7f, 0xec, 0x62, 0x0c,
0x1a, 0x30, 0x25, 0x8b, 0x8c, 0x89, 0x1d, 0x34, 0xfd, 0xa7, 0xdc, 0xf0, 0xdb, 0xce, 0x7c, 0x74,
0x8b, 0xc1, 0x06, 0x18, 0x6d, 0x57, 0x0e, 0x90, 0x13, 0x0d, 0x30, 0x0a, 0xa4, 0xd7, 0x93, 0xf3,
0x8f, 0x9f, 0x4c, 0xc5, 0x7f, 0xb6, 0xde, 0x1b, 0xea, 0x66, 0x6f, 0xa8, 0x3f, 0xf6, 0x86, 0xfa,
0xe1, 0x60, 0x28, 0x9b, 0x83, 0xa1, 0x7c, 0x3d, 0x18, 0xca, 0xeb, 0x3f, 0xdd, 0xf9, 0x7c, 0x4e,
0x02, 0x43, 0x2a, 0x4e, 0xde, 0xbb, 0xea, 0x81, 0x89, 0x0e, 0x61, 0x43, 0x3c, 0xab, 0xc7, 0xbf,
0x02, 0x00, 0x00, 0xff, 0xff, 0x19, 0x75, 0x6f, 0x0e, 0xfd, 0x02, 0x00, 0x00,
// 450 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x6f, 0xd3, 0x40,
0x14, 0xc7, 0xed, 0x52, 0x22, 0xf5, 0x1c, 0x10, 0x75, 0x3b, 0x84, 0x4a, 0xb5, 0x23, 0x0f, 0xa8,
0x8b, 0x6d, 0xb5, 0x6c, 0x88, 0x81, 0x58, 0x15, 0x42, 0x8c, 0xd7, 0xc2, 0xc0, 0x52, 0x9d, 0xcf,
0x87, 0x6b, 0xd5, 0xf6, 0x45, 0x7e, 0x97, 0x90, 0x2c, 0x7c, 0x06, 0x46, 0x46, 0xe6, 0xcc, 0xf9,
0x0c, 0x28, 0x63, 0x94, 0x09, 0x31, 0x24, 0x28, 0xf9, 0x16, 0x4c, 0xe8, 0xce, 0x27, 0x1c, 0x29,
0x20, 0x98, 0xec, 0xf7, 0x7f, 0xef, 0xfd, 0xde, 0xff, 0xdd, 0x1d, 0x3a, 0xbd, 0x23, 0x43, 0x12,
0x32, 0x52, 0x95, 0xe1, 0xf0, 0x3c, 0x66, 0x82, 0x9c, 0x87, 0x43, 0x32, 0xc8, 0x45, 0xd0, 0xaf,
0xb8, 0xe0, 0xf6, 0xa1, 0x4c, 0x07, 0x32, 0x1d, 0xe8, 0xf4, 0xc9, 0x63, 0xca, 0xa1, 0xe0, 0x70,
0xa3, 0x0a, 0xc2, 0x3a, 0xa8, 0xab, 0x4f, 0x9c, 0x3a, 0x0a, 0x63, 0x02, 0xec, 0x37, 0x8e, 0xf2,
0xac, 0xd4, 0xf9, 0xe3, 0x94, 0xa7, 0xbc, 0xee, 0x93, 0x7f, 0x5a, 0xed, 0xee, 0x5a, 0x00, 0x51,
0x11, 0xc1, 0xd2, 0x71, 0x5d, 0xe1, 0x8d, 0x50, 0xbb, 0x97, 0xe7, 0xfc, 0x03, 0x4b, 0xde, 0x4a,
0x6f, 0xf6, 0x31, 0xba, 0x9f, 0xb0, 0x92, 0x17, 0x1d, 0xb3, 0x6b, 0x9e, 0x1d, 0xe0, 0x3a, 0xb0,
0x31, 0x42, 0xba, 0x2f, 0x63, 0xd0, 0xd9, 0xeb, 0xde, 0x3b, 0x7b, 0x78, 0xe1, 0x06, 0x3b, 0x0b,
0x04, 0x57, 0x1a, 0x7e, 0x3d, 0xee, 0xb3, 0xe8, 0x70, 0xb2, 0x72, 0x1f, 0x6c, 0x2b, 0x80, 0xb7,
0x28, 0xde, 0x1b, 0x64, 0xa9, 0x91, 0x98, 0x51, 0x5e, 0x25, 0xf6, 0x4b, 0xd4, 0x16, 0x5c, 0x90,
0xfc, 0x06, 0x6e, 0x49, 0xc5, 0x40, 0xcd, 0xb7, 0x2e, 0x4e, 0xff, 0x30, 0x44, 0x75, 0x5d, 0xc9,
0xaa, 0x68, 0x7f, 0xb6, 0x74, 0x0d, 0x6c, 0xa9, 0x46, 0xa5, 0x80, 0xf7, 0xd5, 0x44, 0x8f, 0x9a,
0x0a, 0x0d, 0x7f, 0x8f, 0x0e, 0x12, 0xd6, 0xe7, 0x90, 0x09, 0x5e, 0x29, 0x72, 0x3b, 0x7a, 0xf5,
0x73, 0xe9, 0xfa, 0x69, 0x26, 0x6e, 0x07, 0x71, 0x40, 0x79, 0xa1, 0x4f, 0x5b, 0x7f, 0x7c, 0x48,
0xee, 0x42, 0x21, 0x2d, 0x07, 0x3d, 0x4a, 0x7b, 0x49, 0x52, 0x31, 0x80, 0xc5, 0xd4, 0x3f, 0xd2,
0x77, 0xa2, 0x95, 0x68, 0x2c, 0x18, 0xe0, 0x06, 0x6d, 0xbf, 0x46, 0x2d, 0x6d, 0x5f, 0x9e, 0xd1,
0x3f, 0xed, 0x1f, 0x49, 0xfb, 0x93, 0x95, 0x6b, 0x35, 0x1a, 0x60, 0x4d, 0xf0, 0x3e, 0x22, 0xd4,
0xc8, 0x7f, 0xb9, 0x97, 0x6b, 0xd4, 0x22, 0x05, 0x1f, 0x94, 0xa2, 0xb3, 0x27, 0xe5, 0xe8, 0xb9,
0x04, 0x7e, 0x5f, 0xba, 0x4f, 0xfe, 0x63, 0xb1, 0x4b, 0x46, 0x17, 0x53, 0x1f, 0xe9, 0x8d, 0x2e,
0x19, 0xc5, 0x9a, 0xf5, 0x6c, 0xff, 0xf3, 0x17, 0xd7, 0x88, 0x5e, 0xcc, 0xd6, 0x8e, 0x39, 0x5f,
0x3b, 0xe6, 0x8f, 0xb5, 0x63, 0x7e, 0xda, 0x38, 0xc6, 0x7c, 0xe3, 0x18, 0xdf, 0x36, 0x8e, 0xf1,
0x6e, 0x9b, 0x2e, 0xf7, 0xf3, 0x73, 0x12, 0x83, 0xfa, 0x0b, 0x47, 0xf5, 0x63, 0x53, 0x13, 0xe2,
0x96, 0x7a, 0x62, 0x4f, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xae, 0x23, 0x43, 0xb6, 0x09, 0x03,
0x00, 0x00,
}
func (m *AllowedVault) Marshal() (dAtA []byte, err error) {
@ -289,10 +290,23 @@ func (m *AllowedVault) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VaultStrategy != 0 {
i = encodeVarintVault(dAtA, i, uint64(m.VaultStrategy))
if len(m.Strategies) > 0 {
dAtA2 := make([]byte, len(m.Strategies)*10)
var j1 int
for _, num := range m.Strategies {
for num >= 1<<7 {
dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j1++
}
dAtA2[j1] = uint8(num)
j1++
}
i -= j1
copy(dAtA[i:], dAtA2[:j1])
i = encodeVarintVault(dAtA, i, uint64(j1))
i--
dAtA[i] = 0x10
dAtA[i] = 0x12
}
if len(m.Denom) > 0 {
i -= len(m.Denom)
@ -442,8 +456,12 @@ func (m *AllowedVault) Size() (n int) {
if l > 0 {
n += 1 + l + sovVault(uint64(l))
}
if m.VaultStrategy != 0 {
n += 1 + sovVault(uint64(m.VaultStrategy))
if len(m.Strategies) > 0 {
l = 0
for _, e := range m.Strategies {
l += sovVault(uint64(e))
}
n += 1 + sovVault(uint64(l)) + l
}
return n
}
@ -561,10 +579,8 @@ func (m *AllowedVault) Unmarshal(dAtA []byte) error {
m.Denom = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field VaultStrategy", wireType)
}
m.VaultStrategy = 0
if wireType == 0 {
var v StrategyType
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowVault
@ -574,11 +590,63 @@ func (m *AllowedVault) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.VaultStrategy |= StrategyType(b&0x7F) << shift
v |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Strategies = append(m.Strategies, v)
} else if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowVault
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if packedLen < 0 {
return ErrInvalidLengthVault
}
postIndex := iNdEx + packedLen
if postIndex < 0 {
return ErrInvalidLengthVault
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
var elementCount int
if elementCount != 0 && len(m.Strategies) == 0 {
m.Strategies = make([]StrategyType, 0, elementCount)
}
for iNdEx < postIndex {
var v StrategyType
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowVault
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= StrategyType(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Strategies = append(m.Strategies, v)
}
} else {
return fmt.Errorf("proto: wrong wireType = %d for field Strategies", wireType)
}
default:
iNdEx = preIndex
skippy, err := skipVault(dAtA[iNdEx:])

View File

@ -209,11 +209,11 @@ func TestAllowedVaultsValidate(t *testing.T) {
vaultRecords: types.AllowedVaults{
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
},
{
Denom: "busd",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
},
},
errArgs: errArgs{
@ -225,11 +225,11 @@ func TestAllowedVaultsValidate(t *testing.T) {
vaultRecords: types.AllowedVaults{
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
},
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
},
},
errArgs: errArgs{
@ -242,7 +242,7 @@ func TestAllowedVaultsValidate(t *testing.T) {
vaultRecords: types.AllowedVaults{
{
Denom: "",
VaultStrategy: types.STRATEGY_TYPE_HARD,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD},
},
},
errArgs: errArgs{
@ -255,12 +255,12 @@ func TestAllowedVaultsValidate(t *testing.T) {
vaultRecords: types.AllowedVaults{
{
Denom: "usdx",
VaultStrategy: types.STRATEGY_TYPE_UNSPECIFIED,
Strategies: []types.StrategyType{types.STRATEGY_TYPE_UNSPECIFIED},
},
},
errArgs: errArgs{
expectPass: false,
contains: "invalid vault strategy",
contains: "invalid strategy STRATEGY_TYPE_UNSPECIFIED",
},
},
}