From 90e88d622cd3e907800509440b159605ed42d097 Mon Sep 17 00:00:00 2001 From: Tian Qin Date: Thu, 1 Aug 2024 15:23:06 -0400 Subject: [PATCH] return empty vault orders if clob pair does not exist or is in final settlement --- protocol/x/vault/keeper/orders.go | 36 ++++++++--------- protocol/x/vault/keeper/orders_test.go | 56 ++++++++++++++++---------- protocol/x/vault/types/errors.go | 40 +++++++++--------- 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/protocol/x/vault/keeper/orders.go b/protocol/x/vault/keeper/orders.go index 990867eb550..52123bcfb55 100644 --- a/protocol/x/vault/keeper/orders.go +++ b/protocol/x/vault/keeper/orders.go @@ -151,11 +151,8 @@ func (k Keeper) GetVaultClobOrders( ) (orders []*clobtypes.Order, err error) { // Get clob pair, perpetual, market parameter, and market price that correspond to this vault. clobPair, exists := k.clobKeeper.GetClobPair(ctx, clobtypes.ClobPairId(vaultId.Number)) - if !exists { - return orders, errorsmod.Wrap( - types.ErrClobPairNotFound, - fmt.Sprintf("VaultId: %v", vaultId), - ) + if !exists || clobPair.Status == clobtypes.ClobPair_STATUS_FINAL_SETTLEMENT { + return []*clobtypes.Order{}, nil } perpId := clobPair.Metadata.(*clobtypes.ClobPair_PerpetualClobMetadata).PerpetualClobMetadata.PerpetualId perpetual, err := k.perpetualsKeeper.GetPerpetual(ctx, perpId) @@ -349,11 +346,19 @@ func (k Keeper) GetVaultClobOrders( } } - orderIds, err := k.GetVaultClobOrderIds(ctx, vaultId) - if err != nil { - return orders, err - } + orderIds := k.GetVaultClobOrderIds(ctx, vaultId) orders = make([]*clobtypes.Order, 2*params.Layers) + if len(orders) != len(orderIds) { // sanity check + return orders, errorsmod.Wrap( + types.ErrOrdersAndOrderIdsDiffLen, + fmt.Sprintf( + "VaultId: %v, len(Orders):%d, len(OrderIds):%d", + vaultId, + len(orders), + len(orderIds), + ), + ) + } for i := uint32(0); i < params.Layers; i++ { // Construct ask at this layer. orders[2*i] = constructOrder(clobtypes.Order_SIDE_SELL, i, orderIds[2*i]) @@ -372,14 +377,7 @@ func (k Keeper) GetVaultClobOrders( func (k Keeper) GetVaultClobOrderIds( ctx sdk.Context, vaultId types.VaultId, -) (orderIds []*clobtypes.OrderId, err error) { - clobPair, exists := k.clobKeeper.GetClobPair(ctx, clobtypes.ClobPairId(vaultId.Number)) - if !exists { - return orderIds, errorsmod.Wrap( - types.ErrClobPairNotFound, - fmt.Sprintf("VaultId: %v", vaultId), - ) - } +) (orderIds []*clobtypes.OrderId) { vault := vaultId.ToSubaccountId() constructOrderId := func( side clobtypes.Order_Side, @@ -389,7 +387,7 @@ func (k Keeper) GetVaultClobOrderIds( SubaccountId: *vault, ClientId: types.GetVaultClobOrderClientId(side, uint8(layer)), OrderFlags: clobtypes.OrderIdFlags_LongTerm, - ClobPairId: clobPair.Id, + ClobPairId: clobtypes.ClobPairId(vaultId.Number).ToUint32(), } } @@ -403,7 +401,7 @@ func (k Keeper) GetVaultClobOrderIds( orderIds[2*i+1] = constructOrderId(clobtypes.Order_SIDE_BUY, i) } - return orderIds, nil + return orderIds } // PlaceVaultClobOrder places a vault CLOB order internal to the protocol, skipping various diff --git a/protocol/x/vault/keeper/orders_test.go b/protocol/x/vault/keeper/orders_test.go index 70a8c2f1b25..b814b3dddae 100644 --- a/protocol/x/vault/keeper/orders_test.go +++ b/protocol/x/vault/keeper/orders_test.go @@ -303,12 +303,11 @@ func TestRefreshVaultClobOrders(t *testing.T) { }, ordersShouldRefresh: true, }, - "Error - Vault for non-existent Clob Pair 4321": { + "Success - Vault for non-existent Clob Pair 4321": { vaultId: vaulttypes.VaultId{ Type: vaulttypes.VaultType_VAULT_TYPE_CLOB, Number: 4321, }, - expectedErr: vaulttypes.ErrClobPairNotFound, }, } @@ -396,8 +395,7 @@ func TestRefreshVaultClobOrders(t *testing.T) { require.Equal(t, expectedClientIds, mostRecentClientIds) } // Get canonical and flipped client IDs of this vault's orders. - orderIds, err := tApp.App.VaultKeeper.GetVaultClobOrderIds(ctx, tc.vaultId) - require.NoError(t, err) + orderIds := tApp.App.VaultKeeper.GetVaultClobOrderIds(ctx, tc.vaultId) canonicalClientIds := make([]uint32, len(orderIds)) flippedClientIds := make([]uint32, len(orderIds)) for i, orderId := range orderIds { @@ -787,14 +785,36 @@ func TestGetVaultClobOrders(t *testing.T) { // order size is 0. expectedOrderQuantums: []uint64{}, }, - "Error - Clob Pair doesn't exist": { + "Success - Clob Pair doesn't exist, Empty orders": { + vaultParams: vaulttypes.DefaultParams(), + vaultId: constants.Vault_Clob0, + clobPair: constants.ClobPair_Eth, + marketParam: constants.TestMarketParams[1], + marketPrice: constants.TestMarketPrices[1], + perpetual: constants.EthUsd_NoMarginRequirement, + expectedOrderSubticks: []uint64{}, + expectedOrderQuantums: []uint64{}, + }, + "Success - Clob Pair in status final settlement, Empty orders": { vaultParams: vaulttypes.DefaultParams(), - vaultId: constants.Vault_Clob0, - clobPair: constants.ClobPair_Eth, - marketParam: constants.TestMarketParams[1], - marketPrice: constants.TestMarketPrices[1], - perpetual: constants.EthUsd_NoMarginRequirement, - expectedErr: vaulttypes.ErrClobPairNotFound, + vaultId: constants.Vault_Clob1, + clobPair: clobtypes.ClobPair{ + Id: 1, + Metadata: &clobtypes.ClobPair_PerpetualClobMetadata{ + PerpetualClobMetadata: &clobtypes.PerpetualClobMetadata{ + PerpetualId: 1, + }, + }, + StepBaseQuantums: 1000, + SubticksPerTick: 1000, + QuantumConversionExponent: -9, + Status: clobtypes.ClobPair_STATUS_FINAL_SETTLEMENT, + }, + marketParam: constants.TestMarketParams[1], + marketPrice: constants.TestMarketPrices[1], + perpetual: constants.EthUsd_NoMarginRequirement, + expectedOrderSubticks: []uint64{}, + expectedOrderQuantums: []uint64{}, }, "Error - Vault equity is zero": { vaultParams: vaulttypes.DefaultParams(), @@ -995,13 +1015,12 @@ func TestGetVaultClobOrderIds(t *testing.T) { vaultId: constants.Vault_Clob0, layers: 0, }, - "Vault Clob 797 (non-existent clob pair), 2 layers": { + "Vault Clob 797, 2 layers": { vaultId: vaulttypes.VaultId{ Type: vaulttypes.VaultType_VAULT_TYPE_CLOB, Number: 797, }, - layers: 2, - expectedErr: vaulttypes.ErrClobPairNotFound, + layers: 2, }, } @@ -1035,14 +1054,7 @@ func TestGetVaultClobOrderIds(t *testing.T) { } // Verify order IDs. - orderIds, err := k.GetVaultClobOrderIds(ctx, tc.vaultId) - if tc.expectedErr != nil { - require.ErrorContains(t, err, tc.expectedErr.Error()) - require.Empty(t, orderIds) - } else { - require.NoError(t, err) - require.Equal(t, expectedOrderIds, orderIds) - } + require.Equal(t, expectedOrderIds, k.GetVaultClobOrderIds(ctx, tc.vaultId)) }) } } diff --git a/protocol/x/vault/types/errors.go b/protocol/x/vault/types/errors.go index 656cc4b00a7..8dc36313422 100644 --- a/protocol/x/vault/types/errors.go +++ b/protocol/x/vault/types/errors.go @@ -10,84 +10,84 @@ var ( 1, "Shares are negative", ) - ErrClobPairNotFound = errorsmod.Register( - ModuleName, - 2, - "ClobPair not found", - ) ErrMarketParamNotFound = errorsmod.Register( ModuleName, - 3, + 2, "MarketParam not found", ) ErrInvalidDepositAmount = errorsmod.Register( ModuleName, - 4, + 3, "Deposit amount is invalid", ) ErrNonPositiveEquity = errorsmod.Register( ModuleName, - 5, + 4, "Equity is non-positive", ) ErrZeroDenominator = errorsmod.Register( ModuleName, - 6, + 5, "Denominator is zero", ) ErrNilFraction = errorsmod.Register( ModuleName, - 7, + 6, "Fraction is nil", ) ErrInvalidOrderSizePctPpm = errorsmod.Register( ModuleName, - 8, + 7, "OrderSizePctPpm must be strictly greater than 0", ) ErrInvalidOrderExpirationSeconds = errorsmod.Register( ModuleName, - 9, + 8, "OrderExpirationSeconds must be strictly greater than 0", ) ErrInvalidSpreadMinPpm = errorsmod.Register( ModuleName, - 10, + 9, "SpreadMinPpm must be strictly greater than 0", ) ErrInvalidLayers = errorsmod.Register( ModuleName, - 11, + 10, "Layers must be less than or equal to MaxUint8", ) ErrZeroSharesToMint = errorsmod.Register( ModuleName, - 12, + 11, "Cannot mint zero shares", ) ErrInvalidActivationThresholdQuoteQuantums = errorsmod.Register( ModuleName, - 13, + 12, "ActivationThresholdQuoteQuantums must be non-negative", ) ErrInvalidOrderSize = errorsmod.Register( ModuleName, - 14, + 13, "OrderSize is invalid", ) ErrInvalidOwner = errorsmod.Register( ModuleName, - 15, + 14, "Owner is invalid", ) ErrMismatchedTotalAndOwnerShares = errorsmod.Register( ModuleName, - 16, + 15, "TotalShares does not match sum of OwnerShares", ) ErrZeroMarketPrice = errorsmod.Register( ModuleName, - 17, + 16, "MarketPrice is zero", ) + ErrOrdersAndOrderIdsDiffLen = errorsmod.Register( + ModuleName, + 17, + "Orders and OrderIds must have the same length", + ) )