Skip to content

Commit 8452a70

Browse files
committed
fix market bid order validation
1 parent 468a3be commit 8452a70

1 file changed

Lines changed: 56 additions & 13 deletions

File tree

matchengine/me_market.c

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -858,31 +858,74 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
858858

859859
int market_put_market_order(bool real, json_t **result, market_t *m, uint32_t user_id, uint32_t side, mpd_t *amount, mpd_t *taker_fee, const char *source)
860860
{
861-
mpd_t *balance = balance_get(user_id, BALANCE_TYPE_AVAILABLE, m->stock);
862-
if (!balance || mpd_cmp(balance, amount, &mpd_ctx) < 0) {
863-
return -1;
864-
}
865-
866-
if (mpd_cmp(amount, m->min_amount, &mpd_ctx) < 0) {
867-
return -2;
868-
}
869-
870861
if (side == MARKET_ORDER_SIDE_ASK) {
862+
// validate user has the balance available to fulfil order
863+
mpd_t *balance = balance_get(user_id, BALANCE_TYPE_AVAILABLE, m->stock);
864+
if (!balance || mpd_cmp(balance, amount, &mpd_ctx) < 0) {
865+
return -1;
866+
}
867+
868+
// validate there are any market participants on the other side of the order
871869
skiplist_iter *iter = skiplist_get_iterator(m->bids);
872870
skiplist_node *node = skiplist_next(iter);
873871
if (node == NULL) {
874872
skiplist_release_iterator(iter);
875873
return -3;
876874
}
877875
skiplist_release_iterator(iter);
876+
878877
} else {
878+
// calculate money required and number of asks
879+
mpd_t *money_required = mpd_new(&mpd_ctx);
880+
mpd_t *left = mpd_new(&mpd_ctx);
881+
mpd_t *amount_tx = mpd_new(&mpd_ctx);
882+
mpd_t *price = mpd_new(&mpd_ctx);
883+
mpd_t *deal = mpd_new(&mpd_ctx);
884+
mpd_copy(money_required, mpd_zero, &mpd_ctx);
885+
mpd_copy(left, amount, &mpd_ctx);
886+
int ask_count = 0;
887+
skiplist_node *node;
879888
skiplist_iter *iter = skiplist_get_iterator(m->asks);
880-
skiplist_node *node = skiplist_next(iter);
881-
if (node == NULL) {
882-
skiplist_release_iterator(iter);
883-
return -3;
889+
while ((node = skiplist_next(iter)) != NULL) {
890+
ask_count++;
891+
if (mpd_cmp(left, mpd_zero, &mpd_ctx) == 0) {
892+
break;
893+
}
894+
895+
order_t *maker = node->value;
896+
mpd_copy(price, maker->price, &mpd_ctx);
897+
if (mpd_cmp(maker->left, left, &mpd_ctx) < 0) {
898+
mpd_copy(amount_tx, maker->left, &mpd_ctx);
899+
} else {
900+
mpd_copy(amount_tx, left, &mpd_ctx);
901+
}
902+
903+
mpd_mul(deal, price, amount_tx, &mpd_ctx);
904+
mpd_sub(left, left, amount_tx, &mpd_ctx);
905+
mpd_add(money_required, money_required, deal, &mpd_ctx);
884906
}
885907
skiplist_release_iterator(iter);
908+
mpd_del(money_required);
909+
mpd_del(left);
910+
mpd_del(amount_tx);
911+
mpd_del(price);
912+
mpd_del(deal);
913+
914+
// validate user has the balance available to fulfil order
915+
mpd_t *balance = balance_get(user_id, BALANCE_TYPE_AVAILABLE, m->money);
916+
if (!balance || mpd_cmp(balance, money_required, &mpd_ctx) < 0) {
917+
return -1;
918+
}
919+
920+
// validate there are any market participants on the other side of the order
921+
if (ask_count == 0) {
922+
return -3;
923+
}
924+
}
925+
926+
// validate order amount is at least the minimum order amount
927+
if (mpd_cmp(amount, m->min_amount, &mpd_ctx) < 0) {
928+
return -2;
886929
}
887930

888931
order_t *order = malloc(sizeof(order_t));

0 commit comments

Comments
 (0)