Skip to content

Commit 984e064

Browse files
authored
fix(orderbook): prevent stuck replace order holds (#1842)
This fixes a bug whereby an order could be placed on hold without that hold ever being removed. When replacing an order, we place the existing order on hold until the replacement order has finished matching, and only then do we remove the original order. However, the order was being placed on hold before the checks for sufficient balance to fill this order, and in case those checks failed the remainder of the `placeOrder` routine would be skipped including the part that removes the original order. In such a case, the original order would be put on hold indefinitely. Instead, we place the existing order on hold immediately before we begin matching and after any checks on the validity of the new order are passed. If the checks fail, then the new order is rejected and the order it was intended to replace remains in the order book without a hold, allowing it to be replaced or removed again by a future call. Fixes #1835.
1 parent ed43416 commit 984e064

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

Diff for: lib/orderbook/OrderBook.ts

+12-13
Original file line numberDiff line numberDiff line change
@@ -444,19 +444,6 @@ class OrderBook extends EventEmitter {
444444
}
445445
}
446446

447-
assert(!(replaceOrderId && discardRemaining), 'can not replace order and discard remaining order');
448-
449-
let replacedOrderIdentifier: OrderIdentifier | undefined;
450-
if (replaceOrderId) {
451-
// put the order we are replacing on hold while we place the new order
452-
replacedOrderIdentifier = this.localIdMap.get(replaceOrderId);
453-
if (!replacedOrderIdentifier) {
454-
throw errors.ORDER_NOT_FOUND(replaceOrderId);
455-
}
456-
assert(replacedOrderIdentifier.pairId === order.pairId);
457-
this.addOrderHold(replacedOrderIdentifier.id, replacedOrderIdentifier.pairId);
458-
}
459-
460447
// this method can be called recursively on swap failures retries.
461448
// if max time exceeded, don't try to match
462449
if (maxTime && Date.now() > maxTime) {
@@ -493,6 +480,18 @@ class OrderBook extends EventEmitter {
493480
}
494481
}
495482

483+
assert(!(replaceOrderId && discardRemaining), 'can not replace order and discard remaining order');
484+
let replacedOrderIdentifier: OrderIdentifier | undefined;
485+
if (replaceOrderId) {
486+
// put the order we are replacing on hold while we place the new order
487+
replacedOrderIdentifier = this.localIdMap.get(replaceOrderId);
488+
if (!replacedOrderIdentifier) {
489+
throw errors.ORDER_NOT_FOUND(replaceOrderId);
490+
}
491+
assert(replacedOrderIdentifier.pairId === order.pairId);
492+
this.addOrderHold(replacedOrderIdentifier.id, replacedOrderIdentifier.pairId);
493+
}
494+
496495
// perform matching routine. maker orders that are matched will be removed from the order book.
497496
const tp = this.getTradingPair(order.pairId);
498497
const matchingResult = tp.match(order);

0 commit comments

Comments
 (0)