From 8593d26c24e59b548b99183c08243b3bbf8cfa8c Mon Sep 17 00:00:00 2001 From: Derrick Lee Date: Mon, 12 Sep 2022 10:29:35 -0700 Subject: [PATCH] Add private Earn vault with allowed depositors (#1289) * Add IsPrivateVault and AllowedDepositors to types * Check if account is allowed to deposit --- client/docs/swagger-ui/swagger.yaml | 165 +++++++++++++++++++++++ docs/core/proto-docs.md | 4 + proto/kava/earn/v1beta1/query.proto | 14 +- proto/kava/earn/v1beta1/vault.proto | 13 ++ x/earn/genesis_test.go | 34 ++++- x/earn/keeper/deposit.go | 6 + x/earn/keeper/deposit_test.go | 31 ++++- x/earn/keeper/grpc_query.go | 19 ++- x/earn/keeper/grpc_query_test.go | 56 ++++---- x/earn/keeper/msg_server_test.go | 4 +- x/earn/keeper/strategy_hard_test.go | 26 ++-- x/earn/keeper/vault_share_test.go | 2 +- x/earn/keeper/vault_test.go | 12 +- x/earn/keeper/withdraw_test.go | 14 +- x/earn/testutil/suite.go | 9 +- x/earn/types/errors.go | 1 + x/earn/types/query.pb.go | 201 ++++++++++++++++++++-------- x/earn/types/vault.go | 82 ++++++++---- x/earn/types/vault.pb.go | 165 ++++++++++++++++++----- x/earn/types/vault_test.go | 117 ++++++++++++++-- 20 files changed, 783 insertions(+), 192 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index dafdd2f0..f6937da3 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -7180,6 +7180,30 @@ paths: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows + depositors contained in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + format: byte + description: >- + AllowedDepositors is a list of addresses that are + allowed to deposit to + + this vault if IsPrivateVault is true. Addresses not + contained in this list + + are not allowed to deposit into this vault. If + IsPrivateVault is false, + + this should be empty and ignored. description: >- AllowedVault is a vault that is allowed to be created. These can be @@ -7250,6 +7274,29 @@ paths: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows + depositors contained in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + description: >- + AllowedDepositors is a list of addresses that are + allowed to deposit to + + this vault if IsPrivateVault is true. Addresses not + contained in this list + + are not allowed to deposit into this vault. If + IsPrivateVault is false, + + this should be empty and ignored. total_shares: type: string description: >- @@ -54212,6 +54259,30 @@ definitions: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows depositors contained + in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + format: byte + description: >- + AllowedDepositors is a list of addresses that are allowed to deposit + to + + this vault if IsPrivateVault is true. Addresses not contained in this + list + + are not allowed to deposit into this vault. If IsPrivateVault is + false, + + this should be empty and ignored. description: |- AllowedVault is a vault that is allowed to be created. These can be modified via parameter governance. @@ -54287,6 +54358,30 @@ definitions: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows depositors + contained in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + format: byte + description: >- + AllowedDepositors is a list of addresses that are allowed to + deposit to + + this vault if IsPrivateVault is true. Addresses not contained in + this list + + are not allowed to deposit into this vault. If IsPrivateVault is + false, + + this should be empty and ignored. description: |- AllowedVault is a vault that is allowed to be created. These can be modified via parameter governance. @@ -54399,6 +54494,30 @@ definitions: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows depositors + contained in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + format: byte + description: >- + AllowedDepositors is a list of addresses that are allowed to + deposit to + + this vault if IsPrivateVault is true. Addresses not + contained in this list + + are not allowed to deposit into this vault. If + IsPrivateVault is false, + + this should be empty and ignored. description: >- AllowedVault is a vault that is allowed to be created. These can be @@ -54438,6 +54557,29 @@ definitions: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows depositors + contained in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + description: >- + AllowedDepositors is a list of addresses that are allowed to + deposit to + + this vault if IsPrivateVault is true. Addresses not contained in + this list + + are not allowed to deposit into this vault. If IsPrivateVault is + false, + + this should be empty and ignored. total_shares: type: string description: TotalShares is the total amount of shares issued to depositors. @@ -54491,6 +54633,29 @@ definitions: - 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. + is_private_vault: + type: boolean + format: boolean + description: >- + IsPrivateVault is true if the vault only allows depositors contained + in + + AllowedDepositors. + allowed_depositors: + type: array + items: + type: string + description: >- + AllowedDepositors is a list of addresses that are allowed to deposit + to + + this vault if IsPrivateVault is true. Addresses not contained in this + list + + are not allowed to deposit into this vault. If IsPrivateVault is + false, + + this should be empty and ignored. total_shares: type: string description: TotalShares is the total amount of shares issued to depositors. diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 777b52fd..c2f9c807 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -2807,6 +2807,8 @@ modified via parameter governance. | ----- | ---- | ----- | ----------- | | `denom` | [string](#string) | | Denom is the only supported denomination of the vault for deposits and withdrawals. | | `strategies` | [StrategyType](#kava.earn.v1beta1.StrategyType) | repeated | VaultStrategy is the strategy used for this vault. | +| `is_private_vault` | [bool](#bool) | | IsPrivateVault is true if the vault only allows depositors contained in AllowedDepositors. | +| `allowed_depositors` | [bytes](#bytes) | repeated | AllowedDepositors is a list of addresses that are allowed to deposit to this vault if IsPrivateVault is true. Addresses not contained in this list are not allowed to deposit into this vault. If IsPrivateVault is false, this should be empty and ignored. | @@ -3055,6 +3057,8 @@ VaultResponse is the response type for a vault. | ----- | ---- | ----- | ----------- | | `denom` | [string](#string) | | denom represents the denom of the vault | | `strategies` | [StrategyType](#kava.earn.v1beta1.StrategyType) | repeated | VaultStrategy is the strategy used for this vault. | +| `is_private_vault` | [bool](#bool) | | IsPrivateVault is true if the vault only allows depositors contained in AllowedDepositors. | +| `allowed_depositors` | [string](#string) | repeated | AllowedDepositors is a list of addresses that are allowed to deposit to this vault if IsPrivateVault is true. Addresses not contained in this list are not allowed to deposit into this vault. If IsPrivateVault is false, this should be empty and ignored. | | `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. | diff --git a/proto/kava/earn/v1beta1/query.proto b/proto/kava/earn/v1beta1/query.proto index abd22f72..5dca231c 100644 --- a/proto/kava/earn/v1beta1/query.proto +++ b/proto/kava/earn/v1beta1/query.proto @@ -60,12 +60,22 @@ message VaultResponse { // VaultStrategy is the strategy used for this vault. repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"]; + // IsPrivateVault is true if the vault only allows depositors contained in + // AllowedDepositors. + bool is_private_vault = 3; + + // AllowedDepositors is a list of addresses that are allowed to deposit to + // this vault if IsPrivateVault is true. Addresses not contained in this list + // are not allowed to deposit into this vault. If IsPrivateVault is false, + // this should be empty and ignored. + repeated string allowed_depositors = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // TotalShares is the total amount of shares issued to depositors. - string total_shares = 3; + string total_shares = 5; // TotalValue is the total value of denom coins supplied to the vault if the // vault were to be liquidated. - string total_value = 4 [ + string total_value = 6 [ (cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false diff --git a/proto/kava/earn/v1beta1/vault.proto b/proto/kava/earn/v1beta1/vault.proto index 7baf0276..aea5d6d9 100644 --- a/proto/kava/earn/v1beta1/vault.proto +++ b/proto/kava/earn/v1beta1/vault.proto @@ -15,6 +15,19 @@ message AllowedVault { // VaultStrategy is the strategy used for this vault. repeated StrategyType strategies = 2 [(gogoproto.castrepeated) = "StrategyTypes"]; + + // IsPrivateVault is true if the vault only allows depositors contained in + // AllowedDepositors. + bool is_private_vault = 3; + + // AllowedDepositors is a list of addresses that are allowed to deposit to + // this vault if IsPrivateVault is true. Addresses not contained in this list + // are not allowed to deposit into this vault. If IsPrivateVault is false, + // this should be empty and ignored. + repeated bytes allowed_depositors = 4 [ + (cosmos_proto.scalar) = "cosmos.AddressBytes", + (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" + ]; } // VaultRecord is the state of a vault. diff --git a/x/earn/genesis_test.go b/x/earn/genesis_test.go index e52b559e..2d982a6d 100644 --- a/x/earn/genesis_test.go +++ b/x/earn/genesis_test.go @@ -20,7 +20,11 @@ func (suite *genesisTestSuite) Test_InitGenesis_ValidationPanic() { invalidState := types.NewGenesisState( types.Params{ AllowedVaults: types.AllowedVaults{ - types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD), + types.NewAllowedVault( + "usdx", types.StrategyTypes{types.STRATEGY_TYPE_HARD}, + false, + nil, + ), }, }, types.VaultRecords{ @@ -48,8 +52,18 @@ func (suite *genesisTestSuite) Test_InitAndExportGenesis() { state := types.NewGenesisState( types.Params{ AllowedVaults: types.AllowedVaults{ - types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD), - types.NewAllowedVault("ukava", types.STRATEGY_TYPE_SAVINGS), + types.NewAllowedVault( + "usdx", + types.StrategyTypes{types.STRATEGY_TYPE_HARD}, + false, + nil, + ), + types.NewAllowedVault( + "ukava", + types.StrategyTypes{types.STRATEGY_TYPE_SAVINGS}, + true, + []sdk.AccAddress{suite.AccountKeeper.GetModuleAddress("distribution")}, + ), }, }, types.VaultRecords{ @@ -106,8 +120,18 @@ func (suite *genesisTestSuite) Test_Marshall() { state := types.NewGenesisState( types.Params{ AllowedVaults: types.AllowedVaults{ - types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD), - types.NewAllowedVault("ukava", types.STRATEGY_TYPE_SAVINGS), + types.NewAllowedVault( + "usdx", + types.StrategyTypes{types.STRATEGY_TYPE_HARD}, + false, + nil, + ), + types.NewAllowedVault( + "ukava", + types.StrategyTypes{types.STRATEGY_TYPE_SAVINGS}, + true, + []sdk.AccAddress{suite.AccountKeeper.GetModuleAddress("distribution")}, + ), }, }, types.VaultRecords{ diff --git a/x/earn/keeper/deposit.go b/x/earn/keeper/deposit.go index b577608b..3ee6e7b8 100644 --- a/x/earn/keeper/deposit.go +++ b/x/earn/keeper/deposit.go @@ -30,6 +30,12 @@ func (k *Keeper) Deposit( return types.ErrInvalidVaultStrategy } + // Check if account can deposit -- this checks if the vault is private + // and if so, if the depositor is in the AllowedDepositors list + if !allowedVault.IsAccountAllowed(depositor) { + return types.ErrAccountDepositNotAllowed + } + // Check if VaultRecord exists, create if not exist vaultRecord, found := k.GetVaultRecord(ctx, amount.Denom) if !found { diff --git a/x/earn/keeper/deposit_test.go b/x/earn/keeper/deposit_test.go index 7405b2be..0c2cc763 100644 --- a/x/earn/keeper/deposit_test.go +++ b/x/earn/keeper/deposit_test.go @@ -38,7 +38,7 @@ func (suite *depositTestSuite) TestDeposit_Balances() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -61,7 +61,7 @@ func (suite *depositTestSuite) TestDeposit_Exceed() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 1001) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -86,7 +86,7 @@ func (suite *depositTestSuite) TestDeposit_Zero() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 0) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -136,7 +136,7 @@ func (suite *depositTestSuite) TestDeposit_InvalidStrategy() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 1001) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -144,3 +144,26 @@ func (suite *depositTestSuite) TestDeposit_InvalidStrategy() { suite.Require().Error(err) suite.Require().ErrorIs(err, types.ErrInvalidVaultStrategy) } + +func (suite *depositTestSuite) TestDeposit_PrivateVault() { + vaultDenom := "usdx" + startBalance := sdk.NewInt64Coin(vaultDenom, 1000) + depositAmount := sdk.NewInt64Coin(vaultDenom, 100) + + acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) + acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1) + + suite.CreateVault( + vaultDenom, + types.StrategyTypes{types.STRATEGY_TYPE_HARD}, + true, + []sdk.AccAddress{acc1.GetAddress()}, + ) + + err := suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD) + suite.Require().Error(err) + suite.Require().ErrorIs(err, types.ErrAccountDepositNotAllowed, "private vault should not allow deposits from non-allowed addresses") + + err = suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD) + suite.Require().NoError(err, "private vault should allow deposits from allowed addresses") +} diff --git a/x/earn/keeper/grpc_query.go b/x/earn/keeper/grpc_query.go index 38017e8f..14d06715 100644 --- a/x/earn/keeper/grpc_query.go +++ b/x/earn/keeper/grpc_query.go @@ -81,10 +81,12 @@ func (s queryServer) Vaults( } vaults = append(vaults, types.VaultResponse{ - Denom: allowedVault.Denom, - Strategies: allowedVault.Strategies, - TotalShares: vaultTotalShares.Amount.String(), - TotalValue: totalValue.Amount, + Denom: allowedVault.Denom, + Strategies: allowedVault.Strategies, + IsPrivateVault: allowedVault.IsPrivateVault, + AllowedDepositors: addressSliceToStringSlice(allowedVault.AllowedDepositors), + TotalShares: vaultTotalShares.Amount.String(), + TotalValue: totalValue.Amount, }) } @@ -315,3 +317,12 @@ func getAccountValue( return value, nil } + +func addressSliceToStringSlice(addresses []sdk.AccAddress) []string { + var strings []string + for _, address := range addresses { + strings = append(strings, address.String()) + } + + return strings +} diff --git a/x/earn/keeper/grpc_query_test.go b/x/earn/keeper/grpc_query_test.go index 86f98277..2146cc9e 100644 --- a/x/earn/keeper/grpc_query_test.go +++ b/x/earn/keeper/grpc_query_test.go @@ -44,14 +44,14 @@ func (suite *grpcQueryTestSuite) TestQueryParams() { suite.Require().ElementsMatch(types.DefaultParams().AllowedVaults, res.Params.AllowedVaults) // Add vault to params - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Query again for added vault res, err = suite.queryClient.Params(context.Background(), types.NewQueryParamsRequest()) suite.Require().NoError(err) suite.Require().Equal( types.AllowedVaults{ - types.NewAllowedVault(vaultDenom, types.STRATEGY_TYPE_HARD), + types.NewAllowedVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil), }, res.Params.AllowedVaults, ) @@ -59,8 +59,8 @@ func (suite *grpcQueryTestSuite) TestQueryParams() { func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() { // Add vaults - suite.CreateVault("usdx", types.STRATEGY_TYPE_HARD) - suite.CreateVault("busd", types.STRATEGY_TYPE_HARD) + suite.CreateVault("usdx", types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) + suite.CreateVault("busd", types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) suite.Run("single", func() { res, err := suite.queryClient.Vaults(context.Background(), types.NewQueryVaultsRequest("usdx")) @@ -68,10 +68,12 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() { suite.Require().Len(res.Vaults, 1) suite.Require().Equal( types.VaultResponse{ - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, - TotalShares: sdk.NewDec(0).String(), - TotalValue: sdk.NewInt(0), + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: nil, + TotalShares: sdk.NewDec(0).String(), + TotalValue: sdk.NewInt(0), }, res.Vaults[0], ) @@ -84,16 +86,20 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() { suite.Require().ElementsMatch( []types.VaultResponse{ { - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, - TotalShares: sdk.NewDec(0).String(), - TotalValue: sdk.NewInt(0), + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: nil, + TotalShares: sdk.NewDec(0).String(), + TotalValue: sdk.NewInt(0), }, { - Denom: "busd", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, - TotalShares: sdk.NewDec(0).String(), - TotalValue: sdk.NewInt(0), + Denom: "busd", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: nil, + TotalShares: sdk.NewDec(0).String(), + TotalValue: sdk.NewInt(0), }, }, res.Vaults, @@ -107,7 +113,7 @@ func (suite *grpcQueryTestSuite) TestVaults_WithSupply() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -119,10 +125,12 @@ func (suite *grpcQueryTestSuite) TestVaults_WithSupply() { suite.Require().Len(res.Vaults, 1) suite.Require().Equal( types.VaultResponse{ - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, - TotalShares: depositAmount.Amount.ToDec().String(), - TotalValue: depositAmount.Amount, + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: nil, + TotalShares: depositAmount.Amount.ToDec().String(), + TotalValue: depositAmount.Amount, }, res.Vaults[0], ) @@ -140,9 +148,9 @@ func (suite *grpcQueryTestSuite) TestDeposits() { vault3Denom := "kava" // Add vaults - suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD) - suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD) - suite.CreateVault(vault3Denom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vault1Denom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) + suite.CreateVault(vault2Denom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) + suite.CreateVault(vault3Denom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) startBalance := sdk.NewCoins( sdk.NewInt64Coin(vault1Denom, 1000), diff --git a/x/earn/keeper/msg_server_test.go b/x/earn/keeper/msg_server_test.go index 88a5246b..31a3e8cd 100644 --- a/x/earn/keeper/msg_server_test.go +++ b/x/earn/keeper/msg_server_test.go @@ -34,7 +34,7 @@ func TestMsgServerTestSuite(t *testing.T) { func (suite *msgServerTestSuite) TestDeposit() { vaultDenom := "usdx" - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) @@ -87,7 +87,7 @@ func (suite *msgServerTestSuite) TestDeposit() { func (suite *msgServerTestSuite) TestWithdraw() { vaultDenom := "usdx" - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) diff --git a/x/earn/keeper/strategy_hard_test.go b/x/earn/keeper/strategy_hard_test.go index dacc0e7d..08261718 100644 --- a/x/earn/keeper/strategy_hard_test.go +++ b/x/earn/keeper/strategy_hard_test.go @@ -36,7 +36,7 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -61,7 +61,7 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc_MultipleDeposits() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -93,7 +93,7 @@ func (suite *strategyHardTestSuite) TestDeposit_MultipleAcc_MultipleDeposits() { expectedTotalValue := sdk.NewCoin(vaultDenom, depositAmount.Amount.MulRaw(4)) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -125,7 +125,7 @@ func (suite *strategyHardTestSuite) TestDeposit_MultipleAcc_MultipleDeposits() { func (suite *strategyHardTestSuite) TestGetVaultTotalValue_Empty() { vaultDenom := "usdx" - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Query vault total totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom) @@ -141,8 +141,8 @@ func (suite *strategyHardTestSuite) TestGetVaultTotalValue_NoDenomDeposit() { vaultDenom := "usdx" vaultDenomBusd := "busd" - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) - suite.CreateVault(vaultDenomBusd, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) + suite.CreateVault(vaultDenomBusd, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) @@ -170,7 +170,7 @@ func (suite *strategyHardTestSuite) TestWithdraw() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD) @@ -206,7 +206,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_OnlyWithdrawOwnSupply() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposits from 2 accounts acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() @@ -236,7 +236,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposits accounts acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() @@ -295,7 +295,7 @@ func (suite *strategyHardTestSuite) TestAccountShares() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 1000))) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposit from account1 acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() @@ -370,7 +370,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedAmount() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 1000))) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposit from account1 acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() @@ -408,7 +408,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedTruncated() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 1000))) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposit from account1 acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() @@ -453,7 +453,7 @@ func (suite *strategyHardTestSuite) TestWithdraw_ExpensiveShares() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 2000))) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposit from account1 acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress() diff --git a/x/earn/keeper/vault_share_test.go b/x/earn/keeper/vault_share_test.go index 35a46e88..c46d253b 100644 --- a/x/earn/keeper/vault_share_test.go +++ b/x/earn/keeper/vault_share_test.go @@ -67,7 +67,7 @@ func (suite *vaultShareTestSuite) TestConvertToShares() { suite.Run(tt.name, func() { // Reset state suite.Suite.SetupTest() - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) err := suite.App.FundModuleAccount( suite.Ctx, types.ModuleName, diff --git a/x/earn/keeper/vault_test.go b/x/earn/keeper/vault_test.go index 15a77028..308513f8 100644 --- a/x/earn/keeper/vault_test.go +++ b/x/earn/keeper/vault_test.go @@ -28,7 +28,7 @@ func (suite *vaultTestSuite) TestGetVaultTotalShares() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) depositAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -51,7 +51,7 @@ func (suite *vaultTestSuite) TestGetVaultTotalShares_NotFound() { func (suite *vaultTestSuite) TestGetVaultTotalValue() { vaultDenom := "usdx" - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom) suite.Require().NoError(err) @@ -70,7 +70,7 @@ func (suite *vaultTestSuite) TestInvalidVaultStrategy() { vaultDenom := "usdx" suite.PanicsWithValue("value from ParamSetPair is invalid: invalid strategy 99999", func() { - suite.CreateVault(vaultDenom, 99999) // not valid strategy type + suite.CreateVault(vaultDenom, types.StrategyTypes{99999}, false, nil) // not valid strategy type }) } @@ -80,7 +80,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountSupplied() { deposit1Amount := sdk.NewInt64Coin(vaultDenom, 100) deposit2Amount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1) @@ -120,7 +120,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue() { acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD) suite.Require().NoError(err) @@ -147,7 +147,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue_ShareNotFound() { acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Deposit from acc1 so that vault record exists err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), depositAmount, types.STRATEGY_TYPE_HARD) diff --git a/x/earn/keeper/withdraw_test.go b/x/earn/keeper/withdraw_test.go index 26450b68..ad28241e 100644 --- a/x/earn/keeper/withdraw_test.go +++ b/x/earn/keeper/withdraw_test.go @@ -28,7 +28,7 @@ func (suite *withdrawTestSuite) TestWithdraw_NoVaultRecord() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) withdrawAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -55,7 +55,7 @@ func (suite *withdrawTestSuite) TestWithdraw_NoVaultShareRecord() { acc1DepositAmount := sdk.NewCoin(vaultDenom, sdk.NewInt(100)) acc2WithdrawAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) // Create deposit from acc1 so the VaultRecord exists in state acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -87,7 +87,7 @@ func (suite *withdrawTestSuite) TestWithdraw_ExceedBalance() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) withdrawAmount := sdk.NewInt64Coin(vaultDenom, 200) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -115,7 +115,7 @@ func (suite *withdrawTestSuite) TestWithdraw_Zero() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) withdrawAmount := sdk.NewInt64Coin(vaultDenom, 0) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -165,7 +165,7 @@ func (suite *withdrawTestSuite) TestWithdraw_InvalidStrategy() { startBalance := sdk.NewInt64Coin(vaultDenom, 1000) withdrawAmount := sdk.NewInt64Coin(vaultDenom, 1001) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -180,7 +180,7 @@ func (suite *withdrawTestSuite) TestWithdraw_FullBalance() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) withdrawAmount := sdk.NewInt64Coin(vaultDenom, 100) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) @@ -207,7 +207,7 @@ func (suite *withdrawTestSuite) TestWithdraw_Partial() { depositAmount := sdk.NewInt64Coin(vaultDenom, 100) partialWithdrawAmount := sdk.NewInt64Coin(vaultDenom, 50) - suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD) + suite.CreateVault(vaultDenom, types.StrategyTypes{types.STRATEGY_TYPE_HARD}, false, nil) acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0) diff --git a/x/earn/testutil/suite.go b/x/earn/testutil/suite.go index 0a2ff495..39a4c093 100644 --- a/x/earn/testutil/suite.go +++ b/x/earn/testutil/suite.go @@ -214,8 +214,13 @@ 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) +func (suite *Suite) CreateVault( + vaultDenom string, + vaultStrategies types.StrategyTypes, + isPrivateVault bool, + allowedDepositors []sdk.AccAddress, +) { + vault := types.NewAllowedVault(vaultDenom, vaultStrategies, isPrivateVault, allowedDepositors) allowedVaults := suite.Keeper.GetAllowedVaults(suite.Ctx) allowedVaults = append(allowedVaults, vault) diff --git a/x/earn/types/errors.go b/x/earn/types/errors.go index 7f65a1eb..e344695b 100644 --- a/x/earn/types/errors.go +++ b/x/earn/types/errors.go @@ -12,4 +12,5 @@ var ( ErrInsufficientValue = sdkerrors.Register(ModuleName, 5, "insufficient vault account value") ErrVaultRecordNotFound = sdkerrors.Register(ModuleName, 6, "vault record not found") ErrVaultShareRecordNotFound = sdkerrors.Register(ModuleName, 7, "vault share record not found") + ErrAccountDepositNotAllowed = sdkerrors.Register(ModuleName, 8, "account is not allowed to deposit to this vault") ) diff --git a/x/earn/types/query.pb.go b/x/earn/types/query.pb.go index 88ffc5ee..2c4e6d06 100644 --- a/x/earn/types/query.pb.go +++ b/x/earn/types/query.pb.go @@ -193,11 +193,19 @@ type VaultResponse struct { Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` // VaultStrategy is the strategy used for this vault. Strategies StrategyTypes `protobuf:"varint,2,rep,packed,name=strategies,proto3,enum=kava.earn.v1beta1.StrategyType,castrepeated=StrategyTypes" json:"strategies,omitempty"` + // IsPrivateVault is true if the vault only allows depositors contained in + // AllowedDepositors. + IsPrivateVault bool `protobuf:"varint,3,opt,name=is_private_vault,json=isPrivateVault,proto3" json:"is_private_vault,omitempty"` + // AllowedDepositors is a list of addresses that are allowed to deposit to + // this vault if IsPrivateVault is true. Addresses not contained in this list + // are not allowed to deposit into this vault. If IsPrivateVault is false, + // this should be empty and ignored. + AllowedDepositors []string `protobuf:"bytes,4,rep,name=allowed_depositors,json=allowedDepositors,proto3" json:"allowed_depositors,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"` + TotalShares string `protobuf:"bytes,5,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 // vault were to be liquidated. - TotalValue github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=total_value,json=totalValue,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_value"` + TotalValue github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,6,opt,name=total_value,json=totalValue,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_value"` } func (m *VaultResponse) Reset() { *m = VaultResponse{} } @@ -376,56 +384,59 @@ func init() { func init() { proto.RegisterFile("kava/earn/v1beta1/query.proto", fileDescriptor_63f8dee2f3192a6b) } var fileDescriptor_63f8dee2f3192a6b = []byte{ - // 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, + // 825 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xbf, 0x4f, 0x1b, 0x49, + 0x14, 0xf6, 0xda, 0xd8, 0x82, 0xf1, 0xc1, 0x1d, 0x83, 0x4f, 0xb2, 0xcd, 0xb1, 0x36, 0x8b, 0x0e, + 0xf6, 0x90, 0xbc, 0x7b, 0xf8, 0xa4, 0x4b, 0x13, 0x45, 0x8a, 0x83, 0x82, 0x48, 0x11, 0x91, 0x25, + 0xa1, 0x88, 0x14, 0x59, 0x63, 0x3c, 0x5a, 0x56, 0xd8, 0x3b, 0x66, 0x67, 0x6c, 0x42, 0xa2, 0x34, + 0xf4, 0x91, 0x22, 0xe5, 0x5f, 0x88, 0x52, 0x50, 0xf3, 0x47, 0x50, 0x22, 0xd2, 0x44, 0x29, 0x20, + 0x81, 0xd4, 0xa9, 0x53, 0x46, 0xf3, 0x63, 0xfd, 0xdb, 0x71, 0x2a, 0xd8, 0x79, 0xef, 0x7d, 0xdf, + 0xf7, 0xde, 0x7c, 0xf3, 0x0c, 0x16, 0xf6, 0x51, 0x0b, 0xd9, 0x18, 0x05, 0xbe, 0xdd, 0x5a, 0xab, + 0x60, 0x86, 0xd6, 0xec, 0x83, 0x26, 0x0e, 0x8e, 0xac, 0x46, 0x40, 0x18, 0x81, 0xb3, 0x3c, 0x6c, + 0xf1, 0xb0, 0xa5, 0xc2, 0xd9, 0xcc, 0x2e, 0xa1, 0x75, 0x42, 0xcb, 0x22, 0xc1, 0x96, 0x1f, 0x32, + 0x3b, 0xbb, 0x2a, 0xbf, 0xec, 0x0a, 0xa2, 0x58, 0xc2, 0xb4, 0x41, 0x1b, 0xc8, 0xf5, 0x7c, 0xc4, + 0x3c, 0xe2, 0xab, 0x5c, 0xbd, 0x3b, 0x37, 0xcc, 0xda, 0x25, 0x5e, 0x18, 0x4f, 0xb9, 0xc4, 0x25, + 0x92, 0x83, 0xff, 0xa7, 0x4e, 0xff, 0x72, 0x09, 0x71, 0x6b, 0xd8, 0x46, 0x0d, 0xcf, 0x46, 0xbe, + 0x4f, 0x98, 0x80, 0x0c, 0xf9, 0xf5, 0xc1, 0x66, 0x1a, 0x28, 0x40, 0xf5, 0x30, 0x9e, 0x1f, 0x8c, + 0x53, 0x16, 0x20, 0x86, 0x5d, 0xd5, 0x6f, 0x76, 0xc8, 0x38, 0x5a, 0xa8, 0x59, 0x63, 0x32, 0x6c, + 0xa4, 0x00, 0x7c, 0xc4, 0xdb, 0xda, 0x12, 0xa8, 0x0e, 0x3e, 0x68, 0x62, 0xca, 0x8c, 0x87, 0x60, + 0xae, 0xe7, 0x94, 0x36, 0x88, 0x4f, 0x31, 0xbc, 0x05, 0x12, 0x92, 0x3d, 0xad, 0xe5, 0x35, 0x33, + 0x59, 0xcc, 0x58, 0x03, 0xc3, 0xb4, 0x64, 0x49, 0x69, 0xe2, 0xec, 0x32, 0x17, 0x71, 0x54, 0xba, + 0xb1, 0xaa, 0x58, 0x76, 0x38, 0x73, 0xc8, 0x02, 0x53, 0x20, 0x5e, 0xc5, 0x3e, 0xa9, 0x0b, 0xb4, + 0x29, 0x47, 0x7e, 0x18, 0x4f, 0x14, 0x77, 0x98, 0xab, 0xb8, 0xef, 0x80, 0x84, 0xd0, 0xcd, 0xb9, + 0x63, 0x66, 0xb2, 0x98, 0x1f, 0xc2, 0x2d, 0x4a, 0xc2, 0x8a, 0x50, 0x82, 0xac, 0x32, 0xbe, 0x45, + 0xc1, 0x74, 0x4f, 0x7c, 0x38, 0x3d, 0x74, 0x00, 0x50, 0x13, 0xf4, 0x30, 0x4d, 0x47, 0xf3, 0x31, + 0x73, 0xa6, 0x98, 0x1b, 0xc2, 0xb5, 0xad, 0xc6, 0xfc, 0xf8, 0xa8, 0x81, 0x4b, 0xb3, 0x27, 0x57, + 0xb9, 0xe9, 0xee, 0x13, 0xea, 0x74, 0xa1, 0x40, 0x13, 0xfc, 0xe1, 0x71, 0x7b, 0x79, 0x2d, 0xc4, + 0x70, 0x59, 0x08, 0x4a, 0xc7, 0xf2, 0x9a, 0x39, 0xe9, 0xcc, 0x78, 0x74, 0x4b, 0x1e, 0x0b, 0x6d, + 0x70, 0x03, 0x40, 0x54, 0xab, 0x91, 0x43, 0x5c, 0x2d, 0x57, 0x71, 0x83, 0x50, 0x8f, 0x91, 0x80, + 0xa6, 0x27, 0xf2, 0x31, 0x73, 0xaa, 0x94, 0xbe, 0x38, 0x2d, 0xa4, 0x94, 0x3b, 0xef, 0x56, 0xab, + 0x01, 0xa6, 0x74, 0x9b, 0x05, 0x9e, 0xef, 0x3a, 0xb3, 0xaa, 0x66, 0xbd, 0x5d, 0x02, 0x17, 0xc1, + 0x6f, 0x8c, 0x30, 0x54, 0x2b, 0xd3, 0x3d, 0x14, 0x60, 0x9a, 0x8e, 0x8b, 0x1e, 0x93, 0xe2, 0x6c, + 0x5b, 0x1c, 0xc1, 0x67, 0x40, 0x7e, 0x96, 0x5b, 0xa8, 0xd6, 0xc4, 0xe9, 0x04, 0xcf, 0x28, 0xdd, + 0xe6, 0x43, 0xfb, 0x74, 0x99, 0x5b, 0x76, 0x3d, 0xb6, 0xd7, 0xac, 0x58, 0xbb, 0xa4, 0xae, 0x5e, + 0x84, 0xfa, 0x53, 0xa0, 0xd5, 0x7d, 0x9b, 0xf1, 0x16, 0xad, 0x4d, 0x9f, 0x5d, 0x9c, 0x16, 0x80, + 0x92, 0xb4, 0xe9, 0x33, 0x07, 0x08, 0xc0, 0x1d, 0x8e, 0x67, 0xbc, 0xd3, 0x40, 0x4a, 0x5c, 0xa4, + 0x52, 0xd5, 0xbe, 0x76, 0x0b, 0xc4, 0xc9, 0xa1, 0x8f, 0x03, 0x39, 0xf7, 0x9f, 0xb4, 0x25, 0xd3, + 0x3a, 0xf7, 0x14, 0xed, 0xbe, 0xa7, 0xfb, 0x00, 0x74, 0x5e, 0xa0, 0x98, 0x66, 0xb2, 0xb8, 0x6c, + 0x29, 0x1c, 0xfe, 0x04, 0x2d, 0xf9, 0xea, 0x3b, 0xbe, 0x74, 0xb1, 0x52, 0xe0, 0x74, 0x55, 0x1a, + 0xef, 0x35, 0xf0, 0x67, 0x9f, 0x4c, 0xe5, 0x8f, 0x75, 0x30, 0xa9, 0xee, 0x20, 0xf4, 0x9c, 0x31, + 0xc4, 0x07, 0xaa, 0xac, 0xcf, 0x75, 0xed, 0x4a, 0xb8, 0xd1, 0xa3, 0x33, 0x2a, 0x74, 0xae, 0x8c, + 0xd5, 0x29, 0xc1, 0x7a, 0x84, 0x7e, 0xd7, 0xc0, 0xef, 0x7d, 0x64, 0xf0, 0x7f, 0x30, 0xd5, 0xb6, + 0xc9, 0xd8, 0x71, 0x76, 0x52, 0xe1, 0x03, 0x90, 0x50, 0xbe, 0x88, 0x8a, 0xc6, 0x16, 0x46, 0x3d, + 0x26, 0x61, 0x95, 0xd2, 0x1c, 0xef, 0xe9, 0xe4, 0x2a, 0x97, 0xec, 0x9c, 0x51, 0x47, 0x21, 0x40, + 0x04, 0xe2, 0xd2, 0x40, 0x31, 0x01, 0x95, 0xe9, 0xe9, 0x2d, 0x04, 0xbb, 0x47, 0x3c, 0xbf, 0xf4, + 0xaf, 0x82, 0x31, 0x7f, 0xc1, 0x5b, 0xbc, 0x80, 0x3a, 0x12, 0xb9, 0xf8, 0x3a, 0x06, 0xe2, 0xe2, + 0x8e, 0xe0, 0x0b, 0x90, 0x90, 0x0b, 0x06, 0xfe, 0x3d, 0x44, 0xf2, 0xe0, 0x26, 0xcb, 0x2e, 0x8f, + 0x4b, 0x93, 0x93, 0x34, 0x16, 0x8f, 0x3f, 0x7c, 0x7d, 0x1b, 0x9d, 0x87, 0x19, 0x7b, 0xd4, 0xc6, + 0x85, 0xc7, 0x1a, 0x48, 0xc8, 0xa5, 0x34, 0x9a, 0xbc, 0x67, 0xc1, 0x8d, 0x26, 0xef, 0xdd, 0x6d, + 0xc6, 0x3f, 0x82, 0x7c, 0x09, 0x2e, 0xda, 0x23, 0x96, 0x35, 0xb5, 0x5f, 0x0a, 0xd7, 0xbf, 0xe2, + 0x22, 0x26, 0x43, 0xa7, 0xc2, 0x95, 0x51, 0xf8, 0x7d, 0x4f, 0x2e, 0x6b, 0x8e, 0x4f, 0x54, 0x52, + 0x96, 0x84, 0x94, 0x05, 0x38, 0x3f, 0x44, 0x4a, 0xe8, 0xe9, 0xd2, 0xfa, 0xd9, 0x17, 0x3d, 0x72, + 0x76, 0xad, 0x6b, 0xe7, 0xd7, 0xba, 0xf6, 0xf9, 0x5a, 0xd7, 0xde, 0xdc, 0xe8, 0x91, 0xf3, 0x1b, + 0x3d, 0xf2, 0xf1, 0x46, 0x8f, 0x3c, 0xed, 0x5e, 0x1d, 0x1c, 0xa4, 0x50, 0x43, 0x15, 0x2a, 0xe1, + 0x9e, 0x4b, 0x40, 0x71, 0xc5, 0x95, 0x84, 0xf8, 0x05, 0xfa, 0xef, 0x47, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xa7, 0x27, 0xb6, 0xa1, 0xb1, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -738,13 +749,32 @@ func (m *VaultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x32 if len(m.TotalShares) > 0 { i -= len(m.TotalShares) copy(dAtA[i:], m.TotalShares) i = encodeVarintQuery(dAtA, i, uint64(len(m.TotalShares))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x2a + } + if len(m.AllowedDepositors) > 0 { + for iNdEx := len(m.AllowedDepositors) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AllowedDepositors[iNdEx]) + copy(dAtA[i:], m.AllowedDepositors[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AllowedDepositors[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if m.IsPrivateVault { + i-- + if m.IsPrivateVault { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 } if len(m.Strategies) > 0 { dAtA3 := make([]byte, len(m.Strategies)*10) @@ -1006,6 +1036,15 @@ func (m *VaultResponse) Size() (n int) { } n += 1 + sovQuery(uint64(l)) + l } + if m.IsPrivateVault { + n += 2 + } + if len(m.AllowedDepositors) > 0 { + for _, s := range m.AllowedDepositors { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } l = len(m.TotalShares) if l > 0 { n += 1 + l + sovQuery(uint64(l)) @@ -1516,6 +1555,58 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: wrong wireType = %d for field Strategies", wireType) } case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsPrivateVault", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsPrivateVault = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowedDepositors", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllowedDepositors = append(m.AllowedDepositors, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType) } @@ -1547,7 +1638,7 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error { } m.TotalShares = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TotalValue", wireType) } diff --git a/x/earn/types/vault.go b/x/earn/types/vault.go index 2117c1fc..129097b8 100644 --- a/x/earn/types/vault.go +++ b/x/earn/types/vault.go @@ -86,13 +86,68 @@ func (vsrs VaultShareRecords) Validate() error { } // NewAllowedVaults returns a new AllowedVaults with the given denom and strategy type. -func NewAllowedVault(denom string, strategyTypes ...StrategyType) AllowedVault { +func NewAllowedVault( + denom string, + strategyTypes StrategyTypes, + isPrivateVault bool, + allowedDepositors []sdk.AccAddress, +) AllowedVault { return AllowedVault{ - Denom: denom, - Strategies: strategyTypes, + Denom: denom, + Strategies: strategyTypes, + IsPrivateVault: isPrivateVault, + AllowedDepositors: allowedDepositors, } } +// 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()) + } + + // Private -> 1+ allowed depositors + // Non-private -> 0 allowed depositors + if a.IsPrivateVault && len(a.AllowedDepositors) == 0 { + return fmt.Errorf("private vaults require non-empty AllowedDepositors") + } + + if !a.IsPrivateVault && len(a.AllowedDepositors) > 0 { + return fmt.Errorf("non-private vaults cannot have any AllowedDepositors") + } + + return a.Strategies.Validate() +} + +// 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 +} + +// IsAccountAllowed returns true if the given account is allowed to deposit into +// the vault. +func (a *AllowedVault) IsAccountAllowed(account sdk.AccAddress) bool { + // Anyone can deposit to non-private vaults + if !a.IsPrivateVault { + return true + } + + for _, addr := range a.AllowedDepositors { + if addr.Equals(account) { + return true + } + } + + return false +} + // AllowedVaults is a slice of AllowedVault. type AllowedVaults []AllowedVault @@ -114,24 +169,3 @@ func (a AllowedVaults) Validate() error { 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()) - } - - return a.Strategies.Validate() -} - -// 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 -} diff --git a/x/earn/types/vault.pb.go b/x/earn/types/vault.pb.go index 0cc9b5cf..3d96d2d6 100644 --- a/x/earn/types/vault.pb.go +++ b/x/earn/types/vault.pb.go @@ -6,7 +6,6 @@ package types import ( fmt "fmt" _ "github.com/cosmos/cosmos-proto" - _ "github.com/cosmos/cosmos-sdk/types" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" @@ -33,6 +32,14 @@ type AllowedVault struct { Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` // VaultStrategy is the strategy used for this vault. Strategies StrategyTypes `protobuf:"varint,2,rep,packed,name=strategies,proto3,enum=kava.earn.v1beta1.StrategyType,castrepeated=StrategyTypes" json:"strategies,omitempty"` + // IsPrivateVault is true if the vault only allows depositors contained in + // AllowedDepositors. + IsPrivateVault bool `protobuf:"varint,3,opt,name=is_private_vault,json=isPrivateVault,proto3" json:"is_private_vault,omitempty"` + // AllowedDepositors is a list of addresses that are allowed to deposit to + // this vault if IsPrivateVault is true. Addresses not contained in this list + // are not allowed to deposit into this vault. If IsPrivateVault is false, + // this should be empty and ignored. + AllowedDepositors []github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,4,rep,name=allowed_depositors,json=allowedDepositors,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"allowed_depositors,omitempty"` } func (m *AllowedVault) Reset() { *m = AllowedVault{} } @@ -82,6 +89,20 @@ func (m *AllowedVault) GetStrategies() StrategyTypes { return nil } +func (m *AllowedVault) GetIsPrivateVault() bool { + if m != nil { + return m.IsPrivateVault + } + return false +} + +func (m *AllowedVault) GetAllowedDepositors() []github_com_cosmos_cosmos_sdk_types.AccAddress { + if m != nil { + return m.AllowedDepositors + } + return nil +} + // VaultRecord is the state of a vault. type VaultRecord struct { // TotalShares is the total distributed number of shares in the vault. @@ -238,36 +259,38 @@ func init() { func init() { proto.RegisterFile("kava/earn/v1beta1/vault.proto", fileDescriptor_884eb89509fbdc04) } var fileDescriptor_884eb89509fbdc04 = []byte{ - // 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, + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x53, 0x3f, 0x6f, 0xd3, 0x40, + 0x14, 0xb7, 0x93, 0x10, 0xd1, 0x4b, 0xa8, 0x1a, 0xb7, 0x83, 0xa9, 0x54, 0xdb, 0xca, 0x80, 0xbc, + 0xd8, 0x56, 0xcb, 0x86, 0x18, 0x88, 0x15, 0x21, 0xc4, 0x84, 0xae, 0x85, 0x81, 0x25, 0xba, 0xd8, + 0x47, 0x6a, 0xd5, 0xc9, 0x45, 0x7e, 0x17, 0x97, 0x2c, 0x7c, 0x06, 0x46, 0x24, 0x16, 0xe6, 0xce, + 0xfd, 0x0c, 0xa8, 0x63, 0xd5, 0x09, 0x31, 0xa4, 0x28, 0xf9, 0x16, 0x4c, 0xe8, 0xfe, 0xa8, 0x8e, + 0x14, 0x10, 0x0c, 0x4c, 0xb9, 0xfb, 0xbd, 0xf7, 0x7e, 0x7f, 0x5e, 0x7c, 0xe8, 0xe0, 0x8c, 0x94, + 0x24, 0xa2, 0xa4, 0x98, 0x44, 0xe5, 0xe1, 0x90, 0x72, 0x72, 0x18, 0x95, 0x64, 0x96, 0xf3, 0x70, + 0x5a, 0x30, 0xce, 0xac, 0x8e, 0x28, 0x87, 0xa2, 0x1c, 0xea, 0xf2, 0xfe, 0xc3, 0x84, 0xc1, 0x98, + 0xc1, 0x40, 0x36, 0x44, 0xea, 0xa2, 0xba, 0xf7, 0xf7, 0x46, 0x6c, 0xc4, 0x14, 0x2e, 0x4e, 0x1a, + 0xf5, 0x36, 0x25, 0x80, 0x17, 0x84, 0xd3, 0xd1, 0x5c, 0x75, 0x74, 0x3f, 0xd7, 0x50, 0xbb, 0x97, + 0xe7, 0xec, 0x9c, 0xa6, 0x6f, 0x84, 0xb8, 0xb5, 0x87, 0xee, 0xa5, 0x74, 0xc2, 0xc6, 0xb6, 0xe9, + 0x99, 0xfe, 0x16, 0x56, 0x17, 0x0b, 0x23, 0xa4, 0x07, 0x33, 0x0a, 0x76, 0xcd, 0xab, 0xfb, 0xdb, + 0x47, 0x6e, 0xb8, 0xe1, 0x30, 0x3c, 0xd6, 0xec, 0x27, 0xf3, 0x29, 0x8d, 0x3b, 0x17, 0xb7, 0xee, + 0x83, 0x75, 0x04, 0xf0, 0x1a, 0x8b, 0xe5, 0xa3, 0x9d, 0x4c, 0x64, 0xc9, 0x4a, 0xc2, 0xe9, 0x40, + 0x46, 0xb7, 0xeb, 0x9e, 0xe9, 0xdf, 0xc7, 0xdb, 0x19, 0xbc, 0x52, 0xb0, 0xf2, 0x74, 0x8e, 0x2c, + 0xa2, 0x3c, 0x0e, 0x52, 0x3a, 0x65, 0x90, 0x71, 0x56, 0x80, 0xdd, 0xf0, 0xea, 0x7e, 0x3b, 0x7e, + 0xf1, 0x73, 0xe1, 0x06, 0xa3, 0x8c, 0x9f, 0xce, 0x86, 0x61, 0xc2, 0xc6, 0x7a, 0x2b, 0xfa, 0x27, + 0x80, 0xf4, 0x2c, 0xe2, 0x42, 0x39, 0xec, 0x25, 0x49, 0x2f, 0x4d, 0x0b, 0x0a, 0x70, 0x73, 0x19, + 0xec, 0xea, 0xdd, 0x69, 0x24, 0x9e, 0x73, 0x0a, 0xb8, 0xa3, 0x35, 0xfa, 0x77, 0x12, 0xdd, 0xd7, + 0xa8, 0x25, 0x1d, 0x60, 0x9a, 0xb0, 0x22, 0xb5, 0x9e, 0xa3, 0x36, 0x67, 0x9c, 0xe4, 0x03, 0x38, + 0x25, 0x05, 0x05, 0xb9, 0xa2, 0xd6, 0xd1, 0xc1, 0x6f, 0xf6, 0x20, 0xa7, 0x8e, 0x45, 0x57, 0xdc, + 0xb8, 0x5a, 0xb8, 0x06, 0x6e, 0xc9, 0x41, 0x89, 0x40, 0xf7, 0xab, 0x89, 0x76, 0xaa, 0x0e, 0x4d, + 0xfe, 0x0e, 0x6d, 0xdd, 0x85, 0x93, 0xcc, 0xff, 0x33, 0x5b, 0x45, 0x6d, 0xbd, 0x44, 0x4d, 0x6d, + 0x5f, 0xfc, 0x8d, 0x7f, 0xb5, 0xbf, 0x2b, 0xec, 0x5f, 0xdc, 0xba, 0xad, 0x0a, 0x03, 0xac, 0x19, + 0xba, 0x1f, 0x10, 0xaa, 0xe0, 0x3f, 0x7c, 0x3a, 0x27, 0xa8, 0x49, 0xc6, 0x6c, 0x36, 0xe1, 0x76, + 0x4d, 0xc0, 0xf1, 0x53, 0x41, 0xf8, 0x7d, 0xe1, 0x3e, 0xfa, 0x87, 0x60, 0x7d, 0x9a, 0xdc, 0x5c, + 0x06, 0x48, 0x27, 0xea, 0xd3, 0x04, 0x6b, 0xae, 0x27, 0x8d, 0x4f, 0x5f, 0x5c, 0x23, 0x7e, 0x76, + 0xb5, 0x74, 0xcc, 0xeb, 0xa5, 0x63, 0xfe, 0x58, 0x3a, 0xe6, 0xc7, 0x95, 0x63, 0x5c, 0xaf, 0x1c, + 0xe3, 0xdb, 0xca, 0x31, 0xde, 0xae, 0xb3, 0x8b, 0x7c, 0x41, 0x4e, 0x86, 0x20, 0x4f, 0xd1, 0x7b, + 0xf5, 0x20, 0xa4, 0xc2, 0xb0, 0x29, 0x9f, 0xc1, 0xe3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa0, + 0xa9, 0xba, 0x64, 0x8d, 0x03, 0x00, 0x00, } func (m *AllowedVault) Marshal() (dAtA []byte, err error) { @@ -290,6 +313,25 @@ func (m *AllowedVault) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.AllowedDepositors) > 0 { + for iNdEx := len(m.AllowedDepositors) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AllowedDepositors[iNdEx]) + copy(dAtA[i:], m.AllowedDepositors[iNdEx]) + i = encodeVarintVault(dAtA, i, uint64(len(m.AllowedDepositors[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if m.IsPrivateVault { + i-- + if m.IsPrivateVault { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if len(m.Strategies) > 0 { dAtA2 := make([]byte, len(m.Strategies)*10) var j1 int @@ -463,6 +505,15 @@ func (m *AllowedVault) Size() (n int) { } n += 1 + sovVault(uint64(l)) + l } + if m.IsPrivateVault { + n += 2 + } + if len(m.AllowedDepositors) > 0 { + for _, b := range m.AllowedDepositors { + l = len(b) + n += 1 + l + sovVault(uint64(l)) + } + } return n } @@ -647,6 +698,58 @@ func (m *AllowedVault) Unmarshal(dAtA []byte) error { } else { return fmt.Errorf("proto: wrong wireType = %d for field Strategies", wireType) } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsPrivateVault", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVault + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsPrivateVault = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowedDepositors", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVault + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthVault + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthVault + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllowedDepositors = append(m.AllowedDepositors, make([]byte, postIndex-iNdEx)) + copy(m.AllowedDepositors[len(m.AllowedDepositors)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipVault(dAtA[iNdEx:]) diff --git a/x/earn/types/vault_test.go b/x/earn/types/vault_test.go index cdeaeb55..f56b78d9 100644 --- a/x/earn/types/vault_test.go +++ b/x/earn/types/vault_test.go @@ -4,6 +4,7 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/kava-labs/kava/app" @@ -208,12 +209,16 @@ func TestAllowedVaultsValidate(t *testing.T) { name: "valid vault share records", vaultRecords: types.AllowedVaults{ { - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, { - Denom: "busd", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + Denom: "busd", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, }, errArgs: errArgs{ @@ -224,12 +229,16 @@ func TestAllowedVaultsValidate(t *testing.T) { name: "invalid - duplicate denom", vaultRecords: types.AllowedVaults{ { - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, { - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, }, errArgs: errArgs{ @@ -241,8 +250,10 @@ func TestAllowedVaultsValidate(t *testing.T) { name: "invalid - invalid denom", vaultRecords: types.AllowedVaults{ { - Denom: "", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + Denom: "", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, }, errArgs: errArgs{ @@ -254,8 +265,10 @@ func TestAllowedVaultsValidate(t *testing.T) { name: "invalid - invalid strategy", vaultRecords: types.AllowedVaults{ { - Denom: "usdx", - Strategies: []types.StrategyType{types.STRATEGY_TYPE_UNSPECIFIED}, + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_UNSPECIFIED}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{}, }, }, errArgs: errArgs{ @@ -263,6 +276,38 @@ func TestAllowedVaultsValidate(t *testing.T) { contains: "invalid strategy STRATEGY_TYPE_UNSPECIFIED", }, }, + { + name: "invalid - private with no allowed depositors", + vaultRecords: types.AllowedVaults{ + { + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: true, + AllowedDepositors: []sdk.AccAddress{}, + }, + }, + errArgs: errArgs{ + expectPass: false, + contains: "private vaults require non-empty AllowedDepositors", + }, + }, + { + name: "invalid - public with allowed depositors", + vaultRecords: types.AllowedVaults{ + { + Denom: "usdx", + Strategies: []types.StrategyType{types.STRATEGY_TYPE_HARD}, + IsPrivateVault: false, + AllowedDepositors: []sdk.AccAddress{ + sdk.AccAddress("asdfasdf"), + }, + }, + }, + errArgs: errArgs{ + expectPass: false, + contains: "non-private vaults cannot have any AllowedDepositors", + }, + }, } for _, test := range tests { @@ -279,6 +324,54 @@ func TestAllowedVaultsValidate(t *testing.T) { } } +func TestIsStrategyAllowed(t *testing.T) { + vault := types.NewAllowedVault( + "usdx", + []types.StrategyType{types.STRATEGY_TYPE_HARD}, + true, + []sdk.AccAddress{}, + ) + + require.True(t, vault.IsStrategyAllowed(types.STRATEGY_TYPE_HARD)) + require.False(t, vault.IsStrategyAllowed(types.STRATEGY_TYPE_SAVINGS)) + require.False(t, vault.IsStrategyAllowed(types.STRATEGY_TYPE_UNSPECIFIED)) + require.False(t, vault.IsStrategyAllowed(12345)) +} + +func TestIsAccountAllowed_Private(t *testing.T) { + acc1 := sdk.AccAddress("acc1") + acc2 := sdk.AccAddress("acc2") + acc3 := sdk.AccAddress("acc3") + + vault := types.NewAllowedVault( + "usdx", + []types.StrategyType{types.STRATEGY_TYPE_HARD}, + true, + []sdk.AccAddress{acc1, acc2}, + ) + + assert.True(t, vault.IsAccountAllowed(acc1)) + assert.True(t, vault.IsAccountAllowed(acc2)) + assert.False(t, vault.IsAccountAllowed(acc3)) +} + +func TestIsAccountAllowed_Public(t *testing.T) { + acc1 := sdk.AccAddress("acc1") + acc2 := sdk.AccAddress("acc2") + acc3 := sdk.AccAddress("acc3") + + vault := types.NewAllowedVault( + "usdx", + []types.StrategyType{types.STRATEGY_TYPE_HARD}, + false, + []sdk.AccAddress{}, + ) + + assert.True(t, vault.IsAccountAllowed(acc1)) + assert.True(t, vault.IsAccountAllowed(acc2)) + assert.True(t, vault.IsAccountAllowed(acc3)) +} + func TestNewVaultShareRecord(t *testing.T) { _, addrs := app.GeneratePrivKeyAddressPairs(1)