diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.lcd.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.lcd.ts index d816987fff..9350c68ecf 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.lcd.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.lcd.ts @@ -1,6 +1,6 @@ import { setPaginationParams } from "../../helpers"; import { LCDClient } from "@osmonauts/lcd"; -import { QueryParamsRequest, QueryParamsResponseSDKType, QueryVaultRequest, QueryVaultResponseSDKType, QueryAllVaultsRequest, QueryAllVaultsResponseSDKType, QueryMegavaultTotalSharesRequest, QueryMegavaultTotalSharesResponseSDKType, QueryMegavaultOwnerSharesRequest, QueryMegavaultOwnerSharesResponseSDKType, QueryVaultParamsRequest, QueryVaultParamsResponseSDKType } from "./query"; +import { QueryParamsRequest, QueryParamsResponseSDKType, QueryVaultRequest, QueryVaultResponseSDKType, QueryAllVaultsRequest, QueryAllVaultsResponseSDKType, QueryMegavaultTotalSharesRequest, QueryMegavaultTotalSharesResponseSDKType, QueryMegavaultOwnerSharesRequest, QueryMegavaultOwnerSharesResponseSDKType, QueryVaultParamsRequest, QueryVaultParamsResponseSDKType, QueryMegavaultWithdrawalInfoRequest, QueryMegavaultWithdrawalInfoResponseSDKType } from "./query"; export class LCDQueryClient { req: LCDClient; @@ -16,6 +16,7 @@ export class LCDQueryClient { this.megavaultTotalShares = this.megavaultTotalShares.bind(this); this.megavaultOwnerShares = this.megavaultOwnerShares.bind(this); this.vaultParams = this.vaultParams.bind(this); + this.megavaultWithdrawalInfo = this.megavaultWithdrawalInfo.bind(this); } /* Queries the Params. */ @@ -79,5 +80,20 @@ export class LCDQueryClient { const endpoint = `dydxprotocol/vault/params/${params.type}/${params.number}`; return await this.req.get(endpoint); } + /* Queries withdrawal info for megavault. */ + + + async megavaultWithdrawalInfo(params: QueryMegavaultWithdrawalInfoRequest): Promise { + const options: any = { + params: {} + }; + + if (typeof params?.sharesToWithdraw !== "undefined") { + options.params.shares_to_withdraw = params.sharesToWithdraw; + } + + const endpoint = `dydxprotocol/vault/megavault/withdrawal_info`; + return await this.req.get(endpoint, options); + } } \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.rpc.Query.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.rpc.Query.ts index c170958b7d..a77656dc6c 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.rpc.Query.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.rpc.Query.ts @@ -1,7 +1,7 @@ import { Rpc } from "../../helpers"; import * as _m0 from "protobufjs/minimal"; import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate"; -import { QueryParamsRequest, QueryParamsResponse, QueryVaultRequest, QueryVaultResponse, QueryAllVaultsRequest, QueryAllVaultsResponse, QueryMegavaultTotalSharesRequest, QueryMegavaultTotalSharesResponse, QueryMegavaultOwnerSharesRequest, QueryMegavaultOwnerSharesResponse, QueryVaultParamsRequest, QueryVaultParamsResponse } from "./query"; +import { QueryParamsRequest, QueryParamsResponse, QueryVaultRequest, QueryVaultResponse, QueryAllVaultsRequest, QueryAllVaultsResponse, QueryMegavaultTotalSharesRequest, QueryMegavaultTotalSharesResponse, QueryMegavaultOwnerSharesRequest, QueryMegavaultOwnerSharesResponse, QueryVaultParamsRequest, QueryVaultParamsResponse, QueryMegavaultWithdrawalInfoRequest, QueryMegavaultWithdrawalInfoResponse } from "./query"; /** Query defines the gRPC querier service. */ export interface Query { @@ -22,6 +22,9 @@ export interface Query { /** Queries vault params of a vault. */ vaultParams(request: QueryVaultParamsRequest): Promise; + /** Queries withdrawal info for megavault. */ + + megavaultWithdrawalInfo(request: QueryMegavaultWithdrawalInfoRequest): Promise; } export class QueryClientImpl implements Query { private readonly rpc: Rpc; @@ -34,6 +37,7 @@ export class QueryClientImpl implements Query { this.megavaultTotalShares = this.megavaultTotalShares.bind(this); this.megavaultOwnerShares = this.megavaultOwnerShares.bind(this); this.vaultParams = this.vaultParams.bind(this); + this.megavaultWithdrawalInfo = this.megavaultWithdrawalInfo.bind(this); } params(request: QueryParamsRequest = {}): Promise { @@ -76,6 +80,12 @@ export class QueryClientImpl implements Query { return promise.then(data => QueryVaultParamsResponse.decode(new _m0.Reader(data))); } + megavaultWithdrawalInfo(request: QueryMegavaultWithdrawalInfoRequest): Promise { + const data = QueryMegavaultWithdrawalInfoRequest.encode(request).finish(); + const promise = this.rpc.request("dydxprotocol.vault.Query", "MegavaultWithdrawalInfo", data); + return promise.then(data => QueryMegavaultWithdrawalInfoResponse.decode(new _m0.Reader(data))); + } + } export const createRpcQueryExtension = (base: QueryClient) => { const rpc = createProtobufRpcClient(base); @@ -103,6 +113,10 @@ export const createRpcQueryExtension = (base: QueryClient) => { vaultParams(request: QueryVaultParamsRequest): Promise { return queryService.vaultParams(request); + }, + + megavaultWithdrawalInfo(request: QueryMegavaultWithdrawalInfoRequest): Promise { + return queryService.megavaultWithdrawalInfo(request); } }; diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.ts index db52d764dc..2a62eebecc 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/query.ts @@ -1,8 +1,8 @@ import { VaultType, VaultTypeSDKType, VaultId, VaultIdSDKType } from "./vault"; import { PageRequest, PageRequestSDKType, PageResponse, PageResponseSDKType } from "../../cosmos/base/query/v1beta1/pagination"; +import { NumShares, NumSharesSDKType, OwnerShare, OwnerShareSDKType } from "./share"; import { Params, ParamsSDKType, QuotingParams, QuotingParamsSDKType, OperatorParams, OperatorParamsSDKType, VaultParams, VaultParamsSDKType } from "./params"; import { SubaccountId, SubaccountIdSDKType } from "../subaccounts/subaccount"; -import { NumShares, NumSharesSDKType, OwnerShare, OwnerShareSDKType } from "./share"; import * as _m0 from "protobufjs/minimal"; import { DeepPartial } from "../../helpers"; /** QueryParamsRequest is a request type for the Params RPC method. */ @@ -177,6 +177,70 @@ export interface QueryVaultParamsResponseSDKType { vault_id?: VaultIdSDKType; vault_params?: VaultParamsSDKType; } +/** + * QueryMegavaultWithdrawalInfoRequest is a request type for the + * MegavaultWithdrawalInfo RPC method. + */ + +export interface QueryMegavaultWithdrawalInfoRequest { + /** Number of shares to withdraw. */ + sharesToWithdraw?: NumShares; +} +/** + * QueryMegavaultWithdrawalInfoRequest is a request type for the + * MegavaultWithdrawalInfo RPC method. + */ + +export interface QueryMegavaultWithdrawalInfoRequestSDKType { + /** Number of shares to withdraw. */ + shares_to_withdraw?: NumSharesSDKType; +} +/** + * QueryMegavaultWithdrawalInfoResponse is a response type for the + * MegavaultWithdrawalInfo RPC method. + */ + +export interface QueryMegavaultWithdrawalInfoResponse { + /** Number of shares to withdraw. */ + sharesToWithdraw?: NumShares; + /** + * Number of quote quantums above `shares` are expected to redeem. + * Withdrawl slippage can be calculated by comparing + * `expected_quote_quantums` with + * `megavault_equity * shares_to_withdraw / total_shares` + */ + + expectedQuoteQuantums: Uint8Array; + /** Equity of megavault (in quote quantums). */ + + megavaultEquity: Uint8Array; + /** Total shares in megavault. */ + + totalShares?: NumShares; +} +/** + * QueryMegavaultWithdrawalInfoResponse is a response type for the + * MegavaultWithdrawalInfo RPC method. + */ + +export interface QueryMegavaultWithdrawalInfoResponseSDKType { + /** Number of shares to withdraw. */ + shares_to_withdraw?: NumSharesSDKType; + /** + * Number of quote quantums above `shares` are expected to redeem. + * Withdrawl slippage can be calculated by comparing + * `expected_quote_quantums` with + * `megavault_equity * shares_to_withdraw / total_shares` + */ + + expected_quote_quantums: Uint8Array; + /** Equity of megavault (in quote quantums). */ + + megavault_equity: Uint8Array; + /** Total shares in megavault. */ + + total_shares?: NumSharesSDKType; +} function createBaseQueryParamsRequest(): QueryParamsRequest { return {}; @@ -804,4 +868,124 @@ export const QueryVaultParamsResponse = { return message; } +}; + +function createBaseQueryMegavaultWithdrawalInfoRequest(): QueryMegavaultWithdrawalInfoRequest { + return { + sharesToWithdraw: undefined + }; +} + +export const QueryMegavaultWithdrawalInfoRequest = { + encode(message: QueryMegavaultWithdrawalInfoRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.sharesToWithdraw !== undefined) { + NumShares.encode(message.sharesToWithdraw, writer.uint32(10).fork()).ldelim(); + } + + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): QueryMegavaultWithdrawalInfoRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryMegavaultWithdrawalInfoRequest(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + case 1: + message.sharesToWithdraw = NumShares.decode(reader, reader.uint32()); + break; + + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(object: DeepPartial): QueryMegavaultWithdrawalInfoRequest { + const message = createBaseQueryMegavaultWithdrawalInfoRequest(); + message.sharesToWithdraw = object.sharesToWithdraw !== undefined && object.sharesToWithdraw !== null ? NumShares.fromPartial(object.sharesToWithdraw) : undefined; + return message; + } + +}; + +function createBaseQueryMegavaultWithdrawalInfoResponse(): QueryMegavaultWithdrawalInfoResponse { + return { + sharesToWithdraw: undefined, + expectedQuoteQuantums: new Uint8Array(), + megavaultEquity: new Uint8Array(), + totalShares: undefined + }; +} + +export const QueryMegavaultWithdrawalInfoResponse = { + encode(message: QueryMegavaultWithdrawalInfoResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.sharesToWithdraw !== undefined) { + NumShares.encode(message.sharesToWithdraw, writer.uint32(10).fork()).ldelim(); + } + + if (message.expectedQuoteQuantums.length !== 0) { + writer.uint32(18).bytes(message.expectedQuoteQuantums); + } + + if (message.megavaultEquity.length !== 0) { + writer.uint32(26).bytes(message.megavaultEquity); + } + + if (message.totalShares !== undefined) { + NumShares.encode(message.totalShares, writer.uint32(34).fork()).ldelim(); + } + + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): QueryMegavaultWithdrawalInfoResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryMegavaultWithdrawalInfoResponse(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + case 1: + message.sharesToWithdraw = NumShares.decode(reader, reader.uint32()); + break; + + case 2: + message.expectedQuoteQuantums = reader.bytes(); + break; + + case 3: + message.megavaultEquity = reader.bytes(); + break; + + case 4: + message.totalShares = NumShares.decode(reader, reader.uint32()); + break; + + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(object: DeepPartial): QueryMegavaultWithdrawalInfoResponse { + const message = createBaseQueryMegavaultWithdrawalInfoResponse(); + message.sharesToWithdraw = object.sharesToWithdraw !== undefined && object.sharesToWithdraw !== null ? NumShares.fromPartial(object.sharesToWithdraw) : undefined; + message.expectedQuoteQuantums = object.expectedQuoteQuantums ?? new Uint8Array(); + message.megavaultEquity = object.megavaultEquity ?? new Uint8Array(); + message.totalShares = object.totalShares !== undefined && object.totalShares !== null ? NumShares.fromPartial(object.totalShares) : undefined; + return message; + } + }; \ No newline at end of file diff --git a/proto/dydxprotocol/vault/query.proto b/proto/dydxprotocol/vault/query.proto index 57b22b5909..faff37c692 100644 --- a/proto/dydxprotocol/vault/query.proto +++ b/proto/dydxprotocol/vault/query.proto @@ -39,6 +39,13 @@ service Query { rpc VaultParams(QueryVaultParamsRequest) returns (QueryVaultParamsResponse) { option (google.api.http).get = "/dydxprotocol/vault/params/{type}/{number}"; } + + // Queries withdrawal info for megavault. + rpc MegavaultWithdrawalInfo(QueryMegavaultWithdrawalInfoRequest) + returns (QueryMegavaultWithdrawalInfoResponse) { + option (google.api.http).get = + "/dydxprotocol/vault/megavault/withdrawal_info"; + } } // QueryParamsRequest is a request type for the Params RPC method. @@ -119,3 +126,34 @@ message QueryVaultParamsResponse { VaultId vault_id = 1 [ (gogoproto.nullable) = false ]; VaultParams vault_params = 2 [ (gogoproto.nullable) = false ]; } + +// QueryMegavaultWithdrawalInfoRequest is a request type for the +// MegavaultWithdrawalInfo RPC method. +message QueryMegavaultWithdrawalInfoRequest { + // Number of shares to withdraw. + NumShares shares_to_withdraw = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryMegavaultWithdrawalInfoResponse is a response type for the +// MegavaultWithdrawalInfo RPC method. +message QueryMegavaultWithdrawalInfoResponse { + // Number of shares to withdraw. + NumShares shares_to_withdraw = 1 [ (gogoproto.nullable) = false ]; + // Number of quote quantums above `shares` are expected to redeem. + // Withdrawl slippage can be calculated by comparing + // `expected_quote_quantums` with + // `megavault_equity * shares_to_withdraw / total_shares` + bytes expected_quote_quantums = 2 [ + (gogoproto.customtype) = + "github.com/dydxprotocol/v4-chain/protocol/dtypes.SerializableInt", + (gogoproto.nullable) = false + ]; + // Equity of megavault (in quote quantums). + bytes megavault_equity = 3 [ + (gogoproto.customtype) = + "github.com/dydxprotocol/v4-chain/protocol/dtypes.SerializableInt", + (gogoproto.nullable) = false + ]; + // Total shares in megavault. + NumShares total_shares = 4 [ (gogoproto.nullable) = false ]; +} diff --git a/protocol/x/vault/client/cli/query.go b/protocol/x/vault/client/cli/query.go index 1e72499948..93b2c5a115 100644 --- a/protocol/x/vault/client/cli/query.go +++ b/protocol/x/vault/client/cli/query.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/dydxprotocol/v4-chain/protocol/dtypes" "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" ) @@ -28,6 +29,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryListVault()) cmd.AddCommand(CmdQueryTotalShares()) cmd.AddCommand(CmdQueryListOwnerShares()) + cmd.AddCommand(CmdQueryMegavaultWithdrawalInfo()) return cmd } @@ -185,3 +187,37 @@ func CmdQueryListOwnerShares() *cobra.Command { return cmd } + +func CmdQueryMegavaultWithdrawalInfo() *cobra.Command { + cmd := &cobra.Command{ + Use: "megavault-withdrawal-info [shares_to_withdraw]", + Short: "get megavault withdrawal info", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx := client.GetClientContextFromCmd(cmd) + queryClient := types.NewQueryClient(clientCtx) + + shares, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + + res, err := queryClient.MegavaultWithdrawalInfo( + context.Background(), + &types.QueryMegavaultWithdrawalInfoRequest{ + SharesToWithdraw: types.NumShares{ + NumShares: dtypes.NewIntFromUint64(shares), + }, + }, + ) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/protocol/x/vault/keeper/grpc_query_withdrawal_info.go b/protocol/x/vault/keeper/grpc_query_withdrawal_info.go new file mode 100644 index 0000000000..c8f7c9a36d --- /dev/null +++ b/protocol/x/vault/keeper/grpc_query_withdrawal_info.go @@ -0,0 +1,40 @@ +package keeper + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/dydxprotocol/v4-chain/protocol/dtypes" + "github.com/dydxprotocol/v4-chain/protocol/lib" + "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" +) + +func (k Keeper) MegavaultWithdrawalInfo( + goCtx context.Context, + req *types.QueryMegavaultWithdrawalInfoRequest, +) (*types.QueryMegavaultWithdrawalInfoResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName) + + redeemedQuoteQuantums, megavaultEquity, totalShares, err := k.RedeemFromMainAndSubVaults( + ctx, + req.SharesToWithdraw.NumShares.BigInt(), + false, + ) + if err != nil { + return nil, err + } + + return &types.QueryMegavaultWithdrawalInfoResponse{ + SharesToWithdraw: req.SharesToWithdraw, + ExpectedQuoteQuantums: dtypes.NewIntFromBigInt(redeemedQuoteQuantums), + MegavaultEquity: dtypes.NewIntFromBigInt(megavaultEquity), + TotalShares: types.NumShares{ + NumShares: dtypes.NewIntFromBigInt(totalShares), + }, + }, nil +} diff --git a/protocol/x/vault/keeper/grpc_query_withdrawal_info_test.go b/protocol/x/vault/keeper/grpc_query_withdrawal_info_test.go new file mode 100644 index 0000000000..5b8fe373e8 --- /dev/null +++ b/protocol/x/vault/keeper/grpc_query_withdrawal_info_test.go @@ -0,0 +1,235 @@ +package keeper_test + +import ( + "math/big" + "testing" + + "github.com/cometbft/cometbft/types" + "github.com/dydxprotocol/v4-chain/protocol/dtypes" + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" + assetstypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" + clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" + perptypes "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types" + pricestypes "github.com/dydxprotocol/v4-chain/protocol/x/prices/types" + satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" + vaulttypes "github.com/dydxprotocol/v4-chain/protocol/x/vault/types" + "github.com/stretchr/testify/require" +) + +func TestQueryMegavaultWithdrawalInfo(t *testing.T) { + tests := map[string]struct { + /* --- Setup --- */ + // Quote quantums that main vault has. + mainVaultBalance *big.Int + // Total shares. + totalShares uint64 + // Vaults. + vaults []VaultSetup + // Query request. + req *vaulttypes.QueryMegavaultWithdrawalInfoRequest + + /* --- Expectations --- */ + res *vaulttypes.QueryMegavaultWithdrawalInfoResponse + expectedErr string + }{ + "Success: Withdraw 10%, 100 quantums in main vault, one sub-vault with 0 leverage and 50 equity": { + mainVaultBalance: big.NewInt(100), + totalShares: 50, + vaults: []VaultSetup{ + { + id: constants.Vault_Clob0, + params: vaulttypes.VaultParams{ + Status: vaulttypes.VaultStatus_VAULT_STATUS_QUOTING, + }, + assetQuoteQuantums: big.NewInt(50), + positionBaseQuantums: big.NewInt(0), + clobPair: constants.ClobPair_Btc, + perpetual: constants.BtcUsd_20PercentInitial_10PercentMaintenance, + marketParam: constants.TestMarketParams[0], + marketPrice: constants.TestMarketPrices[0], + }, + }, + req: &vaulttypes.QueryMegavaultWithdrawalInfoRequest{ + SharesToWithdraw: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(5), + }, + }, + res: &vaulttypes.QueryMegavaultWithdrawalInfoResponse{ + SharesToWithdraw: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(5), + }, + ExpectedQuoteQuantums: dtypes.NewInt(15), + MegavaultEquity: dtypes.NewInt(150), + TotalShares: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(50), + }, + }, + }, + "Success: Withdraw ~0.65%, 5_471_283_193_197 quantums in main vault, one sub-vault with 1 leverage and 1_500_000_000 equity": { + mainVaultBalance: big.NewInt(5_471_283_193_197), + totalShares: 128_412_843_128, + vaults: []VaultSetup{ + { + id: constants.Vault_Clob1, + params: vaulttypes.VaultParams{ + Status: vaulttypes.VaultStatus_VAULT_STATUS_QUOTING, + }, + // open_notional = 1_000_000_000 * 10^-9 * 3_000 * 10^6 = 3_000_000_000 + // equity = -1_500_000_000 + 3_000_000_000 = 1_500_000_000 + assetQuoteQuantums: big.NewInt(-1_500_000_000), + positionBaseQuantums: big.NewInt(1_000_000_000), + clobPair: constants.ClobPair_Eth, + perpetual: constants.EthUsd_20PercentInitial_10PercentMaintenance, + marketParam: constants.TestMarketParams[1], + marketPrice: constants.TestMarketPrices[1], + }, + }, + req: &vaulttypes.QueryMegavaultWithdrawalInfoRequest{ + SharesToWithdraw: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(831_571_304), + }, + }, + res: &vaulttypes.QueryMegavaultWithdrawalInfoResponse{ + SharesToWithdraw: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(831_571_304), + }, + // expected_quote_quantums + // = shares_to_withdraw / total_shares * main_vault_balance + + // shares_to_withdraw / total_shares * sub_vault_equity * (1 - slippage) + // = 831_571_304 / 128_412_843_128 * 5_471_283_193_197 + + // 831_571_304 / 128_412_843_128 * 1_500_000_000 * (1 - 0.4) + // = 35_430_740_327 + 5_828_187 = 35_436_568_514 + ExpectedQuoteQuantums: dtypes.NewInt(35_436_568_514), + // megavault_equity + // = main_vault_balance + sub_vault_equity + // = 5_471_283_193_197 + 1_500_000_000 + // = 5_472_783_193_197 + MegavaultEquity: dtypes.NewInt(5_472_783_193_197), + TotalShares: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(128_412_843_128), + }, + }, + }, + "Error: Withdraw more than total shares": { + mainVaultBalance: big.NewInt(100), + totalShares: 50, + req: &vaulttypes.QueryMegavaultWithdrawalInfoRequest{ + SharesToWithdraw: vaulttypes.NumShares{ + NumShares: dtypes.NewInt(51), + }, + }, + expectedErr: vaulttypes.ErrInvalidSharesToWithdraw.Error(), + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // Initialize tApp and ctx. + tApp := testapp.NewTestAppBuilder(t).WithGenesisDocFn(func() (genesis types.GenesisDoc) { + genesis = testapp.DefaultGenesis() + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *satypes.GenesisState) { + subaccounts := []satypes.Subaccount{ + { + Id: &vaulttypes.MegavaultMainSubaccount, + AssetPositions: []*satypes.AssetPosition{ + { + AssetId: assetstypes.AssetUsdc.Id, + Quantums: dtypes.NewIntFromBigInt(tc.mainVaultBalance), + }, + }, + }, + } + for _, vault := range tc.vaults { + subaccounts = append(subaccounts, satypes.Subaccount{ + Id: vault.id.ToSubaccountId(), + AssetPositions: []*satypes.AssetPosition{ + { + AssetId: assetstypes.AssetUsdc.Id, + Quantums: dtypes.NewIntFromBigInt(vault.assetQuoteQuantums), + }, + }, + PerpetualPositions: []*satypes.PerpetualPosition{ + { + PerpetualId: vault.perpetual.Params.Id, + Quantums: dtypes.NewIntFromBigInt(vault.positionBaseQuantums), + }, + }, + }) + } + genesisState.Subaccounts = subaccounts + }, + ) + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *vaulttypes.GenesisState) { + genesisState.TotalShares = vaulttypes.NumShares{ + NumShares: dtypes.NewIntFromUint64(tc.totalShares), + } + vaults := make([]vaulttypes.Vault, len(tc.vaults)) + for i, vault := range tc.vaults { + vaults[i] = vaulttypes.Vault{ + VaultId: vault.id, + VaultParams: vault.params, + } + } + genesisState.Vaults = vaults + }, + ) + // Initialize prices. + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *pricestypes.GenesisState) { + marketParams := make([]pricestypes.MarketParam, len(tc.vaults)) + marketPrices := make([]pricestypes.MarketPrice, len(tc.vaults)) + for i, vault := range tc.vaults { + vault.marketParam.Id = vault.id.Number + marketParams[i] = vault.marketParam + vault.marketPrice.Id = vault.id.Number + marketPrices[i] = vault.marketPrice + } + genesisState.MarketParams = marketParams + genesisState.MarketPrices = marketPrices + }, + ) + // Initialize perpetuals. + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *perptypes.GenesisState) { + genesisState.LiquidityTiers = constants.LiquidityTiers + perpetuals := make([]perptypes.Perpetual, len(tc.vaults)) + for i, vault := range tc.vaults { + vault.perpetual.Params.Id = vault.id.Number + perpetuals[i] = vault.perpetual + } + genesisState.Perpetuals = perpetuals + }, + ) + // Initialize clob pairs. + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *clobtypes.GenesisState) { + clobPairs := make([]clobtypes.ClobPair, len(tc.vaults)) + for i, vault := range tc.vaults { + vault.clobPair.Id = vault.id.Number + clobPairs[i] = vault.clobPair + } + genesisState.ClobPairs = clobPairs + }, + ) + return genesis + }).Build() + ctx := tApp.InitChain() + + response, err := tApp.App.VaultKeeper.MegavaultWithdrawalInfo(ctx, tc.req) + if tc.expectedErr != "" { + require.ErrorContains(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + require.Equal(t, tc.res, response) + } + }) + } +} diff --git a/protocol/x/vault/keeper/withdraw.go b/protocol/x/vault/keeper/withdraw.go index 957518e7c5..98c75a85ee 100644 --- a/protocol/x/vault/keeper/withdraw.go +++ b/protocol/x/vault/keeper/withdraw.go @@ -150,126 +150,15 @@ func (k Keeper) WithdrawFromMegavault( ) } - // 2. Redeem from main vault. - totalShares := k.GetTotalShares(ctx).NumShares.BigInt() - megavaultEquity, err := k.GetSubaccountEquity(ctx, types.MegavaultMainSubaccount) - redeemedQuoteQuantums = new(big.Int).Set(megavaultEquity) + // 2. Redeem from main and sub vaults. + // Note that in below function, quote quantums redeemed from each sub vault are transferred to the main vault. + redeemedQuoteQuantums, megavaultEquity, totalShares, err := + k.RedeemFromMainAndSubVaults(ctx, sharesToWithdraw, true) if err != nil { - log.ErrorLogWithError(ctx, "Megavault withdrawal: failed to get megavault main vault equity", err) return nil, err } - redeemedQuoteQuantums.Mul(redeemedQuoteQuantums, sharesToWithdraw) - redeemedQuoteQuantums.Quo(redeemedQuoteQuantums, totalShares) - - // 3. Redeem from each sub vault. - vaultParamsIterator := k.getVaultParamsIterator(ctx) - defer vaultParamsIterator.Close() - for ; vaultParamsIterator.Valid(); vaultParamsIterator.Next() { - var vaultParams types.VaultParams - k.cdc.MustUnmarshal(vaultParamsIterator.Value(), &vaultParams) - // Skip deactivated vaults. - if vaultParams.Status == types.VaultStatus_VAULT_STATUS_DEACTIVATED { - continue - } - - vaultId, err := types.GetVaultIdFromStateKey(vaultParamsIterator.Key()) - if err != nil { - log.ErrorLogWithError( - ctx, - "Megavault withdrawal: error when getting vault ID from state key. Skipping this vault", - err, - ) - continue - } - - _, perpetual, marketParam, marketPrice, err := k.GetVaultClobPerpAndMarket(ctx, *vaultId) - if err != nil { - log.ErrorLogWithError( - ctx, - "Megavault withdrawal: error when getting perpetual and market. Skipping this vault", - err, - "Vault ID", - vaultId, - ) - continue - } - leverage, equity, err := k.GetVaultLeverageAndEquity(ctx, *vaultId, &perpetual, &marketPrice) - if err != nil { - log.ErrorLogWithError( - ctx, - "Megavault withdrawal: error when getting vault leverage and equity. Skipping this vault", - err, - "Vault ID", - vaultId, - ) - continue - } - - slippage, err := k.GetVaultWithdrawalSlippage( - ctx, - *vaultId, - sharesToWithdraw, - totalShares, - leverage, - &perpetual, - &marketParam, - ) - if err != nil { - log.ErrorLogWithError( - ctx, - "Megavault withdrawal: error when getting vault withdrawal slippage. Skipping this vault", - err, - "Vault ID", - vaultId, - ) - continue - } - - // Transfer `equity * shares / totalShares * (1 - slippage)` from sub vault to main vault. - redeemedFromSubVault := new(big.Rat).SetFrac(equity, big.NewInt(1)) - redeemedFromSubVault.Mul(redeemedFromSubVault, new(big.Rat).SetFrac(sharesToWithdraw, totalShares)) - redeemedFromSubVault.Mul(redeemedFromSubVault, new(big.Rat).Sub(lib.BigRat1(), slippage)) - quantumsToTransfer := new(big.Int).Quo(redeemedFromSubVault.Num(), redeemedFromSubVault.Denom()) - if quantumsToTransfer.Sign() <= 0 || !quantumsToTransfer.IsUint64() { - log.InfoLog( - ctx, - "Megavault withdrawal: quantums to transfer is invalid. Skipping this vault", - "Vault ID", - vaultId, - "Quantums", - quantumsToTransfer, - ) - continue - } - err = k.sendingKeeper.ProcessTransfer( - ctx, - &sendingtypes.Transfer{ - Sender: *vaultId.ToSubaccountId(), - Recipient: types.MegavaultMainSubaccount, - AssetId: assetstypes.AssetUsdc.Id, - Amount: quantumsToTransfer.Uint64(), // validated above. - }, - ) - if err != nil { - log.ErrorLogWithError( - ctx, - "Megavault withdrawal: error when transferring from sub vault to main vault. Skipping this vault", - err, - "Vault ID", - vaultId, - "Quantums", - quantumsToTransfer, - ) - continue - } - - // Increment total redeemed quote quantums and record this vault's equity as part of megavault equity. - redeemedQuoteQuantums.Add(redeemedQuoteQuantums, quantumsToTransfer) - megavaultEquity.Add(megavaultEquity, equity) - } - - // 4. Return error if redeemed quantums is invalid. + // 3. Return error if redeemed quantums is invalid. if redeemedQuoteQuantums.Sign() <= 0 || !redeemedQuoteQuantums.IsUint64() || redeemedQuoteQuantums.Cmp(minQuoteQuantums) < 0 { return nil, errorsmod.Wrapf( @@ -280,7 +169,7 @@ func (k Keeper) WithdrawFromMegavault( ) } - // 5. Transfer from main vault to destination subaccount. + // 4. Transfer from main vault to destination subaccount. err = k.sendingKeeper.ProcessTransfer( ctx, &sendingtypes.Transfer{ @@ -303,7 +192,7 @@ func (k Keeper) WithdrawFromMegavault( return nil, err } - // 6. Decrement total and owner shares. + // 5. Decrement total and owner shares. if err = k.SetTotalShares( ctx, types.BigIntToNumShares(new(big.Int).Sub(totalShares, sharesToWithdraw)), @@ -332,3 +221,161 @@ func (k Keeper) WithdrawFromMegavault( return redeemedQuoteQuantums, nil } + +// RedeemFromMainAndSubVaults redeems `shares` number of shares from main and sub vaults. +// If and only if `txMode` is true, logs are enabled and quote quantums redeemed from each +// sub vault are transferred to the main vault. +func (k Keeper) RedeemFromMainAndSubVaults( + ctx sdk.Context, + shares *big.Int, + txMode bool, +) ( + redeemedQuoteQuantums *big.Int, + megavaultEquity *big.Int, + totalShares *big.Int, + err error, +) { + // Redeem from main vault. + totalShares = k.GetTotalShares(ctx).NumShares.BigInt() + if shares.Cmp(totalShares) > 0 { + return nil, nil, totalShares, errorsmod.Wrapf( + types.ErrInvalidSharesToWithdraw, + "shares to withdraw %s exceeds total shares %s", + shares, + totalShares, + ) + } + megavaultEquity, err = k.GetSubaccountEquity(ctx, types.MegavaultMainSubaccount) + if err != nil { + if txMode { + log.ErrorLogWithError(ctx, "Megavault withdrawal: failed to get megavault main vault equity", err) + } + return nil, nil, totalShares, err + } + redeemedQuoteQuantums = new(big.Int).Set(megavaultEquity) + redeemedQuoteQuantums.Mul(redeemedQuoteQuantums, shares) + redeemedQuoteQuantums.Quo(redeemedQuoteQuantums, totalShares) + + // Redeem from each sub vault. + vaultParamsIterator := k.getVaultParamsIterator(ctx) + defer vaultParamsIterator.Close() + for ; vaultParamsIterator.Valid(); vaultParamsIterator.Next() { + var vaultParams types.VaultParams + k.cdc.MustUnmarshal(vaultParamsIterator.Value(), &vaultParams) + // Skip deactivated vaults. + if vaultParams.Status == types.VaultStatus_VAULT_STATUS_DEACTIVATED { + continue + } + + vaultId, err := types.GetVaultIdFromStateKey(vaultParamsIterator.Key()) + if err != nil { + if txMode { + log.ErrorLogWithError( + ctx, + "Megavault withdrawal: error when getting vault ID from state key. Skipping this vault", + err, + ) + } + continue + } + + _, perpetual, marketParam, marketPrice, err := k.GetVaultClobPerpAndMarket(ctx, *vaultId) + if err != nil { + if txMode { + log.ErrorLogWithError( + ctx, + "Megavault withdrawal: error when getting perpetual and market. Skipping this vault", + err, + "Vault ID", + vaultId, + ) + } + continue + } + leverage, equity, err := k.GetVaultLeverageAndEquity(ctx, *vaultId, &perpetual, &marketPrice) + if err != nil { + if txMode { + log.ErrorLogWithError( + ctx, + "Megavault withdrawal: error when getting vault leverage and equity. Skipping this vault", + err, + "Vault ID", + vaultId, + ) + } + continue + } + + slippage, err := k.GetVaultWithdrawalSlippage( + ctx, + *vaultId, + shares, + totalShares, + leverage, + &perpetual, + &marketParam, + ) + if err != nil { + if txMode { + log.ErrorLogWithError( + ctx, + "Megavault withdrawal: error when getting vault withdrawal slippage. Skipping this vault", + err, + "Vault ID", + vaultId, + ) + } + continue + } + + // Amount redeemed from this sub-vault is `equity * shares / totalShares * (1 - slippage)`. + redeemedFromSubVault := new(big.Rat).SetFrac(equity, big.NewInt(1)) + redeemedFromSubVault.Mul(redeemedFromSubVault, new(big.Rat).SetFrac(shares, totalShares)) + redeemedFromSubVault.Mul(redeemedFromSubVault, new(big.Rat).Sub(lib.BigRat1(), slippage)) + quantumsToTransfer := new(big.Int).Quo(redeemedFromSubVault.Num(), redeemedFromSubVault.Denom()) + + if quantumsToTransfer.Sign() <= 0 || !quantumsToTransfer.IsUint64() { + if txMode { + log.InfoLog( + ctx, + "Megavault withdrawal: quantums to transfer is invalid. Skipping this vault", + "Vault ID", + vaultId, + "Quantums", + quantumsToTransfer, + ) + } + continue + } + if txMode { + // Transfer from sub vault to main vault. + err = k.sendingKeeper.ProcessTransfer( + ctx, + &sendingtypes.Transfer{ + Sender: *vaultId.ToSubaccountId(), + Recipient: types.MegavaultMainSubaccount, + AssetId: assetstypes.AssetUsdc.Id, + Amount: quantumsToTransfer.Uint64(), // validated above. + }, + ) + if err != nil { + log.ErrorLogWithError( + ctx, + "Megavault withdrawal: error when transferring from sub vault to main vault. Skipping this vault", + err, + "Vault ID", + vaultId, + "Quantums", + quantumsToTransfer, + ) + continue + } + } + + // Increment total redeemed quote quantums and record this vault's equity as part of megavault equity. + redeemedQuoteQuantums.Add(redeemedQuoteQuantums, quantumsToTransfer) + megavaultEquity.Add(megavaultEquity, equity) + } + + return redeemedQuoteQuantums, megavaultEquity, totalShares, nil +} diff --git a/protocol/x/vault/types/query.pb.go b/protocol/x/vault/types/query.pb.go index 4eeaa864f5..3a20349960 100644 --- a/protocol/x/vault/types/query.pb.go +++ b/protocol/x/vault/types/query.pb.go @@ -636,6 +636,116 @@ func (m *QueryVaultParamsResponse) GetVaultParams() VaultParams { return VaultParams{} } +// QueryMegavaultWithdrawalInfoRequest is a request type for the +// MegavaultWithdrawalInfo RPC method. +type QueryMegavaultWithdrawalInfoRequest struct { + // Number of shares to withdraw. + SharesToWithdraw NumShares `protobuf:"bytes,1,opt,name=shares_to_withdraw,json=sharesToWithdraw,proto3" json:"shares_to_withdraw"` +} + +func (m *QueryMegavaultWithdrawalInfoRequest) Reset() { *m = QueryMegavaultWithdrawalInfoRequest{} } +func (m *QueryMegavaultWithdrawalInfoRequest) String() string { return proto.CompactTextString(m) } +func (*QueryMegavaultWithdrawalInfoRequest) ProtoMessage() {} +func (*QueryMegavaultWithdrawalInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_478fb8dc0ff21ea6, []int{12} +} +func (m *QueryMegavaultWithdrawalInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMegavaultWithdrawalInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMegavaultWithdrawalInfoRequest.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 *QueryMegavaultWithdrawalInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMegavaultWithdrawalInfoRequest.Merge(m, src) +} +func (m *QueryMegavaultWithdrawalInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryMegavaultWithdrawalInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMegavaultWithdrawalInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMegavaultWithdrawalInfoRequest proto.InternalMessageInfo + +func (m *QueryMegavaultWithdrawalInfoRequest) GetSharesToWithdraw() NumShares { + if m != nil { + return m.SharesToWithdraw + } + return NumShares{} +} + +// QueryMegavaultWithdrawalInfoResponse is a response type for the +// MegavaultWithdrawalInfo RPC method. +type QueryMegavaultWithdrawalInfoResponse struct { + // Number of shares to withdraw. + SharesToWithdraw NumShares `protobuf:"bytes,1,opt,name=shares_to_withdraw,json=sharesToWithdraw,proto3" json:"shares_to_withdraw"` + // Number of quote quantums above `shares` are expected to redeem. + // Withdrawl slippage can be calculated by comparing + // `expected_quote_quantums` with + // `megavault_equity * shares_to_withdraw / total_shares` + ExpectedQuoteQuantums github_com_dydxprotocol_v4_chain_protocol_dtypes.SerializableInt `protobuf:"bytes,2,opt,name=expected_quote_quantums,json=expectedQuoteQuantums,proto3,customtype=github.com/dydxprotocol/v4-chain/protocol/dtypes.SerializableInt" json:"expected_quote_quantums"` + // Equity of megavault (in quote quantums). + MegavaultEquity github_com_dydxprotocol_v4_chain_protocol_dtypes.SerializableInt `protobuf:"bytes,3,opt,name=megavault_equity,json=megavaultEquity,proto3,customtype=github.com/dydxprotocol/v4-chain/protocol/dtypes.SerializableInt" json:"megavault_equity"` + // Total shares in megavault. + TotalShares NumShares `protobuf:"bytes,4,opt,name=total_shares,json=totalShares,proto3" json:"total_shares"` +} + +func (m *QueryMegavaultWithdrawalInfoResponse) Reset() { *m = QueryMegavaultWithdrawalInfoResponse{} } +func (m *QueryMegavaultWithdrawalInfoResponse) String() string { return proto.CompactTextString(m) } +func (*QueryMegavaultWithdrawalInfoResponse) ProtoMessage() {} +func (*QueryMegavaultWithdrawalInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_478fb8dc0ff21ea6, []int{13} +} +func (m *QueryMegavaultWithdrawalInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryMegavaultWithdrawalInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryMegavaultWithdrawalInfoResponse.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 *QueryMegavaultWithdrawalInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryMegavaultWithdrawalInfoResponse.Merge(m, src) +} +func (m *QueryMegavaultWithdrawalInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryMegavaultWithdrawalInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryMegavaultWithdrawalInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryMegavaultWithdrawalInfoResponse proto.InternalMessageInfo + +func (m *QueryMegavaultWithdrawalInfoResponse) GetSharesToWithdraw() NumShares { + if m != nil { + return m.SharesToWithdraw + } + return NumShares{} +} + +func (m *QueryMegavaultWithdrawalInfoResponse) GetTotalShares() NumShares { + if m != nil { + return m.TotalShares + } + return NumShares{} +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "dydxprotocol.vault.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "dydxprotocol.vault.QueryParamsResponse") @@ -649,71 +759,83 @@ func init() { proto.RegisterType((*QueryMegavaultOwnerSharesResponse)(nil), "dydxprotocol.vault.QueryMegavaultOwnerSharesResponse") proto.RegisterType((*QueryVaultParamsRequest)(nil), "dydxprotocol.vault.QueryVaultParamsRequest") proto.RegisterType((*QueryVaultParamsResponse)(nil), "dydxprotocol.vault.QueryVaultParamsResponse") + proto.RegisterType((*QueryMegavaultWithdrawalInfoRequest)(nil), "dydxprotocol.vault.QueryMegavaultWithdrawalInfoRequest") + proto.RegisterType((*QueryMegavaultWithdrawalInfoResponse)(nil), "dydxprotocol.vault.QueryMegavaultWithdrawalInfoResponse") } func init() { proto.RegisterFile("dydxprotocol/vault/query.proto", fileDescriptor_478fb8dc0ff21ea6) } var fileDescriptor_478fb8dc0ff21ea6 = []byte{ - // 939 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xe3, 0x44, - 0x14, 0x8e, 0x93, 0x36, 0xcb, 0x4e, 0xb2, 0x8b, 0x18, 0x42, 0x09, 0xd9, 0xc5, 0xd9, 0x5a, 0x62, - 0x97, 0x76, 0x17, 0x5b, 0x09, 0x8b, 0x90, 0x10, 0x42, 0xbb, 0x3d, 0xc0, 0xf6, 0x00, 0x6d, 0xdc, - 0x8a, 0x03, 0x12, 0x84, 0x49, 0x32, 0x75, 0x8d, 0x1c, 0x8f, 0x63, 0x8f, 0x43, 0x43, 0xd5, 0x0b, - 0x88, 0x03, 0x37, 0x24, 0xae, 0x5c, 0xe0, 0x8e, 0x38, 0x22, 0xfe, 0x83, 0x1e, 0x2b, 0x71, 0x41, - 0x1c, 0x2a, 0xd4, 0xf2, 0x87, 0x20, 0xcf, 0x4c, 0xe2, 0x1f, 0xb1, 0x53, 0x6f, 0x95, 0x4b, 0xe4, - 0xbc, 0x79, 0xef, 0x7b, 0xdf, 0xbc, 0x1f, 0x9f, 0x0d, 0xe4, 0xc1, 0x64, 0x70, 0xe4, 0xb8, 0x84, - 0x92, 0x3e, 0xb1, 0xb4, 0x31, 0xf2, 0x2d, 0xaa, 0x8d, 0x7c, 0xec, 0x4e, 0x54, 0x66, 0x84, 0x30, - 0x7a, 0xae, 0xb2, 0xf3, 0x46, 0xcd, 0x20, 0x06, 0x61, 0x36, 0x2d, 0x78, 0xe2, 0x9e, 0x8d, 0xbb, - 0x06, 0x21, 0x86, 0x85, 0x35, 0xe4, 0x98, 0x1a, 0xb2, 0x6d, 0x42, 0x11, 0x35, 0x89, 0xed, 0x89, - 0xd3, 0xcd, 0x3e, 0xf1, 0x86, 0xc4, 0xd3, 0x7a, 0xc8, 0xc3, 0x3c, 0x81, 0x36, 0x6e, 0xf5, 0x30, - 0x45, 0x2d, 0xcd, 0x41, 0x86, 0x69, 0x33, 0x67, 0xe1, 0xbb, 0x11, 0xe3, 0xe4, 0xf9, 0x3d, 0xd4, - 0xef, 0x13, 0xdf, 0xa6, 0x5e, 0xe4, 0x59, 0xb8, 0x36, 0x53, 0xe8, 0x3b, 0xc8, 0x45, 0xc3, 0x69, - 0xde, 0xb4, 0xfb, 0x79, 0x87, 0xc8, 0xc5, 0x0b, 0xce, 0xd9, 0x2f, 0x3f, 0x57, 0x6a, 0x00, 0x76, - 0x02, 0xb6, 0xbb, 0x0c, 0x54, 0xc7, 0x23, 0x1f, 0x7b, 0x54, 0xf9, 0xae, 0x08, 0x5e, 0x8e, 0x99, - 0x3d, 0x87, 0xd8, 0x1e, 0x86, 0xef, 0x81, 0x32, 0xcf, 0x5e, 0x97, 0xee, 0x49, 0x6f, 0x56, 0xda, - 0x0d, 0x75, 0xbe, 0x7c, 0x2a, 0x8f, 0xd9, 0x2a, 0x9f, 0x9e, 0x37, 0x0b, 0x75, 0x49, 0x17, 0x11, - 0xf0, 0x73, 0xb0, 0x36, 0xc0, 0x07, 0x81, 0x47, 0x77, 0xe4, 0x13, 0x6a, 0xda, 0x46, 0x57, 0x60, - 0x15, 0x19, 0xd6, 0x7a, 0x1a, 0x56, 0x87, 0x7b, 0x0a, 0xc8, 0x95, 0x00, 0x52, 0xaf, 0x09, 0x98, - 0xd8, 0x19, 0xec, 0x80, 0x17, 0x89, 0x83, 0x5d, 0x44, 0x89, 0x3b, 0xc5, 0x2d, 0x31, 0x5c, 0x25, - 0x0d, 0x77, 0x47, 0xb8, 0xc6, 0x80, 0x6f, 0x93, 0x98, 0x55, 0xf9, 0x02, 0xbc, 0xc4, 0x8a, 0xf0, - 0x69, 0x10, 0x22, 0x4a, 0x03, 0x5b, 0x60, 0x85, 0x4e, 0x1c, 0xcc, 0x0a, 0x70, 0xbb, 0xfd, 0x7a, - 0x1a, 0x38, 0xf3, 0xdf, 0x9f, 0x38, 0x58, 0x67, 0xae, 0x70, 0x0d, 0x94, 0x6d, 0x7f, 0xd8, 0xc3, - 0x2e, 0xbb, 0xe9, 0x2d, 0x5d, 0xfc, 0x53, 0xfe, 0x2c, 0x89, 0xe2, 0x8b, 0x04, 0xa2, 0xc8, 0xef, - 0x83, 0x17, 0x18, 0x4e, 0xd7, 0x1c, 0x88, 0x32, 0xdf, 0xc9, 0xcc, 0xb2, 0x3d, 0x10, 0xdc, 0x6f, - 0x8c, 0xf9, 0x5f, 0xd8, 0x01, 0xb7, 0xc2, 0x29, 0x0a, 0x20, 0x78, 0x75, 0xef, 0xc7, 0x21, 0x22, - 0x43, 0xa7, 0xee, 0xcd, 0x9e, 0x67, 0x68, 0x55, 0x2f, 0x62, 0x83, 0x5f, 0x82, 0x32, 0x1e, 0xf9, - 0x26, 0x9d, 0xb0, 0x8a, 0x56, 0xb7, 0x9e, 0x05, 0x3e, 0xff, 0x9c, 0x37, 0x9f, 0x18, 0x26, 0x3d, - 0xf4, 0x7b, 0x6a, 0x9f, 0x0c, 0xb5, 0xf8, 0x98, 0x3d, 0x7e, 0xab, 0x7f, 0x88, 0x4c, 0x5b, 0x9b, - 0x59, 0x06, 0x41, 0x21, 0x3c, 0x75, 0x0f, 0xbb, 0x26, 0xb2, 0xcc, 0x6f, 0x50, 0xcf, 0xc2, 0xdb, - 0x36, 0xd5, 0x05, 0x2e, 0x3c, 0x00, 0x37, 0x4d, 0x7b, 0x8c, 0x6d, 0x4a, 0xdc, 0x49, 0x7d, 0x65, - 0xc9, 0x49, 0x42, 0x68, 0xf8, 0x0c, 0x54, 0x79, 0x69, 0xc5, 0x84, 0xac, 0xb2, 0xda, 0x34, 0x33, - 0xcb, 0x1b, 0x1b, 0x8f, 0xca, 0x38, 0x34, 0x29, 0x5d, 0xf0, 0x0a, 0x6b, 0xdd, 0x53, 0xcb, 0x62, - 0x9e, 0xd3, 0xd5, 0x81, 0x1f, 0x02, 0x10, 0x2e, 0xbc, 0xe8, 0xdf, 0x7d, 0x95, 0xab, 0x83, 0x1a, - 0xa8, 0x83, 0xca, 0xe5, 0x47, 0xa8, 0x83, 0xba, 0x8b, 0x0c, 0x2c, 0x62, 0xf5, 0x48, 0xa4, 0xf2, - 0x8b, 0x04, 0xd6, 0x92, 0x19, 0xc4, 0x80, 0x7c, 0x00, 0xca, 0x8c, 0x4a, 0xb0, 0x85, 0xa5, 0xf9, - 0xde, 0x4e, 0x37, 0x27, 0x39, 0x58, 0xba, 0x88, 0x82, 0x1f, 0xc5, 0x28, 0xf2, 0xf9, 0x78, 0x70, - 0x25, 0x45, 0x01, 0x12, 0xe5, 0xa8, 0x80, 0x7b, 0x2c, 0xcd, 0xc7, 0xd8, 0x40, 0x0c, 0x7b, 0x9f, - 0x50, 0x64, 0xed, 0x05, 0xf2, 0x33, 0x93, 0x12, 0x0c, 0xd6, 0x17, 0xf8, 0x88, 0x1b, 0x3d, 0x01, - 0x55, 0x1a, 0x98, 0xbb, 0x4c, 0xba, 0xa6, 0xea, 0x92, 0xba, 0x5c, 0x9f, 0xf8, 0x43, 0x11, 0x5c, - 0xa1, 0x21, 0x92, 0xf2, 0x55, 0x92, 0xca, 0xce, 0xd7, 0x36, 0x76, 0x63, 0x54, 0x12, 0xad, 0x29, - 0x5d, 0xbb, 0x35, 0xbf, 0x4b, 0xc9, 0x3b, 0xc5, 0x92, 0x89, 0x3b, 0x3d, 0x05, 0x55, 0x12, 0x98, - 0xc3, 0x3b, 0x05, 0xbd, 0x92, 0x53, 0xd5, 0x68, 0x16, 0xae, 0x57, 0x48, 0x08, 0xb5, 0xbc, 0x46, - 0x0d, 0xc0, 0xab, 0xe1, 0x3c, 0xc4, 0xa4, 0x7e, 0x99, 0x7a, 0xf6, 0xab, 0x04, 0xea, 0xf3, 0x69, - 0x96, 0xa2, 0x6a, 0xc9, 0xc5, 0x2d, 0x5e, 0x77, 0x71, 0xdb, 0xbf, 0xdd, 0x00, 0xab, 0x8c, 0x24, - 0x3c, 0x01, 0x65, 0xf1, 0xee, 0xc8, 0x5e, 0xa0, 0x58, 0xad, 0x1a, 0x0f, 0xae, 0xf4, 0xe3, 0x97, - 0x55, 0x94, 0x6f, 0xff, 0xfa, 0xef, 0xa7, 0xe2, 0x5d, 0xd8, 0xd0, 0x32, 0xdf, 0xdf, 0xf0, 0x07, - 0x09, 0xac, 0x32, 0xae, 0xf0, 0x8d, 0xab, 0xf6, 0x97, 0x67, 0xcf, 0xb9, 0xe6, 0x4a, 0x8b, 0x25, - 0x7f, 0x08, 0x37, 0xb4, 0xac, 0x77, 0xbf, 0x76, 0x1c, 0xf4, 0xf1, 0x44, 0x3b, 0xe6, 0x8d, 0x3b, - 0x81, 0xdf, 0x4b, 0xe0, 0xe6, 0x4c, 0x67, 0xe0, 0x46, 0x66, 0xa2, 0xa4, 0xda, 0x35, 0x36, 0xf3, - 0xb8, 0x0a, 0x5e, 0xeb, 0x8c, 0xd7, 0x1d, 0xf8, 0x5a, 0x26, 0x2f, 0xf8, 0x87, 0x04, 0x6a, 0x69, - 0x42, 0x01, 0x1f, 0x67, 0xe6, 0x59, 0xa0, 0x3d, 0x8d, 0x77, 0x9e, 0x33, 0x4a, 0x10, 0x6d, 0x33, - 0xa2, 0x8f, 0xe0, 0x66, 0x1a, 0xd1, 0xe1, 0x34, 0x52, 0x8b, 0x2a, 0x56, 0x9c, 0x79, 0x44, 0x0e, - 0xf2, 0x30, 0x9f, 0x97, 0xaa, 0x3c, 0xcc, 0x53, 0x34, 0x27, 0x2f, 0xf3, 0xa8, 0x2e, 0xc1, 0x9f, - 0x25, 0x50, 0x89, 0xec, 0x0c, 0x7c, 0xb8, 0x78, 0xcc, 0xe2, 0x1b, 0xf1, 0x28, 0x9f, 0x73, 0x1e, - 0x7a, 0x7c, 0x2d, 0x92, 0xa3, 0xb9, 0xd5, 0x39, 0xbd, 0x90, 0xa5, 0xb3, 0x0b, 0x59, 0xfa, 0xf7, - 0x42, 0x96, 0x7e, 0xbc, 0x94, 0x0b, 0x67, 0x97, 0x72, 0xe1, 0xef, 0x4b, 0xb9, 0xf0, 0xd9, 0xbb, - 0xf9, 0xbf, 0x0c, 0x8e, 0x44, 0x0e, 0xf6, 0x81, 0xd0, 0x2b, 0x33, 0xfb, 0xdb, 0xff, 0x07, 0x00, - 0x00, 0xff, 0xff, 0x07, 0x2f, 0xa4, 0x54, 0x1c, 0x0c, 0x00, 0x00, + // 1090 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xcf, 0xe6, 0x8f, 0x69, 0x9f, 0xdd, 0x3f, 0x0c, 0x69, 0x12, 0xdc, 0xe2, 0x34, 0x0b, 0xb4, + 0x24, 0x6d, 0x77, 0x95, 0xd0, 0xaa, 0x08, 0x21, 0xd4, 0x46, 0xa2, 0x34, 0x07, 0x68, 0xed, 0x44, + 0x20, 0x21, 0xc1, 0x32, 0xb6, 0x27, 0xce, 0x22, 0x7b, 0xc7, 0xde, 0x9d, 0x75, 0x62, 0xaa, 0x48, + 0x08, 0xc4, 0x81, 0x1b, 0x12, 0x57, 0x2e, 0xf0, 0x05, 0x38, 0x22, 0xce, 0x5c, 0x7a, 0xac, 0xc4, + 0x05, 0x71, 0xa8, 0x50, 0xc2, 0x37, 0xe0, 0x0b, 0xa0, 0x9d, 0x79, 0x5e, 0xef, 0xda, 0xbb, 0xce, + 0xb6, 0x32, 0x97, 0xc8, 0x99, 0x79, 0xef, 0xf7, 0x7e, 0xf3, 0xfe, 0xfc, 0xde, 0x42, 0xa9, 0xde, + 0xab, 0x1f, 0xb4, 0x5d, 0x2e, 0x78, 0x8d, 0x37, 0xcd, 0x2e, 0xf5, 0x9b, 0xc2, 0xec, 0xf8, 0xcc, + 0xed, 0x19, 0xf2, 0x90, 0x90, 0xe8, 0xbd, 0x21, 0xef, 0x8b, 0xf3, 0x0d, 0xde, 0xe0, 0xf2, 0xcc, + 0x0c, 0x7e, 0x29, 0xcb, 0xe2, 0xa5, 0x06, 0xe7, 0x8d, 0x26, 0x33, 0x69, 0xdb, 0x36, 0xa9, 0xe3, + 0x70, 0x41, 0x85, 0xcd, 0x1d, 0x0f, 0x6f, 0xd7, 0x6a, 0xdc, 0x6b, 0x71, 0xcf, 0xac, 0x52, 0x8f, + 0xa9, 0x00, 0x66, 0x77, 0xbd, 0xca, 0x04, 0x5d, 0x37, 0xdb, 0xb4, 0x61, 0x3b, 0xd2, 0x18, 0x6d, + 0x57, 0x63, 0x9c, 0x3c, 0xbf, 0x4a, 0x6b, 0x35, 0xee, 0x3b, 0xc2, 0x8b, 0xfc, 0x46, 0xd3, 0xe5, + 0x04, 0xfa, 0x6d, 0xea, 0xd2, 0x56, 0x3f, 0x6e, 0xd2, 0xfb, 0xbc, 0x3d, 0xea, 0xb2, 0x31, 0xf7, + 0xf2, 0xaf, 0xba, 0xd7, 0xe7, 0x81, 0x94, 0x03, 0xb6, 0x0f, 0x25, 0x68, 0x85, 0x75, 0x7c, 0xe6, + 0x09, 0xfd, 0x9b, 0x69, 0x78, 0x29, 0x76, 0xec, 0xb5, 0xb9, 0xe3, 0x31, 0xf2, 0x36, 0xe4, 0x54, + 0xf4, 0x25, 0xed, 0xb2, 0xf6, 0x46, 0x7e, 0xa3, 0x68, 0x8c, 0xa6, 0xcf, 0x50, 0x3e, 0x9b, 0xb9, + 0xc7, 0x4f, 0x97, 0xa7, 0x96, 0xb4, 0x0a, 0x7a, 0x90, 0x4f, 0x61, 0xa1, 0xce, 0x76, 0x03, 0x0b, + 0xab, 0xe3, 0x73, 0x61, 0x3b, 0x0d, 0x0b, 0xb1, 0xa6, 0x25, 0xd6, 0x4a, 0x12, 0x56, 0x59, 0x59, + 0x22, 0xe4, 0x6c, 0x00, 0x59, 0x99, 0x47, 0x98, 0xd8, 0x1d, 0x29, 0xc3, 0x39, 0xde, 0x66, 0x2e, + 0x15, 0xdc, 0xed, 0xe3, 0xce, 0x48, 0x5c, 0x3d, 0x09, 0xf7, 0x01, 0x9a, 0xc6, 0x80, 0xcf, 0xf2, + 0xd8, 0xa9, 0xfe, 0x19, 0xbc, 0x28, 0x93, 0xf0, 0x51, 0xe0, 0x82, 0xa9, 0x21, 0xeb, 0x30, 0x2b, + 0x7a, 0x6d, 0x26, 0x13, 0x70, 0x76, 0xe3, 0x95, 0x24, 0x70, 0x69, 0xbf, 0xd3, 0x6b, 0xb3, 0x8a, + 0x34, 0x25, 0x0b, 0x90, 0x73, 0xfc, 0x56, 0x95, 0xb9, 0xf2, 0xa5, 0x67, 0x2a, 0xf8, 0x9f, 0xfe, + 0xdb, 0x0c, 0x26, 0x1f, 0x03, 0x60, 0x92, 0xdf, 0x81, 0x53, 0x12, 0xc7, 0xb2, 0xeb, 0x98, 0xe6, + 0x8b, 0xa9, 0x51, 0xb6, 0xea, 0xc8, 0xfd, 0x85, 0xae, 0xfa, 0x97, 0x94, 0xe1, 0xcc, 0xa0, 0x8b, + 0x02, 0x08, 0x95, 0xdd, 0x2b, 0x71, 0x88, 0x48, 0xd3, 0x19, 0xdb, 0xe1, 0xef, 0x10, 0xad, 0xe0, + 0x45, 0xce, 0xc8, 0xe7, 0x90, 0x63, 0x1d, 0xdf, 0x16, 0x3d, 0x99, 0xd1, 0xc2, 0xe6, 0xfd, 0xc0, + 0xe6, 0xaf, 0xa7, 0xcb, 0x77, 0x1a, 0xb6, 0xd8, 0xf3, 0xab, 0x46, 0x8d, 0xb7, 0xcc, 0x78, 0x9b, + 0xdd, 0xbc, 0x51, 0xdb, 0xa3, 0xb6, 0x63, 0x86, 0x27, 0xf5, 0x20, 0x11, 0x9e, 0xb1, 0xcd, 0x5c, + 0x9b, 0x36, 0xed, 0x2f, 0x69, 0xb5, 0xc9, 0xb6, 0x1c, 0x51, 0x41, 0x5c, 0xb2, 0x0b, 0xa7, 0x6d, + 0xa7, 0xcb, 0x1c, 0xc1, 0xdd, 0xde, 0xd2, 0xec, 0x84, 0x83, 0x0c, 0xa0, 0xc9, 0x7d, 0x28, 0xa8, + 0xd4, 0x62, 0x87, 0xcc, 0xc9, 0xdc, 0x2c, 0xa7, 0xa6, 0x37, 0xd6, 0x1e, 0xf9, 0xee, 0xe0, 0x48, + 0xb7, 0xe0, 0x82, 0x2c, 0xdd, 0xdd, 0x66, 0x53, 0x5a, 0xf6, 0x47, 0x87, 0xdc, 0x03, 0x18, 0x0c, + 0x3c, 0xd6, 0xef, 0x8a, 0xa1, 0xd4, 0xc1, 0x08, 0xd4, 0xc1, 0x50, 0xf2, 0x83, 0xea, 0x60, 0x3c, + 0xa4, 0x0d, 0x86, 0xbe, 0x95, 0x88, 0xa7, 0xfe, 0x93, 0x06, 0x0b, 0xc3, 0x11, 0xb0, 0x41, 0xde, + 0x85, 0x9c, 0xa4, 0x12, 0x4c, 0xe1, 0xcc, 0x68, 0x6d, 0xfb, 0x93, 0x33, 0xdc, 0x58, 0x15, 0xf4, + 0x22, 0xef, 0xc7, 0x28, 0xaa, 0xfe, 0xb8, 0x7a, 0x22, 0x45, 0x04, 0x89, 0x72, 0xd4, 0xe1, 0xb2, + 0x0c, 0xf3, 0x01, 0x6b, 0x50, 0x89, 0xbd, 0xc3, 0x05, 0x6d, 0x6e, 0x07, 0xf2, 0x13, 0x4a, 0x09, + 0x83, 0x95, 0x31, 0x36, 0xf8, 0xa2, 0x3b, 0x50, 0x10, 0xc1, 0xb1, 0x25, 0xa5, 0xab, 0xaf, 0x2e, + 0x89, 0xc3, 0xf5, 0xa1, 0xdf, 0x42, 0xe7, 0xbc, 0x18, 0x20, 0xe9, 0x5f, 0x0c, 0x53, 0x79, 0xb0, + 0xef, 0x30, 0x37, 0x46, 0x65, 0xa8, 0x34, 0x33, 0xcf, 0x5d, 0x9a, 0x5f, 0xb4, 0xe1, 0x37, 0xc5, + 0x82, 0xe1, 0x9b, 0xee, 0x42, 0x81, 0x07, 0xc7, 0x83, 0x37, 0x05, 0xb5, 0x2a, 0x25, 0xaa, 0x51, + 0xe8, 0x5e, 0xc9, 0xf3, 0x01, 0xd4, 0xe4, 0x0a, 0x55, 0x87, 0xc5, 0x41, 0x3f, 0xc4, 0xa4, 0x7e, + 0x92, 0x7a, 0xf6, 0xb3, 0x06, 0x4b, 0xa3, 0x61, 0x26, 0xa2, 0x6a, 0xc3, 0x83, 0x3b, 0xfd, 0xdc, + 0x83, 0x7b, 0x00, 0xaf, 0xc6, 0x6b, 0xf7, 0xb1, 0x2d, 0xf6, 0xea, 0x2e, 0xdd, 0xa7, 0xcd, 0x2d, + 0x67, 0x97, 0xf7, 0xd3, 0x52, 0x06, 0xa2, 0xea, 0x66, 0x09, 0x6e, 0xed, 0xa3, 0x49, 0xa6, 0xbe, + 0xc4, 0xa0, 0xe7, 0x95, 0xfb, 0x0e, 0xef, 0xe3, 0x07, 0x72, 0xff, 0xda, 0xf8, 0xd0, 0x98, 0xaa, + 0xc9, 0xc7, 0x26, 0x5f, 0x69, 0xb0, 0xc8, 0x0e, 0xda, 0xac, 0x26, 0x58, 0x5d, 0xae, 0x5f, 0x66, + 0x75, 0x7c, 0xea, 0x08, 0x1f, 0x73, 0x39, 0x49, 0xbd, 0xbd, 0xd0, 0x0f, 0x14, 0x2c, 0x68, 0x56, + 0xc6, 0x30, 0xc4, 0x83, 0xf3, 0xad, 0xfe, 0xc3, 0xad, 0xff, 0x69, 0x9f, 0x9c, 0x0b, 0x23, 0xbc, + 0xa7, 0x16, 0xcb, 0xbd, 0x21, 0x61, 0x99, 0xcd, 0x9e, 0xc4, 0xa8, 0xbc, 0x6c, 0xfc, 0x7b, 0x0a, + 0xe6, 0x64, 0xed, 0xc8, 0x21, 0xe4, 0xf0, 0x8b, 0x23, 0x5d, 0x76, 0x63, 0x13, 0x56, 0xbc, 0x7a, + 0xa2, 0x9d, 0xaa, 0xbb, 0xae, 0x7f, 0xfd, 0xc7, 0x3f, 0x3f, 0x4c, 0x5f, 0x22, 0x45, 0x33, 0xf5, + 0xab, 0x8f, 0x7c, 0xa7, 0xc1, 0x9c, 0xec, 0x70, 0xf2, 0xfa, 0x49, 0xaa, 0xaf, 0xa2, 0x67, 0x5c, + 0x0e, 0xfa, 0xba, 0x0c, 0x7e, 0x8d, 0xac, 0x9a, 0x69, 0x5f, 0x8c, 0xe6, 0xa3, 0x20, 0xe9, 0x87, + 0xe6, 0x23, 0x35, 0xee, 0x87, 0xe4, 0x5b, 0x0d, 0x4e, 0x87, 0xdb, 0x89, 0xac, 0xa6, 0x06, 0x1a, + 0xde, 0x91, 0xc5, 0xb5, 0x2c, 0xa6, 0xc8, 0x6b, 0x45, 0xf2, 0xba, 0x48, 0x5e, 0x4e, 0xe5, 0x45, + 0x7e, 0xd5, 0x60, 0x3e, 0x69, 0xbd, 0x90, 0x9b, 0xa9, 0x71, 0xc6, 0x6c, 0xac, 0xe2, 0xad, 0x67, + 0xf4, 0x42, 0xa2, 0x1b, 0x92, 0xe8, 0x75, 0xb2, 0x96, 0x44, 0x34, 0xec, 0x4b, 0x33, 0xda, 0x8e, + 0x71, 0xe6, 0x91, 0x25, 0x92, 0x85, 0xf9, 0xe8, 0x82, 0xcb, 0xc2, 0x3c, 0x61, 0x53, 0x65, 0x65, + 0x1e, 0xdd, 0x66, 0xe4, 0x47, 0x0d, 0xf2, 0x11, 0xa5, 0x25, 0xd7, 0xc6, 0xb7, 0x59, 0x7c, 0x22, + 0xae, 0x67, 0x33, 0xce, 0x42, 0x4f, 0x8d, 0xc5, 0x48, 0x6b, 0xfe, 0xae, 0xc1, 0x62, 0x8a, 0xcc, + 0x92, 0xdb, 0x27, 0x67, 0x29, 0x71, 0x27, 0x14, 0xdf, 0x7a, 0x76, 0x47, 0x7c, 0xc2, 0x2d, 0xf9, + 0x04, 0x93, 0xdc, 0x18, 0x9f, 0xe1, 0xfd, 0xd0, 0xdb, 0xb2, 0x9d, 0x5d, 0xbe, 0x59, 0x7e, 0x7c, + 0x54, 0xd2, 0x9e, 0x1c, 0x95, 0xb4, 0xbf, 0x8f, 0x4a, 0xda, 0xf7, 0xc7, 0xa5, 0xa9, 0x27, 0xc7, + 0xa5, 0xa9, 0x3f, 0x8f, 0x4b, 0x53, 0x9f, 0xdc, 0xce, 0x2e, 0x95, 0x07, 0x18, 0x46, 0x2a, 0x66, + 0x35, 0x27, 0xcf, 0xdf, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x82, 0xa3, 0x58, 0x95, 0x18, 0x0f, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -740,6 +862,8 @@ type QueryClient interface { MegavaultOwnerShares(ctx context.Context, in *QueryMegavaultOwnerSharesRequest, opts ...grpc.CallOption) (*QueryMegavaultOwnerSharesResponse, error) // Queries vault params of a vault. VaultParams(ctx context.Context, in *QueryVaultParamsRequest, opts ...grpc.CallOption) (*QueryVaultParamsResponse, error) + // Queries withdrawal info for megavault. + MegavaultWithdrawalInfo(ctx context.Context, in *QueryMegavaultWithdrawalInfoRequest, opts ...grpc.CallOption) (*QueryMegavaultWithdrawalInfoResponse, error) } type queryClient struct { @@ -804,6 +928,15 @@ func (c *queryClient) VaultParams(ctx context.Context, in *QueryVaultParamsReque return out, nil } +func (c *queryClient) MegavaultWithdrawalInfo(ctx context.Context, in *QueryMegavaultWithdrawalInfoRequest, opts ...grpc.CallOption) (*QueryMegavaultWithdrawalInfoResponse, error) { + out := new(QueryMegavaultWithdrawalInfoResponse) + err := c.cc.Invoke(ctx, "/dydxprotocol.vault.Query/MegavaultWithdrawalInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Queries the Params. @@ -818,6 +951,8 @@ type QueryServer interface { MegavaultOwnerShares(context.Context, *QueryMegavaultOwnerSharesRequest) (*QueryMegavaultOwnerSharesResponse, error) // Queries vault params of a vault. VaultParams(context.Context, *QueryVaultParamsRequest) (*QueryVaultParamsResponse, error) + // Queries withdrawal info for megavault. + MegavaultWithdrawalInfo(context.Context, *QueryMegavaultWithdrawalInfoRequest) (*QueryMegavaultWithdrawalInfoResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -842,6 +977,9 @@ func (*UnimplementedQueryServer) MegavaultOwnerShares(ctx context.Context, req * func (*UnimplementedQueryServer) VaultParams(ctx context.Context, req *QueryVaultParamsRequest) (*QueryVaultParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method VaultParams not implemented") } +func (*UnimplementedQueryServer) MegavaultWithdrawalInfo(ctx context.Context, req *QueryMegavaultWithdrawalInfoRequest) (*QueryMegavaultWithdrawalInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MegavaultWithdrawalInfo not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -955,6 +1093,24 @@ func _Query_VaultParams_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Query_MegavaultWithdrawalInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryMegavaultWithdrawalInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).MegavaultWithdrawalInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dydxprotocol.vault.Query/MegavaultWithdrawalInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).MegavaultWithdrawalInfo(ctx, req.(*QueryMegavaultWithdrawalInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "dydxprotocol.vault.Query", HandlerType: (*QueryServer)(nil), @@ -983,6 +1139,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "VaultParams", Handler: _Query_VaultParams_Handler, }, + { + MethodName: "MegavaultWithdrawalInfo", + Handler: _Query_MegavaultWithdrawalInfo_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "dydxprotocol/vault/query.proto", @@ -1472,6 +1632,102 @@ func (m *QueryVaultParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *QueryMegavaultWithdrawalInfoRequest) 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 *QueryMegavaultWithdrawalInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMegavaultWithdrawalInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.SharesToWithdraw.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 (m *QueryMegavaultWithdrawalInfoResponse) 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 *QueryMegavaultWithdrawalInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryMegavaultWithdrawalInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.TotalShares.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size := m.MegavaultEquity.Size() + i -= size + if _, err := m.MegavaultEquity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size := m.ExpectedQuoteQuantums.Size() + i -= size + if _, err := m.ExpectedQuoteQuantums.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.SharesToWithdraw.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 { offset -= sovQuery(v) base := offset @@ -1655,6 +1911,34 @@ func (m *QueryVaultParamsResponse) Size() (n int) { return n } +func (m *QueryMegavaultWithdrawalInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.SharesToWithdraw.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryMegavaultWithdrawalInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.SharesToWithdraw.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.ExpectedQuoteQuantums.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.MegavaultEquity.Size() + n += 1 + l + sovQuery(uint64(l)) + l = m.TotalShares.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2915,6 +3199,271 @@ func (m *QueryVaultParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryMegavaultWithdrawalInfoRequest) 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: QueryMegavaultWithdrawalInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMegavaultWithdrawalInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SharesToWithdraw", 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 + } + if err := m.SharesToWithdraw.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 (m *QueryMegavaultWithdrawalInfoResponse) 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: QueryMegavaultWithdrawalInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryMegavaultWithdrawalInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SharesToWithdraw", 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 + } + if err := m.SharesToWithdraw.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpectedQuoteQuantums", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExpectedQuoteQuantums.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MegavaultEquity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MegavaultEquity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalShares", 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 + } + if err := m.TotalShares.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) { l := len(dAtA) iNdEx := 0 diff --git a/protocol/x/vault/types/query.pb.gw.go b/protocol/x/vault/types/query.pb.gw.go index 332ed011bd..87c4c5c0a8 100644 --- a/protocol/x/vault/types/query.pb.gw.go +++ b/protocol/x/vault/types/query.pb.gw.go @@ -305,6 +305,42 @@ func local_request_Query_VaultParams_0(ctx context.Context, marshaler runtime.Ma } +var ( + filter_Query_MegavaultWithdrawalInfo_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_MegavaultWithdrawalInfo_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMegavaultWithdrawalInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_MegavaultWithdrawalInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.MegavaultWithdrawalInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_MegavaultWithdrawalInfo_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryMegavaultWithdrawalInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_MegavaultWithdrawalInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.MegavaultWithdrawalInfo(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -449,6 +485,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_MegavaultWithdrawalInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_MegavaultWithdrawalInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_MegavaultWithdrawalInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -610,6 +669,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_MegavaultWithdrawalInfo_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_MegavaultWithdrawalInfo_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_MegavaultWithdrawalInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -625,6 +704,8 @@ var ( pattern_Query_MegavaultOwnerShares_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"dydxprotocol", "vault", "megavault", "owner_shares"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_VaultParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"dydxprotocol", "vault", "params", "type", "number"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_MegavaultWithdrawalInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"dydxprotocol", "vault", "megavault", "withdrawal_info"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -639,4 +720,6 @@ var ( forward_Query_MegavaultOwnerShares_0 = runtime.ForwardResponseMessage forward_Query_VaultParams_0 = runtime.ForwardResponseMessage + + forward_Query_MegavaultWithdrawalInfo_0 = runtime.ForwardResponseMessage )