Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Implement BSIP 74: Margin Call Fee Ratio #2130
Implement BSIP 74: Margin Call Fee Ratio #2130
Changes from 8 commits
e9e0e7e
00b2ed1
8d5aad6
fee9fe6
ca6f361
fa7d4d5
a43e18a
2b120c9
4fd251c
35d797a
3ea265a
4684e51
1aee59c
750c720
9ea7962
84c3e04
75374de
a394deb
d11ecbf
fad10a6
0fae92f
3531df9
96c2d98
1424257
476e3fd
efff548
d062cd2
eb9a898
4c0ac06
f3f363c
7df91b4
5c2210b
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't fully understand what's your definition of "a margin call" nor the logic around this parameter. Looks like it is always equal to
!is_maker
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems different from the specification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem I have is clarifying the specifications. I apologize for the lengthy post, but it is how my mind works. The BSIP says:
My interpretation (which I will attempt to keep updated within this comment, and probably move to my blog to help me in the future):
Doug the Debtor put up collateral of token C which created token D. Doug was charged an operation fee I think, although I am not sure but it is unimportant. We will assume Doug then sold or transferred D ( also unimportant in this context).
Larry the creator of a Limit order would like to sell the desired quantity of token D and receive the desired quantity of token C. Upon placing the order, Larry was charged a limit order create fee, which is not important in this context.
When the debt position was created, a call order was created for Doug the debtor. Within that call order is the current debt and collateral balances.
When the settlement price of the price feed reaches a certain level, Doug's position will get called. Such a margin call will generate revenue for the asset issuer, if the issuer has set the new
margin_call_fee_ratio
within that asset's options.This fee does not affect Larry. He simply placed a limit order on the book of the exchange.
Doug will see the fee if he compares the amount of collateral he received from the transaction with the amount of debt that was paid off by the margin call.
Now the more technical details:
When will these orders be matched? When the settlement price from the price feed pushes the value of Doug's collateral below the allowed threshold for the debt asset (see
db_market.cpp#database::check_call_orders
).What will Larry receive? Exactly what he wished in his limit order.
What will Doug receive? Relief from (some or all of) his debt, and some of his collateral back. He will not receive the full value of his collateral, based on the feed's settlement price. Some of the value of the transaction was paid to the issuer of the debt asset as a margin call fee.
Implementation details:
database::check_call_orders (db_market.cpp) knows when to trigger a margin call. When triggered,
fill_call_order
is called, and thenfill_limit_order
is called.Within
fill_call_order
the fee is taken from the debtor's debt position and given to the asset issuer as a vesting balance. The remaining value of the debt is used to calculate the collateral that the debtor receives. That collateral is then placed in the debtor's available account balance.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In looking at the spec, I believe that I need to adjust the "trigger" of the margin call. The spec reads:
And that is part of
check_call_orders
Update: No, this only affects the debtor, not when the margin call happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may have written something wrong in previous comments. Let's forget them and start here.
With bsip74,
feed_price / mssr
, it will match the call order,feed_price / (mssr - mcfr)
, it will match the call order,feed_price / (mssr - mcfr)
, the call order pays (be filled) atfeed_price / mssr
, the difference goes to the debt asset owner;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One important thing, the fee is some amount of the collateral asset, so it can not go to the
accumulated_fees
field of the debt asset, which means we likely can not reuse the code ofpay_market_fees
. It can not go to theaccumulated_fees
field of the collateral asset either, since the asset can be owned by someone else.In addition, a complex scenario is the debt asset can change from one collateral to another, so we need to store the fees in a multi-asset container. Adding new fields into asset_object or another object means we need to add new operations to claim them, that's too much work to implement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing in mind:
mssr-mcfr
in the specification, and we don't allow something for nonthing, so it's implied thatmssr>mcfr
. However, mssr is updated by price feed producers and an internal timer, mcfr is updated by asset owner, so likely we can't validate when one of them is updated. So we need to cap the value of mcfr when use it in calculation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abitmore
I believe I am clear that this change modifies which limit orders qualify to be matched.
To be clear, let me walk through what I am seeing in db_market.cpp::check_call_orders. And just focusing on the price the limit order will transact at...
Prior to this change, the limit order was filled at the price dictated by the order itself:
price match_price = limit_order.sell_price;
Based on what I'm reading in your comment above, after the hardfork, the limit order will transact at a price based on feed price, MSSR and MCFR. That will result in the limit order receiving a price potentially very different than their order.
Or it could be that I am misreading your comment above, and you were only presenting the extreme example of when a limit order just happens to match right at the new calculated price for what qualifies a match, which would mean the order gets exactly what it asked for.
Or I am making assumptions in the code that are incorrect.
Would you clarify please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep in mind that match price is always price of the maker, see BSIP 32.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the reference to BSIP 32. There are some inconsistencies in that BSIP that make it difficult to understand, but I believe the gist is as you say, when the limit order is the maker, the maker price is what is used.
So that leads me to believe that BSIP 74 applies only when the call order is the maker. Hence the margin call fee will not apply when the limit order is the maker. Is that correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the margin call fee should always apply, although how much to pay is not clearly described in the BSIP when Peter approved the pull request.
In case when the call order is taker, I think it's fine to charge the amount
filled_debt * mcfr / feed_price
from the call order as fee.