-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Review and test something-for-nothing check #460
Comments
The situation to be prevented is, roughly, when a something-for-nothing trade would occur due to quantization effects. In this case, the desired response, roughly, is to cancel the order of the party who would receive nothing. |
The simple situation to handle is when an order is fully satisfied with a surplus balance. E.g. if Alice is top-of-book buying 3 B for 99 A, and Bob enters an order to sell 3 B for 100 A, then Bob should be totally filled and become the new top-of-book; but he should be immediately cancelled as he has a zero quantity.
The more subtle problem is a quantization problem. Say Alice has the existing top-of-book order which is matching Bob's incoming order. Let Define an If the matched volume is greater than or equal to If the matched volume is smaller, the system must find trades that don't occur at Alice's exact price, but rather have some premium or discount to her exact price. To be consistent with the definition of price [1], this premium / discount must be more favorable than Alice's price. It must similarly match Bob's price. This can lead to situations where no integer-valued trade can occur between Alice and Bob, even though their prices overlap. It is tempting to simply rule that any order with an insufficient balance to perform a unit trade is subject to cancellation when matched. However, the matched order may be a margin call, which cannot be cancelled. We need to either cancel orders which nearly match a margin call, or walk (potentially unboundedly?) deep in the book in order to find a match which is capable of unit exchange. [1] Price can be defined as "the least favorable exchange rate a party is willing to accept in trade." |
Here is an example: Alice's order: Sell CORE at $3 / 8, balance 1000000 CORE Both assets have precision of 1, i.e. the order balances are 1000000 CORE-satoshis and 10 USD-satoshis repectively. Alice is selling at $3/8 CORE = $0.375 / CORE and Bob is buying at $19 / 50 CORE = $0.38, so based on the price, Alice and Bob should match. Bob's $10 / $0.38 ~ 26.3. So 26.3 is the fewest CORE he is willing to accept (assuming that the meaning of "price" is "the least favorable exchange rate a party is willing to accept in trade"). Combined with the design restriction that satoshis are indivisible, in practice this means Bob will only accept 27 or more CORE for his $10. But $10 / 27 gives a price smaller than $0.370 and $0.371, which is smaller than Alice's sale price of $0.375. So neither party can fill this offer. |
Here are the possible solutions to the problem:
|
TLDR: I believe we did think about this and the current code tries to implement (c), but I think the implementation may be buggy and/or untested. And even correctly implemented it may behave in a way which sometimes makes perverse decisions from an economic policy perspective. |
Assigning to @bytemaster for analysis / opinion on what course of action to take. In particular, I need to know if this is problem enough to be considered a blocker for the next release. |
The proper response is to cancel the dust order and do nothing to the order the dust order was attempting to match against. So if I have a large order to buy $100 worth of BTS, and someone tries to buy an amount of bts worth less than 0.0000 BitUSD from me, my order should stand and they should get canceled. By definition all orders are for an amount greater than 0 (or they are removed/filled). The order that would "receive nothing" is by definition paired against a dust order that will receive something (dust). The dust order is what should be canceled, not the order that would receive nothing. |
Upon further review of the code and the math involved, it is not possible to construct a new order with a price and amount that would get matched with an existing order and trigger the existing order to be canceled. We have defined a dust order as one where ORDER_PRICE * ORDER_AMOUNT == 0 This is the point at which the unfilled portion of the order is smaller than the resolution of the orders price and thus should be refunded to the user. |
There's a consistent issue with orders that are not perfectly match causing the left-over to execute at prices far above/below the actual prices of the original orders, and bypassing the orderbook completely. As an example, here's the market history for OBITS:BTS yesterday: Price OBITS BTS DATE Throughout this there was massive sell support at around 25 BTS/OBITS, but the dust orders executed well above this. I'm not sure if this deserves a new issue or if it fits with the problem described in this issue. |
price bts open.BTC but price open.BTC BTS 283000×0,00283 = 800,89 so ORDER_PRICE * ORDER_AMOUNT == 0 Im not sure how its working just guessing. |
My conclusion is that the market engine is correct, and that what users are complaining about is merely a display issue. The UI displays the trade price as calculated from paid/received, which can be significantly different from bid/ask on low-volume orders. A possible fix might be to somehow include the order price in market history entries and have the UI display that instead of the trade price. |
This issue was moved to bitshares/bitshares-core#132 |
EDIT: TLDR: I believe we did think about this and the current code tries to implement (c), but I think the implementation may be buggy and/or untested. And even correctly implemented it may behave in a way which sometimes makes perverse decisions from an economic policy perspective.
Long version: (end EDIT)
The
amount == 0
check here is apparently testing for a something-for-nothing situation, whereby the quantization of trade leads to a fill logic which results in something-for-nothing trade.We need to carefully analyze the trade and determine that this logic can only trigger for dust values. Also, I think this logic is in the wrong place.
What needs to be done on this is:
The text was updated successfully, but these errors were encountered: