Skip to content

Commit

Permalink
Skip collat check for untriggered conditional order placement (#1370)
Browse files Browse the repository at this point in the history
* Skip collat check for untriggered conditional order placement

* e2e test
  • Loading branch information
jayy04 authored Apr 10, 2024
1 parent d78b415 commit de5a0f9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 19 deletions.
4 changes: 4 additions & 0 deletions protocol/testutil/constants/positions.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ var (
AssetId: 0,
Quantums: dtypes.NewInt(-9_900_000_000), // $-9,900
}
Usdc_Asset_1 = satypes.AssetPosition{
AssetId: 0,
Quantums: dtypes.NewInt(1_000_000), // $1
}
Usdc_Asset_10_000 = satypes.AssetPosition{
AssetId: 0,
Quantums: dtypes.NewInt(10_000_000_000), // $10,000
Expand Down
7 changes: 7 additions & 0 deletions protocol/testutil/constants/subaccounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (

var (
// Subaccounts.
Alice_Num0_1USD = satypes.Subaccount{
Id: &Alice_Num0,
AssetPositions: []*satypes.AssetPosition{
&Usdc_Asset_1,
},
PerpetualPositions: []*satypes.PerpetualPosition{},
}
Alice_Num0_10_000USD = satypes.Subaccount{
Id: &Alice_Num0,
AssetPositions: []*satypes.AssetPosition{
Expand Down
52 changes: 52 additions & 0 deletions protocol/x/clob/e2e/conditional_orders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,58 @@ func TestConditionalOrder(t *testing.T) {
},
},
},
"Undercollateralized conditional order can be placed": {
subaccounts: []satypes.Subaccount{
constants.Alice_Num0_1USD,
},
orders: []clobtypes.Order{
constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999,
},
priceUpdateForFirstBlock: &prices.MsgUpdateMarketPrices{},
priceUpdateForSecondBlock: &prices.MsgUpdateMarketPrices{},

expectedExistInState: map[clobtypes.OrderId]bool{
constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: true,
},
expectedInTriggeredStateAfterBlock: map[uint32]map[clobtypes.OrderId]bool{
2: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false},
3: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false},
4: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false},
},
},
"Undercollateralized conditional order can be placed, trigger, fail collat check and get removed from state": {
subaccounts: []satypes.Subaccount{
constants.Alice_Num0_1USD,
constants.Dave_Num0_10000USD,
},
orders: []clobtypes.Order{
constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999,
constants.Order_Dave_Num0_Id1_Clob0_Sell025BTC_Price50000_GTB11,
},
priceUpdateForFirstBlock: &prices.MsgUpdateMarketPrices{},
priceUpdateForSecondBlock: &prices.MsgUpdateMarketPrices{
MarketPriceUpdates: []*prices.MsgUpdateMarketPrices_MarketPrice{
prices.NewMarketPriceUpdate(0, 4_999_700_000),
},
},

expectedExistInState: map[clobtypes.OrderId]bool{
constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false,
},
expectedInTriggeredStateAfterBlock: map[uint32]map[clobtypes.OrderId]bool{
2: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false},
3: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: true},
4: {constants.ConditionalOrder_Alice_Num0_Id0_Clob0_Buy1BTC_Price50000_GTBT10_TP_49999.OrderId: false},
},
expectedSubaccounts: []satypes.Subaccount{
{
Id: &constants.Alice_Num0,
AssetPositions: []*satypes.AssetPosition{
&constants.Usdc_Asset_1,
},
},
},
},
}

for name, tc := range tests {
Expand Down
40 changes: 21 additions & 19 deletions protocol/x/clob/keeper/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,28 +300,30 @@ func (k Keeper) PlaceStatefulOrder(

// 4. Perform a collateralization check for the full size of the order to mitigate spam.
// TODO(CLOB-725): Consider using a pessimistic collateralization check.
_, successPerSubaccountUpdate := k.AddOrderToOrderbookCollatCheck(
ctx,
order.GetClobPairId(),
map[satypes.SubaccountId][]types.PendingOpenOrder{
order.OrderId.SubaccountId: {
{
RemainingQuantums: order.GetBaseQuantums(),
IsBuy: order.IsBuy(),
Subticks: order.GetOrderSubticks(),
ClobPairId: order.GetClobPairId(),
if !order.IsConditionalOrder() {
_, successPerSubaccountUpdate := k.AddOrderToOrderbookCollatCheck(
ctx,
order.GetClobPairId(),
map[satypes.SubaccountId][]types.PendingOpenOrder{
order.OrderId.SubaccountId: {
{
RemainingQuantums: order.GetBaseQuantums(),
IsBuy: order.IsBuy(),
Subticks: order.GetOrderSubticks(),
ClobPairId: order.GetClobPairId(),
},
},
},
},
)

if !successPerSubaccountUpdate[order.OrderId.SubaccountId].IsSuccess() {
return errorsmod.Wrapf(
types.ErrStatefulOrderCollateralizationCheckFailed,
"PlaceStatefulOrder: order (%+v), result (%s)",
order,
successPerSubaccountUpdate[order.OrderId.SubaccountId].String(),
)

if !successPerSubaccountUpdate[order.OrderId.SubaccountId].IsSuccess() {
return errorsmod.Wrapf(
types.ErrStatefulOrderCollateralizationCheckFailed,
"PlaceStatefulOrder: order (%+v), result (%s)",
order,
successPerSubaccountUpdate[order.OrderId.SubaccountId].String(),
)
}
}

// 5. If we are in `deliverTx` then we write the order to committed state otherwise add the order to uncommitted
Expand Down

0 comments on commit de5a0f9

Please sign in to comment.