Skip to content
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

Margin call order fills at price of matching limit_order but not at a price related to itself or settlement_price #338

Closed
alexpmorris opened this issue Jul 28, 2017 · 13 comments

Comments

@alexpmorris
Copy link

just wanted to share this issue I came across. I outlined it here, with a possible solution (or at least, a better understanding of what the problem is likely to be)...

https://steemit.com/bitshares/@alexpmorris/beware-crossing-the-offer-with-your-bid-on-the-bitshares-dex-or-it-might-cost-you-a-bundle

@pmconrad
Copy link
Contributor

I don't think the described behaviour is a bug. Did you ever receive less payment than you requested?

@oxarbitrage
Copy link
Member

We discussed the issue today in the telegram chat, we are getting aligned on a possible blockchain patch.

the issue will be discussed formally in this thread:

https://bitsharestalk.org/index.php/topic,24715.0.html

by now i will be after trying to replicate the problem in the testnet and/or make a unit test for the problem. in the meantime we will be discussing consensus on hot to best fix it.

@alexpmorris thank you very much for bringing this issue here.

@abitmore
Copy link
Member

@abitmore abitmore changed the title crossing the offer with your bid may cause you to overpay the inside offer Margin call order fills at price of matching limit_order but not at a price related to itself Jul 29, 2017
@abitmore
Copy link
Member

abitmore commented Jul 29, 2017

Among these lines in https://github.com/bitshares/bitshares-core/blob/2.0.170710/libraries/chain/db_market.cpp#L503-L507 (quoted below),

       margin_called = true;

       auto usd_to_buy   = call_itr->get_debt();

       if( usd_to_buy * match_price > call_itr->get_collateral() )

we can adjust match_price to min_price before the if, and need to be guarded by a hard fork check, of course, so something like this:

       margin_called = true;

       if( head_block_time() >= HF_CORE_ISSUE_338_TIME )
          match_price = min_price;

       auto usd_to_buy   = call_itr->get_debt();

       if( usd_to_buy * match_price > call_itr->get_collateral() )

//Update: not this simple.

@abitmore abitmore changed the title Margin call order fills at price of matching limit_order but not at a price related to itself Margin call order fills at price of matching limit_order but not at a price related to itself or settlement_price Jul 29, 2017
@abitmore
Copy link
Member

By the way, there seems to be something wrong with the code.

https://github.com/bitshares/bitshares-core/blob/2.0.170710/libraries/chain/db_market.cpp#L464

bool filled_limit = false;

should be defined inside the loop, because check_call_orders is not only be called when a new limit_order is created, but will also be called when there is a price feed change, in this case there may be multiple limit_order objects as well as multiple call_order objects be processed. I guess this issue has happened in production for many times, fixing this would require a hard fork as well.

Another minor issue, this line
https://github.com/bitshares/bitshares-core/blob/2.0.170710/libraries/chain/db_market.cpp#L541

       auto old_limit_itr = filled_limit ? limit_itr++ : limit_itr;
       fill_order(*old_limit_itr, order_pays, order_receives, true);

should be changed to something like this for better performance

       auto old_limit_itr = limit_itr;
       if( filled_limit ) ++limit_itr;
       fill_order(*old_limit_itr, order_pays, order_receives, true);

@pmconrad
Copy link
Contributor

Nice find.

@abitmore
Copy link
Member

@oxarbitrage GOLD has been global settled. Try SILVER.

@abitmore
Copy link
Member

abitmore commented Jul 29, 2017

Another issue indicated in the post is related to rounding, which is actually a very old & known issue. For example:

image

The order was selling 0.185 BTS, but apparently it's not enough to get 21 satoshi of HERO, so finally it got 20. However, to get 20 satoshi of HERO, only need to pay 0.1838 BTS.

#132 and #184 are probably related. Or perhaps best to open a new ticket.

//Edit:
Current implementation is in favor of the maker. Should we change it to in favor of the taker, or anything that is fairer? At least we need a clearer feature definition.

@abitmore
Copy link
Member

By the way, there is another feature about call orders which I think is debatable: for example, in BTS:bitCNY market (price shows as X bitcny per BTS), when there are bids above the settlement price, even when there is a call order with insufficient collateral, they won't match.

@abitmore
Copy link
Member

As I posted in forum, The fix I proposed above is not ideal:

there are at least two scenarios, they should be treated differently:

  1. There are old bids on the book, when a new price feed is published, a short position get margin called. In this case, the call order should walk through the bids until MSSP, it's best to use the bid prices.
  2. There are already margin call orders waiting to be filled, then a new bid is created against it. In this case, it's best to use MSSP.

In short, in favor of the taker.

@abitmore
Copy link
Member

Moving discussion of rounding issue to #342.

@oxarbitrage oxarbitrage added this to the Roadmap to hardfork milestone Aug 13, 2017
@abitmore
Copy link
Member

abitmore commented Nov 1, 2017

Created a new ticket (#453) for the multiple order matching issue described in this ticket.

@abitmore abitmore modified the milestones: Hardfork - Bugs , Future Consensus-Changing Release Nov 27, 2017
@abitmore abitmore modified the milestones: Future Consensus-Changing Release, 201803 - Consensus Changing Release Dec 23, 2017
oxarbitrage added a commit that referenced this issue Dec 23, 2017
@abitmore abitmore added the bug label Jan 29, 2018
@abitmore abitmore assigned abitmore and unassigned abitmore Jan 29, 2018
abitmore added a commit that referenced this issue Feb 3, 2018
For:
* #338 Margin call order fills at price of matching limit_order
* #343 Inconsistent sorting of call orders between matching against a limit order and a force settle order
* #453 Multiple limit order and call order matching issue
* #606 Undercollateralized short positions should be called regardless of asks
abitmore added a commit that referenced this issue Feb 6, 2018
abitmore added a commit that referenced this issue Feb 7, 2018
abitmore added a commit that referenced this issue Feb 8, 2018
abitmore added a commit that referenced this issue Apr 7, 2018
abitmore added a commit that referenced this issue Apr 7, 2018
For:
* #338 Margin call order fills at price of matching limit_order
* #343 Inconsistent sorting of call orders between matching against a limit order and a force settle order
* #453 Multiple limit order and call order matching issue
* #606 Undercollateralized short positions should be called regardless of asks
abitmore added a commit that referenced this issue Apr 7, 2018
abitmore added a commit that referenced this issue Apr 7, 2018
@abitmore
Copy link
Member

Done with #829.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants