Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow operator and governance to retrieve from vaults #2290

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a type alias instead of an empty interface.

The MsgRetrieveFromVaultResponse interface is currently empty, which is equivalent to {}. Using an empty interface is not recommended as it can lead to confusion and maintenance issues.

Consider using a type alias instead:

-export interface MsgRetrieveFromVaultResponse {}
+export type MsgRetrieveFromVaultResponse = Record<string, never>;

This provides a cleaner and more explicit way to represent an empty type.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface MsgRetrieveFromVaultResponse {}
export type MsgRetrieveFromVaultResponse = Record<string, never>;
Tools
Biome

[error] 233-233: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

/** MsgRetrieveFromVaultResponse is the Msg/RetrieveFromVault response type. */

export interface MsgRetrieveFromVaultResponseSDKType {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a type alias instead of an empty interface.

The MsgRetrieveFromVaultResponseSDKType interface is currently empty, which is equivalent to {}. Using an empty interface is not recommended as it can lead to confusion and maintenance issues.

Consider using a type alias instead:

-export interface MsgRetrieveFromVaultResponseSDKType {}
+export type MsgRetrieveFromVaultResponseSDKType = Record<string, never>;

This provides a cleaner and more explicit way to represent an empty type.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface MsgRetrieveFromVaultResponseSDKType {}
export type MsgRetrieveFromVaultResponseSDKType = Record<string, never>;
Tools
Biome

[error] 236-236: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)


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
Loading