mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 10:37:26 +00:00 
			
		
		
		
	Update Earn vaults to use sdk.Dec shares (#1283)
* Change vault supply to shares * Update deposit shares * Use shares instead of supplied * Update tests, fix share calculation * Pass hard and savings keeper as pointer to earn keeper * Update remaining failing test * Add different share price test, fix comment for share price * Add shares amount to events * Additional share tests, use share to asset conversion for withdraw amount * Update VaultTotalValue test * Use sdk.Dec for vault shares instead of sdk.Int * Add test for expensive 20:1 shares * Update ConvertToShares comment for division, remove redundant test * Add vault share tests
This commit is contained in:
		
							parent
							
								
									fe89ba938d
								
							
						
					
					
						commit
						b5e162a930
					
				@ -604,8 +604,8 @@ func NewApp(
 | 
				
			|||||||
		earnSubspace,
 | 
							earnSubspace,
 | 
				
			||||||
		app.accountKeeper,
 | 
							app.accountKeeper,
 | 
				
			||||||
		app.bankKeeper,
 | 
							app.bankKeeper,
 | 
				
			||||||
		hardKeeper,
 | 
							&hardKeeper,
 | 
				
			||||||
		savingsKeeper,
 | 
							&savingsKeeper,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// create committee keeper with router
 | 
						// create committee keeper with router
 | 
				
			||||||
 | 
				
			|||||||
@ -184,6 +184,7 @@
 | 
				
			|||||||
- [kava/earn/v1beta1/vault.proto](#kava/earn/v1beta1/vault.proto)
 | 
					- [kava/earn/v1beta1/vault.proto](#kava/earn/v1beta1/vault.proto)
 | 
				
			||||||
    - [AllowedVault](#kava.earn.v1beta1.AllowedVault)
 | 
					    - [AllowedVault](#kava.earn.v1beta1.AllowedVault)
 | 
				
			||||||
    - [VaultRecord](#kava.earn.v1beta1.VaultRecord)
 | 
					    - [VaultRecord](#kava.earn.v1beta1.VaultRecord)
 | 
				
			||||||
 | 
					    - [VaultShare](#kava.earn.v1beta1.VaultShare)
 | 
				
			||||||
    - [VaultShareRecord](#kava.earn.v1beta1.VaultShareRecord)
 | 
					    - [VaultShareRecord](#kava.earn.v1beta1.VaultShareRecord)
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
- [kava/earn/v1beta1/params.proto](#kava/earn/v1beta1/params.proto)
 | 
					- [kava/earn/v1beta1/params.proto](#kava/earn/v1beta1/params.proto)
 | 
				
			||||||
@ -198,8 +199,6 @@
 | 
				
			|||||||
    - [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse)
 | 
					    - [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse)
 | 
				
			||||||
    - [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest)
 | 
					    - [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest)
 | 
				
			||||||
    - [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse)
 | 
					    - [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse)
 | 
				
			||||||
    - [QueryTotalDepositedRequest](#kava.earn.v1beta1.QueryTotalDepositedRequest)
 | 
					 | 
				
			||||||
    - [QueryTotalDepositedResponse](#kava.earn.v1beta1.QueryTotalDepositedResponse)
 | 
					 | 
				
			||||||
    - [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest)
 | 
					    - [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest)
 | 
				
			||||||
    - [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse)
 | 
					    - [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse)
 | 
				
			||||||
    - [VaultResponse](#kava.earn.v1beta1.VaultResponse)
 | 
					    - [VaultResponse](#kava.earn.v1beta1.VaultResponse)
 | 
				
			||||||
@ -2817,14 +2816,28 @@ modified via parameter governance.
 | 
				
			|||||||
<a name="kava.earn.v1beta1.VaultRecord"></a>
 | 
					<a name="kava.earn.v1beta1.VaultRecord"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### VaultRecord
 | 
					### VaultRecord
 | 
				
			||||||
VaultRecord is the state of a vault and is used to store the state of a
 | 
					VaultRecord is the state of a vault.
 | 
				
			||||||
vault.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| Field | Type | Label | Description |
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
| ----- | ---- | ----- | ----------- |
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
| `denom` | [string](#string) |  | Denom is the only supported denomination of the vault for deposits and withdrawals. |
 | 
					| `total_shares` | [VaultShare](#kava.earn.v1beta1.VaultShare) |  | TotalShares is the total distributed number of shares in the vault. |
 | 
				
			||||||
| `total_supply` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) |  | TotalSupply is the total supply of the vault, denominated **only** in the user deposit/withdrawal denom, must be the same as the Denom field. |
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="kava.earn.v1beta1.VaultShare"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### VaultShare
 | 
				
			||||||
 | 
					VaultShare defines shares of a vault owned by a depositor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
 | 
					| `denom` | [string](#string) |  |  |
 | 
				
			||||||
 | 
					| `amount` | [string](#string) |  |  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2840,7 +2853,7 @@ VaultShareRecord defines the vault shares owned by a depositor.
 | 
				
			|||||||
| Field | Type | Label | Description |
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
| ----- | ---- | ----- | ----------- |
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
| `depositor` | [bytes](#bytes) |  | Depositor represents the owner of the shares |
 | 
					| `depositor` | [bytes](#bytes) |  | Depositor represents the owner of the shares |
 | 
				
			||||||
| `amount_supplied` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | AmountSupplied represents the total amount a depositor has supplied to the vault. The vault is determined by the coin denom. |
 | 
					| `shares` | [VaultShare](#kava.earn.v1beta1.VaultShare) | repeated | Shares represent the vault shares owned by the depositor. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2936,7 +2949,7 @@ DepositResponse defines a deposit query response type.
 | 
				
			|||||||
| Field | Type | Label | Description |
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
| ----- | ---- | ----- | ----------- |
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
| `depositor` | [string](#string) |  | depositor represents the owner of the deposit. |
 | 
					| `depositor` | [string](#string) |  | depositor represents the owner of the deposit. |
 | 
				
			||||||
| `amount_supplied` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amount represents the amount supplied to vaults. |
 | 
					| `shares` | [VaultShare](#kava.earn.v1beta1.VaultShare) | repeated | Shares represent the issued shares from their corresponding vaults. |
 | 
				
			||||||
| `value` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | 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. |
 | 
					| `value` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | 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. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3002,36 +3015,6 @@ QueryParamsResponse defines the response type for querying x/earn parameters.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a name="kava.earn.v1beta1.QueryTotalDepositedRequest"></a>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### QueryTotalDepositedRequest
 | 
					 | 
				
			||||||
QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Field | Type | Label | Description |
 | 
					 | 
				
			||||||
| ----- | ---- | ----- | ----------- |
 | 
					 | 
				
			||||||
| `denom` | [string](#string) |  | denom represents the vault denom to query total deposited amount for. |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<a name="kava.earn.v1beta1.QueryTotalDepositedResponse"></a>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### QueryTotalDepositedResponse
 | 
					 | 
				
			||||||
QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Field | Type | Label | Description |
 | 
					 | 
				
			||||||
| ----- | ---- | ----- | ----------- |
 | 
					 | 
				
			||||||
| `supplied_coins` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated |  |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<a name="kava.earn.v1beta1.QueryVaultsRequest"></a>
 | 
					<a name="kava.earn.v1beta1.QueryVaultsRequest"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### QueryVaultsRequest
 | 
					### QueryVaultsRequest
 | 
				
			||||||
@ -3072,7 +3055,7 @@ VaultResponse is the response type for a vault.
 | 
				
			|||||||
| ----- | ---- | ----- | ----------- |
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
| `denom` | [string](#string) |  | denom represents the denom of the vault |
 | 
					| `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. |
 | 
					| `vault_strategy` | [StrategyType](#kava.earn.v1beta1.StrategyType) |  | VaultStrategy is the strategy used for this vault. |
 | 
				
			||||||
| `total_supplied` | [string](#string) |  | TotalSupplied is the total amount of denom coins supplied to the 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. |
 | 
					| `total_value` | [string](#string) |  | TotalValue is the total value of denom coins supplied to the vault if the vault were to be liquidated. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3096,7 +3079,6 @@ Query defines the gRPC querier service for earn module
 | 
				
			|||||||
| `Params` | [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse) | Params queries all parameters of the earn module. | GET|/kava/earn/v1beta1/params|
 | 
					| `Params` | [QueryParamsRequest](#kava.earn.v1beta1.QueryParamsRequest) | [QueryParamsResponse](#kava.earn.v1beta1.QueryParamsResponse) | Params queries all parameters of the earn module. | GET|/kava/earn/v1beta1/params|
 | 
				
			||||||
| `Vaults` | [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest) | [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse) | Vaults queries vaults based on vault denom | GET|/kava/earn/v1beta1/vaults/{denom}|
 | 
					| `Vaults` | [QueryVaultsRequest](#kava.earn.v1beta1.QueryVaultsRequest) | [QueryVaultsResponse](#kava.earn.v1beta1.QueryVaultsResponse) | Vaults queries vaults based on vault denom | GET|/kava/earn/v1beta1/vaults/{denom}|
 | 
				
			||||||
| `Deposits` | [QueryDepositsRequest](#kava.earn.v1beta1.QueryDepositsRequest) | [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse) | Deposits queries deposit details based on owner address and vault | GET|/kava/earn/v1beta1/deposits|
 | 
					| `Deposits` | [QueryDepositsRequest](#kava.earn.v1beta1.QueryDepositsRequest) | [QueryDepositsResponse](#kava.earn.v1beta1.QueryDepositsResponse) | Deposits queries deposit details based on owner address and vault | GET|/kava/earn/v1beta1/deposits|
 | 
				
			||||||
| `TotalDeposited` | [QueryTotalDepositedRequest](#kava.earn.v1beta1.QueryTotalDepositedRequest) | [QueryTotalDepositedResponse](#kava.earn.v1beta1.QueryTotalDepositedResponse) | TotalDeposited queries total deposited amount for each vault. | GET|/kava/earn/v1beta1/total-deposited/{denom}|
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 <!-- end services -->
 | 
					 <!-- end services -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3131,6 +3113,11 @@ MsgDeposit represents a message for depositing assedts into a vault
 | 
				
			|||||||
MsgDepositResponse defines the Msg/Deposit response type.
 | 
					MsgDepositResponse defines the Msg/Deposit response type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
 | 
					| `shares` | [VaultShare](#kava.earn.v1beta1.VaultShare) |  |  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3157,6 +3144,11 @@ MsgWithdraw represents a message for withdrawing liquidity from a vault
 | 
				
			|||||||
MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
					MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Field | Type | Label | Description |
 | 
				
			||||||
 | 
					| ----- | ---- | ----- | ----------- |
 | 
				
			||||||
 | 
					| `shares` | [VaultShare](#kava.earn.v1beta1.VaultShare) |  |  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ import "gogoproto/gogo.proto";
 | 
				
			|||||||
import "google/api/annotations.proto";
 | 
					import "google/api/annotations.proto";
 | 
				
			||||||
import "kava/earn/v1beta1/params.proto";
 | 
					import "kava/earn/v1beta1/params.proto";
 | 
				
			||||||
import "kava/earn/v1beta1/strategy.proto";
 | 
					import "kava/earn/v1beta1/strategy.proto";
 | 
				
			||||||
 | 
					import "kava/earn/v1beta1/vault.proto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Query defines the gRPC querier service for earn module
 | 
					// Query defines the gRPC querier service for earn module
 | 
				
			||||||
service Query {
 | 
					service Query {
 | 
				
			||||||
@ -28,11 +29,6 @@ service Query {
 | 
				
			|||||||
  rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
 | 
					  rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
 | 
				
			||||||
    option (google.api.http).get = "/kava/earn/v1beta1/deposits";
 | 
					    option (google.api.http).get = "/kava/earn/v1beta1/deposits";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // TotalDeposited queries total deposited amount for each vault.
 | 
					 | 
				
			||||||
  rpc TotalDeposited(QueryTotalDepositedRequest) returns (QueryTotalDepositedResponse) {
 | 
					 | 
				
			||||||
    option (google.api.http).get = "/kava/earn/v1beta1/total-deposited/{denom}";
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QueryParamsRequest defines the request type for querying x/earn parameters.
 | 
					// QueryParamsRequest defines the request type for querying x/earn parameters.
 | 
				
			||||||
@ -40,7 +36,6 @@ message QueryParamsRequest {}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// QueryParamsResponse defines the response type for querying x/earn parameters.
 | 
					// QueryParamsResponse defines the response type for querying x/earn parameters.
 | 
				
			||||||
message QueryParamsResponse {
 | 
					message QueryParamsResponse {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // params represents the earn module parameters
 | 
					  // params represents the earn module parameters
 | 
				
			||||||
  Params params = 1 [(gogoproto.nullable) = false];
 | 
					  Params params = 1 [(gogoproto.nullable) = false];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -65,12 +60,8 @@ message VaultResponse {
 | 
				
			|||||||
  // VaultStrategy is the strategy used for this vault.
 | 
					  // VaultStrategy is the strategy used for this vault.
 | 
				
			||||||
  StrategyType vault_strategy = 2;
 | 
					  StrategyType vault_strategy = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TotalSupplied is the total amount of denom coins supplied to the vault.
 | 
					  // TotalShares is the total amount of shares issued to depositors.
 | 
				
			||||||
  string total_supplied = 3 [
 | 
					  string total_shares = 3;
 | 
				
			||||||
    (cosmos_proto.scalar)  = "cosmos.Int",
 | 
					 | 
				
			||||||
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
 | 
					 | 
				
			||||||
    (gogoproto.nullable)   = false
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TotalValue is the total value of denom coins supplied to the vault if the
 | 
					  // TotalValue is the total value of denom coins supplied to the vault if the
 | 
				
			||||||
  // vault were to be liquidated.
 | 
					  // vault were to be liquidated.
 | 
				
			||||||
@ -107,9 +98,8 @@ message DepositResponse {
 | 
				
			|||||||
  // depositor represents the owner of the deposit.
 | 
					  // depositor represents the owner of the deposit.
 | 
				
			||||||
  string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
 | 
					  string depositor = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Amount represents the amount supplied to vaults.
 | 
					  // Shares represent the issued shares from their corresponding vaults.
 | 
				
			||||||
  repeated cosmos.base.v1beta1.Coin amount_supplied = 2
 | 
					  repeated VaultShare shares = 2 [(gogoproto.castrepeated) = "VaultShares", (gogoproto.nullable) = false];
 | 
				
			||||||
      [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Value represents the total accumulated value of denom coins supplied to
 | 
					  // Value represents the total accumulated value of denom coins supplied to
 | 
				
			||||||
  // vaults. This may be greater than or equal to amount_supplied depending on
 | 
					  // vaults. This may be greater than or equal to amount_supplied depending on
 | 
				
			||||||
@ -117,15 +107,3 @@ message DepositResponse {
 | 
				
			|||||||
  repeated cosmos.base.v1beta1.Coin value = 3
 | 
					  repeated cosmos.base.v1beta1.Coin value = 3
 | 
				
			||||||
      [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
 | 
					      [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
message QueryTotalDepositedRequest {
 | 
					 | 
				
			||||||
  // denom represents the vault denom to query total deposited amount for.
 | 
					 | 
				
			||||||
  string denom = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
message QueryTotalDepositedResponse {
 | 
					 | 
				
			||||||
  repeated cosmos.base.v1beta1.Coin supplied_coins = 1
 | 
					 | 
				
			||||||
      [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ package kava.earn.v1beta1;
 | 
				
			|||||||
import "cosmos_proto/cosmos.proto";
 | 
					import "cosmos_proto/cosmos.proto";
 | 
				
			||||||
import "cosmos/base/v1beta1/coin.proto";
 | 
					import "cosmos/base/v1beta1/coin.proto";
 | 
				
			||||||
import "gogoproto/gogo.proto";
 | 
					import "gogoproto/gogo.proto";
 | 
				
			||||||
 | 
					import "kava/earn/v1beta1/vault.proto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
option go_package = "github.com/kava-labs/kava/x/earn/types";
 | 
					option go_package = "github.com/kava-labs/kava/x/earn/types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +28,9 @@ message MsgDeposit {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MsgDepositResponse defines the Msg/Deposit response type.
 | 
					// MsgDepositResponse defines the Msg/Deposit response type.
 | 
				
			||||||
message MsgDepositResponse {}
 | 
					message MsgDepositResponse {
 | 
				
			||||||
 | 
					  VaultShare shares = 1 [(gogoproto.nullable) = false];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MsgWithdraw represents a message for withdrawing liquidity from a vault
 | 
					// MsgWithdraw represents a message for withdrawing liquidity from a vault
 | 
				
			||||||
message MsgWithdraw {
 | 
					message MsgWithdraw {
 | 
				
			||||||
@ -42,4 +45,6 @@ message MsgWithdraw {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
					// MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
				
			||||||
message MsgWithdrawResponse {}
 | 
					message MsgWithdrawResponse {
 | 
				
			||||||
 | 
					  VaultShare shares = 1 [(gogoproto.nullable) = false];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,15 +18,10 @@ message AllowedVault {
 | 
				
			|||||||
  StrategyType vault_strategy = 2;
 | 
					  StrategyType vault_strategy = 2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VaultRecord is the state of a vault and is used to store the state of a
 | 
					// VaultRecord is the state of a vault.
 | 
				
			||||||
// vault.
 | 
					 | 
				
			||||||
message VaultRecord {
 | 
					message VaultRecord {
 | 
				
			||||||
  // Denom is the only supported denomination of the vault for deposits and
 | 
					  // TotalShares is the total distributed number of shares in the vault.
 | 
				
			||||||
  // withdrawals.
 | 
					  VaultShare total_shares = 1 [(gogoproto.nullable) = false];
 | 
				
			||||||
  string denom = 1;
 | 
					 | 
				
			||||||
  // TotalSupply is the total supply of the vault, denominated **only** in the
 | 
					 | 
				
			||||||
  // user deposit/withdrawal denom, must be the same as the Denom field.
 | 
					 | 
				
			||||||
  cosmos.base.v1beta1.Coin total_supply = 2 [(gogoproto.nullable) = false];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VaultShareRecord defines the vault shares owned by a depositor.
 | 
					// VaultShareRecord defines the vault shares owned by a depositor.
 | 
				
			||||||
@ -36,8 +31,18 @@ message VaultShareRecord {
 | 
				
			|||||||
    (cosmos_proto.scalar) = "cosmos.AddressBytes",
 | 
					    (cosmos_proto.scalar) = "cosmos.AddressBytes",
 | 
				
			||||||
    (gogoproto.casttype)  = "github.com/cosmos/cosmos-sdk/types.AccAddress"
 | 
					    (gogoproto.casttype)  = "github.com/cosmos/cosmos-sdk/types.AccAddress"
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
  // AmountSupplied represents the total amount a depositor has supplied to the
 | 
					  // Shares represent the vault shares owned by the depositor.
 | 
				
			||||||
  // vault. The vault is determined by the coin denom.
 | 
					  repeated VaultShare shares = 2 [(gogoproto.castrepeated) = "VaultShares", (gogoproto.nullable) = false];
 | 
				
			||||||
  repeated cosmos.base.v1beta1.Coin amount_supplied = 2
 | 
					}
 | 
				
			||||||
      [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
 | 
					
 | 
				
			||||||
 | 
					// VaultShare defines shares of a vault owned by a depositor.
 | 
				
			||||||
 | 
					message VaultShare {
 | 
				
			||||||
 | 
					  option (gogoproto.goproto_stringer) = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string denom  = 1;
 | 
				
			||||||
 | 
					  string amount = 2 [
 | 
				
			||||||
 | 
					    (cosmos_proto.scalar)  = "cosmos.Dec",
 | 
				
			||||||
 | 
					    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
 | 
				
			||||||
 | 
					    (gogoproto.nullable)   = false
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -33,7 +33,6 @@ func GetQueryCmd() *cobra.Command {
 | 
				
			|||||||
		queryParamsCmd(),
 | 
							queryParamsCmd(),
 | 
				
			||||||
		queryVaultsCmd(),
 | 
							queryVaultsCmd(),
 | 
				
			||||||
		queryDepositsCmd(),
 | 
							queryDepositsCmd(),
 | 
				
			||||||
		queryTotalDepositedCmd(),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, cmd := range cmds {
 | 
						for _, cmd := range cmds {
 | 
				
			||||||
@ -155,35 +154,3 @@ func queryDepositsCmd() *cobra.Command {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return cmd
 | 
						return cmd
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func queryTotalDepositedCmd() *cobra.Command {
 | 
					 | 
				
			||||||
	return &cobra.Command{
 | 
					 | 
				
			||||||
		Use:   "total-deposited",
 | 
					 | 
				
			||||||
		Short: "get the current total deposited amount",
 | 
					 | 
				
			||||||
		Long:  "Get the current total deposited amount in the earn module vaults.",
 | 
					 | 
				
			||||||
		Args:  cobra.MaximumNArgs(1),
 | 
					 | 
				
			||||||
		Example: fmt.Sprintf(`%[1]s q %[2]s total-deposited
 | 
					 | 
				
			||||||
%[1]s q %[2]s total-deposited usdx`, version.AppName, types.ModuleName),
 | 
					 | 
				
			||||||
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
					 | 
				
			||||||
			clientCtx, err := client.GetClientQueryContext(cmd)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			queryClient := types.NewQueryClient(clientCtx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			vaultDenom := ""
 | 
					 | 
				
			||||||
			if len(args) > 1 {
 | 
					 | 
				
			||||||
				vaultDenom = args[0]
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			req := types.NewQueryTotalDepositedRequest(vaultDenom)
 | 
					 | 
				
			||||||
			res, err := queryClient.TotalDeposited(context.Background(), req)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return clientCtx.PrintProto(res)
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -21,14 +21,14 @@ func InitGenesis(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Total of all vault share records, vault record total supply should equal this
 | 
						// Total of all vault share records, vault record total supply should equal this
 | 
				
			||||||
	vaultTotalSupplies := sdk.NewCoins()
 | 
						vaultTotalShares := types.NewVaultShares()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, vaultShareRecord := range gs.VaultShareRecords {
 | 
						for _, vaultShareRecord := range gs.VaultShareRecords {
 | 
				
			||||||
		if err := vaultShareRecord.Validate(); err != nil {
 | 
							if err := vaultShareRecord.Validate(); err != nil {
 | 
				
			||||||
			panic(fmt.Sprintf("invalid vault share: %s", err))
 | 
								panic(fmt.Sprintf("invalid vault share: %s", err))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		vaultTotalSupplies = vaultTotalSupplies.Add(vaultShareRecord.AmountSupplied...)
 | 
							vaultTotalShares = vaultTotalShares.Add(vaultShareRecord.Shares...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		k.SetVaultShareRecord(ctx, vaultShareRecord)
 | 
							k.SetVaultShareRecord(ctx, vaultShareRecord)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -38,12 +38,12 @@ func InitGenesis(
 | 
				
			|||||||
			panic(fmt.Sprintf("invalid vault record: %s", err))
 | 
								panic(fmt.Sprintf("invalid vault record: %s", err))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !vaultRecord.TotalSupply.Amount.Equal(vaultTotalSupplies.AmountOf(vaultRecord.Denom)) {
 | 
							if !vaultRecord.TotalShares.Amount.Equal(vaultTotalShares.AmountOf(vaultRecord.TotalShares.Denom)) {
 | 
				
			||||||
			panic(fmt.Sprintf(
 | 
								panic(fmt.Sprintf(
 | 
				
			||||||
				"invalid vault record total supply for %s, got %s but sum of vault shares is %s",
 | 
									"invalid vault record total supply for %s, got %s but sum of vault shares is %s",
 | 
				
			||||||
				vaultRecord.Denom,
 | 
									vaultRecord.TotalShares.Denom,
 | 
				
			||||||
				vaultRecord.TotalSupply.Amount,
 | 
									vaultRecord.TotalShares.Amount,
 | 
				
			||||||
				vaultTotalSupplies.AmountOf(vaultRecord.Denom),
 | 
									vaultTotalShares.AmountOf(vaultRecord.TotalShares.Denom),
 | 
				
			||||||
			))
 | 
								))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,9 @@ func (suite *genesisTestSuite) Test_InitGenesis_ValidationPanic() {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultRecords{
 | 
							types.VaultRecords{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Denom:       "",
 | 
									TotalShares: types.VaultShare{
 | 
				
			||||||
				TotalSupply: sdk.NewInt64Coin("usdx", 0),
 | 
										Denom: "", Amount: sdk.NewDec(1),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultShareRecords{},
 | 
							types.VaultShareRecords{},
 | 
				
			||||||
@ -53,22 +54,26 @@ func (suite *genesisTestSuite) Test_InitAndExportGenesis() {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultRecords{
 | 
							types.VaultRecords{
 | 
				
			||||||
			types.VaultRecord{
 | 
								types.VaultRecord{
 | 
				
			||||||
				Denom:       "ukava",
 | 
									TotalShares: types.NewVaultShare("ukava", sdk.NewDec(3800000)),
 | 
				
			||||||
				TotalSupply: sdk.NewInt64Coin("ukava", 2000000),
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.VaultRecord{
 | 
								types.VaultRecord{
 | 
				
			||||||
				Denom:       "usdx",
 | 
									TotalShares: types.NewVaultShare("usdx", sdk.NewDec(1000000)),
 | 
				
			||||||
				TotalSupply: sdk.NewInt64Coin("usdx", 1000000),
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultShareRecords{
 | 
							types.VaultShareRecords{
 | 
				
			||||||
			types.VaultShareRecord{
 | 
								types.VaultShareRecord{
 | 
				
			||||||
				Depositor: depositor_1,
 | 
									Depositor: depositor_1,
 | 
				
			||||||
				AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 1900000)),
 | 
									Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
										types.NewVaultShare("usdx", sdk.NewDec(500000)),
 | 
				
			||||||
 | 
										types.NewVaultShare("ukava", sdk.NewDec(1900000)),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.VaultShareRecord{
 | 
								types.VaultShareRecord{
 | 
				
			||||||
				Depositor: depositor_2,
 | 
									Depositor: depositor_2,
 | 
				
			||||||
				AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 100000)),
 | 
									Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
										types.NewVaultShare("usdx", sdk.NewDec(500000)),
 | 
				
			||||||
 | 
										types.NewVaultShare("ukava", sdk.NewDec(1900000)),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@ -107,22 +112,26 @@ func (suite *genesisTestSuite) Test_Marshall() {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultRecords{
 | 
							types.VaultRecords{
 | 
				
			||||||
			types.VaultRecord{
 | 
								types.VaultRecord{
 | 
				
			||||||
				Denom:       "ukava",
 | 
									TotalShares: types.NewVaultShare("ukava", sdk.NewDec(3800000)),
 | 
				
			||||||
				TotalSupply: sdk.NewInt64Coin("ukava", 2000000),
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.VaultRecord{
 | 
								types.VaultRecord{
 | 
				
			||||||
				Denom:       "usdx",
 | 
									TotalShares: types.NewVaultShare("usdx", sdk.NewDec(1000000)),
 | 
				
			||||||
				TotalSupply: sdk.NewInt64Coin("usdx", 1000000),
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		types.VaultShareRecords{
 | 
							types.VaultShareRecords{
 | 
				
			||||||
			types.VaultShareRecord{
 | 
								types.VaultShareRecord{
 | 
				
			||||||
				Depositor: depositor_1,
 | 
									Depositor: depositor_1,
 | 
				
			||||||
				AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 1900000)),
 | 
									Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
										types.NewVaultShare("usdx", sdk.NewDec(500000)),
 | 
				
			||||||
 | 
										types.NewVaultShare("ukava", sdk.NewDec(1900000)),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.VaultShareRecord{
 | 
								types.VaultShareRecord{
 | 
				
			||||||
				Depositor: depositor_2,
 | 
									Depositor: depositor_2,
 | 
				
			||||||
				AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 100000)),
 | 
									Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
										types.NewVaultShare("usdx", sdk.NewDec(500000)),
 | 
				
			||||||
 | 
										types.NewVaultShare("ukava", sdk.NewDec(1900000)),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
package keeper
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/earn/types"
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -22,7 +24,7 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
 | 
				
			|||||||
	vaultRecord, found := k.GetVaultRecord(ctx, amount.Denom)
 | 
						vaultRecord, found := k.GetVaultRecord(ctx, amount.Denom)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		// Create a new VaultRecord with 0 supply
 | 
							// Create a new VaultRecord with 0 supply
 | 
				
			||||||
		vaultRecord = types.NewVaultRecord(amount.Denom)
 | 
							vaultRecord = types.NewVaultRecord(amount.Denom, sdk.ZeroDec())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get the strategy for the vault
 | 
						// Get the strategy for the vault
 | 
				
			||||||
@ -45,14 +47,17 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
 | 
				
			|||||||
	vaultShareRecord, found := k.GetVaultShareRecord(ctx, depositor)
 | 
						vaultShareRecord, found := k.GetVaultShareRecord(ctx, depositor)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		// Create a new empty VaultShareRecord with 0 supply
 | 
							// Create a new empty VaultShareRecord with 0 supply
 | 
				
			||||||
		vaultShareRecord = types.NewVaultShareRecord(depositor)
 | 
							vaultShareRecord = types.NewVaultShareRecord(depositor, types.NewVaultShares())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Increment VaultRecord supply
 | 
						shares, err := k.ConvertToShares(ctx, amount)
 | 
				
			||||||
	vaultRecord.TotalSupply = vaultRecord.TotalSupply.Add(amount)
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to convert assets to shares: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Increment VaultShareRecord supply
 | 
						// Increment VaultRecord total shares and account shares
 | 
				
			||||||
	vaultShareRecord.AmountSupplied = vaultShareRecord.AmountSupplied.Add(amount)
 | 
						vaultRecord.TotalShares = vaultRecord.TotalShares.Add(shares)
 | 
				
			||||||
 | 
						vaultShareRecord.Shares = vaultShareRecord.Shares.Add(shares)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update VaultRecord and VaultShareRecord
 | 
						// Update VaultRecord and VaultShareRecord
 | 
				
			||||||
	k.SetVaultRecord(ctx, vaultRecord)
 | 
						k.SetVaultRecord(ctx, vaultRecord)
 | 
				
			||||||
@ -68,6 +73,7 @@ func (k *Keeper) Deposit(ctx sdk.Context, depositor sdk.AccAddress, amount sdk.C
 | 
				
			|||||||
			types.EventTypeVaultDeposit,
 | 
								types.EventTypeVaultDeposit,
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyVaultDenom, amount.Denom),
 | 
								sdk.NewAttribute(types.AttributeKeyVaultDenom, amount.Denom),
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyDepositor, depositor.String()),
 | 
								sdk.NewAttribute(types.AttributeKeyDepositor, depositor.String()),
 | 
				
			||||||
 | 
								sdk.NewAttribute(types.AttributeKeyShares, shares.Amount.String()),
 | 
				
			||||||
			sdk.NewAttribute(sdk.AttributeKeyAmount, amount.Amount.String()),
 | 
								sdk.NewAttribute(sdk.AttributeKeyAmount, amount.Amount.String()),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
				
			|||||||
@ -51,7 +51,9 @@ func (suite *depositTestSuite) TestDeposit_Balances() {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(depositAmount.Denom, depositAmount.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *depositTestSuite) TestDeposit_Exceed() {
 | 
					func (suite *depositTestSuite) TestDeposit_Exceed() {
 | 
				
			||||||
 | 
				
			|||||||
@ -69,10 +69,10 @@ func (s queryServer) Vaults(
 | 
				
			|||||||
	vaults := []types.VaultResponse{}
 | 
						vaults := []types.VaultResponse{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, allowedVault := range queriedAllowedVaults {
 | 
						for _, allowedVault := range queriedAllowedVaults {
 | 
				
			||||||
		totalSupplied, err := s.keeper.GetVaultTotalSupplied(sdkCtx, allowedVault.Denom)
 | 
							vaultTotalShares, found := s.keeper.GetVaultTotalShares(sdkCtx, allowedVault.Denom)
 | 
				
			||||||
		if err != nil {
 | 
							if !found {
 | 
				
			||||||
			// No supply yet, no error just zero
 | 
								// No supply yet, no error just zero
 | 
				
			||||||
			totalSupplied = sdk.NewCoin(allowedVault.Denom, sdk.ZeroInt())
 | 
								vaultTotalShares = types.NewVaultShare(allowedVault.Denom, sdk.ZeroDec())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		totalValue, err := s.keeper.GetVaultTotalValue(sdkCtx, allowedVault.Denom)
 | 
							totalValue, err := s.keeper.GetVaultTotalValue(sdkCtx, allowedVault.Denom)
 | 
				
			||||||
@ -83,7 +83,7 @@ func (s queryServer) Vaults(
 | 
				
			|||||||
		vaults = append(vaults, types.VaultResponse{
 | 
							vaults = append(vaults, types.VaultResponse{
 | 
				
			||||||
			Denom:         allowedVault.Denom,
 | 
								Denom:         allowedVault.Denom,
 | 
				
			||||||
			VaultStrategy: allowedVault.VaultStrategy,
 | 
								VaultStrategy: allowedVault.VaultStrategy,
 | 
				
			||||||
			TotalSupplied: totalSupplied.Amount,
 | 
								TotalShares:   vaultTotalShares.Amount.String(),
 | 
				
			||||||
			TotalValue:    totalValue.Amount,
 | 
								TotalValue:    totalValue.Amount,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -106,21 +106,44 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// 1. Specific account and specific vault
 | 
						// 1. Specific account and specific vault
 | 
				
			||||||
	if req.Owner != "" && req.Denom != "" {
 | 
						if req.Owner != "" && req.Denom != "" {
 | 
				
			||||||
 | 
							return s.getAccountVaultDeposit(sdkCtx, req)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. All accounts, specific vault
 | 
				
			||||||
 | 
						if req.Owner == "" && req.Denom != "" {
 | 
				
			||||||
 | 
							return s.getVaultAllDeposits(sdkCtx, req)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 3. Specific account, all vaults
 | 
				
			||||||
 | 
						if req.Owner != "" && req.Denom == "" {
 | 
				
			||||||
 | 
							return s.getAccountAllDeposits(sdkCtx, req)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 4. All accounts, all vaults
 | 
				
			||||||
 | 
						return s.getAllDeposits(sdkCtx, req)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getAccountVaultDeposit returns deposits for a specific vault and a specific
 | 
				
			||||||
 | 
					// account
 | 
				
			||||||
 | 
					func (s queryServer) getAccountVaultDeposit(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						req *types.QueryDepositsRequest,
 | 
				
			||||||
 | 
					) (*types.QueryDepositsResponse, error) {
 | 
				
			||||||
	owner, err := sdk.AccAddressFromBech32(req.Owner)
 | 
						owner, err := sdk.AccAddressFromBech32(req.Owner)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, status.Error(codes.InvalidArgument, "Invalid address")
 | 
							return nil, status.Error(codes.InvalidArgument, "Invalid address")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		shareRecord, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
 | 
						shareRecord, found := s.keeper.GetVaultShareRecord(ctx, owner)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return nil, status.Error(codes.NotFound, "No deposit found for owner")
 | 
							return nil, status.Error(codes.NotFound, "No deposit found for owner")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if shareRecord.AmountSupplied.AmountOf(req.Denom).IsZero() {
 | 
						if shareRecord.Shares.AmountOf(req.Denom).IsZero() {
 | 
				
			||||||
		return nil, status.Error(codes.NotFound, fmt.Sprintf("No deposit for denom %s found for owner", req.Denom))
 | 
							return nil, status.Error(codes.NotFound, fmt.Sprintf("No deposit for denom %s found for owner", req.Denom))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		value, err := getAccountValue(sdkCtx, s.keeper, owner, shareRecord.AmountSupplied)
 | 
						value, err := getAccountValue(ctx, s.keeper, owner, shareRecord.Shares)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, status.Error(codes.InvalidArgument, err.Error())
 | 
							return nil, status.Error(codes.InvalidArgument, err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -129,23 +152,26 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
		Deposits: []types.DepositResponse{
 | 
							Deposits: []types.DepositResponse{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Depositor: owner.String(),
 | 
									Depositor: owner.String(),
 | 
				
			||||||
					AmountSupplied: shareRecord.AmountSupplied,
 | 
									Shares:    shareRecord.Shares,
 | 
				
			||||||
				Value:     value,
 | 
									Value:     value,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Pagination: nil,
 | 
							Pagination: nil,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 2. All accounts, specific vault
 | 
					// getVaultAllDeposits returns all deposits for a specific vault
 | 
				
			||||||
	if req.Owner == "" && req.Denom != "" {
 | 
					func (s queryServer) getVaultAllDeposits(
 | 
				
			||||||
		_, found := s.keeper.GetVaultRecord(sdkCtx, req.Denom)
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						req *types.QueryDepositsRequest,
 | 
				
			||||||
 | 
					) (*types.QueryDepositsResponse, error) {
 | 
				
			||||||
 | 
						_, found := s.keeper.GetVaultRecord(ctx, req.Denom)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return nil, status.Error(codes.NotFound, "Vault record for denom not found")
 | 
							return nil, status.Error(codes.NotFound, "Vault record for denom not found")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deposits := []types.DepositResponse{}
 | 
						deposits := []types.DepositResponse{}
 | 
				
			||||||
		store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pageRes, err := query.FilteredPaginate(
 | 
						pageRes, err := query.FilteredPaginate(
 | 
				
			||||||
		store,
 | 
							store,
 | 
				
			||||||
@ -158,13 +184,13 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Only those that have amount of requested denom
 | 
								// Only those that have amount of requested denom
 | 
				
			||||||
				if record.AmountSupplied.AmountOf(req.Denom).IsZero() {
 | 
								if record.Shares.AmountOf(req.Denom).IsZero() {
 | 
				
			||||||
				// inform paginate that there was no match on this key
 | 
									// inform paginate that there was no match on this key
 | 
				
			||||||
				return false, nil
 | 
									return false, nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if accumulate {
 | 
								if accumulate {
 | 
				
			||||||
					accValue, err := getAccountValue(sdkCtx, s.keeper, record.Depositor, record.AmountSupplied)
 | 
									accValue, err := getAccountValue(ctx, s.keeper, record.Depositor, record.Shares)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return false, err
 | 
										return false, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -172,7 +198,7 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
				// only add to results if paginate tells us to
 | 
									// only add to results if paginate tells us to
 | 
				
			||||||
				deposits = append(deposits, types.DepositResponse{
 | 
									deposits = append(deposits, types.DepositResponse{
 | 
				
			||||||
					Depositor: record.Depositor.String(),
 | 
										Depositor: record.Depositor.String(),
 | 
				
			||||||
						AmountSupplied: record.AmountSupplied,
 | 
										Shares:    record.Shares,
 | 
				
			||||||
					Value:     accValue,
 | 
										Value:     accValue,
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -190,10 +216,13 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
		Deposits:   deposits,
 | 
							Deposits:   deposits,
 | 
				
			||||||
		Pagination: pageRes,
 | 
							Pagination: pageRes,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 3. Specific account, all vaults
 | 
					// getAccountAllDeposits returns deposits for all vaults for a specific account
 | 
				
			||||||
	if req.Owner != "" && req.Denom == "" {
 | 
					func (s queryServer) getAccountAllDeposits(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						req *types.QueryDepositsRequest,
 | 
				
			||||||
 | 
					) (*types.QueryDepositsResponse, error) {
 | 
				
			||||||
	owner, err := sdk.AccAddressFromBech32(req.Owner)
 | 
						owner, err := sdk.AccAddressFromBech32(req.Owner)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, status.Error(codes.InvalidArgument, "Invalid address")
 | 
							return nil, status.Error(codes.InvalidArgument, "Invalid address")
 | 
				
			||||||
@ -201,19 +230,19 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	deposits := []types.DepositResponse{}
 | 
						deposits := []types.DepositResponse{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		accountShare, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
 | 
						accountShare, found := s.keeper.GetVaultShareRecord(ctx, owner)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return nil, status.Error(codes.NotFound, "No deposit found for owner")
 | 
							return nil, status.Error(codes.NotFound, "No deposit found for owner")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		value, err := getAccountValue(sdkCtx, s.keeper, owner, accountShare.AmountSupplied)
 | 
						value, err := getAccountValue(ctx, s.keeper, owner, accountShare.Shares)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, status.Error(codes.InvalidArgument, err.Error())
 | 
							return nil, status.Error(codes.InvalidArgument, err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deposits = append(deposits, types.DepositResponse{
 | 
						deposits = append(deposits, types.DepositResponse{
 | 
				
			||||||
		Depositor: owner.String(),
 | 
							Depositor: owner.String(),
 | 
				
			||||||
			AmountSupplied: accountShare.AmountSupplied,
 | 
							Shares:    accountShare.Shares,
 | 
				
			||||||
		Value:     value,
 | 
							Value:     value,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -221,11 +250,15 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
		Deposits:   deposits,
 | 
							Deposits:   deposits,
 | 
				
			||||||
		Pagination: nil,
 | 
							Pagination: nil,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 4. All accounts, all vaults
 | 
					// getAllDeposits returns all deposits for all vaults
 | 
				
			||||||
 | 
					func (s queryServer) getAllDeposits(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						req *types.QueryDepositsRequest,
 | 
				
			||||||
 | 
					) (*types.QueryDepositsResponse, error) {
 | 
				
			||||||
	deposits := []types.DepositResponse{}
 | 
						deposits := []types.DepositResponse{}
 | 
				
			||||||
	store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
 | 
						store := prefix.NewStore(ctx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pageRes, err := query.Paginate(
 | 
						pageRes, err := query.Paginate(
 | 
				
			||||||
		store,
 | 
							store,
 | 
				
			||||||
@ -237,7 +270,7 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			accValue, err := getAccountValue(sdkCtx, s.keeper, record.Depositor, record.AmountSupplied)
 | 
								accValue, err := getAccountValue(ctx, s.keeper, record.Depositor, record.Shares)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -245,7 +278,7 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
			// only add to results if paginate tells us to
 | 
								// only add to results if paginate tells us to
 | 
				
			||||||
			deposits = append(deposits, types.DepositResponse{
 | 
								deposits = append(deposits, types.DepositResponse{
 | 
				
			||||||
				Depositor: record.Depositor.String(),
 | 
									Depositor: record.Depositor.String(),
 | 
				
			||||||
				AmountSupplied: record.AmountSupplied,
 | 
									Shares:    record.Shares,
 | 
				
			||||||
				Value:     accValue,
 | 
									Value:     accValue,
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -263,56 +296,21 @@ func (s queryServer) Deposits(
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Deposits implements the gRPC service handler for querying x/earn deposits.
 | 
					 | 
				
			||||||
func (s queryServer) TotalDeposited(
 | 
					 | 
				
			||||||
	ctx context.Context,
 | 
					 | 
				
			||||||
	req *types.QueryTotalDepositedRequest,
 | 
					 | 
				
			||||||
) (*types.QueryTotalDepositedResponse, error) {
 | 
					 | 
				
			||||||
	if req == nil {
 | 
					 | 
				
			||||||
		return nil, status.Errorf(codes.InvalidArgument, "empty request")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sdkCtx := sdk.UnwrapSDKContext(ctx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Single vault
 | 
					 | 
				
			||||||
	if req.Denom != "" {
 | 
					 | 
				
			||||||
		totalSupplied, err := s.keeper.GetVaultTotalSupplied(sdkCtx, req.Denom)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return &types.QueryTotalDepositedResponse{
 | 
					 | 
				
			||||||
			SuppliedCoins: sdk.NewCoins(totalSupplied),
 | 
					 | 
				
			||||||
		}, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	coins := sdk.NewCoins()
 | 
					 | 
				
			||||||
	vaults := s.keeper.GetAllVaultRecords(sdkCtx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, vault := range vaults {
 | 
					 | 
				
			||||||
		coins = coins.Add(vault.TotalSupply)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &types.QueryTotalDepositedResponse{
 | 
					 | 
				
			||||||
		SuppliedCoins: coins,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getAccountValue(
 | 
					func getAccountValue(
 | 
				
			||||||
	ctx sdk.Context,
 | 
						ctx sdk.Context,
 | 
				
			||||||
	keeper Keeper,
 | 
						keeper Keeper,
 | 
				
			||||||
	account sdk.AccAddress,
 | 
						account sdk.AccAddress,
 | 
				
			||||||
	supplied sdk.Coins,
 | 
						shares types.VaultShares,
 | 
				
			||||||
) (sdk.Coins, error) {
 | 
					) (sdk.Coins, error) {
 | 
				
			||||||
	value := sdk.NewCoins()
 | 
						value := sdk.NewCoins()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, coin := range supplied {
 | 
						for _, share := range shares {
 | 
				
			||||||
		accValue, err := keeper.GetVaultAccountValue(ctx, coin.Denom, account)
 | 
							accValue, err := keeper.GetVaultAccountValue(ctx, share.Denom, account)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		value = value.Add(sdk.NewCoin(coin.Denom, accValue.Amount))
 | 
							value = value.Add(sdk.NewCoin(share.Denom, accValue.Amount))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return value, nil
 | 
						return value, nil
 | 
				
			||||||
 | 
				
			|||||||
@ -70,7 +70,7 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() {
 | 
				
			|||||||
			types.VaultResponse{
 | 
								types.VaultResponse{
 | 
				
			||||||
				Denom:         "usdx",
 | 
									Denom:         "usdx",
 | 
				
			||||||
				VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
									VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
				
			||||||
				TotalSupplied: sdk.NewInt(0),
 | 
									TotalShares:   sdk.NewDec(0).String(),
 | 
				
			||||||
				TotalValue:    sdk.NewInt(0),
 | 
									TotalValue:    sdk.NewInt(0),
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			res.Vaults[0],
 | 
								res.Vaults[0],
 | 
				
			||||||
@ -86,13 +86,13 @@ func (suite *grpcQueryTestSuite) TestVaults_ZeroSupply() {
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:         "usdx",
 | 
										Denom:         "usdx",
 | 
				
			||||||
					VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
										VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
				
			||||||
					TotalSupplied: sdk.NewInt(0),
 | 
										TotalShares:   sdk.NewDec(0).String(),
 | 
				
			||||||
					TotalValue:    sdk.NewInt(0),
 | 
										TotalValue:    sdk.NewInt(0),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:         "busd",
 | 
										Denom:         "busd",
 | 
				
			||||||
					VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
										VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
				
			||||||
					TotalSupplied: sdk.NewInt(0),
 | 
										TotalShares:   sdk.NewDec(0).String(),
 | 
				
			||||||
					TotalValue:    sdk.NewInt(0),
 | 
										TotalValue:    sdk.NewInt(0),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -121,7 +121,7 @@ func (suite *grpcQueryTestSuite) TestVaults_WithSupply() {
 | 
				
			|||||||
		types.VaultResponse{
 | 
							types.VaultResponse{
 | 
				
			||||||
			Denom:         "usdx",
 | 
								Denom:         "usdx",
 | 
				
			||||||
			VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
								VaultStrategy: types.STRATEGY_TYPE_HARD,
 | 
				
			||||||
			TotalSupplied: depositAmount.Amount,
 | 
								TotalShares:   depositAmount.Amount.ToDec().String(),
 | 
				
			||||||
			TotalValue:    depositAmount.Amount,
 | 
								TotalValue:    depositAmount.Amount,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		res.Vaults[0],
 | 
							res.Vaults[0],
 | 
				
			||||||
@ -183,7 +183,10 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: acc1.String(),
 | 
										Depositor: acc1.String(),
 | 
				
			||||||
					// Still includes all deposits
 | 
										// Still includes all deposits
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
					Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -214,7 +217,10 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
 | 
				
			|||||||
			[]types.DepositResponse{
 | 
								[]types.DepositResponse{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: acc1.String(),
 | 
										Depositor: acc1.String(),
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
					Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -234,7 +240,10 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
 | 
				
			|||||||
			[]types.DepositResponse{
 | 
								[]types.DepositResponse{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: acc2.String(),
 | 
										Depositor: acc2.String(),
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit3Amount.Denom, deposit3Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
					Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
										Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -254,12 +263,18 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
 | 
				
			|||||||
			[]types.DepositResponse{
 | 
								[]types.DepositResponse{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: acc1.String(),
 | 
										Depositor: acc1.String(),
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
					Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
										Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: acc2.String(),
 | 
										Depositor: acc2.String(),
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
											types.NewVaultShare(deposit3Amount.Denom, deposit3Amount.Amount.ToDec()),
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
					Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
										Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -294,103 +309,3 @@ func (suite *grpcQueryTestSuite) TestDeposits_InvalidAddress() {
 | 
				
			|||||||
	suite.Require().Error(err)
 | 
						suite.Require().Error(err)
 | 
				
			||||||
	suite.Require().ErrorIs(err, status.Error(codes.InvalidArgument, "Invalid address"))
 | 
						suite.Require().ErrorIs(err, status.Error(codes.InvalidArgument, "Invalid address"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *grpcQueryTestSuite) TestTotalDeposited_NoSupply() {
 | 
					 | 
				
			||||||
	// Add vaults
 | 
					 | 
				
			||||||
	suite.CreateVault("usdx", types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
	suite.CreateVault("cats", types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	res, err := suite.queryClient.TotalDeposited(context.Background(), types.NewQueryTotalDepositedRequest(""))
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
	suite.Require().True(res.SuppliedCoins.Empty(), "supplied coins should be empty")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *grpcQueryTestSuite) TestTotalDeposited_All() {
 | 
					 | 
				
			||||||
	vault1Denom := "usdx"
 | 
					 | 
				
			||||||
	vault2Denom := "busd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Add vaults
 | 
					 | 
				
			||||||
	suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
	suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	startBalance := sdk.NewCoins(
 | 
					 | 
				
			||||||
		sdk.NewInt64Coin(vault1Denom, 1000),
 | 
					 | 
				
			||||||
		sdk.NewInt64Coin(vault2Denom, 1000),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	deposit1Amount := sdk.NewInt64Coin(vault1Denom, 100)
 | 
					 | 
				
			||||||
	deposit2Amount := sdk.NewInt64Coin(vault2Denom, 100)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	acc := suite.CreateAccount(startBalance, 0).GetAddress()
 | 
					 | 
				
			||||||
	err := suite.Keeper.Deposit(suite.Ctx, acc, deposit1Amount)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	res, err := suite.queryClient.TotalDeposited(
 | 
					 | 
				
			||||||
		context.Background(),
 | 
					 | 
				
			||||||
		types.NewQueryTotalDepositedRequest(""), // query all
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
	suite.Require().Equal(
 | 
					 | 
				
			||||||
		sdk.NewCoins(deposit1Amount),
 | 
					 | 
				
			||||||
		res.SuppliedCoins,
 | 
					 | 
				
			||||||
		"supplied coins should be sum of all supplied coins",
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = suite.Keeper.Deposit(suite.Ctx, acc, deposit2Amount)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	res, err = suite.queryClient.TotalDeposited(
 | 
					 | 
				
			||||||
		context.Background(),
 | 
					 | 
				
			||||||
		types.NewQueryTotalDepositedRequest(""), // query all
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
	suite.Require().Equal(
 | 
					 | 
				
			||||||
		sdk.NewCoins(deposit1Amount, deposit2Amount),
 | 
					 | 
				
			||||||
		res.SuppliedCoins,
 | 
					 | 
				
			||||||
		"supplied coins should be sum of all supplied coins for multiple coins",
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *grpcQueryTestSuite) TestTotalDeposited_Single() {
 | 
					 | 
				
			||||||
	vault1Denom := "usdx"
 | 
					 | 
				
			||||||
	vault2Denom := "busd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Add vaults
 | 
					 | 
				
			||||||
	suite.CreateVault(vault1Denom, types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
	suite.CreateVault(vault2Denom, types.STRATEGY_TYPE_HARD)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	startBalance := sdk.NewCoins(
 | 
					 | 
				
			||||||
		sdk.NewInt64Coin(vault1Denom, 1000),
 | 
					 | 
				
			||||||
		sdk.NewInt64Coin(vault2Denom, 1000),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	deposit1Amount := sdk.NewInt64Coin(vault1Denom, 100)
 | 
					 | 
				
			||||||
	deposit2Amount := sdk.NewInt64Coin(vault2Denom, 100)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	acc := suite.CreateAccount(startBalance, 0).GetAddress()
 | 
					 | 
				
			||||||
	err := suite.Keeper.Deposit(suite.Ctx, acc, deposit1Amount)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = suite.Keeper.Deposit(suite.Ctx, acc, deposit2Amount)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	res, err := suite.queryClient.TotalDeposited(
 | 
					 | 
				
			||||||
		context.Background(),
 | 
					 | 
				
			||||||
		types.NewQueryTotalDepositedRequest(vault1Denom),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
	suite.Require().Equal(
 | 
					 | 
				
			||||||
		sdk.NewCoins(deposit1Amount),
 | 
					 | 
				
			||||||
		res.SuppliedCoins,
 | 
					 | 
				
			||||||
		"should only contain queried denom",
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	res, err = suite.queryClient.TotalDeposited(
 | 
					 | 
				
			||||||
		context.Background(),
 | 
					 | 
				
			||||||
		types.NewQueryTotalDepositedRequest(vault2Denom),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
					 | 
				
			||||||
	suite.Require().Equal(
 | 
					 | 
				
			||||||
		sdk.NewCoins(deposit2Amount),
 | 
					 | 
				
			||||||
		res.SuppliedCoins,
 | 
					 | 
				
			||||||
		"should only contain queried denom",
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,8 @@ func (suite *msgServerTestSuite) TestDeposit() {
 | 
				
			|||||||
			types.EventTypeVaultDeposit,
 | 
								types.EventTypeVaultDeposit,
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyVaultDenom, depositAmount.Denom),
 | 
								sdk.NewAttribute(types.AttributeKeyVaultDenom, depositAmount.Denom),
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyDepositor, acc.GetAddress().String()),
 | 
								sdk.NewAttribute(types.AttributeKeyDepositor, acc.GetAddress().String()),
 | 
				
			||||||
 | 
								// Shares 1:1 to amount
 | 
				
			||||||
 | 
								sdk.NewAttribute(types.AttributeKeyShares, depositAmount.Amount.ToDec().String()),
 | 
				
			||||||
			sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.Amount.String()),
 | 
								sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.Amount.String()),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@ -120,6 +122,7 @@ func (suite *msgServerTestSuite) TestWithdraw() {
 | 
				
			|||||||
			types.EventTypeVaultWithdraw,
 | 
								types.EventTypeVaultWithdraw,
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyVaultDenom, depositAmount.Denom),
 | 
								sdk.NewAttribute(types.AttributeKeyVaultDenom, depositAmount.Denom),
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyOwner, acc.GetAddress().String()),
 | 
								sdk.NewAttribute(types.AttributeKeyOwner, acc.GetAddress().String()),
 | 
				
			||||||
 | 
								sdk.NewAttribute(types.AttributeKeyShares, depositAmount.Amount.ToDec().String()),
 | 
				
			||||||
			sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.Amount.String()),
 | 
								sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.Amount.String()),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,9 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.HardDepositAmountEqual(sdk.NewCoins(depositAmount))
 | 
						suite.HardDepositAmountEqual(sdk.NewCoins(depositAmount))
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(depositAmount.Denom, depositAmount.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Query vault total
 | 
						// Query vault total
 | 
				
			||||||
	totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
						totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
				
			||||||
@ -70,10 +72,12 @@ func (suite *strategyHardTestSuite) TestDeposit_SingleAcc_MultipleDeposits() {
 | 
				
			|||||||
	err = suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
 | 
						err = suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	expectedVaultBalance := sdk.NewCoins(depositAmount.Add(depositAmount))
 | 
						expectedVaultBalance := depositAmount.Add(depositAmount)
 | 
				
			||||||
	suite.HardDepositAmountEqual(expectedVaultBalance)
 | 
						suite.HardDepositAmountEqual(sdk.NewCoins(expectedVaultBalance))
 | 
				
			||||||
	suite.VaultTotalValuesEqual(expectedVaultBalance)
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(expectedVaultBalance))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(expectedVaultBalance)
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(expectedVaultBalance.Denom, expectedVaultBalance.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Query vault total
 | 
						// Query vault total
 | 
				
			||||||
	totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
						totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
				
			||||||
@ -107,7 +111,9 @@ func (suite *strategyHardTestSuite) TestDeposit_MultipleAcc_MultipleDeposits() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.HardDepositAmountEqual(sdk.NewCoins(expectedTotalValue))
 | 
						suite.HardDepositAmountEqual(sdk.NewCoins(expectedTotalValue))
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins(expectedTotalValue))
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(expectedTotalValue))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins(expectedTotalValue))
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(expectedTotalValue.Denom, expectedTotalValue.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Query vault total
 | 
						// Query vault total
 | 
				
			||||||
	totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
						totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
				
			||||||
@ -183,7 +189,7 @@ func (suite *strategyHardTestSuite) TestWithdraw() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.HardDepositAmountEqual(sdk.NewCoins())
 | 
						suite.HardDepositAmountEqual(sdk.NewCoins())
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins())
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins())
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins())
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	totalValue, err = suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
						totalValue, err = suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
@ -232,26 +238,32 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
 | 
						suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Deposits from 2 accounts
 | 
						// Deposits accounts
 | 
				
			||||||
	acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
 | 
						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)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Deposit from acc2 so the vault doesn't get deleted when withdrawing
 | 
				
			||||||
 | 
						err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Direct hard deposit from module account to increase vault value
 | 
						// Direct hard deposit from module account to increase vault value
 | 
				
			||||||
	suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 10)))
 | 
						suite.App.FundModuleAccount(suite.Ctx, types.ModuleName, sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 20)))
 | 
				
			||||||
	macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
	suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 10)))
 | 
						suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 20)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Query account value
 | 
						// Query account value
 | 
				
			||||||
	accValue, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc)
 | 
						accValue, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
	suite.Equal(depositAmount.AddAmount(sdk.NewInt(10)), accValue)
 | 
						suite.Equal(depositAmount.AddAmount(sdk.NewInt(10)), accValue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Withdraw 10, 10 remaining
 | 
						// Withdraw 100, 10 remaining
 | 
				
			||||||
	err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
 | 
						err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Withdraw again -- too much
 | 
						// Withdraw 100 again -- too much
 | 
				
			||||||
	err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
 | 
						err = suite.Keeper.Withdraw(suite.Ctx, acc, depositAmount)
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().Error(err)
 | 
				
			||||||
	suite.Require().ErrorIs(
 | 
						suite.Require().ErrorIs(
 | 
				
			||||||
@ -268,7 +280,209 @@ func (suite *strategyHardTestSuite) TestWithdraw_WithAccumulatedHard() {
 | 
				
			|||||||
	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)))
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc)
 | 
						accValue, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc)
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().Errorf(
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound)
 | 
							err,
 | 
				
			||||||
 | 
							"account should be deleted when all shares withdrawn but has %s value still",
 | 
				
			||||||
 | 
							accValue,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						suite.Require().Equal("account vault share record for usdx not found", err.Error())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *strategyHardTestSuite) TestAccountShares() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Deposit from account1
 | 
				
			||||||
 | 
						acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
 | 
				
			||||||
 | 
						acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1. acc1 deposit 100
 | 
				
			||||||
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewDec(100), acc1Shares.AmountOf(vaultDenom), "initial deposit 1:1 shares")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. Direct hard deposit from module account to increase vault value
 | 
				
			||||||
 | 
						// Total value: 100 -> 110
 | 
				
			||||||
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
 | 
						err = suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 10)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. acc2 deposit 100
 | 
				
			||||||
 | 
						// share price is 10% more expensive now
 | 
				
			||||||
 | 
						// hard 110 -> 210
 | 
				
			||||||
 | 
						err = suite.Keeper.Deposit(suite.Ctx, acc2, depositAmount)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 100 * 100 / 210 = 47.619047619 shares
 | 
				
			||||||
 | 
						// 2.1 price * 47.619047619 = 99.9999999999
 | 
				
			||||||
 | 
						acc2Value, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc2)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
						suite.Equal(
 | 
				
			||||||
 | 
							sdk.NewInt(99),
 | 
				
			||||||
 | 
							acc2Value.Amount,
 | 
				
			||||||
 | 
							"value 1 less than deposit amount with different share price, decimals truncated",
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc2Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc2)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						// 100 * 100 / 110 = 190.909090909090909091
 | 
				
			||||||
 | 
						// QuoInt64() truncates
 | 
				
			||||||
 | 
						expectedAcc2Shares := sdk.NewDec(100).MulInt64(100).QuoInt64(110)
 | 
				
			||||||
 | 
						suite.Equal(expectedAcc2Shares, acc2Shares.AmountOf(vaultDenom))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaultTotalShares, found := suite.Keeper.GetVaultTotalShares(suite.Ctx, vaultDenom)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewDec(100).Add(expectedAcc2Shares), vaultTotalShares.Amount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Hard deposit again from module account to triple original value
 | 
				
			||||||
 | 
						// 210 -> 300
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						// totalShares = 100 + 90            = 190
 | 
				
			||||||
 | 
						// totalValue  = 100 + 10 + 100 + 90 = 300
 | 
				
			||||||
 | 
						// sharesIssued = assetAmount * (shareCount / totalTokens)
 | 
				
			||||||
 | 
						// sharedIssued = 100 * 190 / 300 = 63.3 = 63
 | 
				
			||||||
 | 
						// total shares = 100 + 63 = 163
 | 
				
			||||||
 | 
						suite.Equal(
 | 
				
			||||||
 | 
							sdk.NewDec(100).Add(sdk.NewDec(100).Mul(vaultTotalShares.Amount).Quo(sdk.NewDec(300))),
 | 
				
			||||||
 | 
							acc1Shares.AmountOf(vaultDenom),
 | 
				
			||||||
 | 
							"shares should consist of 100 of 1x share price and 63 of 3x share price",
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedAmount() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Deposit from account1
 | 
				
			||||||
 | 
						acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
 | 
				
			||||||
 | 
						acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1. acc1 deposit 100
 | 
				
			||||||
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewDec(100), acc1Shares.AmountOf(vaultDenom), "initial deposit 1:1 shares")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. Direct hard deposit from module account to increase vault value
 | 
				
			||||||
 | 
						// Total value: 200 -> 220, 110 each account
 | 
				
			||||||
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
 | 
						err = suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 20)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 3. Withdraw all from acc1 - including accumulated amount
 | 
				
			||||||
 | 
						err = suite.Keeper.Withdraw(suite.Ctx, acc1, depositAmount.AddAmount(sdk.NewInt(10)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().False(found, "should have withdrawn entire shares")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *strategyHardTestSuite) TestWithdraw_AccumulatedTruncated() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Deposit from account1
 | 
				
			||||||
 | 
						acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
 | 
				
			||||||
 | 
						acc2 := suite.CreateAccount(sdk.NewCoins(startBalance), 1).GetAddress()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1. acc1 deposit 100
 | 
				
			||||||
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewDec(100), acc1Shares.AmountOf(vaultDenom), "initial deposit 1:1 shares")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. Direct hard deposit from module account to increase vault value
 | 
				
			||||||
 | 
						// Total value: 200 -> 211, 105.5 each account
 | 
				
			||||||
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
 | 
						err = suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 11)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accBal, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc1)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
						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)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().Falsef(found, "should have withdrawn entire shares but has %s", acc1Shares)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc1)
 | 
				
			||||||
 | 
						suite.Require().Error(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *strategyHardTestSuite) TestWithdraw_ExpensiveShares() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Deposit from account1
 | 
				
			||||||
 | 
						acc1 := suite.CreateAccount(sdk.NewCoins(startBalance), 0).GetAddress()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1. acc1 deposit 100
 | 
				
			||||||
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc1, depositAmount)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewDec(100), acc1Shares.AmountOf(vaultDenom), "initial deposit 1:1 shares")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. Direct hard deposit from module account to increase vault value
 | 
				
			||||||
 | 
						// Total value: 100 -> 2000, shares now 10usdx each
 | 
				
			||||||
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
 | 
						err = suite.HardKeeper.Deposit(suite.Ctx, macc.GetAddress(), sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 1900)))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accBal, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc1)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
						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))
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acc1Shares, found = suite.Keeper.GetVaultAccountShares(suite.Ctx, acc1)
 | 
				
			||||||
 | 
						suite.Require().Falsef(found, "should have withdrawn entire shares but has %s", acc1Shares)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc1)
 | 
				
			||||||
 | 
						suite.Require().Error(err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,24 +1,25 @@
 | 
				
			|||||||
package keeper
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/cosmos/cosmos-sdk/store/prefix"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
	"github.com/kava-labs/kava/x/earn/types"
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetVaultTotalSupplied returns the total balance supplied to the vault. This
 | 
					// GetVaultTotalShares returns the total balance supplied to the vault. This
 | 
				
			||||||
// may not necessarily be the current value of the vault, as it is the sum
 | 
					// may not necessarily be the current value of the vault, as it is the sum
 | 
				
			||||||
// of the supplied denom and the value may be higher due to accumulated APYs.
 | 
					// of the supplied denom and the value may be higher due to accumulated APYs.
 | 
				
			||||||
func (k *Keeper) GetVaultTotalSupplied(
 | 
					func (k *Keeper) GetVaultTotalShares(
 | 
				
			||||||
	ctx sdk.Context,
 | 
						ctx sdk.Context,
 | 
				
			||||||
	denom string,
 | 
						denom string,
 | 
				
			||||||
) (sdk.Coin, error) {
 | 
					) (types.VaultShare, bool) {
 | 
				
			||||||
	vault, found := k.GetVaultRecord(ctx, denom)
 | 
						vault, found := k.GetVaultRecord(ctx, denom)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return sdk.Coin{}, types.ErrVaultRecordNotFound
 | 
							return types.VaultShare{}, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return vault.TotalSupply, nil
 | 
						return vault.TotalShares, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTotalValue returns the total **value** of all coins in this vault,
 | 
					// GetTotalValue returns the total **value** of all coins in this vault,
 | 
				
			||||||
@ -47,16 +48,16 @@ func (k *Keeper) GetVaultTotalValue(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// GetVaultAccountSupplied returns the supplied amount for a single address
 | 
					// GetVaultAccountSupplied returns the supplied amount for a single address
 | 
				
			||||||
// within a vault.
 | 
					// within a vault.
 | 
				
			||||||
func (k *Keeper) GetVaultAccountSupplied(
 | 
					func (k *Keeper) GetVaultAccountShares(
 | 
				
			||||||
	ctx sdk.Context,
 | 
						ctx sdk.Context,
 | 
				
			||||||
	acc sdk.AccAddress,
 | 
						acc sdk.AccAddress,
 | 
				
			||||||
) (sdk.Coins, error) {
 | 
					) (types.VaultShares, bool) {
 | 
				
			||||||
	vaultShareRecord, found := k.GetVaultShareRecord(ctx, acc)
 | 
						vaultShareRecord, found := k.GetVaultShareRecord(ctx, acc)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return sdk.Coins{}, types.ErrVaultShareRecordNotFound
 | 
							return nil, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return vaultShareRecord.AmountSupplied, nil
 | 
						return vaultShareRecord.Shares, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetVaultAccountValue returns the value of a single address within a vault
 | 
					// GetVaultAccountValue returns the value of a single address within a vault
 | 
				
			||||||
@ -66,190 +67,10 @@ func (k *Keeper) GetVaultAccountValue(
 | 
				
			|||||||
	denom string,
 | 
						denom string,
 | 
				
			||||||
	acc sdk.AccAddress,
 | 
						acc sdk.AccAddress,
 | 
				
			||||||
) (sdk.Coin, error) {
 | 
					) (sdk.Coin, error) {
 | 
				
			||||||
	totalSupplied, err := k.GetVaultTotalSupplied(ctx, denom)
 | 
						accShares, found := k.GetVaultAccountShares(ctx, acc)
 | 
				
			||||||
	if err != nil {
 | 
						if !found {
 | 
				
			||||||
		return sdk.Coin{}, err
 | 
							return sdk.Coin{}, fmt.Errorf("account vault share record for %s not found", denom)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	accSupplied, err := k.GetVaultAccountSupplied(ctx, acc)
 | 
						return k.ConvertToAssets(ctx, accShares.GetShare(denom))
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return sdk.Coin{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vaultTotalValue, err := k.GetVaultTotalValue(ctx, denom)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return sdk.Coin{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Percent of vault account ownership = accountSupply / totalSupply
 | 
					 | 
				
			||||||
	// Value of vault account ownership = percentOwned * totalValue
 | 
					 | 
				
			||||||
	vaultShare := accSupplied.AmountOf(denom).ToDec().Quo(totalSupplied.Amount.ToDec())
 | 
					 | 
				
			||||||
	shareValueDec := vaultTotalValue.Amount.ToDec().Mul(vaultShare)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sdk.NewCoin(denom, shareValueDec.TruncateInt()), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// VaultRecord -- vault total supplies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetVaultRecord returns the vault record for a given denom.
 | 
					 | 
				
			||||||
func (k *Keeper) GetVaultRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	vaultDenom string,
 | 
					 | 
				
			||||||
) (types.VaultRecord, bool) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bz := store.Get(types.VaultKey(vaultDenom))
 | 
					 | 
				
			||||||
	if bz == nil {
 | 
					 | 
				
			||||||
		return types.VaultRecord{}, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var record types.VaultRecord
 | 
					 | 
				
			||||||
	k.cdc.MustUnmarshal(bz, &record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return record, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateVaultRecord updates the vault record in state for a given denom. This
 | 
					 | 
				
			||||||
// deletes it if the supply is zero and updates the state if supply is non-zero.
 | 
					 | 
				
			||||||
func (k *Keeper) UpdateVaultRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	vaultRecord types.VaultRecord,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	if vaultRecord.TotalSupply.IsZero() {
 | 
					 | 
				
			||||||
		k.DeleteVaultRecord(ctx, vaultRecord.Denom)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		k.SetVaultRecord(ctx, vaultRecord)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DeleteVaultRecord deletes the vault record for a given denom.
 | 
					 | 
				
			||||||
func (k *Keeper) DeleteVaultRecord(ctx sdk.Context, vaultDenom string) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
					 | 
				
			||||||
	store.Delete(types.VaultKey(vaultDenom))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetVaultRecord sets the vault record for a given denom.
 | 
					 | 
				
			||||||
func (k *Keeper) SetVaultRecord(ctx sdk.Context, record types.VaultRecord) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
					 | 
				
			||||||
	bz := k.cdc.MustMarshal(&record)
 | 
					 | 
				
			||||||
	store.Set(types.VaultKey(record.Denom), bz)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IterateVaultRecords iterates over all vault objects in the store and performs
 | 
					 | 
				
			||||||
// a callback function.
 | 
					 | 
				
			||||||
func (k Keeper) IterateVaultRecords(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	cb func(record types.VaultRecord) (stop bool),
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
					 | 
				
			||||||
	iterator := sdk.KVStorePrefixIterator(store, []byte{})
 | 
					 | 
				
			||||||
	defer iterator.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ; iterator.Valid(); iterator.Next() {
 | 
					 | 
				
			||||||
		var record types.VaultRecord
 | 
					 | 
				
			||||||
		k.cdc.MustUnmarshal(iterator.Value(), &record)
 | 
					 | 
				
			||||||
		if cb(record) {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetAllVaultRecords returns all vault records from the store.
 | 
					 | 
				
			||||||
func (k Keeper) GetAllVaultRecords(ctx sdk.Context) types.VaultRecords {
 | 
					 | 
				
			||||||
	var records types.VaultRecords
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	k.IterateVaultRecords(ctx, func(record types.VaultRecord) bool {
 | 
					 | 
				
			||||||
		records = append(records, record)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return records
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// VaultShare -- user shares per vault
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetVaultShareRecord returns the vault share record for a given denom and
 | 
					 | 
				
			||||||
// account.
 | 
					 | 
				
			||||||
func (k *Keeper) GetVaultShareRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	acc sdk.AccAddress,
 | 
					 | 
				
			||||||
) (types.VaultShareRecord, bool) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bz := store.Get(types.DepositorVaultSharesKey(acc))
 | 
					 | 
				
			||||||
	if bz == nil {
 | 
					 | 
				
			||||||
		return types.VaultShareRecord{}, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var record types.VaultShareRecord
 | 
					 | 
				
			||||||
	k.cdc.MustUnmarshal(bz, &record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return record, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateVaultShareRecord updates the vault share record in state for a given
 | 
					 | 
				
			||||||
// denom and account. This deletes it if the supply is zero and updates the
 | 
					 | 
				
			||||||
// state if supply is non-zero.
 | 
					 | 
				
			||||||
func (k *Keeper) UpdateVaultShareRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	record types.VaultShareRecord,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	if record.AmountSupplied.IsZero() {
 | 
					 | 
				
			||||||
		k.DeleteVaultShareRecord(ctx, record.Depositor)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		k.SetVaultShareRecord(ctx, record)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DeleteVaultShareRecord deletes the vault share record for a given denom and
 | 
					 | 
				
			||||||
// account.
 | 
					 | 
				
			||||||
func (k *Keeper) DeleteVaultShareRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	acc sdk.AccAddress,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
					 | 
				
			||||||
	store.Delete(types.DepositorVaultSharesKey(acc))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetVaultShareRecord sets the vault share record for a given denom and account.
 | 
					 | 
				
			||||||
func (k *Keeper) SetVaultShareRecord(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	record types.VaultShareRecord,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
					 | 
				
			||||||
	bz := k.cdc.MustMarshal(&record)
 | 
					 | 
				
			||||||
	store.Set(types.DepositorVaultSharesKey(record.Depositor), bz)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IterateVaultShareRecords iterates over all vault share objects in the store
 | 
					 | 
				
			||||||
// and performs a callback function.
 | 
					 | 
				
			||||||
func (k Keeper) IterateVaultShareRecords(
 | 
					 | 
				
			||||||
	ctx sdk.Context,
 | 
					 | 
				
			||||||
	cb func(record types.VaultShareRecord) (stop bool),
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
					 | 
				
			||||||
	iterator := sdk.KVStorePrefixIterator(store, []byte{})
 | 
					 | 
				
			||||||
	defer iterator.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ; iterator.Valid(); iterator.Next() {
 | 
					 | 
				
			||||||
		var record types.VaultShareRecord
 | 
					 | 
				
			||||||
		k.cdc.MustUnmarshal(iterator.Value(), &record)
 | 
					 | 
				
			||||||
		if cb(record) {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetAllVaultShareRecords returns all vault share records from the store.
 | 
					 | 
				
			||||||
func (k Keeper) GetAllVaultShareRecords(ctx sdk.Context) types.VaultShareRecords {
 | 
					 | 
				
			||||||
	var records types.VaultShareRecords
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	k.IterateVaultShareRecords(ctx, func(record types.VaultShareRecord) bool {
 | 
					 | 
				
			||||||
		records = append(records, record)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return records
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										85
									
								
								x/earn/keeper/vault_record.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								x/earn/keeper/vault_record.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/cosmos/cosmos-sdk/store/prefix"
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// VaultRecord -- vault total shares
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetVaultRecord returns the vault record for a given denom.
 | 
				
			||||||
 | 
					func (k *Keeper) GetVaultRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						vaultDenom string,
 | 
				
			||||||
 | 
					) (types.VaultRecord, bool) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bz := store.Get(types.VaultKey(vaultDenom))
 | 
				
			||||||
 | 
						if bz == nil {
 | 
				
			||||||
 | 
							return types.VaultRecord{}, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var record types.VaultRecord
 | 
				
			||||||
 | 
						k.cdc.MustUnmarshal(bz, &record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return record, true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateVaultRecord updates the vault record in state for a given denom. This
 | 
				
			||||||
 | 
					// deletes it if the supply is zero and updates the state if supply is non-zero.
 | 
				
			||||||
 | 
					func (k *Keeper) UpdateVaultRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						vaultRecord types.VaultRecord,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						if vaultRecord.TotalShares.Amount.IsZero() {
 | 
				
			||||||
 | 
							k.DeleteVaultRecord(ctx, vaultRecord.TotalShares.Denom)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							k.SetVaultRecord(ctx, vaultRecord)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeleteVaultRecord deletes the vault record for a given denom.
 | 
				
			||||||
 | 
					func (k *Keeper) DeleteVaultRecord(ctx sdk.Context, vaultDenom string) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
				
			||||||
 | 
						store.Delete(types.VaultKey(vaultDenom))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetVaultRecord sets the vault record for a given denom.
 | 
				
			||||||
 | 
					func (k *Keeper) SetVaultRecord(ctx sdk.Context, record types.VaultRecord) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
				
			||||||
 | 
						bz := k.cdc.MustMarshal(&record)
 | 
				
			||||||
 | 
						store.Set(types.VaultKey(record.TotalShares.Denom), bz)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IterateVaultRecords iterates over all vault objects in the store and performs
 | 
				
			||||||
 | 
					// a callback function.
 | 
				
			||||||
 | 
					func (k Keeper) IterateVaultRecords(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						cb func(record types.VaultRecord) (stop bool),
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultRecordKeyPrefix)
 | 
				
			||||||
 | 
						iterator := sdk.KVStorePrefixIterator(store, []byte{})
 | 
				
			||||||
 | 
						defer iterator.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ; iterator.Valid(); iterator.Next() {
 | 
				
			||||||
 | 
							var record types.VaultRecord
 | 
				
			||||||
 | 
							k.cdc.MustUnmarshal(iterator.Value(), &record)
 | 
				
			||||||
 | 
							if cb(record) {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAllVaultRecords returns all vault records from the store.
 | 
				
			||||||
 | 
					func (k Keeper) GetAllVaultRecords(ctx sdk.Context) types.VaultRecords {
 | 
				
			||||||
 | 
						var records types.VaultRecords
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k.IterateVaultRecords(ctx, func(record types.VaultRecord) bool {
 | 
				
			||||||
 | 
							records = append(records, record)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return records
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										82
									
								
								x/earn/keeper/vault_share.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								x/earn/keeper/vault_share.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConvertToShares converts a given amount of tokens to shares.
 | 
				
			||||||
 | 
					func (k *Keeper) ConvertToShares(ctx sdk.Context, assets sdk.Coin) (types.VaultShare, error) {
 | 
				
			||||||
 | 
						totalShares, found := k.GetVaultTotalShares(ctx, assets.Denom)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							// No shares issued yet, so shares are issued 1:1
 | 
				
			||||||
 | 
							return types.NewVaultShare(assets.Denom, assets.Amount.ToDec()), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalValue, err := k.GetVaultTotalValue(ctx, assets.Denom)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return types.VaultShare{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if totalValue.Amount.IsZero() {
 | 
				
			||||||
 | 
							return types.VaultShare{}, fmt.Errorf("total value of vault is zero")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// sharePrice   = totalValue / totalShares
 | 
				
			||||||
 | 
						// issuedShares = assets / sharePrice
 | 
				
			||||||
 | 
						// issuedShares = assets / (totalValue / totalShares)
 | 
				
			||||||
 | 
						//              = assets * (totalShares / totalValue)
 | 
				
			||||||
 | 
						//              = (assets * totalShares) / totalValue
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Multiply by reciprocal of sharePrice to avoid two divisions and limit
 | 
				
			||||||
 | 
						// rounding to one time. Per-share price is also not used as there is a loss
 | 
				
			||||||
 | 
						// of precision.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Division is done at the last step as there is a slight amount that is
 | 
				
			||||||
 | 
						// rounded down.
 | 
				
			||||||
 | 
						// For example:
 | 
				
			||||||
 | 
						// 100 * 100 / 105   == 10000 / 105                == 95.238095238095238095
 | 
				
			||||||
 | 
						// 100 * (100 / 105) == 100 * 0.952380952380952380 == 95.238095238095238000
 | 
				
			||||||
 | 
						//                    rounded down and truncated ^    loss of precision ^
 | 
				
			||||||
 | 
						issuedShares := assets.Amount.ToDec().Mul(totalShares.Amount).QuoTruncate(totalValue.Amount.ToDec())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if issuedShares.IsZero() {
 | 
				
			||||||
 | 
							return types.VaultShare{}, fmt.Errorf("share count is zero")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return types.NewVaultShare(assets.Denom, issuedShares), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConvertToAssets converts a given amount of shares to tokens.
 | 
				
			||||||
 | 
					func (k *Keeper) ConvertToAssets(ctx sdk.Context, share types.VaultShare) (sdk.Coin, error) {
 | 
				
			||||||
 | 
						totalVaultShares, found := k.GetVaultTotalShares(ctx, share.Denom)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							return sdk.Coin{}, fmt.Errorf("vault for %s not found", share.Denom)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalValue, err := k.GetVaultTotalValue(ctx, share.Denom)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return sdk.Coin{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// percentOwnership := accShares / totalVaultShares
 | 
				
			||||||
 | 
						// accValue := totalValue * percentOwnership
 | 
				
			||||||
 | 
						// accValue := totalValue * accShares / totalVaultShares
 | 
				
			||||||
 | 
						// Division must be last to avoid rounding errors and properly truncate.
 | 
				
			||||||
 | 
						value := totalValue.Amount.ToDec().Mul(share.Amount).QuoTruncate(totalVaultShares.Amount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sdk.NewCoin(share.Denom, value.TruncateInt()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ShareIsDust returns true if the share value is less than 1 coin
 | 
				
			||||||
 | 
					func (k *Keeper) ShareIsDust(ctx sdk.Context, share types.VaultShare) (bool, error) {
 | 
				
			||||||
 | 
						coin, err := k.ConvertToAssets(ctx, share)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Truncated int, becomes zero if < 1
 | 
				
			||||||
 | 
						return coin.IsZero(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										94
									
								
								x/earn/keeper/vault_share_record.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								x/earn/keeper/vault_share_record.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					package keeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/cosmos/cosmos-sdk/store/prefix"
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// VaultShareRecords -- user shares per vault
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetVaultShareRecord returns the vault share record for a given denom and
 | 
				
			||||||
 | 
					// account.
 | 
				
			||||||
 | 
					func (k *Keeper) GetVaultShareRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						acc sdk.AccAddress,
 | 
				
			||||||
 | 
					) (types.VaultShareRecord, bool) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bz := store.Get(types.DepositorVaultSharesKey(acc))
 | 
				
			||||||
 | 
						if bz == nil {
 | 
				
			||||||
 | 
							return types.VaultShareRecord{}, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var record types.VaultShareRecord
 | 
				
			||||||
 | 
						k.cdc.MustUnmarshal(bz, &record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return record, true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateVaultShareRecord updates the vault share record in state for a given
 | 
				
			||||||
 | 
					// denom and account. This deletes it if the supply is zero and updates the
 | 
				
			||||||
 | 
					// state if supply is non-zero.
 | 
				
			||||||
 | 
					func (k *Keeper) UpdateVaultShareRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						record types.VaultShareRecord,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						if record.Shares.IsZero() {
 | 
				
			||||||
 | 
							k.DeleteVaultShareRecord(ctx, record.Depositor)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							k.SetVaultShareRecord(ctx, record)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeleteVaultShareRecord deletes the vault share record for a given denom and
 | 
				
			||||||
 | 
					// account.
 | 
				
			||||||
 | 
					func (k *Keeper) DeleteVaultShareRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						acc sdk.AccAddress,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
						store.Delete(types.DepositorVaultSharesKey(acc))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetVaultShareRecord sets the vault share record for a given denom and account.
 | 
				
			||||||
 | 
					func (k *Keeper) SetVaultShareRecord(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						record types.VaultShareRecord,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
						bz := k.cdc.MustMarshal(&record)
 | 
				
			||||||
 | 
						store.Set(types.DepositorVaultSharesKey(record.Depositor), bz)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IterateVaultShareRecords iterates over all vault share objects in the store
 | 
				
			||||||
 | 
					// and performs a callback function.
 | 
				
			||||||
 | 
					func (k Keeper) IterateVaultShareRecords(
 | 
				
			||||||
 | 
						ctx sdk.Context,
 | 
				
			||||||
 | 
						cb func(record types.VaultShareRecord) (stop bool),
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
 | 
				
			||||||
 | 
						iterator := sdk.KVStorePrefixIterator(store, []byte{})
 | 
				
			||||||
 | 
						defer iterator.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ; iterator.Valid(); iterator.Next() {
 | 
				
			||||||
 | 
							var record types.VaultShareRecord
 | 
				
			||||||
 | 
							k.cdc.MustUnmarshal(iterator.Value(), &record)
 | 
				
			||||||
 | 
							if cb(record) {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAllVaultShareRecords returns all vault share records from the store.
 | 
				
			||||||
 | 
					func (k Keeper) GetAllVaultShareRecords(ctx sdk.Context) types.VaultShareRecords {
 | 
				
			||||||
 | 
						var records types.VaultShareRecords
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k.IterateVaultShareRecords(ctx, func(record types.VaultShareRecord) bool {
 | 
				
			||||||
 | 
							records = append(records, record)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return records
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								x/earn/keeper/vault_share_record_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								x/earn/keeper/vault_share_record_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					package keeper_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// State methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultTestSuite) TestGetVaultRecord() {
 | 
				
			||||||
 | 
						record := types.NewVaultRecord("usdx", sdk.ZeroDec())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.TotalShares.Denom)
 | 
				
			||||||
 | 
						suite.Require().False(found)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.Keeper.SetVaultRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stateRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.TotalShares.Denom)
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Require().Equal(record, stateRecord)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultTestSuite) TestUpdateVaultRecord() {
 | 
				
			||||||
 | 
						record := types.NewVaultRecord("usdx", sdk.ZeroDec())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						record.TotalShares = types.NewVaultShare("usdx", sdk.NewDec(100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update vault
 | 
				
			||||||
 | 
						suite.Keeper.UpdateVaultRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stateRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.TotalShares.Denom)
 | 
				
			||||||
 | 
						suite.Require().True(found, "vault record with supply should exist")
 | 
				
			||||||
 | 
						suite.Require().Equal(record, stateRecord)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Remove supply
 | 
				
			||||||
 | 
						record.TotalShares = types.NewVaultShare("usdx", sdk.NewDec(0))
 | 
				
			||||||
 | 
						suite.Keeper.UpdateVaultRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found = suite.Keeper.GetVaultRecord(suite.Ctx, record.TotalShares.Denom)
 | 
				
			||||||
 | 
						suite.Require().False(found, "vault record with 0 supply should be deleted")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultTestSuite) TestGetVaultShareRecord() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						record := types.NewVaultShareRecord(acc.GetAddress(), types.NewVaultShares())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check share doesn't exist before deposit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
				
			||||||
 | 
						suite.Require().False(found, "vault share record should not exist before deposit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update share record
 | 
				
			||||||
 | 
						record.Shares = types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(vaultDenom, sdk.NewDec(100)),
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						suite.Keeper.SetVaultShareRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check share exists and matches set value
 | 
				
			||||||
 | 
						stateRecord, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
				
			||||||
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
						suite.Require().Equal(record, stateRecord)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultTestSuite) TestUpdateVaultShareRecord() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
 | 
						acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						record := types.NewVaultShareRecord(acc.GetAddress(), types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(vaultDenom, sdk.NewDec(100)),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update vault
 | 
				
			||||||
 | 
						suite.Keeper.UpdateVaultShareRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stateRecord, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
				
			||||||
 | 
						suite.Require().True(found, "vault share record with supply should exist")
 | 
				
			||||||
 | 
						suite.Require().Equal(record, stateRecord)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Remove supply
 | 
				
			||||||
 | 
						record.Shares = types.NewVaultShares()
 | 
				
			||||||
 | 
						suite.Keeper.UpdateVaultShareRecord(suite.Ctx, record)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, found = suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
				
			||||||
 | 
						suite.Require().False(found, "vault share record with 0 supply should be deleted")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										132
									
								
								x/earn/keeper/vault_share_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								x/earn/keeper/vault_share_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					package keeper_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/suite"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/testutil"
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type vaultShareTestSuite struct {
 | 
				
			||||||
 | 
						testutil.Suite
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultShareTestSuite) SetupTest() {
 | 
				
			||||||
 | 
						suite.Suite.SetupTest()
 | 
				
			||||||
 | 
						suite.Keeper.SetParams(suite.Ctx, types.DefaultParams())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestVaultShareTestSuite(t *testing.T) {
 | 
				
			||||||
 | 
						suite.Run(t, new(vaultShareTestSuite))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultShareTestSuite) TestConvertToShares() {
 | 
				
			||||||
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name          string
 | 
				
			||||||
 | 
							beforeConvert func()
 | 
				
			||||||
 | 
							giveAmount    sdk.Coin
 | 
				
			||||||
 | 
							wantShares    types.VaultShare
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:          "initial 1:1",
 | 
				
			||||||
 | 
								beforeConvert: func() {},
 | 
				
			||||||
 | 
								giveAmount:    sdk.NewCoin(vaultDenom, sdk.NewInt(100)),
 | 
				
			||||||
 | 
								wantShares:    types.NewVaultShare(vaultDenom, sdk.NewDec(100)),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "value doubled",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								beforeConvert: func() {
 | 
				
			||||||
 | 
									// set total shares set total value for hard
 | 
				
			||||||
 | 
									// value is double than shares
 | 
				
			||||||
 | 
									// shares is 2x price now
 | 
				
			||||||
 | 
									suite.addTotalShareAndValue(vaultDenom, sdk.NewDec(100), sdk.NewInt(200))
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								giveAmount: sdk.NewCoin(vaultDenom, sdk.NewInt(100)),
 | 
				
			||||||
 | 
								wantShares: types.NewVaultShare(vaultDenom, sdk.NewDec(50)),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "truncate",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								beforeConvert: func() {
 | 
				
			||||||
 | 
									suite.addTotalShareAndValue(vaultDenom, sdk.NewDec(1000), sdk.NewInt(1001))
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								giveAmount: sdk.NewCoin(vaultDenom, sdk.NewInt(100)),
 | 
				
			||||||
 | 
								// 100 * 100 / 101 = 99.0099something
 | 
				
			||||||
 | 
								wantShares: types.NewVaultShare(vaultDenom, sdk.NewDec(100).MulInt64(1000).QuoInt64(1001)),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							suite.Run(tt.name, func() {
 | 
				
			||||||
 | 
								// Reset state
 | 
				
			||||||
 | 
								suite.Suite.SetupTest()
 | 
				
			||||||
 | 
								suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
 | 
				
			||||||
 | 
								err := suite.App.FundModuleAccount(
 | 
				
			||||||
 | 
									suite.Ctx,
 | 
				
			||||||
 | 
									types.ModuleName,
 | 
				
			||||||
 | 
									sdk.NewCoins(sdk.NewInt64Coin(vaultDenom, 10000)),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Run any deposits or any other setup
 | 
				
			||||||
 | 
								tt.beforeConvert()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								issuedShares, err := suite.Keeper.ConvertToShares(suite.Ctx, tt.giveAmount)
 | 
				
			||||||
 | 
								suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								suite.Equal(tt.wantShares, issuedShares)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *vaultShareTestSuite) addTotalShareAndValue(
 | 
				
			||||||
 | 
						vaultDenom string,
 | 
				
			||||||
 | 
						vaultShares sdk.Dec,
 | 
				
			||||||
 | 
						hardDeposit sdk.Int,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						macc := suite.AccountKeeper.GetModuleAccount(suite.Ctx, types.ModuleName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaultRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, vaultDenom)
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							vaultRecord = types.NewVaultRecord(vaultDenom, sdk.ZeroDec())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add to vault record
 | 
				
			||||||
 | 
						vaultRecord.TotalShares.Amount = vaultRecord.TotalShares.Amount.Add(vaultShares)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// set total shares
 | 
				
			||||||
 | 
						suite.Keeper.UpdateVaultRecord(
 | 
				
			||||||
 | 
							suite.Ctx,
 | 
				
			||||||
 | 
							vaultRecord,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						// add value for hard -- this does not set
 | 
				
			||||||
 | 
						err := suite.HardKeeper.Deposit(
 | 
				
			||||||
 | 
							suite.Ctx,
 | 
				
			||||||
 | 
							macc.GetAddress(),
 | 
				
			||||||
 | 
							sdk.NewCoins(sdk.NewCoin(vaultDenom, hardDeposit)),
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestPrecisionMulQuoOrder(t *testing.T) {
 | 
				
			||||||
 | 
						assetAmount := sdk.NewDec(100)
 | 
				
			||||||
 | 
						totalShares := sdk.NewDec(100)
 | 
				
			||||||
 | 
						totalValue := sdk.NewDec(105)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// issuedShares =  assetAmount * (totalValue / totalShares)
 | 
				
			||||||
 | 
						//              = (assetAmount * totalShares) / totalValue
 | 
				
			||||||
 | 
						mulFirst := assetAmount.Mul(totalShares).QuoTruncate(totalValue)
 | 
				
			||||||
 | 
						quoFirst := assetAmount.Mul(totalShares.QuoTruncate(totalValue))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equal(t, sdk.MustNewDecFromStr("95.238095238095238095"), mulFirst)
 | 
				
			||||||
 | 
						assert.Equal(t, sdk.MustNewDecFromStr("95.238095238095238000"), quoFirst)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.NotEqual(t, mulFirst, quoFirst)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -23,7 +23,7 @@ func TestVaultTestSuite(t *testing.T) {
 | 
				
			|||||||
	suite.Run(t, new(vaultTestSuite))
 | 
						suite.Run(t, new(vaultTestSuite))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultTotalSupplied() {
 | 
					func (suite *vaultTestSuite) TestGetVaultTotalShares() {
 | 
				
			||||||
	vaultDenom := "usdx"
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
	startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
						startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
				
			||||||
	depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
 | 
						depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
 | 
				
			||||||
@ -35,22 +35,27 @@ func (suite *vaultTestSuite) TestGetVaultTotalSupplied() {
 | 
				
			|||||||
	err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc.GetAddress(), depositAmount)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vaultTotalSupplied, err := suite.Keeper.GetVaultTotalSupplied(suite.Ctx, vaultDenom)
 | 
						vaultTotalShares, found := suite.Keeper.GetVaultTotalShares(suite.Ctx, vaultDenom)
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.Equal(depositAmount, vaultTotalSupplied)
 | 
						suite.Equal(depositAmount.Amount.ToDec(), vaultTotalShares.Amount)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultTotalSupplied_NotFound() {
 | 
					func (suite *vaultTestSuite) TestGetVaultTotalShares_NotFound() {
 | 
				
			||||||
	vaultDenom := "usdx"
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := suite.Keeper.GetVaultTotalSupplied(suite.Ctx, vaultDenom)
 | 
						_, found := suite.Keeper.GetVaultTotalShares(suite.Ctx, vaultDenom)
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().False(found)
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultTotalValue() {
 | 
					func (suite *vaultTestSuite) TestGetVaultTotalValue() {
 | 
				
			||||||
	// TODO: After strategy implemented GetEstimatedTotalAssets
 | 
						vaultDenom := "usdx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.CreateVault(vaultDenom, types.STRATEGY_TYPE_HARD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalValue, err := suite.Keeper.GetVaultTotalValue(suite.Ctx, vaultDenom)
 | 
				
			||||||
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
						suite.Equal(sdk.NewInt(0), totalValue.Amount)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultTotalValue_NotFound() {
 | 
					func (suite *vaultTestSuite) TestGetVaultTotalValue_NotFound() {
 | 
				
			||||||
@ -83,17 +88,14 @@ func (suite *vaultTestSuite) TestGetVaultAccountSupplied() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Before deposit, account supplied is 0
 | 
						// Before deposit, account supplied is 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := suite.Keeper.GetVaultAccountSupplied(suite.Ctx, acc1.GetAddress())
 | 
						_, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc1.GetAddress())
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().False(found)
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultShareRecordNotFound)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = suite.Keeper.GetVaultAccountSupplied(suite.Ctx, acc2.GetAddress())
 | 
						_, found = suite.Keeper.GetVaultShareRecord(suite.Ctx, acc2.GetAddress())
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().False(found)
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultShareRecordNotFound)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Deposits from both accounts
 | 
						// Deposits from both accounts
 | 
				
			||||||
 | 
						err := suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), deposit1Amount)
 | 
				
			||||||
	err = suite.Keeper.Deposit(suite.Ctx, acc1.GetAddress(), deposit1Amount)
 | 
					 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().NoError(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), deposit2Amount)
 | 
						err = suite.Keeper.Deposit(suite.Ctx, acc2.GetAddress(), deposit2Amount)
 | 
				
			||||||
@ -101,15 +103,15 @@ func (suite *vaultTestSuite) TestGetVaultAccountSupplied() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Check balances
 | 
						// Check balances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vaultAcc1Supplied, err := suite.Keeper.GetVaultAccountSupplied(suite.Ctx, acc1.GetAddress())
 | 
						vaultAcc1Supplied, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc1.GetAddress())
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vaultAcc2Supplied, err := suite.Keeper.GetVaultAccountSupplied(suite.Ctx, acc2.GetAddress())
 | 
						vaultAcc2Supplied, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc2.GetAddress())
 | 
				
			||||||
	suite.Require().NoError(err)
 | 
						suite.Require().True(found)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Account supply only includes the deposit from respective accounts
 | 
						// Account supply only includes the deposit from respective accounts
 | 
				
			||||||
	suite.Equal(sdk.NewCoins(deposit1Amount), vaultAcc1Supplied)
 | 
						suite.Equal(deposit1Amount.Amount.ToDec(), vaultAcc1Supplied.Shares.AmountOf(vaultDenom))
 | 
				
			||||||
	suite.Equal(sdk.NewCoins(deposit1Amount), vaultAcc2Supplied)
 | 
						suite.Equal(deposit1Amount.Amount.ToDec(), vaultAcc2Supplied.Shares.AmountOf(vaultDenom))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultAccountValue() {
 | 
					func (suite *vaultTestSuite) TestGetVaultAccountValue() {
 | 
				
			||||||
@ -135,7 +137,7 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue_VaultNotFound() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	_, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc.GetAddress())
 | 
						_, err := suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc.GetAddress())
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().Error(err)
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultRecordNotFound)
 | 
						suite.Require().Equal("account vault share record for usdx not found", err.Error())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultAccountValue_ShareNotFound() {
 | 
					func (suite *vaultTestSuite) TestGetVaultAccountValue_ShareNotFound() {
 | 
				
			||||||
@ -155,87 +157,5 @@ func (suite *vaultTestSuite) TestGetVaultAccountValue_ShareNotFound() {
 | 
				
			|||||||
	// Query from acc2 with no share record
 | 
						// Query from acc2 with no share record
 | 
				
			||||||
	_, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc2.GetAddress())
 | 
						_, err = suite.Keeper.GetVaultAccountValue(suite.Ctx, vaultDenom, acc2.GetAddress())
 | 
				
			||||||
	suite.Require().Error(err)
 | 
						suite.Require().Error(err)
 | 
				
			||||||
	suite.Require().ErrorIs(err, types.ErrVaultShareRecordNotFound)
 | 
						suite.Require().Equal("account vault share record for usdx not found", err.Error())
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// State methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultRecord() {
 | 
					 | 
				
			||||||
	record := types.NewVaultRecord("usdx")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.Denom)
 | 
					 | 
				
			||||||
	suite.Require().False(found)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	suite.Keeper.SetVaultRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stateRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.Denom)
 | 
					 | 
				
			||||||
	suite.Require().True(found)
 | 
					 | 
				
			||||||
	suite.Require().Equal(record, stateRecord)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *vaultTestSuite) TestUpdateVaultRecord() {
 | 
					 | 
				
			||||||
	record := types.NewVaultRecord("usdx")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	record.TotalSupply = sdk.NewInt64Coin("usdx", 100)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update vault
 | 
					 | 
				
			||||||
	suite.Keeper.UpdateVaultRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stateRecord, found := suite.Keeper.GetVaultRecord(suite.Ctx, record.Denom)
 | 
					 | 
				
			||||||
	suite.Require().True(found, "vault record with supply should exist")
 | 
					 | 
				
			||||||
	suite.Require().Equal(record, stateRecord)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Remove supply
 | 
					 | 
				
			||||||
	record.TotalSupply = sdk.NewInt64Coin("usdx", 0)
 | 
					 | 
				
			||||||
	suite.Keeper.UpdateVaultRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, found = suite.Keeper.GetVaultRecord(suite.Ctx, record.Denom)
 | 
					 | 
				
			||||||
	suite.Require().False(found, "vault record with 0 supply should be deleted")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *vaultTestSuite) TestGetVaultShareRecord() {
 | 
					 | 
				
			||||||
	vaultDenom := "usdx"
 | 
					 | 
				
			||||||
	startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
					 | 
				
			||||||
	depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
 | 
					 | 
				
			||||||
	acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	record := types.NewVaultShareRecord(acc.GetAddress())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check share doesn't exist before deposit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
					 | 
				
			||||||
	suite.Require().False(found, "vault share record should not exist before deposit")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update share record
 | 
					 | 
				
			||||||
	record.AmountSupplied = sdk.NewCoins(depositAmount)
 | 
					 | 
				
			||||||
	suite.Keeper.SetVaultShareRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check share exists and matches set value
 | 
					 | 
				
			||||||
	stateRecord, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
					 | 
				
			||||||
	suite.Require().True(found)
 | 
					 | 
				
			||||||
	suite.Require().Equal(record, stateRecord)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (suite *vaultTestSuite) TestUpdateVaultShareRecord() {
 | 
					 | 
				
			||||||
	vaultDenom := "usdx"
 | 
					 | 
				
			||||||
	startBalance := sdk.NewInt64Coin(vaultDenom, 1000)
 | 
					 | 
				
			||||||
	depositAmount := sdk.NewInt64Coin(vaultDenom, 100)
 | 
					 | 
				
			||||||
	acc := suite.CreateAccount(sdk.NewCoins(startBalance), 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	record := types.NewVaultShareRecord(acc.GetAddress(), depositAmount)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update vault
 | 
					 | 
				
			||||||
	suite.Keeper.UpdateVaultShareRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stateRecord, found := suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
					 | 
				
			||||||
	suite.Require().True(found, "vault share record with supply should exist")
 | 
					 | 
				
			||||||
	suite.Require().Equal(record, stateRecord)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Remove supply
 | 
					 | 
				
			||||||
	record.AmountSupplied = sdk.NewCoins()
 | 
					 | 
				
			||||||
	suite.Keeper.UpdateVaultShareRecord(suite.Ctx, record)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, found = suite.Keeper.GetVaultShareRecord(suite.Ctx, acc.GetAddress())
 | 
					 | 
				
			||||||
	suite.Require().False(found, "vault share record with 0 supply should be deleted")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,34 +28,48 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
 | 
				
			|||||||
		return types.ErrVaultRecordNotFound
 | 
							return types.ErrVaultRecordNotFound
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get account value for vault
 | 
					 | 
				
			||||||
	vaultAccValue, err := k.GetVaultAccountValue(ctx, wantAmount.Denom, from)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if vaultAccValue.IsZero() {
 | 
					 | 
				
			||||||
		panic("vault account value is zero")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get account share record for the vault
 | 
						// Get account share record for the vault
 | 
				
			||||||
	vaultShareRecord, found := k.GetVaultShareRecord(ctx, from)
 | 
						vaultShareRecord, found := k.GetVaultShareRecord(ctx, from)
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		return types.ErrVaultShareRecordNotFound
 | 
							return types.ErrVaultShareRecordNotFound
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Percent of vault account value the account is withdrawing
 | 
						withdrawShares, err := k.ConvertToShares(ctx, wantAmount)
 | 
				
			||||||
	// This is the total account value, not just the supplied amount.
 | 
						if err != nil {
 | 
				
			||||||
	withdrawAmountPercent := wantAmount.Amount.ToDec().Quo(vaultAccValue.Amount.ToDec())
 | 
							return fmt.Errorf("failed to convert assets to shares: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if account is not withdrawing more than they have
 | 
						accCurrentShares := vaultShareRecord.Shares.AmountOf(wantAmount.Denom)
 | 
				
			||||||
	// account value < want withdraw amount
 | 
						// Check if account is not withdrawing more shares than they have
 | 
				
			||||||
	if vaultAccValue.Amount.LT(wantAmount.Amount) {
 | 
						if accCurrentShares.LT(withdrawShares.Amount) {
 | 
				
			||||||
		return sdkerrors.Wrapf(
 | 
							return sdkerrors.Wrapf(
 | 
				
			||||||
			types.ErrInsufficientValue,
 | 
								types.ErrInsufficientValue,
 | 
				
			||||||
			"account vault value of %s is less than %s desired withdraw amount",
 | 
								"account has less %s vault shares than withdraw shares, %s < %s",
 | 
				
			||||||
			vaultAccValue,
 | 
								wantAmount.Denom,
 | 
				
			||||||
			wantAmount,
 | 
								accCurrentShares,
 | 
				
			||||||
 | 
								withdrawShares.Amount,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert shares to amount to get truncated true share value
 | 
				
			||||||
 | 
						withdrawAmount, err := k.ConvertToAssets(ctx, withdrawShares)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to convert shares to assets: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accountValue, err := k.GetVaultAccountValue(ctx, wantAmount.Denom, from)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to get account value: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if withdrawAmount > account value
 | 
				
			||||||
 | 
						if withdrawAmount.Amount.GT(accountValue.Amount) {
 | 
				
			||||||
 | 
							return sdkerrors.Wrapf(
 | 
				
			||||||
 | 
								types.ErrInsufficientValue,
 | 
				
			||||||
 | 
								"account has less %s vault value than withdraw amount, %s < %s",
 | 
				
			||||||
 | 
								withdrawAmount.Denom,
 | 
				
			||||||
 | 
								accountValue.Amount,
 | 
				
			||||||
 | 
								withdrawAmount.Amount,
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,8 +82,8 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
 | 
				
			|||||||
	// Not necessary to check if amount denom is allowed for the strategy, as
 | 
						// Not necessary to check if amount denom is allowed for the strategy, as
 | 
				
			||||||
	// there would be no vault record if it weren't allowed.
 | 
						// there would be no vault record if it weren't allowed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Withdraw the wantAmount from the strategy
 | 
						// Withdraw the withdrawAmount from the strategy
 | 
				
			||||||
	if err := strategy.Withdraw(ctx, wantAmount); err != nil {
 | 
						if err := strategy.Withdraw(ctx, withdrawAmount); err != nil {
 | 
				
			||||||
		return fmt.Errorf("failed to withdraw from strategy: %w", err)
 | 
							return fmt.Errorf("failed to withdraw from strategy: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,27 +93,33 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
 | 
				
			|||||||
		ctx,
 | 
							ctx,
 | 
				
			||||||
		types.ModuleName,
 | 
							types.ModuleName,
 | 
				
			||||||
		from,
 | 
							from,
 | 
				
			||||||
		sdk.NewCoins(wantAmount),
 | 
							sdk.NewCoins(withdrawAmount),
 | 
				
			||||||
	); err != nil {
 | 
						); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Shares withdrawn from vault
 | 
						// Check if new account balance of shares results in account share value
 | 
				
			||||||
	// For example:
 | 
						// of < 1 of a sdk.Coin. This share value is not able to be withdrawn and
 | 
				
			||||||
	// account supplied = 10hard
 | 
						// should just be removed.
 | 
				
			||||||
	// account value    = 20hard
 | 
						isDust, err := k.ShareIsDust(
 | 
				
			||||||
	// wantAmount       = 10hard
 | 
							ctx,
 | 
				
			||||||
	// withdrawAmountPercent = 10hard / 20hard = 0.5
 | 
							vaultShareRecord.Shares.GetShare(withdrawAmount.Denom).Sub(withdrawShares),
 | 
				
			||||||
	// sharesWithdrawn = 0.5 * 10hard = 5hard
 | 
						)
 | 
				
			||||||
	vaultShareAmount := vaultShareRecord.AmountSupplied.AmountOf(wantAmount.Denom)
 | 
						if err != nil {
 | 
				
			||||||
	sharesWithdrawn := sdk.NewCoin(wantAmount.Denom, vaultShareAmount.
 | 
							return err
 | 
				
			||||||
		ToDec().
 | 
						}
 | 
				
			||||||
		Mul(withdrawAmountPercent).
 | 
					 | 
				
			||||||
		TruncateInt())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Decrement VaultRecord and VaultShareRecord supplies
 | 
						if isDust {
 | 
				
			||||||
	vaultRecord.TotalSupply = vaultRecord.TotalSupply.Sub(sharesWithdrawn)
 | 
							// Modify withdrawShares to subtract entire share balance for denom
 | 
				
			||||||
	vaultShareRecord.AmountSupplied = vaultShareRecord.AmountSupplied.Sub(sdk.NewCoins(sharesWithdrawn))
 | 
							// This does not modify the actual withdraw coin amount as the
 | 
				
			||||||
 | 
							// difference is < 1coin.
 | 
				
			||||||
 | 
							withdrawShares = vaultShareRecord.Shares.GetShare(withdrawAmount.Denom)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decrement VaultRecord and VaultShareRecord supplies - must delete same
 | 
				
			||||||
 | 
						// amounts
 | 
				
			||||||
 | 
						vaultShareRecord.Shares = vaultShareRecord.Shares.Sub(withdrawShares)
 | 
				
			||||||
 | 
						vaultRecord.TotalShares = vaultRecord.TotalShares.Sub(withdrawShares)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update VaultRecord and VaultShareRecord, deletes if zero supply
 | 
						// Update VaultRecord and VaultShareRecord, deletes if zero supply
 | 
				
			||||||
	k.UpdateVaultRecord(ctx, vaultRecord)
 | 
						k.UpdateVaultRecord(ctx, vaultRecord)
 | 
				
			||||||
@ -108,9 +128,10 @@ func (k *Keeper) Withdraw(ctx sdk.Context, from sdk.AccAddress, wantAmount sdk.C
 | 
				
			|||||||
	ctx.EventManager().EmitEvent(
 | 
						ctx.EventManager().EmitEvent(
 | 
				
			||||||
		sdk.NewEvent(
 | 
							sdk.NewEvent(
 | 
				
			||||||
			types.EventTypeVaultWithdraw,
 | 
								types.EventTypeVaultWithdraw,
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyVaultDenom, wantAmount.Denom),
 | 
								sdk.NewAttribute(types.AttributeKeyVaultDenom, withdrawAmount.Denom),
 | 
				
			||||||
			sdk.NewAttribute(types.AttributeKeyOwner, from.String()),
 | 
								sdk.NewAttribute(types.AttributeKeyOwner, from.String()),
 | 
				
			||||||
			sdk.NewAttribute(sdk.AttributeKeyAmount, wantAmount.Amount.String()),
 | 
								sdk.NewAttribute(types.AttributeKeyShares, withdrawShares.Amount.String()),
 | 
				
			||||||
 | 
								sdk.NewAttribute(sdk.AttributeKeyAmount, withdrawAmount.Amount.String()),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,9 @@ func (suite *withdrawTestSuite) TestWithdraw_NoVaultShareRecord() {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins(acc1DepositAmount))
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(acc1DepositAmount))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins(acc1DepositAmount))
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(acc1DepositAmount.Denom, acc1DepositAmount.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *withdrawTestSuite) TestWithdraw_ExceedBalance() {
 | 
					func (suite *withdrawTestSuite) TestWithdraw_ExceedBalance() {
 | 
				
			||||||
@ -103,7 +105,9 @@ func (suite *withdrawTestSuite) TestWithdraw_ExceedBalance() {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalValuesEqual(sdk.NewCoins(depositAmount))
 | 
				
			||||||
	suite.VaultTotalSuppliedEqual(sdk.NewCoins(depositAmount))
 | 
						suite.VaultTotalSharesEqual(types.NewVaultShares(
 | 
				
			||||||
 | 
							types.NewVaultShare(depositAmount.Denom, depositAmount.Amount.ToDec()),
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *withdrawTestSuite) TestWithdraw_Zero() {
 | 
					func (suite *withdrawTestSuite) TestWithdraw_Zero() {
 | 
				
			||||||
 | 
				
			|||||||
@ -256,21 +256,29 @@ func (suite *Suite) VaultTotalValuesEqual(expected sdk.Coins) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *Suite) VaultTotalSuppliedEqual(expected sdk.Coins) {
 | 
					func (suite *Suite) VaultTotalSharesEqual(expected types.VaultShares) {
 | 
				
			||||||
	for _, coin := range expected {
 | 
						for _, share := range expected {
 | 
				
			||||||
		vaultBal, err := suite.Keeper.GetVaultTotalSupplied(suite.Ctx, coin.Denom)
 | 
							vaultBal, found := suite.Keeper.GetVaultTotalShares(suite.Ctx, share.Denom)
 | 
				
			||||||
		suite.Require().NoError(err, "failed to get vault balance")
 | 
							suite.Require().Truef(found, "%s vault does not exist", share.Denom)
 | 
				
			||||||
		suite.Require().Equal(coin, vaultBal)
 | 
							suite.Require().Equal(share.Amount, vaultBal.Amount)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (suite *Suite) AccountTotalSuppliedEqual(accs []sdk.AccAddress, supplies []sdk.Coins) {
 | 
					func (suite *Suite) VaultAccountSharesEqual(accs []sdk.AccAddress, supplies []sdk.Coins) {
 | 
				
			||||||
	for i, acc := range accs {
 | 
						for i, acc := range accs {
 | 
				
			||||||
		coins := supplies[i]
 | 
							coins := supplies[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		accVaultBal, err := suite.Keeper.GetVaultAccountSupplied(suite.Ctx, acc)
 | 
							accVaultBal, found := suite.Keeper.GetVaultAccountShares(suite.Ctx, acc)
 | 
				
			||||||
		suite.Require().NoError(err)
 | 
							suite.Require().True(found)
 | 
				
			||||||
		suite.Require().True(coins.IsEqual(accVaultBal), "expected account vault balance to equal coins %s, but got %s", coins, accVaultBal)
 | 
					
 | 
				
			||||||
 | 
							for _, coin := range coins {
 | 
				
			||||||
 | 
								suite.Require().Equal(
 | 
				
			||||||
 | 
									coin.Amount,
 | 
				
			||||||
 | 
									accVaultBal.AmountOf(coin.Denom),
 | 
				
			||||||
 | 
									"expected account vault balance to equal coins %s, but got %s",
 | 
				
			||||||
 | 
									coins, accVaultBal,
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -26,10 +26,3 @@ func NewQueryDepositsRequest(
 | 
				
			|||||||
		Pagination: pagination,
 | 
							Pagination: pagination,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewQueryTotalDepositedRequest returns a new QueryTotalDepositedRequest
 | 
					 | 
				
			||||||
func NewQueryTotalDepositedRequest(denom string) *QueryTotalDepositedRequest {
 | 
					 | 
				
			||||||
	return &QueryTotalDepositedRequest{
 | 
					 | 
				
			||||||
		Denom: denom,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -193,8 +193,8 @@ type VaultResponse struct {
 | 
				
			|||||||
	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
 | 
						Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
 | 
				
			||||||
	// VaultStrategy is the strategy used for this vault.
 | 
						// 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"`
 | 
						VaultStrategy StrategyType `protobuf:"varint,2,opt,name=vault_strategy,json=vaultStrategy,proto3,enum=kava.earn.v1beta1.StrategyType" json:"vault_strategy,omitempty"`
 | 
				
			||||||
	// TotalSupplied is the total amount of denom coins supplied to the vault.
 | 
						// TotalShares is the total amount of shares issued to depositors.
 | 
				
			||||||
	TotalSupplied github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=total_supplied,json=totalSupplied,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_supplied"`
 | 
						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
 | 
						// TotalValue is the total value of denom coins supplied to the vault if the
 | 
				
			||||||
	// vault were to be liquidated.
 | 
						// 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,4,opt,name=total_value,json=totalValue,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_value"`
 | 
				
			||||||
@ -321,8 +321,8 @@ var xxx_messageInfo_QueryDepositsResponse proto.InternalMessageInfo
 | 
				
			|||||||
type DepositResponse struct {
 | 
					type DepositResponse struct {
 | 
				
			||||||
	// depositor represents the owner of the deposit.
 | 
						// depositor represents the owner of the deposit.
 | 
				
			||||||
	Depositor string `protobuf:"bytes,1,opt,name=depositor,proto3" json:"depositor,omitempty"`
 | 
						Depositor string `protobuf:"bytes,1,opt,name=depositor,proto3" json:"depositor,omitempty"`
 | 
				
			||||||
	// Amount represents the amount supplied to vaults.
 | 
						// Shares represent the issued shares from their corresponding vaults.
 | 
				
			||||||
	AmountSupplied github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount_supplied,json=amountSupplied,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount_supplied"`
 | 
						Shares VaultShares `protobuf:"bytes,2,rep,name=shares,proto3,castrepeated=VaultShares" json:"shares"`
 | 
				
			||||||
	// Value represents the total accumulated value of denom coins supplied to
 | 
						// Value represents the total accumulated value of denom coins supplied to
 | 
				
			||||||
	// vaults. This may be greater than or equal to amount_supplied depending on
 | 
						// vaults. This may be greater than or equal to amount_supplied depending on
 | 
				
			||||||
	// the strategy.
 | 
						// the strategy.
 | 
				
			||||||
@ -362,83 +362,6 @@ func (m *DepositResponse) XXX_DiscardUnknown() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var xxx_messageInfo_DepositResponse proto.InternalMessageInfo
 | 
					var xxx_messageInfo_DepositResponse proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QueryTotalDepositedRequest is the request type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
type QueryTotalDepositedRequest struct {
 | 
					 | 
				
			||||||
	// denom represents the vault denom to query total deposited amount for.
 | 
					 | 
				
			||||||
	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) Reset()         { *m = QueryTotalDepositedRequest{} }
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) String() string { return proto.CompactTextString(m) }
 | 
					 | 
				
			||||||
func (*QueryTotalDepositedRequest) ProtoMessage()    {}
 | 
					 | 
				
			||||||
func (*QueryTotalDepositedRequest) Descriptor() ([]byte, []int) {
 | 
					 | 
				
			||||||
	return fileDescriptor_63f8dee2f3192a6b, []int{8}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) XXX_Unmarshal(b []byte) error {
 | 
					 | 
				
			||||||
	return m.Unmarshal(b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
					 | 
				
			||||||
	if deterministic {
 | 
					 | 
				
			||||||
		return xxx_messageInfo_QueryTotalDepositedRequest.Marshal(b, m, deterministic)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		b = b[:cap(b)]
 | 
					 | 
				
			||||||
		n, err := m.MarshalToSizedBuffer(b)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return b[:n], nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) XXX_Merge(src proto.Message) {
 | 
					 | 
				
			||||||
	xxx_messageInfo_QueryTotalDepositedRequest.Merge(m, src)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) XXX_Size() int {
 | 
					 | 
				
			||||||
	return m.Size()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) XXX_DiscardUnknown() {
 | 
					 | 
				
			||||||
	xxx_messageInfo_QueryTotalDepositedRequest.DiscardUnknown(m)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var xxx_messageInfo_QueryTotalDepositedRequest proto.InternalMessageInfo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// QueryTotalDepositedResponse is the response type for the Query/TotalDeposited RPC method.
 | 
					 | 
				
			||||||
type QueryTotalDepositedResponse struct {
 | 
					 | 
				
			||||||
	SuppliedCoins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=supplied_coins,json=suppliedCoins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"supplied_coins"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) Reset()         { *m = QueryTotalDepositedResponse{} }
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) String() string { return proto.CompactTextString(m) }
 | 
					 | 
				
			||||||
func (*QueryTotalDepositedResponse) ProtoMessage()    {}
 | 
					 | 
				
			||||||
func (*QueryTotalDepositedResponse) Descriptor() ([]byte, []int) {
 | 
					 | 
				
			||||||
	return fileDescriptor_63f8dee2f3192a6b, []int{9}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) XXX_Unmarshal(b []byte) error {
 | 
					 | 
				
			||||||
	return m.Unmarshal(b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
					 | 
				
			||||||
	if deterministic {
 | 
					 | 
				
			||||||
		return xxx_messageInfo_QueryTotalDepositedResponse.Marshal(b, m, deterministic)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		b = b[:cap(b)]
 | 
					 | 
				
			||||||
		n, err := m.MarshalToSizedBuffer(b)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return b[:n], nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) XXX_Merge(src proto.Message) {
 | 
					 | 
				
			||||||
	xxx_messageInfo_QueryTotalDepositedResponse.Merge(m, src)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) XXX_Size() int {
 | 
					 | 
				
			||||||
	return m.Size()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) XXX_DiscardUnknown() {
 | 
					 | 
				
			||||||
	xxx_messageInfo_QueryTotalDepositedResponse.DiscardUnknown(m)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var xxx_messageInfo_QueryTotalDepositedResponse proto.InternalMessageInfo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	proto.RegisterType((*QueryParamsRequest)(nil), "kava.earn.v1beta1.QueryParamsRequest")
 | 
						proto.RegisterType((*QueryParamsRequest)(nil), "kava.earn.v1beta1.QueryParamsRequest")
 | 
				
			||||||
	proto.RegisterType((*QueryParamsResponse)(nil), "kava.earn.v1beta1.QueryParamsResponse")
 | 
						proto.RegisterType((*QueryParamsResponse)(nil), "kava.earn.v1beta1.QueryParamsResponse")
 | 
				
			||||||
@ -448,67 +371,60 @@ func init() {
 | 
				
			|||||||
	proto.RegisterType((*QueryDepositsRequest)(nil), "kava.earn.v1beta1.QueryDepositsRequest")
 | 
						proto.RegisterType((*QueryDepositsRequest)(nil), "kava.earn.v1beta1.QueryDepositsRequest")
 | 
				
			||||||
	proto.RegisterType((*QueryDepositsResponse)(nil), "kava.earn.v1beta1.QueryDepositsResponse")
 | 
						proto.RegisterType((*QueryDepositsResponse)(nil), "kava.earn.v1beta1.QueryDepositsResponse")
 | 
				
			||||||
	proto.RegisterType((*DepositResponse)(nil), "kava.earn.v1beta1.DepositResponse")
 | 
						proto.RegisterType((*DepositResponse)(nil), "kava.earn.v1beta1.DepositResponse")
 | 
				
			||||||
	proto.RegisterType((*QueryTotalDepositedRequest)(nil), "kava.earn.v1beta1.QueryTotalDepositedRequest")
 | 
					 | 
				
			||||||
	proto.RegisterType((*QueryTotalDepositedResponse)(nil), "kava.earn.v1beta1.QueryTotalDepositedResponse")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() { proto.RegisterFile("kava/earn/v1beta1/query.proto", fileDescriptor_63f8dee2f3192a6b) }
 | 
					func init() { proto.RegisterFile("kava/earn/v1beta1/query.proto", fileDescriptor_63f8dee2f3192a6b) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_63f8dee2f3192a6b = []byte{
 | 
					var fileDescriptor_63f8dee2f3192a6b = []byte{
 | 
				
			||||||
	// 833 bytes of a gzipped FileDescriptorProto
 | 
						// 762 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6f, 0xd3, 0x48,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcf, 0x4f, 0x13, 0x4f,
 | 
				
			||||||
	0x14, 0x8f, 0xd3, 0x26, 0x6a, 0x27, 0x4a, 0xaa, 0x9d, 0xcd, 0x4a, 0x49, 0xba, 0x75, 0x52, 0x57,
 | 
						0x14, 0xef, 0xb6, 0xb4, 0x81, 0xe9, 0x17, 0xbe, 0x71, 0xa8, 0x49, 0x5b, 0x64, 0x5b, 0x96, 0x08,
 | 
				
			||||||
	0xdb, 0x66, 0xab, 0x8d, 0xbd, 0xcd, 0x4a, 0xbb, 0x97, 0xd5, 0x4a, 0x9b, 0xad, 0x16, 0xf5, 0x82,
 | 
						0x95, 0xa4, 0xbb, 0x52, 0x13, 0xbd, 0x18, 0x13, 0x2b, 0xd1, 0xe0, 0xc1, 0xe8, 0xa2, 0x1c, 0x4c,
 | 
				
			||||||
	0xc0, 0x2d, 0x3d, 0x20, 0xa1, 0x68, 0x12, 0x8f, 0x8c, 0xd5, 0xc4, 0xe3, 0xda, 0x93, 0x40, 0x41,
 | 
						0x4c, 0x33, 0xa5, 0x93, 0x65, 0x43, 0xbb, 0xb3, 0xec, 0x4c, 0xab, 0x68, 0xbc, 0x70, 0x37, 0x31,
 | 
				
			||||||
	0x5c, 0xfa, 0x09, 0x40, 0x7c, 0x03, 0x40, 0x1c, 0xb8, 0x21, 0xfa, 0x21, 0x7a, 0xac, 0xca, 0x05,
 | 
						0xf1, 0x5f, 0x30, 0x1e, 0x3c, 0xf3, 0x47, 0x70, 0x24, 0x78, 0x31, 0x1e, 0x50, 0xc1, 0xbb, 0x57,
 | 
				
			||||||
	0x71, 0x28, 0xd0, 0xf2, 0x41, 0x90, 0xe7, 0x4f, 0x52, 0x27, 0x0e, 0xe9, 0xa1, 0xa7, 0x64, 0xe6,
 | 
						0x8f, 0x66, 0x7e, 0x2c, 0x65, 0xdb, 0x6d, 0xea, 0xa9, 0x9d, 0xf7, 0xe3, 0xf3, 0xf9, 0xbc, 0x37,
 | 
				
			||||||
	0xbd, 0xf7, 0xfb, 0xfd, 0xe6, 0xcd, 0x6f, 0x9e, 0xc1, 0xd2, 0x1e, 0xea, 0x23, 0x03, 0x23, 0xdf,
 | 
						0x6f, 0xde, 0x82, 0xf9, 0x1d, 0xd4, 0x43, 0x16, 0x46, 0x81, 0x67, 0xf5, 0x56, 0x9b, 0x98, 0xa1,
 | 
				
			||||||
	0x35, 0xfa, 0x1b, 0x2d, 0x4c, 0xd1, 0x86, 0xb1, 0xdf, 0xc3, 0xfe, 0x81, 0xee, 0xf9, 0x84, 0x12,
 | 
						0x55, 0x6b, 0xb7, 0x8b, 0x83, 0x3d, 0xd3, 0x0f, 0x08, 0x23, 0xf0, 0x12, 0x77, 0x9b, 0xdc, 0x6d,
 | 
				
			||||||
	0xf8, 0x43, 0x18, 0xd6, 0xc3, 0xb0, 0x2e, 0xc2, 0xa5, 0x62, 0x9b, 0x04, 0x5d, 0x12, 0x34, 0x59,
 | 
						0x2a, 0x77, 0xb1, 0xb0, 0x45, 0x68, 0x87, 0xd0, 0x86, 0x08, 0xb0, 0xe4, 0x41, 0x46, 0x17, 0x57,
 | 
				
			||||||
	0x82, 0xc1, 0x17, 0x3c, 0xbb, 0xb4, 0xce, 0x57, 0x46, 0x0b, 0x05, 0x98, 0xc3, 0x0c, 0x40, 0x3d,
 | 
						0xe4, 0xc9, 0x6a, 0x22, 0x8a, 0x25, 0xcc, 0x39, 0xa8, 0x8f, 0x1c, 0xd7, 0x43, 0xcc, 0x25, 0x9e,
 | 
				
			||||||
	0x64, 0x3b, 0x2e, 0xa2, 0x0e, 0x71, 0x45, 0xae, 0x7a, 0x39, 0x57, 0x66, 0xb5, 0x89, 0x23, 0xe3,
 | 
						0x8a, 0xd5, 0x2f, 0xc6, 0x86, 0x51, 0x5b, 0xc4, 0x0d, 0xfd, 0x39, 0x87, 0x38, 0x44, 0x72, 0xf0,
 | 
				
			||||||
	0x79, 0x9b, 0xd8, 0x84, 0x73, 0x84, 0xff, 0xc4, 0xee, 0xcf, 0x36, 0x21, 0x76, 0x07, 0x1b, 0xc8,
 | 
						0x7f, 0xca, 0x7a, 0xc5, 0x21, 0xc4, 0x69, 0x63, 0x0b, 0xf9, 0xae, 0x85, 0x3c, 0x8f, 0x30, 0x01,
 | 
				
			||||||
	0x73, 0x0c, 0xe4, 0xba, 0x84, 0x32, 0x48, 0xc9, 0xaf, 0x8e, 0x1f, 0xc6, 0x43, 0x3e, 0xea, 0xca,
 | 
						0x19, 0xf2, 0xeb, 0xc3, 0xc5, 0xf8, 0x28, 0x40, 0x9d, 0xd0, 0x5f, 0x1e, 0xf6, 0x53, 0x16, 0x20,
 | 
				
			||||||
	0x78, 0x65, 0x3c, 0x1e, 0x50, 0x1f, 0x51, 0x6c, 0x8b, 0xf3, 0x6a, 0x79, 0x00, 0x6f, 0x87, 0xba,
 | 
						0x86, 0x1d, 0x55, 0x6f, 0x31, 0xa6, 0x1d, 0x3d, 0xd4, 0x6d, 0x33, 0xe9, 0x36, 0x72, 0x00, 0x3e,
 | 
				
			||||||
	0x6f, 0xb1, 0x32, 0x13, 0xef, 0xf7, 0x70, 0x40, 0xb5, 0x9b, 0xe0, 0xc7, 0xc8, 0x6e, 0xe0, 0x11,
 | 
						0xe1, 0x65, 0x3d, 0x16, 0xa8, 0x36, 0xde, 0xed, 0x62, 0xca, 0x8c, 0x47, 0x60, 0x36, 0x62, 0xa5,
 | 
				
			||||||
	0x37, 0xc0, 0xf0, 0x2f, 0x90, 0xe6, 0xf0, 0x05, 0xa5, 0xa2, 0x54, 0x33, 0xf5, 0xa2, 0x3e, 0xd6,
 | 
						0x3e, 0xf1, 0x28, 0x86, 0xb7, 0x40, 0x46, 0xb2, 0xe7, 0xb5, 0xb2, 0x56, 0xc9, 0xd6, 0x0a, 0xe6,
 | 
				
			||||||
	0x2d, 0x9d, 0x97, 0x34, 0x66, 0x8f, 0xcf, 0xca, 0x09, 0x53, 0xa4, 0x6b, 0xeb, 0x82, 0x65, 0x17,
 | 
						0x50, 0x33, 0x4d, 0x99, 0x52, 0x9f, 0x38, 0x3c, 0x29, 0x25, 0x6c, 0x15, 0x6e, 0xac, 0x28, 0x96,
 | 
				
			||||||
	0xf5, 0x3a, 0x54, 0xb2, 0xc0, 0x3c, 0x48, 0x59, 0xd8, 0x25, 0x5d, 0x86, 0x36, 0x6f, 0xf2, 0x85,
 | 
						0x4d, 0xce, 0x1c, 0xb2, 0xc0, 0x1c, 0x48, 0xb7, 0xb0, 0x47, 0x3a, 0x02, 0x6d, 0xca, 0x96, 0x07,
 | 
				
			||||||
	0x76, 0x47, 0x70, 0xcb, 0x5c, 0xc1, 0xfd, 0x0f, 0x48, 0xf7, 0xd9, 0x4e, 0x41, 0xa9, 0xcc, 0x54,
 | 
						0xe3, 0x99, 0xe2, 0x0e, 0x63, 0x15, 0xf7, 0x1d, 0x90, 0x11, 0xba, 0x39, 0x77, 0xaa, 0x92, 0xad,
 | 
				
			||||||
	0x33, 0xf5, 0x4a, 0x0c, 0x37, 0x2b, 0x91, 0x15, 0x52, 0x02, 0xaf, 0xd2, 0xde, 0x26, 0x41, 0x36,
 | 
						0x95, 0x63, 0xb8, 0x45, 0x4a, 0x98, 0x11, 0x4a, 0x90, 0x59, 0xc6, 0x6f, 0x0d, 0x4c, 0x47, 0xfc,
 | 
				
			||||||
	0x12, 0x8f, 0xa7, 0x87, 0xff, 0x83, 0x1c, 0xab, 0x68, 0xca, 0x46, 0x15, 0x92, 0x15, 0xa5, 0x9a,
 | 
						0xf1, 0xf4, 0xf0, 0x3e, 0x98, 0x11, 0x19, 0x8d, 0xb0, 0x8f, 0xf9, 0x64, 0x59, 0xab, 0xcc, 0xd4,
 | 
				
			||||||
	0xab, 0x97, 0x63, 0xf8, 0xb6, 0x45, 0xca, 0xce, 0x81, 0x87, 0xcd, 0x2c, 0x2b, 0x93, 0x5b, 0xb0,
 | 
						0x4a, 0x31, 0x7c, 0x1b, 0x2a, 0xe4, 0xe9, 0x9e, 0x8f, 0xed, 0x69, 0x91, 0x16, 0x9a, 0xe0, 0x02,
 | 
				
			||||||
	0x0d, 0x72, 0x94, 0x50, 0xd4, 0x69, 0x06, 0x3d, 0xcf, 0xeb, 0x38, 0xd8, 0x2a, 0xcc, 0x84, 0x34,
 | 
						0xf8, 0x8f, 0x11, 0x86, 0xda, 0x0d, 0xba, 0x8d, 0x02, 0x4c, 0xf3, 0x29, 0x41, 0x92, 0x15, 0xb6,
 | 
				
			||||||
	0x8d, 0xbf, 0x43, 0x55, 0x1f, 0xcf, 0xca, 0xab, 0xb6, 0x43, 0xef, 0xf7, 0x5a, 0x7a, 0x9b, 0x74,
 | 
						0x0d, 0x61, 0x82, 0x2f, 0x80, 0x3c, 0x36, 0x7a, 0xa8, 0xdd, 0xc5, 0xf9, 0x09, 0x1e, 0x51, 0xbf,
 | 
				
			||||||
	0x85, 0xa7, 0xc4, 0x4f, 0x2d, 0xb0, 0xf6, 0x0c, 0x7a, 0xe0, 0xe1, 0x40, 0xdf, 0x72, 0xe9, 0xe9,
 | 
						0xcd, 0x55, 0x7f, 0x3b, 0x29, 0x2d, 0x39, 0x2e, 0xdb, 0xee, 0x36, 0xcd, 0x2d, 0xd2, 0x51, 0x23,
 | 
				
			||||||
	0x51, 0x0d, 0x08, 0xcb, 0x6d, 0xb9, 0xd4, 0xcc, 0x32, 0xcc, 0x6d, 0x01, 0x09, 0xef, 0x81, 0x0c,
 | 
						0xa9, 0x7e, 0xaa, 0xb4, 0xb5, 0x63, 0xb1, 0x3d, 0x1f, 0x53, 0x73, 0xdd, 0x63, 0xc7, 0x07, 0x55,
 | 
				
			||||||
	0x27, 0xe9, 0xa3, 0x4e, 0x0f, 0x17, 0x66, 0xaf, 0x81, 0x01, 0x30, 0xc0, 0xdd, 0x10, 0x4f, 0x7b,
 | 
						0xa0, 0x26, 0x76, 0xdd, 0x63, 0x36, 0x10, 0x80, 0x9b, 0x1c, 0xcf, 0xf8, 0xa8, 0x81, 0x9c, 0xe8,
 | 
				
			||||||
	0xa5, 0x80, 0x3c, 0xbb, 0x8b, 0x4d, 0xec, 0x91, 0xc0, 0x19, 0xde, 0x9c, 0x0e, 0x52, 0xe4, 0x81,
 | 
						0xe4, 0x1a, 0xf6, 0x09, 0x75, 0xfb, 0x7d, 0x37, 0x41, 0x9a, 0xbc, 0xf4, 0x70, 0x20, 0x0b, 0xaf,
 | 
				
			||||||
	0x8b, 0x7d, 0xde, 0xba, 0x46, 0xe1, 0xf4, 0xa8, 0x96, 0x17, 0x18, 0xff, 0x5a, 0x96, 0x8f, 0x83,
 | 
						0xe7, 0x8f, 0x0f, 0xaa, 0x39, 0x85, 0x71, 0xb7, 0xd5, 0x0a, 0x30, 0xa5, 0x1b, 0x2c, 0x70, 0x3d,
 | 
				
			||||||
	0x60, 0x9b, 0xfa, 0x8e, 0x6b, 0x9b, 0x3c, 0x6d, 0xd8, 0xea, 0x64, 0xb4, 0xd5, 0x60, 0xf8, 0x4a,
 | 
						0xc7, 0x96, 0x61, 0xfd, 0x46, 0x25, 0xa3, 0x8d, 0x02, 0xfd, 0x27, 0x20, 0xca, 0xcb, 0xd6, 0x96,
 | 
				
			||||||
	0x58, 0x7b, 0x32, 0xf5, 0x55, 0x5d, 0xe0, 0x84, 0xcf, 0x44, 0xe7, 0x2f, 0x73, 0x68, 0x2d, 0x1b,
 | 
						0x4c, 0x85, 0xc3, 0xdf, 0x80, 0x29, 0x9f, 0x5d, 0x7f, 0x30, 0x1c, 0xac, 0x14, 0xd8, 0x17, 0x32,
 | 
				
			||||||
	0x0b, 0x05, 0xe6, 0xa5, 0x4a, 0xed, 0xb5, 0x02, 0x7e, 0x1a, 0x91, 0x29, 0xae, 0x78, 0x13, 0xcc,
 | 
						0x8d, 0x4f, 0x1a, 0xb8, 0x3c, 0x20, 0x53, 0x5d, 0xd0, 0x1a, 0x98, 0x6c, 0x29, 0x9b, 0xba, 0x74,
 | 
				
			||||||
	0x59, 0x62, 0x4f, 0xd8, 0x46, 0x8b, 0xb9, 0x46, 0x51, 0x36, 0x62, 0x9c, 0x41, 0x25, 0xbc, 0x11,
 | 
						0x23, 0xe6, 0x12, 0x54, 0xda, 0xc0, 0xb5, 0x9f, 0x67, 0xc2, 0x07, 0x11, 0x9d, 0x49, 0xa1, 0x73,
 | 
				
			||||||
	0xd1, 0x99, 0x64, 0x3a, 0xd7, 0xa6, 0xea, 0xe4, 0x60, 0x11, 0xa1, 0x2f, 0x92, 0x60, 0x61, 0x84,
 | 
						0x79, 0xac, 0x4e, 0x09, 0x16, 0x11, 0xfa, 0x47, 0x03, 0xff, 0x0f, 0x90, 0xc1, 0x9b, 0x60, 0x4a,
 | 
				
			||||||
	0x0c, 0xfe, 0x09, 0xe6, 0x05, 0x11, 0x99, 0xde, 0xce, 0x61, 0x2a, 0xa4, 0x60, 0x01, 0x75, 0x49,
 | 
						0x11, 0x91, 0xf1, 0xed, 0xec, 0x87, 0xc2, 0x87, 0x20, 0xa3, 0xe6, 0x22, 0x29, 0x0a, 0x9b, 0x1f,
 | 
				
			||||||
	0xcf, 0xa5, 0x43, 0x83, 0x25, 0xd9, 0x09, 0x8b, 0x11, 0x65, 0x52, 0xd3, 0x7f, 0xc4, 0x71, 0x1b,
 | 
						0x35, 0xcd, 0x62, 0x54, 0xea, 0xb3, 0xbc, 0xa6, 0xcf, 0xdf, 0x4b, 0xd9, 0xbe, 0x8d, 0xda, 0x0a,
 | 
				
			||||||
	0xbf, 0x87, 0x07, 0x7b, 0xf3, 0xa9, 0x5c, 0xbd, 0x82, 0x33, 0xc2, 0x82, 0xc0, 0xcc, 0x71, 0x8e,
 | 
						0x01, 0x22, 0x90, 0x96, 0x03, 0x94, 0x12, 0x50, 0x85, 0x48, 0x6d, 0x21, 0xd8, 0x3d, 0xe2, 0x7a,
 | 
				
			||||||
	0x81, 0xe1, 0x10, 0x48, 0x71, 0xab, 0xcd, 0x5c, 0x3f, 0x17, 0x47, 0xd6, 0xea, 0xa0, 0xc4, 0x2e,
 | 
						0xf5, 0xeb, 0x0a, 0xa6, 0xf2, 0x0f, 0xb3, 0xc5, 0x13, 0xa8, 0x2d, 0x91, 0x6b, 0xef, 0x52, 0x20,
 | 
				
			||||||
	0x73, 0x27, 0xf4, 0xa1, 0xe8, 0x16, 0xb6, 0xbe, 0x3f, 0x33, 0x9e, 0x29, 0x60, 0x31, 0xb6, 0x48,
 | 
						0x2d, 0xee, 0x08, 0xbe, 0x06, 0x19, 0xf9, 0xc2, 0xe1, 0xd5, 0x18, 0xc9, 0xc3, 0xab, 0xa4, 0xb8,
 | 
				
			||||||
	0x34, 0xd9, 0x07, 0x39, 0xd9, 0xa5, 0x66, 0x38, 0x72, 0xa5, 0x1b, 0xae, 0x55, 0x7f, 0x56, 0x52,
 | 
						0x34, 0x2e, 0x4c, 0x76, 0xd2, 0x58, 0xd8, 0xff, 0xf2, 0xeb, 0x43, 0x72, 0x0e, 0x16, 0xac, 0x51,
 | 
				
			||||||
	0xb0, 0x65, 0xfd, 0xdd, 0x2c, 0x48, 0x31, 0x4d, 0xf0, 0x11, 0x48, 0xf3, 0xa9, 0x08, 0x7f, 0x89,
 | 
						0x2b, 0x0f, 0xee, 0x6b, 0x20, 0x23, 0xb7, 0xc2, 0x68, 0xf2, 0xc8, 0x86, 0x19, 0x4d, 0x1e, 0x5d,
 | 
				
			||||||
	0x71, 0xdf, 0xf8, 0xf8, 0x2d, 0xad, 0x4e, 0x4b, 0xe3, 0xc7, 0xd2, 0x96, 0x0f, 0xdf, 0x7f, 0x7d,
 | 
						0x2e, 0xc6, 0x35, 0x41, 0xbe, 0x08, 0x17, 0xac, 0x11, 0xdb, 0x92, 0x5a, 0x6f, 0xc4, 0xd4, 0xbf,
 | 
				
			||||||
	0x9e, 0x5c, 0x84, 0x45, 0x63, 0xd2, 0x77, 0x00, 0x1e, 0x2a, 0x20, 0xcd, 0x27, 0xe9, 0x64, 0xf2,
 | 
						0xe5, 0x22, 0x26, 0xc3, 0x49, 0x85, 0xcb, 0xa3, 0xf0, 0x07, 0x9e, 0x5c, 0xb1, 0x32, 0x3e, 0x50,
 | 
				
			||||||
	0xc8, 0x54, 0x9e, 0x4c, 0x1e, 0x1d, 0xc8, 0xda, 0xaf, 0x8c, 0x7c, 0x05, 0x2e, 0xc7, 0x90, 0xf3,
 | 
						0x49, 0x59, 0x14, 0x52, 0xe6, 0xe1, 0x5c, 0x8c, 0x94, 0x70, 0xa6, 0xeb, 0x6b, 0x87, 0x3f, 0xf5,
 | 
				
			||||||
	0x99, 0x6b, 0x3c, 0x66, 0xb7, 0xf3, 0x24, 0x14, 0x31, 0x27, 0xdf, 0x26, 0x5c, 0x9b, 0x84, 0x3f,
 | 
						0xc4, 0xe1, 0xa9, 0xae, 0x1d, 0x9d, 0xea, 0xda, 0x8f, 0x53, 0x5d, 0x7b, 0x7f, 0xa6, 0x27, 0x8e,
 | 
				
			||||||
	0x32, 0x64, 0x4a, 0xd5, 0xe9, 0x89, 0x42, 0xca, 0x0a, 0x93, 0xb2, 0x04, 0x17, 0x63, 0xa4, 0x0c,
 | 
						0xce, 0xf4, 0xc4, 0xd7, 0x33, 0x3d, 0xf1, 0xfc, 0xe2, 0xea, 0xe0, 0x20, 0xd5, 0x36, 0x6a, 0x52,
 | 
				
			||||||
	0x5e, 0xf1, 0x4b, 0x05, 0xe4, 0xa2, 0xf6, 0x80, 0xb5, 0x49, 0x0c, 0xb1, 0xde, 0x2b, 0xe9, 0x57,
 | 
						0x09, 0xf7, 0x4a, 0x02, 0x8a, 0x2b, 0x6e, 0x66, 0xc4, 0x27, 0xe0, 0xc6, 0xdf, 0x00, 0x00, 0x00,
 | 
				
			||||||
	0x4d, 0x17, 0xb2, 0xea, 0x4c, 0xd6, 0x6f, 0x70, 0x3d, 0x46, 0x16, 0x9b, 0xb2, 0x35, 0x4b, 0xd6,
 | 
						0xff, 0xff, 0x27, 0x75, 0x39, 0xf4, 0x32, 0x07, 0x00, 0x00,
 | 
				
			||||||
	0xc8, 0x56, 0x35, 0x36, 0x8f, 0xbf, 0xa8, 0x89, 0xe3, 0x73, 0x55, 0x39, 0x39, 0x57, 0x95, 0xcf,
 | 
					 | 
				
			||||||
	0xe7, 0xaa, 0xf2, 0xf4, 0x42, 0x4d, 0x9c, 0x5c, 0xa8, 0x89, 0x0f, 0x17, 0x6a, 0xe2, 0xee, 0xe5,
 | 
					 | 
				
			||||||
	0x91, 0x1e, 0x62, 0xd6, 0x3a, 0xa8, 0x15, 0x70, 0xf4, 0x87, 0x1c, 0x9f, 0x19, 0xb2, 0x95, 0x66,
 | 
					 | 
				
			||||||
	0x1f, 0xf7, 0x3f, 0xbe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xb1, 0x1a, 0x34, 0xed, 0x08, 0x00,
 | 
					 | 
				
			||||||
	0x00,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
@ -529,8 +445,6 @@ type QueryClient interface {
 | 
				
			|||||||
	Vaults(ctx context.Context, in *QueryVaultsRequest, opts ...grpc.CallOption) (*QueryVaultsResponse, error)
 | 
						Vaults(ctx context.Context, in *QueryVaultsRequest, opts ...grpc.CallOption) (*QueryVaultsResponse, error)
 | 
				
			||||||
	// Deposits queries deposit details based on owner address and vault
 | 
						// Deposits queries deposit details based on owner address and vault
 | 
				
			||||||
	Deposits(ctx context.Context, in *QueryDepositsRequest, opts ...grpc.CallOption) (*QueryDepositsResponse, error)
 | 
						Deposits(ctx context.Context, in *QueryDepositsRequest, opts ...grpc.CallOption) (*QueryDepositsResponse, error)
 | 
				
			||||||
	// TotalDeposited queries total deposited amount for each vault.
 | 
					 | 
				
			||||||
	TotalDeposited(ctx context.Context, in *QueryTotalDepositedRequest, opts ...grpc.CallOption) (*QueryTotalDepositedResponse, error)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type queryClient struct {
 | 
					type queryClient struct {
 | 
				
			||||||
@ -568,15 +482,6 @@ func (c *queryClient) Deposits(ctx context.Context, in *QueryDepositsRequest, op
 | 
				
			|||||||
	return out, nil
 | 
						return out, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *queryClient) TotalDeposited(ctx context.Context, in *QueryTotalDepositedRequest, opts ...grpc.CallOption) (*QueryTotalDepositedResponse, error) {
 | 
					 | 
				
			||||||
	out := new(QueryTotalDepositedResponse)
 | 
					 | 
				
			||||||
	err := c.cc.Invoke(ctx, "/kava.earn.v1beta1.Query/TotalDeposited", in, out, opts...)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return out, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// QueryServer is the server API for Query service.
 | 
					// QueryServer is the server API for Query service.
 | 
				
			||||||
type QueryServer interface {
 | 
					type QueryServer interface {
 | 
				
			||||||
	// Params queries all parameters of the earn module.
 | 
						// Params queries all parameters of the earn module.
 | 
				
			||||||
@ -585,8 +490,6 @@ type QueryServer interface {
 | 
				
			|||||||
	Vaults(context.Context, *QueryVaultsRequest) (*QueryVaultsResponse, error)
 | 
						Vaults(context.Context, *QueryVaultsRequest) (*QueryVaultsResponse, error)
 | 
				
			||||||
	// Deposits queries deposit details based on owner address and vault
 | 
						// Deposits queries deposit details based on owner address and vault
 | 
				
			||||||
	Deposits(context.Context, *QueryDepositsRequest) (*QueryDepositsResponse, error)
 | 
						Deposits(context.Context, *QueryDepositsRequest) (*QueryDepositsResponse, error)
 | 
				
			||||||
	// TotalDeposited queries total deposited amount for each vault.
 | 
					 | 
				
			||||||
	TotalDeposited(context.Context, *QueryTotalDepositedRequest) (*QueryTotalDepositedResponse, error)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
 | 
					// UnimplementedQueryServer can be embedded to have forward compatible implementations.
 | 
				
			||||||
@ -602,9 +505,6 @@ func (*UnimplementedQueryServer) Vaults(ctx context.Context, req *QueryVaultsReq
 | 
				
			|||||||
func (*UnimplementedQueryServer) Deposits(ctx context.Context, req *QueryDepositsRequest) (*QueryDepositsResponse, error) {
 | 
					func (*UnimplementedQueryServer) Deposits(ctx context.Context, req *QueryDepositsRequest) (*QueryDepositsResponse, error) {
 | 
				
			||||||
	return nil, status.Errorf(codes.Unimplemented, "method Deposits not implemented")
 | 
						return nil, status.Errorf(codes.Unimplemented, "method Deposits not implemented")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (*UnimplementedQueryServer) TotalDeposited(ctx context.Context, req *QueryTotalDepositedRequest) (*QueryTotalDepositedResponse, error) {
 | 
					 | 
				
			||||||
	return nil, status.Errorf(codes.Unimplemented, "method TotalDeposited not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
 | 
					func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
 | 
				
			||||||
	s.RegisterService(&_Query_serviceDesc, srv)
 | 
						s.RegisterService(&_Query_serviceDesc, srv)
 | 
				
			||||||
@ -664,24 +564,6 @@ func _Query_Deposits_Handler(srv interface{}, ctx context.Context, dec func(inte
 | 
				
			|||||||
	return interceptor(ctx, in, info, handler)
 | 
						return interceptor(ctx, in, info, handler)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _Query_TotalDeposited_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 | 
					 | 
				
			||||||
	in := new(QueryTotalDepositedRequest)
 | 
					 | 
				
			||||||
	if err := dec(in); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if interceptor == nil {
 | 
					 | 
				
			||||||
		return srv.(QueryServer).TotalDeposited(ctx, in)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	info := &grpc.UnaryServerInfo{
 | 
					 | 
				
			||||||
		Server:     srv,
 | 
					 | 
				
			||||||
		FullMethod: "/kava.earn.v1beta1.Query/TotalDeposited",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 | 
					 | 
				
			||||||
		return srv.(QueryServer).TotalDeposited(ctx, req.(*QueryTotalDepositedRequest))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return interceptor(ctx, in, info, handler)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var _Query_serviceDesc = grpc.ServiceDesc{
 | 
					var _Query_serviceDesc = grpc.ServiceDesc{
 | 
				
			||||||
	ServiceName: "kava.earn.v1beta1.Query",
 | 
						ServiceName: "kava.earn.v1beta1.Query",
 | 
				
			||||||
	HandlerType: (*QueryServer)(nil),
 | 
						HandlerType: (*QueryServer)(nil),
 | 
				
			||||||
@ -698,10 +580,6 @@ var _Query_serviceDesc = grpc.ServiceDesc{
 | 
				
			|||||||
			MethodName: "Deposits",
 | 
								MethodName: "Deposits",
 | 
				
			||||||
			Handler:    _Query_Deposits_Handler,
 | 
								Handler:    _Query_Deposits_Handler,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			MethodName: "TotalDeposited",
 | 
					 | 
				
			||||||
			Handler:    _Query_TotalDeposited_Handler,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	Streams:  []grpc.StreamDesc{},
 | 
						Streams:  []grpc.StreamDesc{},
 | 
				
			||||||
	Metadata: "kava/earn/v1beta1/query.proto",
 | 
						Metadata: "kava/earn/v1beta1/query.proto",
 | 
				
			||||||
@ -860,16 +738,13 @@ func (m *VaultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	i--
 | 
						i--
 | 
				
			||||||
	dAtA[i] = 0x22
 | 
						dAtA[i] = 0x22
 | 
				
			||||||
	{
 | 
						if len(m.TotalShares) > 0 {
 | 
				
			||||||
		size := m.TotalSupplied.Size()
 | 
							i -= len(m.TotalShares)
 | 
				
			||||||
		i -= size
 | 
							copy(dAtA[i:], m.TotalShares)
 | 
				
			||||||
		if _, err := m.TotalSupplied.MarshalTo(dAtA[i:]); err != nil {
 | 
							i = encodeVarintQuery(dAtA, i, uint64(len(m.TotalShares)))
 | 
				
			||||||
			return 0, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		i = encodeVarintQuery(dAtA, i, uint64(size))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
		i--
 | 
							i--
 | 
				
			||||||
		dAtA[i] = 0x1a
 | 
							dAtA[i] = 0x1a
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if m.VaultStrategy != 0 {
 | 
						if m.VaultStrategy != 0 {
 | 
				
			||||||
		i = encodeVarintQuery(dAtA, i, uint64(m.VaultStrategy))
 | 
							i = encodeVarintQuery(dAtA, i, uint64(m.VaultStrategy))
 | 
				
			||||||
		i--
 | 
							i--
 | 
				
			||||||
@ -1017,10 +892,10 @@ func (m *DepositResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
			dAtA[i] = 0x1a
 | 
								dAtA[i] = 0x1a
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(m.AmountSupplied) > 0 {
 | 
						if len(m.Shares) > 0 {
 | 
				
			||||||
		for iNdEx := len(m.AmountSupplied) - 1; iNdEx >= 0; iNdEx-- {
 | 
							for iNdEx := len(m.Shares) - 1; iNdEx >= 0; iNdEx-- {
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				size, err := m.AmountSupplied[iNdEx].MarshalToSizedBuffer(dAtA[:i])
 | 
									size, err := m.Shares[iNdEx].MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return 0, err
 | 
										return 0, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -1041,73 +916,6 @@ func (m *DepositResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	return len(dAtA) - i, nil
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *QueryTotalDepositedRequest) Marshal() (dAtA []byte, err error) {
 | 
					 | 
				
			||||||
	size := m.Size()
 | 
					 | 
				
			||||||
	dAtA = make([]byte, size)
 | 
					 | 
				
			||||||
	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return dAtA[:n], nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) MarshalTo(dAtA []byte) (int, error) {
 | 
					 | 
				
			||||||
	size := m.Size()
 | 
					 | 
				
			||||||
	return m.MarshalToSizedBuffer(dAtA[:size])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
					 | 
				
			||||||
	i := len(dAtA)
 | 
					 | 
				
			||||||
	_ = i
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	_ = l
 | 
					 | 
				
			||||||
	if len(m.Denom) > 0 {
 | 
					 | 
				
			||||||
		i -= len(m.Denom)
 | 
					 | 
				
			||||||
		copy(dAtA[i:], m.Denom)
 | 
					 | 
				
			||||||
		i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom)))
 | 
					 | 
				
			||||||
		i--
 | 
					 | 
				
			||||||
		dAtA[i] = 0xa
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return len(dAtA) - i, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) Marshal() (dAtA []byte, err error) {
 | 
					 | 
				
			||||||
	size := m.Size()
 | 
					 | 
				
			||||||
	dAtA = make([]byte, size)
 | 
					 | 
				
			||||||
	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return dAtA[:n], nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) MarshalTo(dAtA []byte) (int, error) {
 | 
					 | 
				
			||||||
	size := m.Size()
 | 
					 | 
				
			||||||
	return m.MarshalToSizedBuffer(dAtA[:size])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
					 | 
				
			||||||
	i := len(dAtA)
 | 
					 | 
				
			||||||
	_ = i
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	_ = l
 | 
					 | 
				
			||||||
	if len(m.SuppliedCoins) > 0 {
 | 
					 | 
				
			||||||
		for iNdEx := len(m.SuppliedCoins) - 1; iNdEx >= 0; iNdEx-- {
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				size, err := m.SuppliedCoins[iNdEx].MarshalToSizedBuffer(dAtA[:i])
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					return 0, err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				i -= size
 | 
					 | 
				
			||||||
				i = encodeVarintQuery(dAtA, i, uint64(size))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			i--
 | 
					 | 
				
			||||||
			dAtA[i] = 0xa
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return len(dAtA) - i, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
 | 
					func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
 | 
				
			||||||
	offset -= sovQuery(v)
 | 
						offset -= sovQuery(v)
 | 
				
			||||||
	base := offset
 | 
						base := offset
 | 
				
			||||||
@ -1180,8 +988,10 @@ func (m *VaultResponse) Size() (n int) {
 | 
				
			|||||||
	if m.VaultStrategy != 0 {
 | 
						if m.VaultStrategy != 0 {
 | 
				
			||||||
		n += 1 + sovQuery(uint64(m.VaultStrategy))
 | 
							n += 1 + sovQuery(uint64(m.VaultStrategy))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	l = m.TotalSupplied.Size()
 | 
						l = len(m.TotalShares)
 | 
				
			||||||
 | 
						if l > 0 {
 | 
				
			||||||
		n += 1 + l + sovQuery(uint64(l))
 | 
							n += 1 + l + sovQuery(uint64(l))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	l = m.TotalValue.Size()
 | 
						l = m.TotalValue.Size()
 | 
				
			||||||
	n += 1 + l + sovQuery(uint64(l))
 | 
						n += 1 + l + sovQuery(uint64(l))
 | 
				
			||||||
	return n
 | 
						return n
 | 
				
			||||||
@ -1237,8 +1047,8 @@ func (m *DepositResponse) Size() (n int) {
 | 
				
			|||||||
	if l > 0 {
 | 
						if l > 0 {
 | 
				
			||||||
		n += 1 + l + sovQuery(uint64(l))
 | 
							n += 1 + l + sovQuery(uint64(l))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(m.AmountSupplied) > 0 {
 | 
						if len(m.Shares) > 0 {
 | 
				
			||||||
		for _, e := range m.AmountSupplied {
 | 
							for _, e := range m.Shares {
 | 
				
			||||||
			l = e.Size()
 | 
								l = e.Size()
 | 
				
			||||||
			n += 1 + l + sovQuery(uint64(l))
 | 
								n += 1 + l + sovQuery(uint64(l))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -1252,34 +1062,6 @@ func (m *DepositResponse) Size() (n int) {
 | 
				
			|||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *QueryTotalDepositedRequest) Size() (n int) {
 | 
					 | 
				
			||||||
	if m == nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	_ = l
 | 
					 | 
				
			||||||
	l = len(m.Denom)
 | 
					 | 
				
			||||||
	if l > 0 {
 | 
					 | 
				
			||||||
		n += 1 + l + sovQuery(uint64(l))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) Size() (n int) {
 | 
					 | 
				
			||||||
	if m == nil {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var l int
 | 
					 | 
				
			||||||
	_ = l
 | 
					 | 
				
			||||||
	if len(m.SuppliedCoins) > 0 {
 | 
					 | 
				
			||||||
		for _, e := range m.SuppliedCoins {
 | 
					 | 
				
			||||||
			l = e.Size()
 | 
					 | 
				
			||||||
			n += 1 + l + sovQuery(uint64(l))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func sovQuery(x uint64) (n int) {
 | 
					func sovQuery(x uint64) (n int) {
 | 
				
			||||||
	return (math_bits.Len64(x|1) + 6) / 7
 | 
						return (math_bits.Len64(x|1) + 6) / 7
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1667,7 +1449,7 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		case 3:
 | 
							case 3:
 | 
				
			||||||
			if wireType != 2 {
 | 
								if wireType != 2 {
 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field TotalSupplied", wireType)
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var stringLen uint64
 | 
								var stringLen uint64
 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
@ -1695,9 +1477,7 @@ func (m *VaultResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			if postIndex > l {
 | 
								if postIndex > l {
 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err := m.TotalSupplied.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
								m.TotalShares = string(dAtA[iNdEx:postIndex])
 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
		case 4:
 | 
							case 4:
 | 
				
			||||||
			if wireType != 2 {
 | 
								if wireType != 2 {
 | 
				
			||||||
@ -2087,7 +1867,7 @@ func (m *DepositResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
			if wireType != 2 {
 | 
								if wireType != 2 {
 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field AmountSupplied", wireType)
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Shares", wireType)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var msglen int
 | 
								var msglen int
 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
@ -2114,8 +1894,8 @@ func (m *DepositResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			if postIndex > l {
 | 
								if postIndex > l {
 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m.AmountSupplied = append(m.AmountSupplied, types.Coin{})
 | 
								m.Shares = append(m.Shares, VaultShare{})
 | 
				
			||||||
			if err := m.AmountSupplied[len(m.AmountSupplied)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
								if err := m.Shares[len(m.Shares)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
@ -2174,172 +1954,6 @@ func (m *DepositResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *QueryTotalDepositedRequest) Unmarshal(dAtA []byte) error {
 | 
					 | 
				
			||||||
	l := len(dAtA)
 | 
					 | 
				
			||||||
	iNdEx := 0
 | 
					 | 
				
			||||||
	for iNdEx < l {
 | 
					 | 
				
			||||||
		preIndex := iNdEx
 | 
					 | 
				
			||||||
		var wire uint64
 | 
					 | 
				
			||||||
		for shift := uint(0); ; shift += 7 {
 | 
					 | 
				
			||||||
			if shift >= 64 {
 | 
					 | 
				
			||||||
				return ErrIntOverflowQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if iNdEx >= l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			b := dAtA[iNdEx]
 | 
					 | 
				
			||||||
			iNdEx++
 | 
					 | 
				
			||||||
			wire |= uint64(b&0x7F) << shift
 | 
					 | 
				
			||||||
			if b < 0x80 {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		fieldNum := int32(wire >> 3)
 | 
					 | 
				
			||||||
		wireType := int(wire & 0x7)
 | 
					 | 
				
			||||||
		if wireType == 4 {
 | 
					 | 
				
			||||||
			return fmt.Errorf("proto: QueryTotalDepositedRequest: wiretype end group for non-group")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if fieldNum <= 0 {
 | 
					 | 
				
			||||||
			return fmt.Errorf("proto: QueryTotalDepositedRequest: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch fieldNum {
 | 
					 | 
				
			||||||
		case 1:
 | 
					 | 
				
			||||||
			if wireType != 2 {
 | 
					 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field Denom", 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.Denom = string(dAtA[iNdEx:postIndex])
 | 
					 | 
				
			||||||
			iNdEx = postIndex
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			iNdEx = preIndex
 | 
					 | 
				
			||||||
			skippy, err := skipQuery(dAtA[iNdEx:])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (skippy < 0) || (iNdEx+skippy) < 0 {
 | 
					 | 
				
			||||||
				return ErrInvalidLengthQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (iNdEx + skippy) > l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			iNdEx += skippy
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if iNdEx > l {
 | 
					 | 
				
			||||||
		return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (m *QueryTotalDepositedResponse) Unmarshal(dAtA []byte) error {
 | 
					 | 
				
			||||||
	l := len(dAtA)
 | 
					 | 
				
			||||||
	iNdEx := 0
 | 
					 | 
				
			||||||
	for iNdEx < l {
 | 
					 | 
				
			||||||
		preIndex := iNdEx
 | 
					 | 
				
			||||||
		var wire uint64
 | 
					 | 
				
			||||||
		for shift := uint(0); ; shift += 7 {
 | 
					 | 
				
			||||||
			if shift >= 64 {
 | 
					 | 
				
			||||||
				return ErrIntOverflowQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if iNdEx >= l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			b := dAtA[iNdEx]
 | 
					 | 
				
			||||||
			iNdEx++
 | 
					 | 
				
			||||||
			wire |= uint64(b&0x7F) << shift
 | 
					 | 
				
			||||||
			if b < 0x80 {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		fieldNum := int32(wire >> 3)
 | 
					 | 
				
			||||||
		wireType := int(wire & 0x7)
 | 
					 | 
				
			||||||
		if wireType == 4 {
 | 
					 | 
				
			||||||
			return fmt.Errorf("proto: QueryTotalDepositedResponse: wiretype end group for non-group")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if fieldNum <= 0 {
 | 
					 | 
				
			||||||
			return fmt.Errorf("proto: QueryTotalDepositedResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch fieldNum {
 | 
					 | 
				
			||||||
		case 1:
 | 
					 | 
				
			||||||
			if wireType != 2 {
 | 
					 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field SuppliedCoins", wireType)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			var msglen int
 | 
					 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
					 | 
				
			||||||
				if shift >= 64 {
 | 
					 | 
				
			||||||
					return ErrIntOverflowQuery
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if iNdEx >= l {
 | 
					 | 
				
			||||||
					return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				b := dAtA[iNdEx]
 | 
					 | 
				
			||||||
				iNdEx++
 | 
					 | 
				
			||||||
				msglen |= int(b&0x7F) << shift
 | 
					 | 
				
			||||||
				if b < 0x80 {
 | 
					 | 
				
			||||||
					break
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if msglen < 0 {
 | 
					 | 
				
			||||||
				return ErrInvalidLengthQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			postIndex := iNdEx + msglen
 | 
					 | 
				
			||||||
			if postIndex < 0 {
 | 
					 | 
				
			||||||
				return ErrInvalidLengthQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if postIndex > l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			m.SuppliedCoins = append(m.SuppliedCoins, types.Coin{})
 | 
					 | 
				
			||||||
			if err := m.SuppliedCoins[len(m.SuppliedCoins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			iNdEx = postIndex
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			iNdEx = preIndex
 | 
					 | 
				
			||||||
			skippy, err := skipQuery(dAtA[iNdEx:])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (skippy < 0) || (iNdEx+skippy) < 0 {
 | 
					 | 
				
			||||||
				return ErrInvalidLengthQuery
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (iNdEx + skippy) > l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			iNdEx += skippy
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if iNdEx > l {
 | 
					 | 
				
			||||||
		return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func skipQuery(dAtA []byte) (n int, err error) {
 | 
					func skipQuery(dAtA []byte) (n int, err error) {
 | 
				
			||||||
	l := len(dAtA)
 | 
						l := len(dAtA)
 | 
				
			||||||
	iNdEx := 0
 | 
						iNdEx := 0
 | 
				
			||||||
 | 
				
			|||||||
@ -139,60 +139,6 @@ func local_request_Query_Deposits_0(ctx context.Context, marshaler runtime.Marsh
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func request_Query_TotalDeposited_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
 | 
					 | 
				
			||||||
	var protoReq QueryTotalDepositedRequest
 | 
					 | 
				
			||||||
	var metadata runtime.ServerMetadata
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		val string
 | 
					 | 
				
			||||||
		ok  bool
 | 
					 | 
				
			||||||
		err error
 | 
					 | 
				
			||||||
		_   = err
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val, ok = pathParams["denom"]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protoReq.Denom, err = runtime.String(val)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg, err := client.TotalDeposited(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
 | 
					 | 
				
			||||||
	return msg, metadata, err
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func local_request_Query_TotalDeposited_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
 | 
					 | 
				
			||||||
	var protoReq QueryTotalDepositedRequest
 | 
					 | 
				
			||||||
	var metadata runtime.ServerMetadata
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		val string
 | 
					 | 
				
			||||||
		ok  bool
 | 
					 | 
				
			||||||
		err error
 | 
					 | 
				
			||||||
		_   = err
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val, ok = pathParams["denom"]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protoReq.Denom, err = runtime.String(val)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg, err := server.TotalDeposited(ctx, &protoReq)
 | 
					 | 
				
			||||||
	return msg, metadata, err
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
 | 
					// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
 | 
				
			||||||
// UnaryRPC     :call QueryServer directly.
 | 
					// UnaryRPC     :call QueryServer directly.
 | 
				
			||||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
 | 
					// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
 | 
				
			||||||
@ -259,26 +205,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mux.Handle("GET", pattern_Query_TotalDeposited_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 | 
					 | 
				
			||||||
		ctx, cancel := context.WithCancel(req.Context())
 | 
					 | 
				
			||||||
		defer cancel()
 | 
					 | 
				
			||||||
		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
 | 
					 | 
				
			||||||
		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		resp, md, err := local_request_Query_TotalDeposited_0(rctx, inboundMarshaler, server, req, pathParams)
 | 
					 | 
				
			||||||
		ctx = runtime.NewServerMetadataContext(ctx, md)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		forward_Query_TotalDeposited_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -380,26 +306,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mux.Handle("GET", pattern_Query_TotalDeposited_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 | 
					 | 
				
			||||||
		ctx, cancel := context.WithCancel(req.Context())
 | 
					 | 
				
			||||||
		defer cancel()
 | 
					 | 
				
			||||||
		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
 | 
					 | 
				
			||||||
		rctx, err := runtime.AnnotateContext(ctx, mux, req)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		resp, md, err := request_Query_TotalDeposited_0(rctx, inboundMarshaler, client, req, pathParams)
 | 
					 | 
				
			||||||
		ctx = runtime.NewServerMetadataContext(ctx, md)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		forward_Query_TotalDeposited_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -409,8 +315,6 @@ var (
 | 
				
			|||||||
	pattern_Query_Vaults_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kava", "earn", "v1beta1", "vaults", "denom"}, "", runtime.AssumeColonVerbOpt(false)))
 | 
						pattern_Query_Vaults_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kava", "earn", "v1beta1", "vaults", "denom"}, "", runtime.AssumeColonVerbOpt(false)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pattern_Query_Deposits_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"kava", "earn", "v1beta1", "deposits"}, "", runtime.AssumeColonVerbOpt(false)))
 | 
						pattern_Query_Deposits_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"kava", "earn", "v1beta1", "deposits"}, "", runtime.AssumeColonVerbOpt(false)))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	pattern_Query_TotalDeposited_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kava", "earn", "v1beta1", "total-deposited", "denom"}, "", runtime.AssumeColonVerbOpt(false)))
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@ -419,6 +323,4 @@ var (
 | 
				
			|||||||
	forward_Query_Vaults_0 = runtime.ForwardResponseMessage
 | 
						forward_Query_Vaults_0 = runtime.ForwardResponseMessage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	forward_Query_Deposits_0 = runtime.ForwardResponseMessage
 | 
						forward_Query_Deposits_0 = runtime.ForwardResponseMessage
 | 
				
			||||||
 | 
					 | 
				
			||||||
	forward_Query_TotalDeposited_0 = runtime.ForwardResponseMessage
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										383
									
								
								x/earn/types/share.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										383
									
								
								x/earn/types/share.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,383 @@
 | 
				
			|||||||
 | 
					package types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						fmt "fmt"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
						sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewVaultShare returns a new VaultShare
 | 
				
			||||||
 | 
					func NewVaultShare(denom string, amount sdk.Dec) VaultShare {
 | 
				
			||||||
 | 
						share := VaultShare{
 | 
				
			||||||
 | 
							Denom:  denom,
 | 
				
			||||||
 | 
							Amount: amount,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := share.Validate(); err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return share
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Validate returns an error if a VaultShare is invalid.
 | 
				
			||||||
 | 
					func (share VaultShare) Validate() error {
 | 
				
			||||||
 | 
						if err := sdk.ValidateDenom(share.Denom); err != nil {
 | 
				
			||||||
 | 
							return sdkerrors.Wrap(ErrInvalidVaultDenom, err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if share.Amount.IsNil() {
 | 
				
			||||||
 | 
							return fmt.Errorf("nil share amount: %s", share.Amount)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if share.Amount.IsNegative() {
 | 
				
			||||||
 | 
							return fmt.Errorf("vault share amount %v is negative", share.Amount)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsValid returns true if the VaultShare is valid
 | 
				
			||||||
 | 
					func (share VaultShare) IsValid() bool {
 | 
				
			||||||
 | 
						return share.Validate() == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (share VaultShare) IsPositive() bool {
 | 
				
			||||||
 | 
						return share.Amount.IsPositive()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add adds amounts of two vault shares with same denom. If the shares differ in
 | 
				
			||||||
 | 
					// denom then it panics.
 | 
				
			||||||
 | 
					func (share VaultShare) Add(vsB VaultShare) VaultShare {
 | 
				
			||||||
 | 
						if share.Denom != vsB.Denom {
 | 
				
			||||||
 | 
							panic(fmt.Sprintf("invalid share denominations; %s, %s", share.Denom, vsB.Denom))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NewVaultShare(share.Denom, share.Amount.Add(vsB.Amount))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsZero returns if this represents no shares
 | 
				
			||||||
 | 
					func (share VaultShare) IsZero() bool {
 | 
				
			||||||
 | 
						return share.Amount.IsZero()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsNegative returns true if the share amount is negative and false otherwise.
 | 
				
			||||||
 | 
					func (share VaultShare) IsNegative() bool {
 | 
				
			||||||
 | 
						return share.Amount.IsNegative()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sub subtracts amounts of two vault shares with same denom. If the shares
 | 
				
			||||||
 | 
					// differ in denom then it panics.
 | 
				
			||||||
 | 
					func (share VaultShare) Sub(vsB VaultShare) VaultShare {
 | 
				
			||||||
 | 
						if share.Denom != vsB.Denom {
 | 
				
			||||||
 | 
							panic(fmt.Sprintf("invalid share denominations; %s, %s", share.Denom, vsB.Denom))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res := NewVaultShare(share.Denom, share.Amount.Sub(vsB.Amount))
 | 
				
			||||||
 | 
						if res.Amount.IsNegative() {
 | 
				
			||||||
 | 
							panic("negative share amount")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (share VaultShare) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("%v%v", share.Amount, share.Denom)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VaultShares is a slice of VaultShare.
 | 
				
			||||||
 | 
					type VaultShares []VaultShare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewVaultShares returns new VaultShares
 | 
				
			||||||
 | 
					func NewVaultShares(shares ...VaultShare) VaultShares {
 | 
				
			||||||
 | 
						newVaultShares := sanitizeVaultShares(shares)
 | 
				
			||||||
 | 
						if err := newVaultShares.Validate(); err != nil {
 | 
				
			||||||
 | 
							panic(fmt.Errorf("invalid share set %s: %w", newVaultShares, err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return newVaultShares
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func sanitizeVaultShares(shares VaultShares) VaultShares {
 | 
				
			||||||
 | 
						newVaultShares := removeZeroShares(shares)
 | 
				
			||||||
 | 
						if len(newVaultShares) == 0 {
 | 
				
			||||||
 | 
							return VaultShares{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return newVaultShares.Sort()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Validate returns an error if a slice of VaultShares is invalid.
 | 
				
			||||||
 | 
					func (shares VaultShares) Validate() error {
 | 
				
			||||||
 | 
						switch len(shares) {
 | 
				
			||||||
 | 
						case 0:
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							if err := sdk.ValidateDenom(shares[0].Denom); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !shares[0].IsPositive() {
 | 
				
			||||||
 | 
								return fmt.Errorf("share %s amount is not positive", shares[0])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// check single share case
 | 
				
			||||||
 | 
							if err := (VaultShares{shares[0]}).Validate(); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lowDenom := shares[0].Denom
 | 
				
			||||||
 | 
							seenDenoms := make(map[string]bool)
 | 
				
			||||||
 | 
							seenDenoms[lowDenom] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, share := range shares[1:] {
 | 
				
			||||||
 | 
								if seenDenoms[share.Denom] {
 | 
				
			||||||
 | 
									return fmt.Errorf("duplicate denomination %s", share.Denom)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := sdk.ValidateDenom(share.Denom); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if share.Denom <= lowDenom {
 | 
				
			||||||
 | 
									return fmt.Errorf("denomination %s is not sorted", share.Denom)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if !share.IsPositive() {
 | 
				
			||||||
 | 
									return fmt.Errorf("share %s amount is not positive", share.Denom)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// we compare each share against the last denom
 | 
				
			||||||
 | 
								lowDenom = share.Denom
 | 
				
			||||||
 | 
								seenDenoms[share.Denom] = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsValid returns true if the VaultShares are valid
 | 
				
			||||||
 | 
					func (shares VaultShares) IsValid() bool {
 | 
				
			||||||
 | 
						return shares.Validate() == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AmountOf returns the amount of shares of the given denom.
 | 
				
			||||||
 | 
					func (shares VaultShares) Add(sharesB ...VaultShare) VaultShares {
 | 
				
			||||||
 | 
						return shares.safeAdd(sharesB)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// safeAdd will perform addition of two shares sets. If both share sets are
 | 
				
			||||||
 | 
					// empty, then an empty set is returned. If only a single set is empty, the
 | 
				
			||||||
 | 
					// other set is returned. Otherwise, the shares are compared in order of their
 | 
				
			||||||
 | 
					// denomination and addition only occurs when the denominations match, otherwise
 | 
				
			||||||
 | 
					// the share is simply added to the sum assuming it's not zero.
 | 
				
			||||||
 | 
					// The function panics if `shares` or  `sharesB` are not sorted (ascending).
 | 
				
			||||||
 | 
					func (shares VaultShares) safeAdd(sharesB VaultShares) VaultShares {
 | 
				
			||||||
 | 
						// probably the best way will be to make Shares and interface and hide the structure
 | 
				
			||||||
 | 
						// definition (type alias)
 | 
				
			||||||
 | 
						if !shares.isSorted() {
 | 
				
			||||||
 | 
							panic("Shares (self) must be sorted")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !sharesB.isSorted() {
 | 
				
			||||||
 | 
							panic("Wrong argument: shares must be sorted")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sum := (VaultShares)(nil)
 | 
				
			||||||
 | 
						indexA, indexB := 0, 0
 | 
				
			||||||
 | 
						lenA, lenB := len(shares), len(sharesB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							if indexA == lenA {
 | 
				
			||||||
 | 
								if indexB == lenB {
 | 
				
			||||||
 | 
									// return nil shares if both sets are empty
 | 
				
			||||||
 | 
									return sum
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// return set B (excluding zero shares) if set A is empty
 | 
				
			||||||
 | 
								return append(sum, removeZeroShares(sharesB[indexB:])...)
 | 
				
			||||||
 | 
							} else if indexB == lenB {
 | 
				
			||||||
 | 
								// return set A (excluding zero shares) if set B is empty
 | 
				
			||||||
 | 
								return append(sum, removeZeroShares(shares[indexA:])...)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							shareA, shareB := shares[indexA], sharesB[indexB]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch strings.Compare(shareA.Denom, shareB.Denom) {
 | 
				
			||||||
 | 
							case -1: // share A denom < share B denom
 | 
				
			||||||
 | 
								if !shareA.IsZero() {
 | 
				
			||||||
 | 
									sum = append(sum, shareA)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								indexA++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 0: // share A denom == share B denom
 | 
				
			||||||
 | 
								res := shareA.Add(shareB)
 | 
				
			||||||
 | 
								if !res.IsZero() {
 | 
				
			||||||
 | 
									sum = append(sum, res)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								indexA++
 | 
				
			||||||
 | 
								indexB++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 1: // share A denom > share B denom
 | 
				
			||||||
 | 
								if !shareB.IsZero() {
 | 
				
			||||||
 | 
									sum = append(sum, shareB)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								indexB++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sub subtracts a set of shares from another.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// e.g.
 | 
				
			||||||
 | 
					// {2A, 3B} - {A} = {A, 3B}
 | 
				
			||||||
 | 
					// {2A} - {0B} = {2A}
 | 
				
			||||||
 | 
					// {A, B} - {A} = {B}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// CONTRACT: Sub will never return Shares where one Share has a non-positive
 | 
				
			||||||
 | 
					// amount. In otherwords, IsValid will always return true.
 | 
				
			||||||
 | 
					func (shares VaultShares) Sub(sharesB ...VaultShare) VaultShares {
 | 
				
			||||||
 | 
						diff, hasNeg := shares.SafeSub(sharesB)
 | 
				
			||||||
 | 
						if hasNeg {
 | 
				
			||||||
 | 
							panic("negative share amount")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return diff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SafeSub performs the same arithmetic as Sub but returns a boolean if any
 | 
				
			||||||
 | 
					// negative share amount was returned.
 | 
				
			||||||
 | 
					// The function panics if `shares` or  `sharesB` are not sorted (ascending).
 | 
				
			||||||
 | 
					func (shares VaultShares) SafeSub(sharesB VaultShares) (VaultShares, bool) {
 | 
				
			||||||
 | 
						diff := shares.safeAdd(sharesB.negative())
 | 
				
			||||||
 | 
						return diff, diff.IsAnyNegative()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsAnyNegative returns true if there is at least one share whose amount
 | 
				
			||||||
 | 
					// is negative; returns false otherwise. It returns false if the share set
 | 
				
			||||||
 | 
					// is empty too.
 | 
				
			||||||
 | 
					func (shares VaultShares) IsAnyNegative() bool {
 | 
				
			||||||
 | 
						for _, share := range shares {
 | 
				
			||||||
 | 
							if share.IsNegative() {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// negative returns a set of shares with all amount negative.
 | 
				
			||||||
 | 
					func (shares VaultShares) negative() VaultShares {
 | 
				
			||||||
 | 
						res := make(VaultShares, 0, len(shares))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, share := range shares {
 | 
				
			||||||
 | 
							res = append(res, VaultShare{
 | 
				
			||||||
 | 
								Denom:  share.Denom,
 | 
				
			||||||
 | 
								Amount: share.Amount.Neg(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AmountOf returns the amount of shares of the given denom.
 | 
				
			||||||
 | 
					func (v VaultShares) AmountOf(denom string) sdk.Dec {
 | 
				
			||||||
 | 
						for _, s := range v {
 | 
				
			||||||
 | 
							if s.Denom == denom {
 | 
				
			||||||
 | 
								return s.Amount
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sdk.ZeroDec()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetShare the single share of the given denom.
 | 
				
			||||||
 | 
					func (v VaultShares) GetShare(denom string) VaultShare {
 | 
				
			||||||
 | 
						for _, s := range v {
 | 
				
			||||||
 | 
							if s.Denom == denom {
 | 
				
			||||||
 | 
								return s
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NewVaultShare(denom, sdk.ZeroDec())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsZero returns true if the VaultShares is empty.
 | 
				
			||||||
 | 
					func (v VaultShares) IsZero() bool {
 | 
				
			||||||
 | 
						for _, s := range v {
 | 
				
			||||||
 | 
							// If any amount is non-zero, false
 | 
				
			||||||
 | 
							if !s.Amount.IsZero() {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (shares VaultShares) isSorted() bool {
 | 
				
			||||||
 | 
						for i := 1; i < len(shares); i++ {
 | 
				
			||||||
 | 
							if shares[i-1].Denom > shares[i].Denom {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (shares VaultShares) String() string {
 | 
				
			||||||
 | 
						if len(shares) == 0 {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := ""
 | 
				
			||||||
 | 
						for _, share := range shares {
 | 
				
			||||||
 | 
							out += fmt.Sprintf("%v,", share.String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out[:len(out)-1]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// removeZeroShares removes all zero shares from the given share set in-place.
 | 
				
			||||||
 | 
					func removeZeroShares(shares VaultShares) VaultShares {
 | 
				
			||||||
 | 
						for i := 0; i < len(shares); i++ {
 | 
				
			||||||
 | 
							if shares[i].IsZero() {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							} else if i == len(shares)-1 {
 | 
				
			||||||
 | 
								return shares
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var result VaultShares
 | 
				
			||||||
 | 
						if len(shares) > 0 {
 | 
				
			||||||
 | 
							result = make(VaultShares, 0, len(shares)-1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, share := range shares {
 | 
				
			||||||
 | 
							if !share.IsZero() {
 | 
				
			||||||
 | 
								result = append(result, share)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// VaultShares sort interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a VaultShares) Len() int { return len(a) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Less implements sort.Interface for VaultShares
 | 
				
			||||||
 | 
					func (shares VaultShares) Less(i, j int) bool { return shares[i].Denom < shares[j].Denom }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Swap implements sort.Interface for VaultShares
 | 
				
			||||||
 | 
					func (shares VaultShares) Swap(i, j int) { shares[i], shares[j] = shares[j], shares[i] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ sort.Interface = VaultShares{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sort is a helper function to sort the set of vault shares in-place
 | 
				
			||||||
 | 
					func (shares VaultShares) Sort() VaultShares {
 | 
				
			||||||
 | 
						sort.Sort(shares)
 | 
				
			||||||
 | 
						return shares
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										446
									
								
								x/earn/types/share_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								x/earn/types/share_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,446 @@
 | 
				
			|||||||
 | 
					package types_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/kava-labs/kava/x/earn/types"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/suite"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdk "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						testDenom1 = "ukava"
 | 
				
			||||||
 | 
						testDenom2 = "usdx"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func d(i int64) sdk.Dec {
 | 
				
			||||||
 | 
						return sdk.NewDec(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type vaultShareTestSuite struct {
 | 
				
			||||||
 | 
						suite.Suite
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestVaultShareTestSuite(t *testing.T) {
 | 
				
			||||||
 | 
						suite.Run(t, new(vaultShareTestSuite))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestNewVaultShareFromDec() {
 | 
				
			||||||
 | 
						s.Require().NotPanics(func() {
 | 
				
			||||||
 | 
							types.NewVaultShare(testDenom1, sdk.NewDec(5))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						s.Require().NotPanics(func() {
 | 
				
			||||||
 | 
							types.NewVaultShare(testDenom1, sdk.ZeroDec())
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						s.Require().NotPanics(func() {
 | 
				
			||||||
 | 
							types.NewVaultShare(strings.ToUpper(testDenom1), sdk.NewDec(5))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						s.Require().Panics(func() {
 | 
				
			||||||
 | 
							types.NewVaultShare(testDenom1, sdk.NewDec(-5))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestAddVaultShare() {
 | 
				
			||||||
 | 
						vaultShareA1 := types.NewVaultShare(testDenom1, sdk.NewDecWithPrec(11, 1))
 | 
				
			||||||
 | 
						vaultShareA2 := types.NewVaultShare(testDenom1, sdk.NewDecWithPrec(22, 1))
 | 
				
			||||||
 | 
						vaultShareB1 := types.NewVaultShare(testDenom2, sdk.NewDecWithPrec(11, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// regular add
 | 
				
			||||||
 | 
						res := vaultShareA1.Add(vaultShareA1)
 | 
				
			||||||
 | 
						s.Require().Equal(vaultShareA2, res, "sum of shares is incorrect")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// bad denom add
 | 
				
			||||||
 | 
						s.Require().Panics(func() {
 | 
				
			||||||
 | 
							vaultShareA1.Add(vaultShareB1)
 | 
				
			||||||
 | 
						}, "expected panic on sum of different denoms")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestAddVaultShares() {
 | 
				
			||||||
 | 
						one := sdk.NewDec(1)
 | 
				
			||||||
 | 
						zero := sdk.NewDec(0)
 | 
				
			||||||
 | 
						two := sdk.NewDec(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cases := []struct {
 | 
				
			||||||
 | 
							inputOne types.VaultShares
 | 
				
			||||||
 | 
							inputTwo types.VaultShares
 | 
				
			||||||
 | 
							expected types.VaultShares
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, one},
 | 
				
			||||||
 | 
									{testDenom2, one},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, one},
 | 
				
			||||||
 | 
									{testDenom2, one},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, two},
 | 
				
			||||||
 | 
									{testDenom2, two},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, zero},
 | 
				
			||||||
 | 
									{testDenom2, one},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, zero},
 | 
				
			||||||
 | 
									{testDenom2, zero},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom2, one},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, zero},
 | 
				
			||||||
 | 
									{testDenom2, zero},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									{testDenom1, zero},
 | 
				
			||||||
 | 
									{testDenom2, zero},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.VaultShares(nil),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for tcIndex, tc := range cases {
 | 
				
			||||||
 | 
							res := tc.inputOne.Add(tc.inputTwo...)
 | 
				
			||||||
 | 
							s.Require().Equal(tc.expected, res, "sum of shares is incorrect, tc #%d", tcIndex)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestFilteredZeroVaultShares() {
 | 
				
			||||||
 | 
						cases := []struct {
 | 
				
			||||||
 | 
							name     string
 | 
				
			||||||
 | 
							input    types.VaultShares
 | 
				
			||||||
 | 
							original string
 | 
				
			||||||
 | 
							expected string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "all greater than zero",
 | 
				
			||||||
 | 
								input: types.VaultShares{
 | 
				
			||||||
 | 
									{"testa", sdk.NewDec(1)},
 | 
				
			||||||
 | 
									{"testb", sdk.NewDec(2)},
 | 
				
			||||||
 | 
									{"testc", sdk.NewDec(3)},
 | 
				
			||||||
 | 
									{"testd", sdk.NewDec(4)},
 | 
				
			||||||
 | 
									{"teste", sdk.NewDec(5)},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								original: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste",
 | 
				
			||||||
 | 
								expected: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "zero share in middle",
 | 
				
			||||||
 | 
								input: types.VaultShares{
 | 
				
			||||||
 | 
									{"testa", sdk.NewDec(1)},
 | 
				
			||||||
 | 
									{"testb", sdk.NewDec(2)},
 | 
				
			||||||
 | 
									{"testc", sdk.NewDec(0)},
 | 
				
			||||||
 | 
									{"testd", sdk.NewDec(4)},
 | 
				
			||||||
 | 
									{"teste", sdk.NewDec(5)},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								original: "1.000000000000000000testa,2.000000000000000000testb,0.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste",
 | 
				
			||||||
 | 
								expected: "1.000000000000000000testa,2.000000000000000000testb,4.000000000000000000testd,5.000000000000000000teste",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "zero share end (unordered)",
 | 
				
			||||||
 | 
								input: types.VaultShares{
 | 
				
			||||||
 | 
									{"teste", sdk.NewDec(5)},
 | 
				
			||||||
 | 
									{"testc", sdk.NewDec(3)},
 | 
				
			||||||
 | 
									{"testa", sdk.NewDec(1)},
 | 
				
			||||||
 | 
									{"testd", sdk.NewDec(4)},
 | 
				
			||||||
 | 
									{"testb", sdk.NewDec(0)},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								original: "5.000000000000000000teste,3.000000000000000000testc,1.000000000000000000testa,4.000000000000000000testd,0.000000000000000000testb",
 | 
				
			||||||
 | 
								expected: "1.000000000000000000testa,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tt := range cases {
 | 
				
			||||||
 | 
							undertest := types.NewVaultShares(tt.input...)
 | 
				
			||||||
 | 
							s.Require().Equal(tt.expected, undertest.String(), "NewVaultShares must return expected results")
 | 
				
			||||||
 | 
							s.Require().Equal(tt.original, tt.input.String(), "input must be unmodified and match original")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestIsValid() {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							share      types.VaultShare
 | 
				
			||||||
 | 
							expectPass bool
 | 
				
			||||||
 | 
							msg        string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShare("mytoken", sdk.NewDec(10)),
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid shares should have passed",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShare{Denom: "BTC", Amount: sdk.NewDec(10)},
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid uppercase denom",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShare{Denom: "Bitshare", Amount: sdk.NewDec(10)},
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid mixed case denom",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShare{Denom: "btc", Amount: sdk.NewDec(-10)},
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"negative amount",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tests {
 | 
				
			||||||
 | 
							tc := tc
 | 
				
			||||||
 | 
							if tc.expectPass {
 | 
				
			||||||
 | 
								s.Require().True(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().False(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestSubVaultShare() {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							share      types.VaultShare
 | 
				
			||||||
 | 
							expectPass bool
 | 
				
			||||||
 | 
							msg        string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShare("mytoken", sdk.NewDec(20)),
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid shares should have passed",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShare("othertoken", sdk.NewDec(20)),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"denom mismatch",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShare("mytoken", sdk.NewDec(9)),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"negative amount",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaultShare := types.NewVaultShare("mytoken", sdk.NewDec(10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tests {
 | 
				
			||||||
 | 
							tc := tc
 | 
				
			||||||
 | 
							if tc.expectPass {
 | 
				
			||||||
 | 
								equal := tc.share.Sub(vaultShare)
 | 
				
			||||||
 | 
								s.Require().Equal(equal, vaultShare, tc.msg)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().Panics(func() { tc.share.Sub(vaultShare) }, tc.msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestSubVaultShares() {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							shares     types.VaultShares
 | 
				
			||||||
 | 
							expectPass bool
 | 
				
			||||||
 | 
							msg        string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShares(types.NewVaultShare("mytoken", d(10)), types.NewVaultShare("btc", d(20)), types.NewVaultShare("eth", d(30))),
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"sorted shares should have passed",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{types.NewVaultShare("mytoken", d(10)), types.NewVaultShare("btc", d(20)), types.NewVaultShare("eth", d(30))},
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"unorted shares should panic",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{types.VaultShare{Denom: "BTC", Amount: sdk.NewDec(10)}, types.NewVaultShare("eth", d(15)), types.NewVaultShare("mytoken", d(5))},
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"invalid denoms",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaultShares := types.NewVaultShares(types.NewVaultShare("btc", d(10)), types.NewVaultShare("eth", d(15)), types.NewVaultShare("mytoken", d(5)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tests {
 | 
				
			||||||
 | 
							tc := tc
 | 
				
			||||||
 | 
							if tc.expectPass {
 | 
				
			||||||
 | 
								equal := tc.shares.Sub(vaultShares...)
 | 
				
			||||||
 | 
								s.Require().Equal(equal, vaultShares, tc.msg)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().Panics(func() { tc.shares.Sub(vaultShares...) }, tc.msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestSortVaultShares() {
 | 
				
			||||||
 | 
						good := types.VaultShares{
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("mineral", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("tree", d(1)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						empty := types.VaultShares{
 | 
				
			||||||
 | 
							types.NewVaultShare("gold", d(0)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						badSort1 := types.VaultShares{
 | 
				
			||||||
 | 
							types.NewVaultShare("tree", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("mineral", d(1)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						badSort2 := types.VaultShares{ // both are after the first one, but the second and third are in the wrong order
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("tree", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("mineral", d(1)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						badAmt := types.VaultShares{
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("tree", d(0)),
 | 
				
			||||||
 | 
							types.NewVaultShare("mineral", d(1)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dup := types.VaultShares{
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("gas", d(1)),
 | 
				
			||||||
 | 
							types.NewVaultShare("mineral", d(1)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cases := []struct {
 | 
				
			||||||
 | 
							name          string
 | 
				
			||||||
 | 
							shares        types.VaultShares
 | 
				
			||||||
 | 
							before, after bool // valid before/after sort
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"valid shares", good, true, true},
 | 
				
			||||||
 | 
							{"empty shares", empty, false, false},
 | 
				
			||||||
 | 
							{"unsorted shares (1)", badSort1, false, true},
 | 
				
			||||||
 | 
							{"unsorted shares (2)", badSort2, false, true},
 | 
				
			||||||
 | 
							{"zero amount shares", badAmt, false, false},
 | 
				
			||||||
 | 
							{"duplicate shares", dup, false, false},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range cases {
 | 
				
			||||||
 | 
							s.Require().Equal(tc.before, tc.shares.IsValid(), "share validity is incorrect before sorting; %s", tc.name)
 | 
				
			||||||
 | 
							tc.shares.Sort()
 | 
				
			||||||
 | 
							s.Require().Equal(tc.after, tc.shares.IsValid(), "share validity is incorrect after sorting;  %s", tc.name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestVaultSharesValidate() {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							input        types.VaultShares
 | 
				
			||||||
 | 
							expectedPass bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{types.VaultShares{}, true},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(5)}}, true},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(5)}, types.VaultShare{testDenom2, sdk.NewDec(100000)}}, true},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(-5)}}, false},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{"BTC", sdk.NewDec(5)}}, true},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{"0BTC", sdk.NewDec(5)}}, false},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(5)}, types.VaultShare{"B", sdk.NewDec(100000)}}, false},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(5)}, types.VaultShare{testDenom2, sdk.NewDec(-100000)}}, false},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{testDenom1, sdk.NewDec(-5)}, types.VaultShare{testDenom2, sdk.NewDec(100000)}}, false},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{"BTC", sdk.NewDec(5)}, types.VaultShare{testDenom2, sdk.NewDec(100000)}}, true},
 | 
				
			||||||
 | 
							{types.VaultShares{types.VaultShare{"0BTC", sdk.NewDec(5)}, types.VaultShare{testDenom2, sdk.NewDec(100000)}}, false},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							err := tc.input.Validate()
 | 
				
			||||||
 | 
							if tc.expectedPass {
 | 
				
			||||||
 | 
								s.Require().NoError(err, "unexpected result for test case #%d, input: %v", i, tc.input)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().Error(err, "unexpected result for test case #%d, input: %v", i, tc.input)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestVaultSharesString() {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							input    types.VaultShares
 | 
				
			||||||
 | 
							expected string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{types.VaultShares{}, ""},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.VaultShares{
 | 
				
			||||||
 | 
									types.NewVaultShare("atom", sdk.NewDecWithPrec(5040000000000000000, sdk.Precision)),
 | 
				
			||||||
 | 
									types.NewVaultShare("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision)),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								"5.040000000000000000atom,0.004000000000000000stake",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							out := tc.input.String()
 | 
				
			||||||
 | 
							s.Require().Equal(tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestNewVaultSharesWithIsValid() {
 | 
				
			||||||
 | 
						fake1 := append(types.NewVaultShares(types.NewVaultShare("mytoken", d(10))), types.VaultShare{Denom: "10BTC", Amount: sdk.NewDec(10)})
 | 
				
			||||||
 | 
						fake2 := append(types.NewVaultShares(types.NewVaultShare("mytoken", d(10))), types.VaultShare{Denom: "BTC", Amount: sdk.NewDec(-10)})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							share      types.VaultShares
 | 
				
			||||||
 | 
							expectPass bool
 | 
				
			||||||
 | 
							msg        string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShares(types.NewVaultShare("mytoken", d(10))),
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid shares should have passed",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								fake1,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"invalid denoms",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								fake2,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"negative amount",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tests {
 | 
				
			||||||
 | 
							tc := tc
 | 
				
			||||||
 | 
							if tc.expectPass {
 | 
				
			||||||
 | 
								s.Require().True(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().False(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *vaultShareTestSuite) TestVaultShares_AddVaultShareWithIsValid() {
 | 
				
			||||||
 | 
						lengthTestVaultShares := types.NewVaultShares().Add(types.NewVaultShare("mytoken", d(10))).Add(types.VaultShare{Denom: "BTC", Amount: sdk.NewDec(10)})
 | 
				
			||||||
 | 
						s.Require().Equal(2, len(lengthTestVaultShares), "should be 2")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							share      types.VaultShares
 | 
				
			||||||
 | 
							expectPass bool
 | 
				
			||||||
 | 
							msg        string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShares().Add(types.NewVaultShare("mytoken", d(10))),
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								"valid shares should have passed",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShares().Add(types.NewVaultShare("mytoken", d(10))).Add(types.VaultShare{Denom: "0BTC", Amount: sdk.NewDec(10)}),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"invalid denoms",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								types.NewVaultShares().Add(types.NewVaultShare("mytoken", d(10))).Add(types.VaultShare{Denom: "BTC", Amount: sdk.NewDec(-10)}),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								"negative amount",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tests {
 | 
				
			||||||
 | 
							tc := tc
 | 
				
			||||||
 | 
							if tc.expectPass {
 | 
				
			||||||
 | 
								s.Require().True(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								s.Require().False(tc.share.IsValid(), tc.msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -74,6 +74,7 @@ var xxx_messageInfo_MsgDeposit proto.InternalMessageInfo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// MsgDepositResponse defines the Msg/Deposit response type.
 | 
					// MsgDepositResponse defines the Msg/Deposit response type.
 | 
				
			||||||
type MsgDepositResponse struct {
 | 
					type MsgDepositResponse struct {
 | 
				
			||||||
 | 
						Shares VaultShare `protobuf:"bytes,1,opt,name=shares,proto3" json:"shares"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *MsgDepositResponse) Reset()         { *m = MsgDepositResponse{} }
 | 
					func (m *MsgDepositResponse) Reset()         { *m = MsgDepositResponse{} }
 | 
				
			||||||
@ -109,6 +110,13 @@ func (m *MsgDepositResponse) XXX_DiscardUnknown() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var xxx_messageInfo_MsgDepositResponse proto.InternalMessageInfo
 | 
					var xxx_messageInfo_MsgDepositResponse proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *MsgDepositResponse) GetShares() VaultShare {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Shares
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return VaultShare{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MsgWithdraw represents a message for withdrawing liquidity from a vault
 | 
					// MsgWithdraw represents a message for withdrawing liquidity from a vault
 | 
				
			||||||
type MsgWithdraw struct {
 | 
					type MsgWithdraw struct {
 | 
				
			||||||
	// from represents the address we are withdrawing for
 | 
						// from represents the address we are withdrawing for
 | 
				
			||||||
@ -153,6 +161,7 @@ var xxx_messageInfo_MsgWithdraw proto.InternalMessageInfo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
					// MsgWithdrawResponse defines the Msg/Withdraw response type.
 | 
				
			||||||
type MsgWithdrawResponse struct {
 | 
					type MsgWithdrawResponse struct {
 | 
				
			||||||
 | 
						Shares VaultShare `protobuf:"bytes,1,opt,name=shares,proto3" json:"shares"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *MsgWithdrawResponse) Reset()         { *m = MsgWithdrawResponse{} }
 | 
					func (m *MsgWithdrawResponse) Reset()         { *m = MsgWithdrawResponse{} }
 | 
				
			||||||
@ -188,6 +197,13 @@ func (m *MsgWithdrawResponse) XXX_DiscardUnknown() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var xxx_messageInfo_MsgWithdrawResponse proto.InternalMessageInfo
 | 
					var xxx_messageInfo_MsgWithdrawResponse proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *MsgWithdrawResponse) GetShares() VaultShare {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Shares
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return VaultShare{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	proto.RegisterType((*MsgDeposit)(nil), "kava.earn.v1beta1.MsgDeposit")
 | 
						proto.RegisterType((*MsgDeposit)(nil), "kava.earn.v1beta1.MsgDeposit")
 | 
				
			||||||
	proto.RegisterType((*MsgDepositResponse)(nil), "kava.earn.v1beta1.MsgDepositResponse")
 | 
						proto.RegisterType((*MsgDepositResponse)(nil), "kava.earn.v1beta1.MsgDepositResponse")
 | 
				
			||||||
@ -198,30 +214,33 @@ func init() {
 | 
				
			|||||||
func init() { proto.RegisterFile("kava/earn/v1beta1/tx.proto", fileDescriptor_2e9dcf48a3fa0009) }
 | 
					func init() { proto.RegisterFile("kava/earn/v1beta1/tx.proto", fileDescriptor_2e9dcf48a3fa0009) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_2e9dcf48a3fa0009 = []byte{
 | 
					var fileDescriptor_2e9dcf48a3fa0009 = []byte{
 | 
				
			||||||
	// 367 bytes of a gzipped FileDescriptorProto
 | 
						// 404 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x4e, 0x2c, 0x4b,
 | 
						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,
 | 
						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,
 | 
						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,
 | 
						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,
 | 
						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, 0x44, 0x95, 0x9a, 0x19, 0xb9, 0xb8,
 | 
						0x2f, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0xd1, 0x07, 0x62, 0x41, 0x45, 0x65, 0x31, 0xed, 0x2f, 0x4b,
 | 
				
			||||||
	0x7c, 0x8b, 0xd3, 0x5d, 0x52, 0x0b, 0xf2, 0x8b, 0x33, 0x4b, 0x84, 0xcc, 0xb8, 0x38, 0x53, 0x20,
 | 
						0x2c, 0xcd, 0x29, 0x81, 0x48, 0x2b, 0x35, 0x33, 0x72, 0x71, 0xf9, 0x16, 0xa7, 0xbb, 0xa4, 0x16,
 | 
				
			||||||
	0xcc, 0xfc, 0x22, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x4e, 0x27, 0x89, 0x4b, 0x5b, 0x74, 0x45, 0xa0,
 | 
						0xe4, 0x17, 0x67, 0x96, 0x08, 0x99, 0x71, 0x71, 0xa6, 0x40, 0x98, 0xf9, 0x45, 0x12, 0x8c, 0x0a,
 | 
				
			||||||
	0x36, 0x39, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, 0x21,
 | 
						0x8c, 0x1a, 0x9c, 0x4e, 0x12, 0x97, 0xb6, 0xe8, 0x8a, 0x40, 0x1d, 0xe2, 0x98, 0x92, 0x52, 0x94,
 | 
				
			||||||
	0x94, 0x0a, 0x99, 0x73, 0xb1, 0x25, 0xe6, 0xe6, 0x97, 0xe6, 0x95, 0x48, 0x30, 0x29, 0x30, 0x6a,
 | 
						0x5a, 0x5c, 0x1c, 0x5c, 0x52, 0x94, 0x99, 0x97, 0x1e, 0x84, 0x50, 0x2a, 0x64, 0xce, 0xc5, 0x96,
 | 
				
			||||||
	0x70, 0x1b, 0x49, 0xea, 0x41, 0x75, 0x80, 0x5c, 0x03, 0x73, 0xbd, 0x9e, 0x73, 0x7e, 0x66, 0x9e,
 | 
						0x98, 0x9b, 0x5f, 0x9a, 0x57, 0x22, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa9, 0x07, 0xd5,
 | 
				
			||||||
	0x13, 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0xe5, 0x56, 0x2c, 0x1d, 0x0b, 0xe4, 0x19, 0x94,
 | 
						0x01, 0x72, 0x2c, 0xcc, 0x73, 0x7a, 0xce, 0xf9, 0x99, 0x79, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33,
 | 
				
			||||||
	0x44, 0xb8, 0x84, 0x10, 0x8e, 0x08, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x55, 0xaa, 0xe2,
 | 
						0x04, 0x41, 0x95, 0x5b, 0xb1, 0x74, 0x2c, 0x90, 0x67, 0x50, 0x0a, 0xe4, 0x12, 0x42, 0x38, 0x22,
 | 
				
			||||||
	0xe2, 0xf6, 0x2d, 0x4e, 0x0f, 0xcf, 0x2c, 0xc9, 0x48, 0x29, 0x4a, 0x2c, 0x17, 0xd2, 0xe1, 0x62,
 | 
						0x28, 0xb5, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, 0x9a, 0x8b, 0xad, 0x38, 0x23, 0xb1, 0x28,
 | 
				
			||||||
	0x49, 0x2b, 0xca, 0xcf, 0x25, 0xe8, 0x2c, 0xb0, 0x2a, 0x4a, 0x5d, 0x24, 0xca, 0x25, 0x8c, 0x64,
 | 
						0xb5, 0x18, 0xec, 0x12, 0x6e, 0x23, 0x59, 0x3d, 0x8c, 0xf0, 0xd2, 0x0b, 0x03, 0xf9, 0x25, 0x18,
 | 
				
			||||||
	0x37, 0xcc, 0x49, 0x46, 0xab, 0x18, 0xb9, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0xfc, 0xb9, 0xd8, 0x61,
 | 
						0xa4, 0x0a, 0x66, 0x30, 0x44, 0x8b, 0x52, 0x15, 0x17, 0xb7, 0x6f, 0x71, 0x7a, 0x78, 0x66, 0x49,
 | 
				
			||||||
	0x41, 0x26, 0xab, 0x87, 0x11, 0x4d, 0x7a, 0x08, 0xcf, 0x48, 0xa9, 0xe2, 0x95, 0x86, 0x19, 0x2c,
 | 
						0x46, 0x4a, 0x51, 0x62, 0xb9, 0x90, 0x0e, 0x17, 0x4b, 0x5a, 0x51, 0x7e, 0x2e, 0x41, 0x3f, 0x81,
 | 
				
			||||||
	0x14, 0xc4, 0xc5, 0x01, 0xf7, 0xa8, 0x1c, 0x76, 0x2d, 0x30, 0x79, 0x29, 0x35, 0xfc, 0xf2, 0x30,
 | 
						0x55, 0x51, 0xea, 0x9d, 0x20, 0x2e, 0x61, 0x24, 0xbb, 0xa9, 0xe2, 0x1f, 0xa3, 0x55, 0x8c, 0x5c,
 | 
				
			||||||
	0x33, 0x9d, 0x1c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6,
 | 
						0xcc, 0xbe, 0xc5, 0xe9, 0x42, 0xfe, 0x5c, 0xec, 0xb0, 0xc8, 0xc2, 0xa6, 0x1f, 0x11, 0x8c, 0x52,
 | 
				
			||||||
	0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x2d, 0x3d,
 | 
						0xaa, 0x78, 0xa5, 0xe1, 0xae, 0x0a, 0xe2, 0xe2, 0x80, 0x87, 0x92, 0x1c, 0x76, 0x2d, 0x30, 0x79,
 | 
				
			||||||
	0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x64, 0x96, 0x6e, 0x4e, 0x62, 0x52,
 | 
						0x29, 0x35, 0xfc, 0xf2, 0x30, 0x33, 0x9d, 0x1c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e,
 | 
				
			||||||
	0x31, 0x98, 0xa5, 0x5f, 0x01, 0x49, 0x8c, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x44,
 | 
						0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58,
 | 
				
			||||||
	0x62, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x48, 0xd0, 0x39, 0xa6, 0x02, 0x00, 0x00,
 | 
						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,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
@ -404,6 +423,16 @@ func (m *MsgDepositResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	_ = i
 | 
						_ = i
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size, err := m.Shares.MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i -= size
 | 
				
			||||||
 | 
							i = encodeVarintTx(dAtA, i, uint64(size))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						i--
 | 
				
			||||||
 | 
						dAtA[i] = 0xa
 | 
				
			||||||
	return len(dAtA) - i, nil
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -467,6 +496,16 @@ func (m *MsgWithdrawResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	_ = i
 | 
						_ = i
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size, err := m.Shares.MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i -= size
 | 
				
			||||||
 | 
							i = encodeVarintTx(dAtA, i, uint64(size))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						i--
 | 
				
			||||||
 | 
						dAtA[i] = 0xa
 | 
				
			||||||
	return len(dAtA) - i, nil
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -502,6 +541,8 @@ func (m *MsgDepositResponse) Size() (n int) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
 | 
						l = m.Shares.Size()
 | 
				
			||||||
 | 
						n += 1 + l + sovTx(uint64(l))
 | 
				
			||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -526,6 +567,8 @@ func (m *MsgWithdrawResponse) Size() (n int) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
 | 
						l = m.Shares.Size()
 | 
				
			||||||
 | 
						n += 1 + l + sovTx(uint64(l))
 | 
				
			||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -679,6 +722,39 @@ func (m *MsgDepositResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			return fmt.Errorf("proto: MsgDepositResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
								return fmt.Errorf("proto: MsgDepositResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		switch fieldNum {
 | 
							switch fieldNum {
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								if wireType != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Shares", wireType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var msglen int
 | 
				
			||||||
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
									if shift >= 64 {
 | 
				
			||||||
 | 
										return ErrIntOverflowTx
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if iNdEx >= l {
 | 
				
			||||||
 | 
										return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									b := dAtA[iNdEx]
 | 
				
			||||||
 | 
									iNdEx++
 | 
				
			||||||
 | 
									msglen |= int(b&0x7F) << shift
 | 
				
			||||||
 | 
									if b < 0x80 {
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if msglen < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthTx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								postIndex := iNdEx + msglen
 | 
				
			||||||
 | 
								if postIndex < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthTx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if postIndex > l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := m.Shares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								iNdEx = postIndex
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			iNdEx = preIndex
 | 
								iNdEx = preIndex
 | 
				
			||||||
			skippy, err := skipTx(dAtA[iNdEx:])
 | 
								skippy, err := skipTx(dAtA[iNdEx:])
 | 
				
			||||||
@ -844,6 +920,39 @@ func (m *MsgWithdrawResponse) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			return fmt.Errorf("proto: MsgWithdrawResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
								return fmt.Errorf("proto: MsgWithdrawResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		switch fieldNum {
 | 
							switch fieldNum {
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								if wireType != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Shares", wireType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var msglen int
 | 
				
			||||||
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
									if shift >= 64 {
 | 
				
			||||||
 | 
										return ErrIntOverflowTx
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if iNdEx >= l {
 | 
				
			||||||
 | 
										return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									b := dAtA[iNdEx]
 | 
				
			||||||
 | 
									iNdEx++
 | 
				
			||||||
 | 
									msglen |= int(b&0x7F) << shift
 | 
				
			||||||
 | 
									if b < 0x80 {
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if msglen < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthTx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								postIndex := iNdEx + msglen
 | 
				
			||||||
 | 
								if postIndex < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthTx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if postIndex > l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := m.Shares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								iNdEx = postIndex
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			iNdEx = preIndex
 | 
								iNdEx = preIndex
 | 
				
			||||||
			skippy, err := skipTx(dAtA[iNdEx:])
 | 
								skippy, err := skipTx(dAtA[iNdEx:])
 | 
				
			||||||
 | 
				
			|||||||
@ -8,32 +8,15 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewVaultRecord returns a new VaultRecord with 0 supply.
 | 
					// NewVaultRecord returns a new VaultRecord with 0 supply.
 | 
				
			||||||
func NewVaultRecord(vaultDenom string) VaultRecord {
 | 
					func NewVaultRecord(vaultDenom string, amount sdk.Dec) VaultRecord {
 | 
				
			||||||
	return VaultRecord{
 | 
						return VaultRecord{
 | 
				
			||||||
		Denom:       vaultDenom,
 | 
							TotalShares: NewVaultShare(vaultDenom, amount),
 | 
				
			||||||
		TotalSupply: sdk.NewCoin(vaultDenom, sdk.ZeroInt()),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate returns an error if a VaultRecord is invalid.
 | 
					// Validate returns an error if a VaultRecord is invalid.
 | 
				
			||||||
func (vr *VaultRecord) Validate() error {
 | 
					func (vr *VaultRecord) Validate() error {
 | 
				
			||||||
	if err := sdk.ValidateDenom(vr.Denom); err != nil {
 | 
						return vr.TotalShares.Validate()
 | 
				
			||||||
		return sdkerrors.Wrap(ErrInvalidVaultDenom, err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if vr.TotalSupply.Denom != vr.Denom {
 | 
					 | 
				
			||||||
		return fmt.Errorf(
 | 
					 | 
				
			||||||
			"total supply denom %v does not match vault record denom %v",
 | 
					 | 
				
			||||||
			vr.TotalSupply.Denom,
 | 
					 | 
				
			||||||
			vr.Denom,
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := vr.TotalSupply.Validate(); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("vault total supply is invalid: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VaultRecords is a slice of VaultRecord.
 | 
					// VaultRecords is a slice of VaultRecord.
 | 
				
			||||||
@ -48,11 +31,11 @@ func (vrs VaultRecords) Validate() error {
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if denoms[vr.Denom] {
 | 
							if denoms[vr.TotalShares.Denom] {
 | 
				
			||||||
			return fmt.Errorf("duplicate vault denom %s", vr.Denom)
 | 
								return fmt.Errorf("duplicate vault denom %s", vr.TotalShares.Denom)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		denoms[vr.Denom] = true
 | 
							denoms[vr.TotalShares.Denom] = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@ -60,10 +43,10 @@ func (vrs VaultRecords) Validate() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewVaultShareRecord returns a new VaultShareRecord with the provided supplied
 | 
					// NewVaultShareRecord returns a new VaultShareRecord with the provided supplied
 | 
				
			||||||
// coins.
 | 
					// coins.
 | 
				
			||||||
func NewVaultShareRecord(depositor sdk.AccAddress, supplied ...sdk.Coin) VaultShareRecord {
 | 
					func NewVaultShareRecord(depositor sdk.AccAddress, shares VaultShares) VaultShareRecord {
 | 
				
			||||||
	return VaultShareRecord{
 | 
						return VaultShareRecord{
 | 
				
			||||||
		Depositor: depositor,
 | 
							Depositor: depositor,
 | 
				
			||||||
		AmountSupplied: sdk.NewCoins(supplied...),
 | 
							Shares:    shares,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,8 +56,8 @@ func (vsr VaultShareRecord) Validate() error {
 | 
				
			|||||||
		return fmt.Errorf("depositor is empty")
 | 
							return fmt.Errorf("depositor is empty")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := vsr.AmountSupplied.Validate(); err != nil {
 | 
						if err := vsr.Shares.Validate(); err != nil {
 | 
				
			||||||
		return fmt.Errorf("invalid vault share record amount supplied: %w", err)
 | 
							return fmt.Errorf("invalid vault share record shares: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 | 
				
			|||||||
@ -6,8 +6,8 @@ package types
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	fmt "fmt"
 | 
						fmt "fmt"
 | 
				
			||||||
	_ "github.com/cosmos/cosmos-proto"
 | 
						_ "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_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
 | 
				
			||||||
	types "github.com/cosmos/cosmos-sdk/types"
 | 
					 | 
				
			||||||
	_ "github.com/gogo/protobuf/gogoproto"
 | 
						_ "github.com/gogo/protobuf/gogoproto"
 | 
				
			||||||
	proto "github.com/gogo/protobuf/proto"
 | 
						proto "github.com/gogo/protobuf/proto"
 | 
				
			||||||
	io "io"
 | 
						io "io"
 | 
				
			||||||
@ -82,15 +82,10 @@ func (m *AllowedVault) GetVaultStrategy() StrategyType {
 | 
				
			|||||||
	return STRATEGY_TYPE_UNSPECIFIED
 | 
						return STRATEGY_TYPE_UNSPECIFIED
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VaultRecord is the state of a vault and is used to store the state of a
 | 
					// VaultRecord is the state of a vault.
 | 
				
			||||||
// vault.
 | 
					 | 
				
			||||||
type VaultRecord struct {
 | 
					type VaultRecord struct {
 | 
				
			||||||
	// Denom is the only supported denomination of the vault for deposits and
 | 
						// TotalShares is the total distributed number of shares in the vault.
 | 
				
			||||||
	// withdrawals.
 | 
						TotalShares VaultShare `protobuf:"bytes,1,opt,name=total_shares,json=totalShares,proto3" json:"total_shares"`
 | 
				
			||||||
	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
 | 
					 | 
				
			||||||
	// TotalSupply is the total supply of the vault, denominated **only** in the
 | 
					 | 
				
			||||||
	// user deposit/withdrawal denom, must be the same as the Denom field.
 | 
					 | 
				
			||||||
	TotalSupply types.Coin `protobuf:"bytes,2,opt,name=total_supply,json=totalSupply,proto3" json:"total_supply"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *VaultRecord) Reset()         { *m = VaultRecord{} }
 | 
					func (m *VaultRecord) Reset()         { *m = VaultRecord{} }
 | 
				
			||||||
@ -126,27 +121,19 @@ func (m *VaultRecord) XXX_DiscardUnknown() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var xxx_messageInfo_VaultRecord proto.InternalMessageInfo
 | 
					var xxx_messageInfo_VaultRecord proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *VaultRecord) GetDenom() string {
 | 
					func (m *VaultRecord) GetTotalShares() VaultShare {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Denom
 | 
							return m.TotalShares
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ""
 | 
						return VaultShare{}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *VaultRecord) GetTotalSupply() types.Coin {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.TotalSupply
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return types.Coin{}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VaultShareRecord defines the vault shares owned by a depositor.
 | 
					// VaultShareRecord defines the vault shares owned by a depositor.
 | 
				
			||||||
type VaultShareRecord struct {
 | 
					type VaultShareRecord struct {
 | 
				
			||||||
	// Depositor represents the owner of the shares
 | 
						// Depositor represents the owner of the shares
 | 
				
			||||||
	Depositor github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=depositor,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"depositor,omitempty"`
 | 
						Depositor github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=depositor,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"depositor,omitempty"`
 | 
				
			||||||
	// AmountSupplied represents the total amount a depositor has supplied to the
 | 
						// Shares represent the vault shares owned by the depositor.
 | 
				
			||||||
	// vault. The vault is determined by the coin denom.
 | 
						Shares VaultShares `protobuf:"bytes,2,rep,name=shares,proto3,castrepeated=VaultShares" json:"shares"`
 | 
				
			||||||
	AmountSupplied github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amount_supplied,json=amountSupplied,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount_supplied"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *VaultShareRecord) Reset()         { *m = VaultShareRecord{} }
 | 
					func (m *VaultShareRecord) Reset()         { *m = VaultShareRecord{} }
 | 
				
			||||||
@ -189,50 +176,97 @@ func (m *VaultShareRecord) GetDepositor() github_com_cosmos_cosmos_sdk_types.Acc
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *VaultShareRecord) GetAmountSupplied() github_com_cosmos_cosmos_sdk_types.Coins {
 | 
					func (m *VaultShareRecord) GetShares() VaultShares {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.AmountSupplied
 | 
							return m.Shares
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VaultShare defines shares of a vault owned by a depositor.
 | 
				
			||||||
 | 
					type VaultShare struct {
 | 
				
			||||||
 | 
						Denom  string                                 `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
 | 
				
			||||||
 | 
						Amount github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"amount"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) Reset()      { *m = VaultShare{} }
 | 
				
			||||||
 | 
					func (*VaultShare) ProtoMessage() {}
 | 
				
			||||||
 | 
					func (*VaultShare) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_884eb89509fbdc04, []int{3}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return m.Unmarshal(b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						if deterministic {
 | 
				
			||||||
 | 
							return xxx_messageInfo_VaultShare.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							b = b[:cap(b)]
 | 
				
			||||||
 | 
							n, err := m.MarshalToSizedBuffer(b)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return b[:n], nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_VaultShare.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) XXX_Size() int {
 | 
				
			||||||
 | 
						return m.Size()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_VaultShare.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_VaultShare proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) GetDenom() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Denom
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	proto.RegisterType((*AllowedVault)(nil), "kava.earn.v1beta1.AllowedVault")
 | 
						proto.RegisterType((*AllowedVault)(nil), "kava.earn.v1beta1.AllowedVault")
 | 
				
			||||||
	proto.RegisterType((*VaultRecord)(nil), "kava.earn.v1beta1.VaultRecord")
 | 
						proto.RegisterType((*VaultRecord)(nil), "kava.earn.v1beta1.VaultRecord")
 | 
				
			||||||
	proto.RegisterType((*VaultShareRecord)(nil), "kava.earn.v1beta1.VaultShareRecord")
 | 
						proto.RegisterType((*VaultShareRecord)(nil), "kava.earn.v1beta1.VaultShareRecord")
 | 
				
			||||||
 | 
						proto.RegisterType((*VaultShare)(nil), "kava.earn.v1beta1.VaultShare")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() { proto.RegisterFile("kava/earn/v1beta1/vault.proto", fileDescriptor_884eb89509fbdc04) }
 | 
					func init() { proto.RegisterFile("kava/earn/v1beta1/vault.proto", fileDescriptor_884eb89509fbdc04) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_884eb89509fbdc04 = []byte{
 | 
					var fileDescriptor_884eb89509fbdc04 = []byte{
 | 
				
			||||||
	// 417 bytes of a gzipped FileDescriptorProto
 | 
						// 445 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xbd, 0x8e, 0xd3, 0x40,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x31, 0x8f, 0xd3, 0x30,
 | 
				
			||||||
	0x10, 0xc7, 0xed, 0xe3, 0x43, 0xba, 0x4d, 0x08, 0x60, 0xae, 0xc8, 0x9d, 0x84, 0x6d, 0xa5, 0x40,
 | 
						0x18, 0x4d, 0x8e, 0xa3, 0x52, 0x9d, 0x72, 0x82, 0xdc, 0x0d, 0xc7, 0x49, 0x4d, 0xa2, 0x0c, 0xa8,
 | 
				
			||||||
	0x69, 0xbc, 0xe6, 0x8e, 0x17, 0x20, 0x46, 0x42, 0xd4, 0x36, 0xa2, 0xa0, 0x89, 0xd6, 0xde, 0xc5,
 | 
						0x4b, 0x12, 0xb5, 0x6c, 0x88, 0x81, 0x46, 0x55, 0x85, 0x18, 0xd3, 0xc2, 0xc0, 0x52, 0x39, 0x8e,
 | 
				
			||||||
	0xb1, 0x62, 0x7b, 0x2c, 0xef, 0x3a, 0xe0, 0xb7, 0xe0, 0x39, 0xa8, 0x79, 0x88, 0x94, 0x11, 0x15,
 | 
						0x49, 0xab, 0x26, 0x71, 0x14, 0xbb, 0x85, 0x2c, 0xfc, 0x06, 0x46, 0x46, 0x66, 0xe6, 0xfe, 0x06,
 | 
				
			||||||
	0x55, 0x40, 0xc9, 0x0b, 0x50, 0x53, 0xa1, 0xfd, 0x48, 0x40, 0x8a, 0x40, 0x54, 0xde, 0x9d, 0x99,
 | 
						0xd4, 0xb1, 0xea, 0x84, 0x18, 0x0a, 0x6a, 0xff, 0x05, 0x13, 0xb2, 0xe3, 0x12, 0xa4, 0x82, 0xb8,
 | 
				
			||||||
	0xff, 0xfc, 0xfe, 0x33, 0x5e, 0xf4, 0x78, 0x49, 0x56, 0x24, 0x64, 0xa4, 0xad, 0xc3, 0xd5, 0x75,
 | 
						0x29, 0xf6, 0xfb, 0xde, 0x7b, 0xdf, 0xfb, 0xf2, 0x19, 0xb4, 0xe7, 0x70, 0x09, 0x3d, 0x0c, 0x8b,
 | 
				
			||||||
	0xca, 0x04, 0xb9, 0x0e, 0x57, 0xa4, 0x2b, 0x05, 0x6e, 0x5a, 0x10, 0xe0, 0x3c, 0x94, 0x69, 0x2c,
 | 
						0xcc, 0x5b, 0x76, 0x43, 0xcc, 0x60, 0xd7, 0x5b, 0xc2, 0x45, 0xc2, 0xdc, 0xbc, 0x20, 0x8c, 0xe8,
 | 
				
			||||||
	0xd3, 0xd8, 0xa4, 0xaf, 0x2e, 0x33, 0xe0, 0x15, 0xf0, 0xb9, 0x2a, 0x08, 0xf5, 0x45, 0x57, 0x5f,
 | 
						0x0f, 0x78, 0xd9, 0xe5, 0x65, 0x57, 0x96, 0x6f, 0x1e, 0x22, 0x42, 0x53, 0x42, 0x27, 0x82, 0xe0,
 | 
				
			||||||
	0xb9, 0xfa, 0x16, 0xa6, 0x84, 0xb3, 0x63, 0xbb, 0x0c, 0x8a, 0xda, 0xe4, 0x2f, 0x72, 0xc8, 0x41,
 | 
						0x55, 0x97, 0x8a, 0x7d, 0x63, 0x54, 0x37, 0x2f, 0x84, 0x14, 0xff, 0xb6, 0x43, 0x64, 0x96, 0xc9,
 | 
				
			||||||
	0xeb, 0xe4, 0xc9, 0x44, 0xfd, 0x53, 0x0b, 0x5c, 0xb4, 0x44, 0xb0, 0xbc, 0xd7, 0x15, 0x93, 0x12,
 | 
						0xfa, 0x55, 0x4c, 0x62, 0x52, 0xe9, 0xf8, 0x49, 0xa2, 0xd6, 0x69, 0x04, 0xca, 0x0a, 0xc8, 0x70,
 | 
				
			||||||
	0x0d, 0x67, 0x65, 0x09, 0xef, 0x19, 0x7d, 0x23, 0xbd, 0x39, 0x17, 0xe8, 0x0e, 0x65, 0x35, 0x54,
 | 
						0x5c, 0x56, 0x0c, 0x3b, 0x01, 0xad, 0x7e, 0x92, 0x90, 0xb7, 0x38, 0x7a, 0xc5, 0xb3, 0xe9, 0x57,
 | 
				
			||||||
	0x63, 0xdb, 0xb7, 0xa7, 0xe7, 0xb1, 0xbe, 0x38, 0x2f, 0xd1, 0x48, 0x59, 0x9f, 0x1f, 0xd4, 0xe3,
 | 
						0xe0, 0x6e, 0x84, 0x33, 0x92, 0x5e, 0xab, 0x96, 0xda, 0x69, 0x06, 0xd5, 0x45, 0x1f, 0x82, 0x0b,
 | 
				
			||||||
	0x33, 0xdf, 0x9e, 0x8e, 0x6e, 0x3c, 0x7c, 0x32, 0x04, 0x4e, 0x4c, 0xc9, 0xeb, 0xbe, 0x61, 0xf1,
 | 
						0x11, 0x7d, 0x72, 0x54, 0x5f, 0x9f, 0x59, 0x6a, 0xe7, 0xa2, 0x67, 0xba, 0x27, 0x43, 0xb8, 0x23,
 | 
				
			||||||
	0x3d, 0x25, 0x3b, 0x84, 0x26, 0x39, 0x1a, 0x28, 0x4c, 0xcc, 0x32, 0x68, 0xe9, 0x5f, 0x60, 0x11,
 | 
						0x49, 0x19, 0x97, 0x39, 0x0e, 0xee, 0x09, 0xd9, 0x11, 0xb2, 0x5f, 0x02, 0x4d, 0xb4, 0x09, 0x30,
 | 
				
			||||||
	0x1a, 0x0a, 0x10, 0xa4, 0x9c, 0xf3, 0xae, 0x69, 0x4a, 0x8d, 0x1a, 0xdc, 0x5c, 0x62, 0xb3, 0x0f,
 | 
						0x22, 0x45, 0xa4, 0x0f, 0x41, 0x8b, 0x11, 0x06, 0x93, 0x09, 0x9d, 0xc2, 0x02, 0x53, 0xd1, 0x53,
 | 
				
			||||||
	0xb9, 0x81, 0x23, 0xec, 0x05, 0x14, 0x75, 0x74, 0x7b, 0xbd, 0xf5, 0xac, 0x78, 0xa0, 0x44, 0x89,
 | 
						0xeb, 0xb5, 0xff, 0x62, 0x2a, 0x54, 0x23, 0xce, 0xf2, 0xcf, 0xd7, 0x3b, 0x53, 0x09, 0x34, 0x21,
 | 
				
			||||||
	0xd2, 0x4c, 0x7e, 0xd8, 0xe8, 0x81, 0x22, 0x25, 0x0b, 0xd2, 0x32, 0x83, 0x7b, 0x87, 0xce, 0x29,
 | 
						0x14, 0x08, 0xb5, 0xbf, 0xa8, 0xe0, 0x7e, 0xcd, 0x90, 0xe6, 0x6f, 0x40, 0x33, 0xc2, 0x39, 0xa1,
 | 
				
			||||||
	0x6b, 0x80, 0x17, 0x02, 0x5a, 0x85, 0x1c, 0x46, 0xaf, 0x7e, 0x6e, 0xbd, 0x20, 0x2f, 0xc4, 0xa2,
 | 
						0x33, 0x46, 0x0a, 0xe1, 0xdc, 0xf2, 0x9f, 0xff, 0xdc, 0x99, 0x4e, 0x3c, 0x63, 0xd3, 0x45, 0xe8,
 | 
				
			||||||
	0x4b, 0x71, 0x06, 0x95, 0xd9, 0xb9, 0xf9, 0x04, 0x9c, 0x2e, 0x43, 0xd1, 0x37, 0x8c, 0xe3, 0x59,
 | 
						0x22, 0x92, 0xca, 0x3f, 0x2c, 0x3f, 0x0e, 0x8d, 0xe6, 0x1e, 0x2b, 0x73, 0x4c, 0xdd, 0x3e, 0x42,
 | 
				
			||||||
	0x96, 0xcd, 0x28, 0x6d, 0x19, 0xe7, 0x5f, 0x3e, 0x07, 0x8f, 0x8c, 0x13, 0x13, 0x89, 0x7a, 0xc1,
 | 
						0xfd, 0x28, 0x2a, 0x30, 0xa5, 0xdb, 0x95, 0x73, 0x29, 0xf7, 0x20, 0x11, 0xbf, 0x64, 0x98, 0x06,
 | 
				
			||||||
	0x78, 0xfc, 0xbb, 0xb5, 0x23, 0xd0, 0x7d, 0x52, 0x41, 0x57, 0x0b, 0x3d, 0x41, 0xc1, 0xe8, 0xf8,
 | 
						0xb5, 0xb5, 0xfe, 0x02, 0x34, 0x64, 0xfc, 0x33, 0xeb, 0xce, 0xff, 0xe3, 0x5f, 0xf2, 0xf8, 0x9f,
 | 
				
			||||||
	0xcc, 0xbf, 0xf5, 0xef, 0x19, 0x9e, 0xca, 0x19, 0x3e, 0x7d, 0xf3, 0xa6, 0xff, 0x61, 0x46, 0x0a,
 | 
						0xbf, 0x9b, 0x5a, 0x8d, 0xd1, 0x40, 0x3a, 0xd8, 0xef, 0x01, 0xa8, 0xe1, 0x7f, 0xec, 0x62, 0x0c,
 | 
				
			||||||
	0x78, 0x3c, 0xd2, 0x8c, 0xc4, 0x20, 0xa2, 0xe7, 0xeb, 0x9d, 0x6b, 0x6f, 0x76, 0xae, 0xfd, 0x7d,
 | 
						0x1a, 0x30, 0x25, 0x8b, 0x8c, 0x89, 0x1d, 0x34, 0xfd, 0xa7, 0xdc, 0xf0, 0xdb, 0xce, 0x7c, 0x74,
 | 
				
			||||||
	0xe7, 0xda, 0x1f, 0xf7, 0xae, 0xb5, 0xd9, 0xbb, 0xd6, 0xd7, 0xbd, 0x6b, 0xbd, 0x7d, 0xf2, 0x47,
 | 
						0x8b, 0xc1, 0x06, 0x18, 0x6d, 0x57, 0x0e, 0x90, 0x13, 0x0d, 0x30, 0x0a, 0xa4, 0xd7, 0x93, 0xf3,
 | 
				
			||||||
	0x4f, 0xf9, 0xbf, 0x82, 0x92, 0xa4, 0x5c, 0x9d, 0xc2, 0x0f, 0xfa, 0x71, 0xa8, 0xbe, 0xe9, 0x5d,
 | 
						0x8f, 0x9f, 0x4c, 0xc5, 0x7f, 0xb6, 0xde, 0x1b, 0xea, 0x66, 0x6f, 0xa8, 0x3f, 0xf6, 0x86, 0xfa,
 | 
				
			||||||
	0xf5, 0x24, 0x9e, 0xfd, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x80, 0xa4, 0xff, 0xb9, 0x02, 0x00,
 | 
						0xe1, 0x60, 0x28, 0x9b, 0x83, 0xa1, 0x7c, 0x3d, 0x18, 0xca, 0xeb, 0x3f, 0xdd, 0xf9, 0x7c, 0x4e,
 | 
				
			||||||
	0x00,
 | 
						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,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *AllowedVault) Marshal() (dAtA []byte, err error) {
 | 
					func (m *AllowedVault) Marshal() (dAtA []byte, err error) {
 | 
				
			||||||
@ -291,7 +325,7 @@ func (m *VaultRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		size, err := m.TotalSupply.MarshalToSizedBuffer(dAtA[:i])
 | 
							size, err := m.TotalShares.MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return 0, err
 | 
								return 0, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -299,14 +333,7 @@ func (m *VaultRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
		i = encodeVarintVault(dAtA, i, uint64(size))
 | 
							i = encodeVarintVault(dAtA, i, uint64(size))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	i--
 | 
						i--
 | 
				
			||||||
	dAtA[i] = 0x12
 | 
					 | 
				
			||||||
	if len(m.Denom) > 0 {
 | 
					 | 
				
			||||||
		i -= len(m.Denom)
 | 
					 | 
				
			||||||
		copy(dAtA[i:], m.Denom)
 | 
					 | 
				
			||||||
		i = encodeVarintVault(dAtA, i, uint64(len(m.Denom)))
 | 
					 | 
				
			||||||
		i--
 | 
					 | 
				
			||||||
	dAtA[i] = 0xa
 | 
						dAtA[i] = 0xa
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return len(dAtA) - i, nil
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -330,10 +357,10 @@ func (m *VaultShareRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	_ = i
 | 
						_ = i
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
	if len(m.AmountSupplied) > 0 {
 | 
						if len(m.Shares) > 0 {
 | 
				
			||||||
		for iNdEx := len(m.AmountSupplied) - 1; iNdEx >= 0; iNdEx-- {
 | 
							for iNdEx := len(m.Shares) - 1; iNdEx >= 0; iNdEx-- {
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				size, err := m.AmountSupplied[iNdEx].MarshalToSizedBuffer(dAtA[:i])
 | 
									size, err := m.Shares[iNdEx].MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return 0, err
 | 
										return 0, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -354,6 +381,46 @@ func (m *VaultShareRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
	return len(dAtA) - i, nil
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) Marshal() (dAtA []byte, err error) {
 | 
				
			||||||
 | 
						size := m.Size()
 | 
				
			||||||
 | 
						dAtA = make([]byte, size)
 | 
				
			||||||
 | 
						n, err := m.MarshalToSizedBuffer(dAtA[:size])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return dAtA[:n], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) MarshalTo(dAtA []byte) (int, error) {
 | 
				
			||||||
 | 
						size := m.Size()
 | 
				
			||||||
 | 
						return m.MarshalToSizedBuffer(dAtA[:size])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			||||||
 | 
						i := len(dAtA)
 | 
				
			||||||
 | 
						_ = i
 | 
				
			||||||
 | 
						var l int
 | 
				
			||||||
 | 
						_ = l
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size := m.Amount.Size()
 | 
				
			||||||
 | 
							i -= size
 | 
				
			||||||
 | 
							if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil {
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i = encodeVarintVault(dAtA, i, uint64(size))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						i--
 | 
				
			||||||
 | 
						dAtA[i] = 0x12
 | 
				
			||||||
 | 
						if len(m.Denom) > 0 {
 | 
				
			||||||
 | 
							i -= len(m.Denom)
 | 
				
			||||||
 | 
							copy(dAtA[i:], m.Denom)
 | 
				
			||||||
 | 
							i = encodeVarintVault(dAtA, i, uint64(len(m.Denom)))
 | 
				
			||||||
 | 
							i--
 | 
				
			||||||
 | 
							dAtA[i] = 0xa
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return len(dAtA) - i, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func encodeVarintVault(dAtA []byte, offset int, v uint64) int {
 | 
					func encodeVarintVault(dAtA []byte, offset int, v uint64) int {
 | 
				
			||||||
	offset -= sovVault(v)
 | 
						offset -= sovVault(v)
 | 
				
			||||||
	base := offset
 | 
						base := offset
 | 
				
			||||||
@ -387,11 +454,7 @@ func (m *VaultRecord) Size() (n int) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	var l int
 | 
						var l int
 | 
				
			||||||
	_ = l
 | 
						_ = l
 | 
				
			||||||
	l = len(m.Denom)
 | 
						l = m.TotalShares.Size()
 | 
				
			||||||
	if l > 0 {
 | 
					 | 
				
			||||||
		n += 1 + l + sovVault(uint64(l))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	l = m.TotalSupply.Size()
 | 
					 | 
				
			||||||
	n += 1 + l + sovVault(uint64(l))
 | 
						n += 1 + l + sovVault(uint64(l))
 | 
				
			||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -406,8 +469,8 @@ func (m *VaultShareRecord) Size() (n int) {
 | 
				
			|||||||
	if l > 0 {
 | 
						if l > 0 {
 | 
				
			||||||
		n += 1 + l + sovVault(uint64(l))
 | 
							n += 1 + l + sovVault(uint64(l))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(m.AmountSupplied) > 0 {
 | 
						if len(m.Shares) > 0 {
 | 
				
			||||||
		for _, e := range m.AmountSupplied {
 | 
							for _, e := range m.Shares {
 | 
				
			||||||
			l = e.Size()
 | 
								l = e.Size()
 | 
				
			||||||
			n += 1 + l + sovVault(uint64(l))
 | 
								n += 1 + l + sovVault(uint64(l))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -415,6 +478,21 @@ func (m *VaultShareRecord) Size() (n int) {
 | 
				
			|||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *VaultShare) Size() (n int) {
 | 
				
			||||||
 | 
						if m == nil {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var l int
 | 
				
			||||||
 | 
						_ = l
 | 
				
			||||||
 | 
						l = len(m.Denom)
 | 
				
			||||||
 | 
						if l > 0 {
 | 
				
			||||||
 | 
							n += 1 + l + sovVault(uint64(l))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						l = m.Amount.Size()
 | 
				
			||||||
 | 
						n += 1 + l + sovVault(uint64(l))
 | 
				
			||||||
 | 
						return n
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func sovVault(x uint64) (n int) {
 | 
					func sovVault(x uint64) (n int) {
 | 
				
			||||||
	return (math_bits.Len64(x|1) + 6) / 7
 | 
						return (math_bits.Len64(x|1) + 6) / 7
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -553,39 +631,7 @@ func (m *VaultRecord) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
		switch fieldNum {
 | 
							switch fieldNum {
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
			if wireType != 2 {
 | 
								if wireType != 2 {
 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", wireType)
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			var stringLen uint64
 | 
					 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
					 | 
				
			||||||
				if shift >= 64 {
 | 
					 | 
				
			||||||
					return ErrIntOverflowVault
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				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 ErrInvalidLengthVault
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			postIndex := iNdEx + intStringLen
 | 
					 | 
				
			||||||
			if postIndex < 0 {
 | 
					 | 
				
			||||||
				return ErrInvalidLengthVault
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if postIndex > l {
 | 
					 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			m.Denom = string(dAtA[iNdEx:postIndex])
 | 
					 | 
				
			||||||
			iNdEx = postIndex
 | 
					 | 
				
			||||||
		case 2:
 | 
					 | 
				
			||||||
			if wireType != 2 {
 | 
					 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field TotalSupply", wireType)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var msglen int
 | 
								var msglen int
 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
@ -612,7 +658,7 @@ func (m *VaultRecord) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			if postIndex > l {
 | 
								if postIndex > l {
 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err := m.TotalSupply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
								if err := m.TotalShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
@ -702,7 +748,7 @@ func (m *VaultShareRecord) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
			if wireType != 2 {
 | 
								if wireType != 2 {
 | 
				
			||||||
				return fmt.Errorf("proto: wrong wireType = %d for field AmountSupplied", wireType)
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Shares", wireType)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			var msglen int
 | 
								var msglen int
 | 
				
			||||||
			for shift := uint(0); ; shift += 7 {
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
@ -729,8 +775,124 @@ func (m *VaultShareRecord) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
			if postIndex > l {
 | 
								if postIndex > l {
 | 
				
			||||||
				return io.ErrUnexpectedEOF
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m.AmountSupplied = append(m.AmountSupplied, types.Coin{})
 | 
								m.Shares = append(m.Shares, VaultShare{})
 | 
				
			||||||
			if err := m.AmountSupplied[len(m.AmountSupplied)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
								if err := m.Shares[len(m.Shares)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								iNdEx = postIndex
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								iNdEx = preIndex
 | 
				
			||||||
 | 
								skippy, err := skipVault(dAtA[iNdEx:])
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (skippy < 0) || (iNdEx+skippy) < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (iNdEx + skippy) > l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								iNdEx += skippy
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if iNdEx > l {
 | 
				
			||||||
 | 
							return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *VaultShare) Unmarshal(dAtA []byte) error {
 | 
				
			||||||
 | 
						l := len(dAtA)
 | 
				
			||||||
 | 
						iNdEx := 0
 | 
				
			||||||
 | 
						for iNdEx < l {
 | 
				
			||||||
 | 
							preIndex := iNdEx
 | 
				
			||||||
 | 
							var wire uint64
 | 
				
			||||||
 | 
							for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
								if shift >= 64 {
 | 
				
			||||||
 | 
									return ErrIntOverflowVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if iNdEx >= l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								b := dAtA[iNdEx]
 | 
				
			||||||
 | 
								iNdEx++
 | 
				
			||||||
 | 
								wire |= uint64(b&0x7F) << shift
 | 
				
			||||||
 | 
								if b < 0x80 {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fieldNum := int32(wire >> 3)
 | 
				
			||||||
 | 
							wireType := int(wire & 0x7)
 | 
				
			||||||
 | 
							if wireType == 4 {
 | 
				
			||||||
 | 
								return fmt.Errorf("proto: VaultShare: wiretype end group for non-group")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if fieldNum <= 0 {
 | 
				
			||||||
 | 
								return fmt.Errorf("proto: VaultShare: illegal tag %d (wire type %d)", fieldNum, wire)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch fieldNum {
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								if wireType != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var stringLen uint64
 | 
				
			||||||
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
									if shift >= 64 {
 | 
				
			||||||
 | 
										return ErrIntOverflowVault
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									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 ErrInvalidLengthVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								postIndex := iNdEx + intStringLen
 | 
				
			||||||
 | 
								if postIndex < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if postIndex > l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								m.Denom = string(dAtA[iNdEx:postIndex])
 | 
				
			||||||
 | 
								iNdEx = postIndex
 | 
				
			||||||
 | 
							case 2:
 | 
				
			||||||
 | 
								if wireType != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var stringLen uint64
 | 
				
			||||||
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
									if shift >= 64 {
 | 
				
			||||||
 | 
										return ErrIntOverflowVault
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									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 ErrInvalidLengthVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								postIndex := iNdEx + intStringLen
 | 
				
			||||||
 | 
								if postIndex < 0 {
 | 
				
			||||||
 | 
									return ErrInvalidLengthVault
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if postIndex > l {
 | 
				
			||||||
 | 
									return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
 | 
				
			|||||||
@ -25,12 +25,10 @@ func TestVaultRecordValidate(t *testing.T) {
 | 
				
			|||||||
			name: "valid vault records",
 | 
								name: "valid vault records",
 | 
				
			||||||
			vaultRecords: types.VaultRecords{
 | 
								vaultRecords: types.VaultRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "usdx",
 | 
										TotalShares: types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("usdx", 0),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "ukava",
 | 
										TotalShares: types.NewVaultShare("ukava", sdk.NewDec(5)),
 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("ukava", 5),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			errArgs: errArgs{
 | 
								errArgs: errArgs{
 | 
				
			||||||
@ -41,12 +39,10 @@ func TestVaultRecordValidate(t *testing.T) {
 | 
				
			|||||||
			name: "invalid - duplicate denom",
 | 
								name: "invalid - duplicate denom",
 | 
				
			||||||
			vaultRecords: types.VaultRecords{
 | 
								vaultRecords: types.VaultRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "usdx",
 | 
										TotalShares: types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("usdx", 0),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "usdx",
 | 
										TotalShares: types.NewVaultShare("usdx", sdk.NewDec(5)),
 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("usdx", 5),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			errArgs: errArgs{
 | 
								errArgs: errArgs{
 | 
				
			||||||
@ -58,8 +54,7 @@ func TestVaultRecordValidate(t *testing.T) {
 | 
				
			|||||||
			name: "invalid - invalid denom",
 | 
								name: "invalid - invalid denom",
 | 
				
			||||||
			vaultRecords: types.VaultRecords{
 | 
								vaultRecords: types.VaultRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "",
 | 
										TotalShares: types.VaultShare{Denom: "", Amount: sdk.NewDec(0)},
 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("ukava", 0),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			errArgs: errArgs{
 | 
								errArgs: errArgs{
 | 
				
			||||||
@ -67,30 +62,16 @@ func TestVaultRecordValidate(t *testing.T) {
 | 
				
			|||||||
				contains:   "invalid denom",
 | 
									contains:   "invalid denom",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "invalid - mismatch denom",
 | 
					 | 
				
			||||||
			vaultRecords: types.VaultRecords{
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					Denom:       "usdx",
 | 
					 | 
				
			||||||
					TotalSupply: sdk.NewInt64Coin("ukava", 0),
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			errArgs: errArgs{
 | 
					 | 
				
			||||||
				expectPass: false,
 | 
					 | 
				
			||||||
				contains:   "total supply denom ukava does not match vault record denom usdx",
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "invalid - negative",
 | 
								name: "invalid - negative",
 | 
				
			||||||
			vaultRecords: types.VaultRecords{
 | 
								vaultRecords: types.VaultRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Denom:       "usdx",
 | 
										TotalShares: types.VaultShare{"usdx", sdk.NewDec(-5)},
 | 
				
			||||||
					TotalSupply: sdk.Coin{Denom: "usdx", Amount: sdk.NewInt(-1)},
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			errArgs: errArgs{
 | 
								errArgs: errArgs{
 | 
				
			||||||
				expectPass: false,
 | 
									expectPass: false,
 | 
				
			||||||
				contains:   "negative coin amount",
 | 
									contains:   "vault share amount -5.000000000000000000 is negative",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -127,15 +108,15 @@ func TestVaultShareRecordsValidate(t *testing.T) {
 | 
				
			|||||||
			vaultRecords: types.VaultShareRecords{
 | 
								vaultRecords: types.VaultShareRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: addrs[0],
 | 
										Depositor: addrs[0],
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
						sdk.NewInt64Coin("usdx", 0),
 | 
											types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: addrs[1],
 | 
										Depositor: addrs[1],
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
						sdk.NewInt64Coin("usdx", 0),
 | 
											types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
						sdk.NewInt64Coin("ukava", 5),
 | 
											types.NewVaultShare("ukava", sdk.NewDec(5)),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -148,15 +129,15 @@ func TestVaultShareRecordsValidate(t *testing.T) {
 | 
				
			|||||||
			vaultRecords: types.VaultShareRecords{
 | 
								vaultRecords: types.VaultShareRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: addrs[0],
 | 
										Depositor: addrs[0],
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
						sdk.NewInt64Coin("usdx", 0),
 | 
											types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: addrs[0],
 | 
										Depositor: addrs[0],
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
						sdk.NewInt64Coin("usdx", 0),
 | 
											types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
						sdk.NewInt64Coin("ukava", 5),
 | 
											types.NewVaultShare("ukava", sdk.NewDec(5)),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -170,8 +151,8 @@ func TestVaultShareRecordsValidate(t *testing.T) {
 | 
				
			|||||||
			vaultRecords: types.VaultShareRecords{
 | 
								vaultRecords: types.VaultShareRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: sdk.AccAddress{},
 | 
										Depositor: sdk.AccAddress{},
 | 
				
			||||||
					AmountSupplied: sdk.NewCoins(
 | 
										Shares: types.NewVaultShares(
 | 
				
			||||||
						sdk.NewInt64Coin("usdx", 0),
 | 
											types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
					),
 | 
										),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@ -185,14 +166,15 @@ func TestVaultShareRecordsValidate(t *testing.T) {
 | 
				
			|||||||
			vaultRecords: types.VaultShareRecords{
 | 
								vaultRecords: types.VaultShareRecords{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Depositor: addrs[0],
 | 
										Depositor: addrs[0],
 | 
				
			||||||
					AmountSupplied: sdk.Coins{
 | 
										// Direct slice, not NewVaultShares() which panics
 | 
				
			||||||
						sdk.Coin{Denom: "ukava", Amount: sdk.NewInt(-1)},
 | 
										Shares: types.VaultShares{
 | 
				
			||||||
 | 
											types.VaultShare{"usdx", sdk.NewDec(-5)},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			errArgs: errArgs{
 | 
								errArgs: errArgs{
 | 
				
			||||||
				expectPass: false,
 | 
									expectPass: false,
 | 
				
			||||||
				contains:   "amount is not positive",
 | 
									contains:   "invalid vault share record shares: share -5.000000000000000000usdx amount is not positive",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -300,11 +282,11 @@ func TestAllowedVaultsValidate(t *testing.T) {
 | 
				
			|||||||
func TestNewVaultShareRecord(t *testing.T) {
 | 
					func TestNewVaultShareRecord(t *testing.T) {
 | 
				
			||||||
	_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
						_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	coins := sdk.NewCoins(
 | 
						shares := types.NewVaultShares(
 | 
				
			||||||
		sdk.NewInt64Coin("usdx", 10),
 | 
							types.NewVaultShare("usdx", sdk.NewDec(0)),
 | 
				
			||||||
		sdk.NewInt64Coin("ukava", 5),
 | 
							types.NewVaultShare("ukava", sdk.NewDec(5)),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	shareRecord := types.NewVaultShareRecord(addrs[0], coins...)
 | 
						shareRecord := types.NewVaultShareRecord(addrs[0], shares)
 | 
				
			||||||
	require.Equal(t, coins, shareRecord.AmountSupplied)
 | 
						require.Equal(t, shares, shareRecord.Shares)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user