Skip to content

Commit

Permalink
return empty vault orders if clob pair does not exist or is in final …
Browse files Browse the repository at this point in the history
…settlement (backport #2011) (#2027)

Co-authored-by: Tian <[email protected]>
  • Loading branch information
mergify[bot] and tqin7 authored Aug 5, 2024
1 parent cc64090 commit 89918ee
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 51 deletions.
36 changes: 17 additions & 19 deletions protocol/x/vault/keeper/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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*quotingParams.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 < quotingParams.Layers; i++ {
// Construct ask at this layer.
orders[2*i] = constructOrder(clobtypes.Order_SIDE_SELL, i, orderIds[2*i])
Expand All @@ -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,
Expand All @@ -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(),
}
}

Expand All @@ -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
Expand Down
84 changes: 52 additions & 32 deletions protocol/x/vault/keeper/orders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,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,
},
}

Expand Down Expand Up @@ -397,18 +396,21 @@ 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 {
canonicalClientIds[i] = orderId.ClientId
flippedClientIds[i] = orderId.ClientId ^ 1
}

// If corresponding clob pair doesn't exist, the vault should not place any orders.
_, found := tApp.App.ClobKeeper.GetClobPair(ctx, clobtypes.ClobPairId(tc.vaultId.Number))
if !found {
require.Zero(t, len(tApp.App.ClobKeeper.GetAllStatefulOrders(ctx)))
return
}
// Vault should place its initial orders (client IDs should be canonical).
initialOrders := tApp.App.ClobKeeper.GetAllStatefulOrders(ctx)
require.Len(t, initialOrders, int(defaultQuotingParams.Layers*2))
verifyVaultOrders(
uint32(ctx.BlockTime().Unix())+defaultQuotingParams.OrderExpirationSeconds,
canonicalClientIds,
Expand Down Expand Up @@ -788,14 +790,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": {
vaultQuotingParams: vaulttypes.DefaultQuotingParams(),
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": {
vaultQuotingParams: vaulttypes.DefaultQuotingParams(),
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": {
vaultQuotingParams: vaulttypes.DefaultQuotingParams(),
Expand Down Expand Up @@ -978,28 +1002,30 @@ func TestGetVaultClobOrderIds(t *testing.T) {
layers uint32

/* --- Expectations --- */
// Expected error, if any.
expectedErr error
expectedNumOrders uint32
}{
"Vault Clob 0, 2 layers": {
vaultId: constants.Vault_Clob0,
layers: 2,
vaultId: constants.Vault_Clob0,
layers: 2,
expectedNumOrders: 4,
},
"Vault Clob 1, 7 layers": {
vaultId: constants.Vault_Clob1,
layers: 7,
vaultId: constants.Vault_Clob1,
layers: 7,
expectedNumOrders: 14,
},
"Vault Clob 0, 0 layers": {
vaultId: constants.Vault_Clob0,
layers: 0,
vaultId: constants.Vault_Clob0,
layers: 0,
expectedNumOrders: 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,
expectedNumOrders: 4,
},
}

Expand Down Expand Up @@ -1033,14 +1059,8 @@ 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, tc.expectedNumOrders, uint32(len(expectedOrderIds)))
require.Equal(t, expectedOrderIds, k.GetVaultClobOrderIds(ctx, tc.vaultId))
})
}
}
Expand Down
6 changes: 6 additions & 0 deletions protocol/x/vault/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var (
1,
"Shares are negative",
)
// Deprecated since v6.x
ErrClobPairNotFound = errorsmod.Register(
ModuleName,
2,
Expand Down Expand Up @@ -90,4 +91,9 @@ var (
17,
"MarketPrice is zero",
)
ErrOrdersAndOrderIdsDiffLen = errorsmod.Register(
ModuleName,
18,
"Orders and OrderIds must have the same length",
)
)

0 comments on commit 89918ee

Please sign in to comment.