Skip to content

Commit

Permalink
allow operator and governance to retrieve from vaults (#2290)
Browse files Browse the repository at this point in the history
  • Loading branch information
tqin7 committed Sep 18, 2024
1 parent 036d234 commit b37ff5e
Show file tree
Hide file tree
Showing 10 changed files with 1,006 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Rpc } from "../../helpers";
import * as _m0 from "protobufjs/minimal";
import { MsgDepositToMegavault, MsgDepositToMegavaultResponse, MsgUpdateDefaultQuotingParams, MsgUpdateDefaultQuotingParamsResponse, MsgUpdateOperatorParams, MsgUpdateOperatorParamsResponse, MsgSetVaultParams, MsgSetVaultParamsResponse, MsgUnlockShares, MsgUnlockSharesResponse, MsgAllocateToVault, MsgAllocateToVaultResponse } from "./tx";
import { MsgDepositToMegavault, MsgDepositToMegavaultResponse, MsgUpdateDefaultQuotingParams, MsgUpdateDefaultQuotingParamsResponse, MsgUpdateOperatorParams, MsgUpdateOperatorParamsResponse, MsgSetVaultParams, MsgSetVaultParamsResponse, MsgUnlockShares, MsgUnlockSharesResponse, MsgAllocateToVault, MsgAllocateToVaultResponse, MsgRetrieveFromVault, MsgRetrieveFromVaultResponse } from "./tx";
/** Msg defines the Msg service. */

export interface Msg {
Expand All @@ -24,6 +24,9 @@ export interface Msg {
/** AllocateToVault allocates funds from main vault to a vault. */

allocateToVault(request: MsgAllocateToVault): Promise<MsgAllocateToVaultResponse>;
/** RetrieveFromVault retrieves funds from a vault to main vault. */

retrieveFromVault(request: MsgRetrieveFromVault): Promise<MsgRetrieveFromVaultResponse>;
}
export class MsgClientImpl implements Msg {
private readonly rpc: Rpc;
Expand All @@ -36,6 +39,7 @@ export class MsgClientImpl implements Msg {
this.setVaultParams = this.setVaultParams.bind(this);
this.unlockShares = this.unlockShares.bind(this);
this.allocateToVault = this.allocateToVault.bind(this);
this.retrieveFromVault = this.retrieveFromVault.bind(this);
}

depositToMegavault(request: MsgDepositToMegavault): Promise<MsgDepositToMegavaultResponse> {
Expand Down Expand Up @@ -74,4 +78,10 @@ export class MsgClientImpl implements Msg {
return promise.then(data => MsgAllocateToVaultResponse.decode(new _m0.Reader(data)));
}

retrieveFromVault(request: MsgRetrieveFromVault): Promise<MsgRetrieveFromVaultResponse> {
const data = MsgRetrieveFromVault.encode(request).finish();
const promise = this.rpc.request("dydxprotocol.vault.Msg", "RetrieveFromVault", data);
return promise.then(data => MsgRetrieveFromVaultResponse.decode(new _m0.Reader(data)));
}

}
127 changes: 127 additions & 0 deletions indexer/packages/v4-protos/src/codegen/dydxprotocol/vault/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,34 @@ export interface MsgAllocateToVaultResponse {}
/** MsgAllocateToVaultResponse is the Msg/AllocateToVault response type. */

export interface MsgAllocateToVaultResponseSDKType {}
/** MsgRetrieveFromVault is the Msg/RetrieveFromVault request type. */

export interface MsgRetrieveFromVault {
authority: string;
/** The vault to retrieve from. */

vaultId?: VaultId;
/** Number of quote quantums to retrieve. */

quoteQuantums: Uint8Array;
}
/** MsgRetrieveFromVault is the Msg/RetrieveFromVault request type. */

export interface MsgRetrieveFromVaultSDKType {
authority: string;
/** The vault to retrieve from. */

vault_id?: VaultIdSDKType;
/** Number of quote quantums to retrieve. */

quote_quantums: Uint8Array;
}
/** MsgRetrieveFromVaultResponse is the Msg/RetrieveFromVault response type. */

export interface MsgRetrieveFromVaultResponse {}
/** MsgRetrieveFromVaultResponse is the Msg/RetrieveFromVault response type. */

export interface MsgRetrieveFromVaultResponseSDKType {}

function createBaseMsgDepositToMegavault(): MsgDepositToMegavault {
return {
Expand Down Expand Up @@ -836,4 +864,103 @@ export const MsgAllocateToVaultResponse = {
return message;
}

};

function createBaseMsgRetrieveFromVault(): MsgRetrieveFromVault {
return {
authority: "",
vaultId: undefined,
quoteQuantums: new Uint8Array()
};
}

export const MsgRetrieveFromVault = {
encode(message: MsgRetrieveFromVault, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.authority !== "") {
writer.uint32(10).string(message.authority);
}

if (message.vaultId !== undefined) {
VaultId.encode(message.vaultId, writer.uint32(18).fork()).ldelim();
}

if (message.quoteQuantums.length !== 0) {
writer.uint32(26).bytes(message.quoteQuantums);
}

return writer;
},

decode(input: _m0.Reader | Uint8Array, length?: number): MsgRetrieveFromVault {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseMsgRetrieveFromVault();

while (reader.pos < end) {
const tag = reader.uint32();

switch (tag >>> 3) {
case 1:
message.authority = reader.string();
break;

case 2:
message.vaultId = VaultId.decode(reader, reader.uint32());
break;

case 3:
message.quoteQuantums = reader.bytes();
break;

default:
reader.skipType(tag & 7);
break;
}
}

return message;
},

fromPartial(object: DeepPartial<MsgRetrieveFromVault>): MsgRetrieveFromVault {
const message = createBaseMsgRetrieveFromVault();
message.authority = object.authority ?? "";
message.vaultId = object.vaultId !== undefined && object.vaultId !== null ? VaultId.fromPartial(object.vaultId) : undefined;
message.quoteQuantums = object.quoteQuantums ?? new Uint8Array();
return message;
}

};

function createBaseMsgRetrieveFromVaultResponse(): MsgRetrieveFromVaultResponse {
return {};
}

export const MsgRetrieveFromVaultResponse = {
encode(_: MsgRetrieveFromVaultResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
return writer;
},

decode(input: _m0.Reader | Uint8Array, length?: number): MsgRetrieveFromVaultResponse {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseMsgRetrieveFromVaultResponse();

while (reader.pos < end) {
const tag = reader.uint32();

switch (tag >>> 3) {
default:
reader.skipType(tag & 7);
break;
}
}

return message;
},

fromPartial(_: DeepPartial<MsgRetrieveFromVaultResponse>): MsgRetrieveFromVaultResponse {
const message = createBaseMsgRetrieveFromVaultResponse();
return message;
}

};
24 changes: 24 additions & 0 deletions proto/dydxprotocol/vault/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ service Msg {

// AllocateToVault allocates funds from main vault to a vault.
rpc AllocateToVault(MsgAllocateToVault) returns (MsgAllocateToVaultResponse);

// RetrieveFromVault retrieves funds from a vault to main vault.
rpc RetrieveFromVault(MsgRetrieveFromVault)
returns (MsgRetrieveFromVaultResponse);
}

// MsgDepositToMegavault deposits the specified asset from the subaccount to
Expand Down Expand Up @@ -152,3 +156,23 @@ message MsgAllocateToVault {

// MsgAllocateToVaultResponse is the Msg/AllocateToVault response type.
message MsgAllocateToVaultResponse {}

// MsgRetrieveFromVault is the Msg/RetrieveFromVault request type.
message MsgRetrieveFromVault {
// The address that has the authority to retrieve from a vault.
option (cosmos.msg.v1.signer) = "authority";
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];

// The vault to retrieve from.
VaultId vault_id = 2 [ (gogoproto.nullable) = false ];

// Number of quote quantums to retrieve.
bytes quote_quantums = 3 [
(gogoproto.customtype) =
"github.com/dydxprotocol/v4-chain/protocol/dtypes.SerializableInt",
(gogoproto.nullable) = false
];
}

// MsgRetrieveFromVaultResponse is the Msg/RetrieveFromVault response type.
message MsgRetrieveFromVaultResponse {}
2 changes: 2 additions & 0 deletions protocol/app/msgs/all_msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ var (
"/dydxprotocol.vault.MsgAllocateToVaultResponse": {},
"/dydxprotocol.vault.MsgDepositToMegavault": {},
"/dydxprotocol.vault.MsgDepositToMegavaultResponse": {},
"/dydxprotocol.vault.MsgRetrieveFromVault": {},
"/dydxprotocol.vault.MsgRetrieveFromVaultResponse": {},
"/dydxprotocol.vault.MsgSetVaultParams": {},
"/dydxprotocol.vault.MsgSetVaultParamsResponse": {},
"/dydxprotocol.vault.MsgUnlockShares": {},
Expand Down
2 changes: 2 additions & 0 deletions protocol/app/msgs/normal_msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ var (
"/dydxprotocol.vault.MsgAllocateToVaultResponse": nil,
"/dydxprotocol.vault.MsgDepositToMegavault": &vault.MsgDepositToMegavault{},
"/dydxprotocol.vault.MsgDepositToMegavaultResponse": nil,
"/dydxprotocol.vault.MsgRetrieveFromVault": &vault.MsgRetrieveFromVault{},
"/dydxprotocol.vault.MsgRetrieveFromVaultResponse": nil,
"/dydxprotocol.vault.MsgSetVaultParams": &vault.MsgSetVaultParams{},
"/dydxprotocol.vault.MsgSetVaultParamsResponse": nil,
}
Expand Down
2 changes: 2 additions & 0 deletions protocol/app/msgs/normal_msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ func TestNormalMsgs_Key(t *testing.T) {
"/dydxprotocol.vault.MsgAllocateToVaultResponse",
"/dydxprotocol.vault.MsgDepositToMegavault",
"/dydxprotocol.vault.MsgDepositToMegavaultResponse",
"/dydxprotocol.vault.MsgRetrieveFromVault",
"/dydxprotocol.vault.MsgRetrieveFromVaultResponse",
"/dydxprotocol.vault.MsgSetVaultParams",
"/dydxprotocol.vault.MsgSetVaultParamsResponse",

Expand Down
51 changes: 51 additions & 0 deletions protocol/x/vault/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(CmdDepositToMegavault())
cmd.AddCommand(CmdSetVaultParams())
cmd.AddCommand(CmdAllocateToVault())
cmd.AddCommand(CmdRetrieveFromVault())

return cmd
}
Expand Down Expand Up @@ -192,3 +193,53 @@ func CmdAllocateToVault() *cobra.Command {

return cmd
}

func CmdRetrieveFromVault() *cobra.Command {
cmd := &cobra.Command{
Use: "retrieve-from-vault [authority] [vault_type] [vault_number] [quote_quantums]",
Short: "Broadcast message RetrieveFromVault",
Args: cobra.ExactArgs(4),
RunE: func(cmd *cobra.Command, args []string) (err error) {
// Parse vault type.
vaultType, err := GetVaultTypeFromString(args[1])
if err != nil {
return err
}

// Parse vault number.
vaultNumber, err := strconv.ParseUint(args[2], 10, 32)
if err != nil {
return err
}

// Parse quantums.
quantums, err := cast.ToUint64E(args[3])
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

// Create MsgRetrieveFromVault.
msg := &types.MsgRetrieveFromVault{
Authority: args[0],
VaultId: types.VaultId{
Type: vaultType,
Number: uint32(vaultNumber),
},
QuoteQuantums: dtypes.NewIntFromUint64(quantums),
}

// Broadcast or generate the transaction.
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

// Add the necessary flags.
flags.AddTxFlagsToCmd(cmd)

return cmd
}
47 changes: 47 additions & 0 deletions protocol/x/vault/keeper/msg_server_retrieve_from_vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package keeper

import (
"context"

errorsmod "cosmossdk.io/errors"

"github.com/dydxprotocol/v4-chain/protocol/lib"
assetstypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types"
"github.com/dydxprotocol/v4-chain/protocol/x/vault/types"
)

// RetrieveFromVault retrieves funds from a vault to main vault.
func (k msgServer) RetrieveFromVault(
goCtx context.Context,
msg *types.MsgRetrieveFromVault,
) (*types.MsgRetrieveFromVaultResponse, error) {
ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName)
operator := k.GetOperatorParams(ctx).Operator

// Check if authority is valid (must be a module authority or operator).
if !k.HasAuthority(msg.Authority) && msg.Authority != operator {
return nil, errorsmod.Wrapf(
types.ErrInvalidAuthority,
"invalid authority %s",
msg.Authority,
)
}

// Check if vault exists.
if _, exists := k.Keeper.GetVaultParams(ctx, msg.VaultId); !exists {
return nil, types.ErrVaultParamsNotFound
}

// Transfer from specified vault to main vault.
if err := k.Keeper.subaccountsKeeper.TransferFundsFromSubaccountToSubaccount(
ctx,
*msg.VaultId.ToSubaccountId(),
types.MegavaultMainSubaccount,
assetstypes.AssetUsdc.Id,
msg.QuoteQuantums.BigInt(),
); err != nil {
return nil, err
}

return &types.MsgRetrieveFromVaultResponse{}, nil
}
Loading

0 comments on commit b37ff5e

Please sign in to comment.