Skip to content

Commit

Permalink
allow megavault operator to set vault params (#2262)
Browse files Browse the repository at this point in the history
  • Loading branch information
tqin7 committed Sep 17, 2024
1 parent 0330ae7 commit 0051e87
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 27 deletions.
2 changes: 0 additions & 2 deletions protocol/app/msgs/internal_msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,6 @@ var (
"/dydxprotocol.stats.MsgUpdateParamsResponse": nil,

// vault
"/dydxprotocol.vault.MsgSetVaultParams": &vault.MsgSetVaultParams{},
"/dydxprotocol.vault.MsgSetVaultParamsResponse": nil,
"/dydxprotocol.vault.MsgUnlockShares": &vault.MsgUnlockShares{},
"/dydxprotocol.vault.MsgUnlockSharesResponse": nil,
"/dydxprotocol.vault.MsgUpdateDefaultQuotingParams": &vault.MsgUpdateDefaultQuotingParams{},
Expand Down
2 changes: 0 additions & 2 deletions protocol/app/msgs/internal_msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ func TestInternalMsgSamples_Gov_Key(t *testing.T) {
"/dydxprotocol.stats.MsgUpdateParamsResponse",

// vault
"/dydxprotocol.vault.MsgSetVaultParams",
"/dydxprotocol.vault.MsgSetVaultParamsResponse",
"/dydxprotocol.vault.MsgUnlockShares",
"/dydxprotocol.vault.MsgUnlockSharesResponse",
"/dydxprotocol.vault.MsgUpdateDefaultQuotingParams",
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 @@ -248,6 +248,8 @@ var (
// vault
"/dydxprotocol.vault.MsgDepositToMegavault": &vault.MsgDepositToMegavault{},
"/dydxprotocol.vault.MsgDepositToMegavaultResponse": nil,
"/dydxprotocol.vault.MsgSetVaultParams": &vault.MsgSetVaultParams{},
"/dydxprotocol.vault.MsgSetVaultParamsResponse": nil,
}

NormalMsgsSlinky = map[string]sdk.Msg{
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 @@ -149,6 +149,8 @@ func TestNormalMsgs_Key(t *testing.T) {
// vault
"/dydxprotocol.vault.MsgDepositToMegavault",
"/dydxprotocol.vault.MsgDepositToMegavaultResponse",
"/dydxprotocol.vault.MsgSetVaultParams",
"/dydxprotocol.vault.MsgSetVaultParamsResponse",

// ibc application module: ICA
"/ibc.applications.interchain_accounts.v1.InterchainAccount",
Expand Down
1 change: 0 additions & 1 deletion protocol/lib/ante/internal_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ func IsInternalMsg(msg sdk.Msg) bool {
*stats.MsgUpdateParams,

// vault
*vault.MsgSetVaultParams,
*vault.MsgUnlockShares,
*vault.MsgUpdateDefaultQuotingParams,
*vault.MsgUpdateOperatorParams,
Expand Down
69 changes: 69 additions & 0 deletions protocol/x/vault/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cli

import (
"encoding/json"
"fmt"
"strconv"

"github.com/spf13/cast"
"github.com/spf13/cobra"
Expand All @@ -25,6 +27,7 @@ func GetTxCmd() *cobra.Command {
}

cmd.AddCommand(CmdDepositToMegavault())
cmd.AddCommand(CmdSetVaultParams())

return cmd
}
Expand Down Expand Up @@ -72,3 +75,69 @@ func CmdDepositToMegavault() *cobra.Command {

return cmd
}

func CmdSetVaultParams() *cobra.Command {
cmd := &cobra.Command{
Use: "set-vault-params [authority] [vault_type] [vault_number] [status] [quoting_params_json]",
Short: "Broadcast message SetVaultParams",
Args: cobra.ExactArgs(5),
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 status.
status, err := GetVaultStatusFromString(args[3])
if err != nil {
return err
}

// Parse quoting_params (optional).
var quotingParams *types.QuotingParams
if args[4] != "" {
if err := json.Unmarshal([]byte(args[4]), &quotingParams); err != nil {
return fmt.Errorf("invalid quoting params JSON: %w", err)
}
}

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

// Create MsgSetVaultParams.
msg := &types.MsgSetVaultParams{
Authority: args[0],
VaultId: types.VaultId{
Type: vaultType,
Number: uint32(vaultNumber),
},
VaultParams: types.VaultParams{
Status: status,
QuotingParams: quotingParams, // nil if not provided.
},
}

// Validate vault params.
if err := msg.VaultParams.Validate(); err != nil {
return err
}

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

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

return cmd
}
21 changes: 21 additions & 0 deletions protocol/x/vault/client/cli/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,24 @@ func GetVaultTypeFromString(rawType string) (vaultType types.VaultType, err erro
return vaultType, fmt.Errorf("invalid vault type: %s", rawType)
}
}

// GetVaultStatusFromString returns a vault status from a string.
func GetVaultStatusFromString(rawStatus string) (vaultStatus types.VaultStatus, err error) {
switch rawStatus {
case "deactivated":
return types.VaultStatus_VAULT_STATUS_DEACTIVATED, nil
case "stand_by":
return types.VaultStatus_VAULT_STATUS_STAND_BY, nil
case "quoting":
return types.VaultStatus_VAULT_STATUS_QUOTING, nil
case "close_only":
return types.VaultStatus_VAULT_STATUS_CLOSE_ONLY, nil
default:
return vaultStatus, fmt.Errorf(`invalid vault status: %s.
options are:
- deactivated
- stand_by
- quoting
- close_only`, rawStatus)
}
}
9 changes: 5 additions & 4 deletions protocol/x/vault/keeper/msg_server_set_vault_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ func (k msgServer) SetVaultParams(
goCtx context.Context,
msg *types.MsgSetVaultParams,
) (*types.MsgSetVaultParamsResponse, error) {
// Check if authority is valid.
if !k.HasAuthority(msg.Authority) {
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(
govtypes.ErrInvalidSigner,
"invalid authority %s",
msg.Authority,
)
}

ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName)

// Validate parameters.
if err := msg.VaultParams.Validate(); err != nil {
return nil, err
Expand Down
65 changes: 47 additions & 18 deletions protocol/x/vault/keeper/msg_server_set_vault_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,71 @@ import (
testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app"
"github.com/dydxprotocol/v4-chain/protocol/testutil/constants"

"github.com/cometbft/cometbft/types"
"github.com/dydxprotocol/v4-chain/protocol/x/vault/keeper"
"github.com/dydxprotocol/v4-chain/protocol/x/vault/types"
vaulttypes "github.com/dydxprotocol/v4-chain/protocol/x/vault/types"
"github.com/stretchr/testify/require"
)

func TestMsgSetVaultParams(t *testing.T) {
tests := map[string]struct {
// Operator.
operator string
// Msg.
msg *types.MsgSetVaultParams
msg *vaulttypes.MsgSetVaultParams
// Expected error
expectedErr string
}{
"Success - Vault Clob 0": {
msg: &types.MsgSetVaultParams{
"Success - Gov Authority, Vault Clob 0": {
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: lib.GovModuleAddress.String(),
VaultId: constants.Vault_Clob0,
VaultParams: constants.VaultParams,
},
},
"Success - Vault Clob 1": {
msg: &types.MsgSetVaultParams{
"Success - Gov Authority, Vault Clob 1": {
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: lib.GovModuleAddress.String(),
VaultId: constants.Vault_Clob1,
VaultParams: constants.VaultParams,
},
},
"Failure - Invalid Authority": {
msg: &types.MsgSetVaultParams{
"Success - Operator Authority, Vault Clob 1": {
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: constants.AliceAccAddress.String(),
VaultId: constants.Vault_Clob1,
VaultParams: constants.VaultParams,
},
},
"Failure - Invalid Authority": {
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: constants.BobAccAddress.String(), // not a module authority or operator.
VaultId: constants.Vault_Clob0,
VaultParams: constants.VaultParams,
},
expectedErr: "invalid authority",
},
"Failure - Empty Authority": {
msg: &types.MsgSetVaultParams{
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: "",
VaultId: constants.Vault_Clob0,
VaultParams: constants.VaultParams,
},
expectedErr: "invalid authority",
},
"Failure - Vault Clob 0. Invalid Quoting Params": {
msg: &types.MsgSetVaultParams{
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: lib.GovModuleAddress.String(),
VaultId: constants.Vault_Clob0,
VaultParams: types.VaultParams{
Status: types.VaultStatus_VAULT_STATUS_STAND_BY,
QuotingParams: &types.QuotingParams{
VaultParams: vaulttypes.VaultParams{
Status: vaulttypes.VaultStatus_VAULT_STATUS_STAND_BY,
QuotingParams: &vaulttypes.QuotingParams{
Layers: 3,
SpreadMinPpm: 4_000,
SpreadBufferPpm: 2_000,
Expand All @@ -68,23 +84,36 @@ func TestMsgSetVaultParams(t *testing.T) {
},
},
},
expectedErr: types.ErrInvalidActivationThresholdQuoteQuantums.Error(),
expectedErr: vaulttypes.ErrInvalidActivationThresholdQuoteQuantums.Error(),
},
"Failure - Vault Clob 1. Unspecified status": {
msg: &types.MsgSetVaultParams{
operator: constants.AliceAccAddress.String(),
msg: &vaulttypes.MsgSetVaultParams{
Authority: lib.GovModuleAddress.String(),
VaultId: constants.Vault_Clob0,
VaultParams: types.VaultParams{
VaultParams: vaulttypes.VaultParams{
QuotingParams: &constants.QuotingParams,
},
},
expectedErr: types.ErrUnspecifiedVaultStatus.Error(),
expectedErr: vaulttypes.ErrUnspecifiedVaultStatus.Error(),
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
tApp := testapp.NewTestAppBuilder(t).Build()
tApp := testapp.NewTestAppBuilder(t).WithGenesisDocFn(func() (genesis types.GenesisDoc) {
genesis = testapp.DefaultGenesis()
// Set megavault operator.
testapp.UpdateGenesisDocWithAppStateForModule(
&genesis,
func(genesisState *vaulttypes.GenesisState) {
genesisState.OperatorParams = vaulttypes.OperatorParams{
Operator: tc.operator,
}
},
)
return genesis
}).Build()
ctx := tApp.InitChain()
k := tApp.App.VaultKeeper
ms := keeper.NewMsgServerImpl(k)
Expand Down

0 comments on commit 0051e87

Please sign in to comment.