mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +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,126 +106,159 @@ 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 != "" {
|
||||||
owner, err := sdk.AccAddressFromBech32(req.Owner)
|
return s.getAccountVaultDeposit(sdkCtx, req)
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, "Invalid address")
|
|
||||||
}
|
|
||||||
|
|
||||||
shareRecord, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
|
|
||||||
if !found {
|
|
||||||
return nil, status.Error(codes.NotFound, "No deposit found for owner")
|
|
||||||
}
|
|
||||||
|
|
||||||
if shareRecord.AmountSupplied.AmountOf(req.Denom).IsZero() {
|
|
||||||
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)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.QueryDepositsResponse{
|
|
||||||
Deposits: []types.DepositResponse{
|
|
||||||
{
|
|
||||||
Depositor: owner.String(),
|
|
||||||
AmountSupplied: shareRecord.AmountSupplied,
|
|
||||||
Value: value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Pagination: nil,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. All accounts, specific vault
|
// 2. All accounts, specific vault
|
||||||
if req.Owner == "" && req.Denom != "" {
|
if req.Owner == "" && req.Denom != "" {
|
||||||
_, found := s.keeper.GetVaultRecord(sdkCtx, req.Denom)
|
return s.getVaultAllDeposits(sdkCtx, req)
|
||||||
if !found {
|
|
||||||
return nil, status.Error(codes.NotFound, "Vault record for denom not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
deposits := []types.DepositResponse{}
|
|
||||||
store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
|
|
||||||
|
|
||||||
pageRes, err := query.FilteredPaginate(
|
|
||||||
store,
|
|
||||||
req.Pagination,
|
|
||||||
func(key []byte, value []byte, accumulate bool) (bool, error) {
|
|
||||||
var record types.VaultShareRecord
|
|
||||||
err := s.keeper.cdc.Unmarshal(value, &record)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only those that have amount of requested denom
|
|
||||||
if record.AmountSupplied.AmountOf(req.Denom).IsZero() {
|
|
||||||
// inform paginate that there was no match on this key
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if accumulate {
|
|
||||||
accValue, err := getAccountValue(sdkCtx, s.keeper, record.Depositor, record.AmountSupplied)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// only add to results if paginate tells us to
|
|
||||||
deposits = append(deposits, types.DepositResponse{
|
|
||||||
Depositor: record.Depositor.String(),
|
|
||||||
AmountSupplied: record.AmountSupplied,
|
|
||||||
Value: accValue,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// inform paginate that were was a match on this key
|
|
||||||
return true, nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.QueryDepositsResponse{
|
|
||||||
Deposits: deposits,
|
|
||||||
Pagination: pageRes,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Specific account, all vaults
|
// 3. Specific account, all vaults
|
||||||
if req.Owner != "" && req.Denom == "" {
|
if req.Owner != "" && req.Denom == "" {
|
||||||
owner, err := sdk.AccAddressFromBech32(req.Owner)
|
return s.getAccountAllDeposits(sdkCtx, req)
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, "Invalid address")
|
|
||||||
}
|
|
||||||
|
|
||||||
deposits := []types.DepositResponse{}
|
|
||||||
|
|
||||||
accountShare, found := s.keeper.GetVaultShareRecord(sdkCtx, owner)
|
|
||||||
if !found {
|
|
||||||
return nil, status.Error(codes.NotFound, "No deposit found for owner")
|
|
||||||
}
|
|
||||||
|
|
||||||
value, err := getAccountValue(sdkCtx, s.keeper, owner, accountShare.AmountSupplied)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
deposits = append(deposits, types.DepositResponse{
|
|
||||||
Depositor: owner.String(),
|
|
||||||
AmountSupplied: accountShare.AmountSupplied,
|
|
||||||
Value: value,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &types.QueryDepositsResponse{
|
|
||||||
Deposits: deposits,
|
|
||||||
Pagination: nil,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. All accounts, all vaults
|
// 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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "Invalid address")
|
||||||
|
}
|
||||||
|
|
||||||
|
shareRecord, found := s.keeper.GetVaultShareRecord(ctx, owner)
|
||||||
|
if !found {
|
||||||
|
return nil, status.Error(codes.NotFound, "No deposit found for owner")
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := getAccountValue(ctx, s.keeper, owner, shareRecord.Shares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.QueryDepositsResponse{
|
||||||
|
Deposits: []types.DepositResponse{
|
||||||
|
{
|
||||||
|
Depositor: owner.String(),
|
||||||
|
Shares: shareRecord.Shares,
|
||||||
|
Value: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Pagination: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getVaultAllDeposits returns all deposits for a specific vault
|
||||||
|
func (s queryServer) getVaultAllDeposits(
|
||||||
|
ctx sdk.Context,
|
||||||
|
req *types.QueryDepositsRequest,
|
||||||
|
) (*types.QueryDepositsResponse, error) {
|
||||||
|
_, found := s.keeper.GetVaultRecord(ctx, req.Denom)
|
||||||
|
if !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(
|
||||||
|
store,
|
||||||
|
req.Pagination,
|
||||||
|
func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||||
|
var record types.VaultShareRecord
|
||||||
|
err := s.keeper.cdc.Unmarshal(value, &record)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only those that have amount of requested denom
|
||||||
|
if record.Shares.AmountOf(req.Denom).IsZero() {
|
||||||
|
// inform paginate that there was no match on this key
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if accumulate {
|
||||||
|
accValue, err := getAccountValue(ctx, s.keeper, record.Depositor, record.Shares)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// only add to results if paginate tells us to
|
||||||
|
deposits = append(deposits, types.DepositResponse{
|
||||||
|
Depositor: record.Depositor.String(),
|
||||||
|
Shares: record.Shares,
|
||||||
|
Value: accValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// inform paginate that were was a match on this key
|
||||||
|
return true, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.QueryDepositsResponse{
|
||||||
|
Deposits: deposits,
|
||||||
|
Pagination: pageRes,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAccountAllDeposits returns deposits for all vaults for a specific account
|
||||||
|
func (s queryServer) getAccountAllDeposits(
|
||||||
|
ctx sdk.Context,
|
||||||
|
req *types.QueryDepositsRequest,
|
||||||
|
) (*types.QueryDepositsResponse, error) {
|
||||||
|
owner, err := sdk.AccAddressFromBech32(req.Owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "Invalid address")
|
||||||
|
}
|
||||||
|
|
||||||
|
deposits := []types.DepositResponse{}
|
||||||
|
|
||||||
|
accountShare, found := s.keeper.GetVaultShareRecord(ctx, owner)
|
||||||
|
if !found {
|
||||||
|
return nil, status.Error(codes.NotFound, "No deposit found for owner")
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := getAccountValue(ctx, s.keeper, owner, accountShare.Shares)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
deposits = append(deposits, types.DepositResponse{
|
||||||
|
Depositor: owner.String(),
|
||||||
|
Shares: accountShare.Shares,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
|
||||||
|
return &types.QueryDepositsResponse{
|
||||||
|
Deposits: deposits,
|
||||||
|
Pagination: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAllDeposits returns all deposits for all vaults
|
||||||
|
func (s queryServer) getAllDeposits(
|
||||||
|
ctx sdk.Context,
|
||||||
|
req *types.QueryDepositsRequest,
|
||||||
|
) (*types.QueryDepositsResponse, error) {
|
||||||
|
deposits := []types.DepositResponse{}
|
||||||
|
store := prefix.NewStore(ctx.KVStore(s.keeper.key), types.VaultShareRecordKeyPrefix)
|
||||||
|
|
||||||
pageRes, err := query.Paginate(
|
pageRes, err := query.Paginate(
|
||||||
store,
|
store,
|
||||||
@ -237,16 +270,16 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -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,8 +183,11 @@ 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(
|
||||||
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
|
||||||
|
types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
|
||||||
|
),
|
||||||
|
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res.Deposits,
|
res.Deposits,
|
||||||
@ -213,9 +216,12 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
|
|||||||
suite.Require().ElementsMatch(
|
suite.Require().ElementsMatch(
|
||||||
[]types.DepositResponse{
|
[]types.DepositResponse{
|
||||||
{
|
{
|
||||||
Depositor: acc1.String(),
|
Depositor: acc1.String(),
|
||||||
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
Shares: types.NewVaultShares(
|
||||||
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
|
||||||
|
types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
|
||||||
|
),
|
||||||
|
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res.Deposits,
|
res.Deposits,
|
||||||
@ -233,9 +239,12 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
|
|||||||
suite.Require().ElementsMatch(
|
suite.Require().ElementsMatch(
|
||||||
[]types.DepositResponse{
|
[]types.DepositResponse{
|
||||||
{
|
{
|
||||||
Depositor: acc2.String(),
|
Depositor: acc2.String(),
|
||||||
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
Shares: types.NewVaultShares(
|
||||||
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
|
||||||
|
types.NewVaultShare(deposit3Amount.Denom, deposit3Amount.Amount.ToDec()),
|
||||||
|
),
|
||||||
|
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res.Deposits,
|
res.Deposits,
|
||||||
@ -253,14 +262,20 @@ func (suite *grpcQueryTestSuite) TestDeposits() {
|
|||||||
suite.Require().ElementsMatchf(
|
suite.Require().ElementsMatchf(
|
||||||
[]types.DepositResponse{
|
[]types.DepositResponse{
|
||||||
{
|
{
|
||||||
Depositor: acc1.String(),
|
Depositor: acc1.String(),
|
||||||
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
Shares: types.NewVaultShares(
|
||||||
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
|
||||||
|
types.NewVaultShare(deposit2Amount.Denom, deposit2Amount.Amount.ToDec()),
|
||||||
|
),
|
||||||
|
Value: sdk.NewCoins(deposit1Amount, deposit2Amount),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Depositor: acc2.String(),
|
Depositor: acc2.String(),
|
||||||
AmountSupplied: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
Shares: types.NewVaultShares(
|
||||||
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
types.NewVaultShare(deposit1Amount.Denom, deposit1Amount.Amount.ToDec()),
|
||||||
|
types.NewVaultShare(deposit3Amount.Denom, deposit3Amount.Amount.ToDec()),
|
||||||
|
),
|
||||||
|
Value: sdk.NewCoins(deposit1Amount, deposit3Amount),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res.Deposits,
|
res.Deposits,
|
||||||
@ -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--
|
||||||
}
|
dAtA[i] = 0x1a
|
||||||
i = encodeVarintQuery(dAtA, i, uint64(size))
|
|
||||||
}
|
}
|
||||||
i--
|
|
||||||
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)
|
||||||
n += 1 + l + sovQuery(uint64(l))
|
if l > 0 {
|
||||||
|
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
|
dAtA[i] = 0xa
|
||||||
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
|
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