BitShares-Core  6.1.0
BitShares blockchain implementation and command-line interface software
market_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
27 
29 
32 #include <graphene/chain/hardfork.hpp>
34 
36 
37 namespace graphene { namespace chain {
39 { try {
40  const database& d = db();
41 
43 
44  _seller = this->fee_paying_account;
45  _sell_asset = &op.amount_to_sell.asset_id(d);
46  _receive_asset = &op.min_to_receive.asset_id(d);
47 
48  if( _sell_asset->options.whitelist_markets.size() )
49  {
50  GRAPHENE_ASSERT( _sell_asset->options.whitelist_markets.find(_receive_asset->get_id())
51  != _sell_asset->options.whitelist_markets.end(),
52  limit_order_create_market_not_whitelisted,
53  "This market has not been whitelisted by the selling asset", );
54  }
55  if( _sell_asset->options.blacklist_markets.size() )
56  {
57  GRAPHENE_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->get_id())
58  == _sell_asset->options.blacklist_markets.end(),
59  limit_order_create_market_blacklisted,
60  "This market has been blacklisted by the selling asset", );
61  }
62 
63  GRAPHENE_ASSERT( is_authorized_asset( d, *_seller, *_sell_asset ),
64  limit_order_create_selling_asset_unauthorized,
65  "The account is not allowed to transact the selling asset", );
66 
67  GRAPHENE_ASSERT( is_authorized_asset( d, *_seller, *_receive_asset ),
68  limit_order_create_receiving_asset_unauthorized,
69  "The account is not allowed to transact the receiving asset", );
70 
71  GRAPHENE_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell,
72  limit_order_create_insufficient_balance,
73  "insufficient balance",
74  ("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) );
75 
76  return void_result();
77 } FC_CAPTURE_AND_RETHROW( (op) ) }
78 
80 {
81  if( db().head_block_time() <= HARDFORK_CORE_604_TIME )
83  else if( !trx_state->skip_fee && fee_asset->get_id() != asset_id_type() )
84  {
87  });
88  }
89 }
90 
92 {
93  if( db().head_block_time() <= HARDFORK_445_TIME )
95  else
96  {
97  _deferred_fee = core_fee_paid;
98  if( db().head_block_time() > HARDFORK_CORE_604_TIME && fee_asset->get_id() != asset_id_type() )
99  _deferred_paid_fee = fee_from_account;
100  }
101 }
102 
104 { try {
105  if( op.amount_to_sell.asset_id == asset_id_type() )
106  {
107  db().modify( _seller->statistics(db()), [&op](account_statistics_object& bal) {
108  bal.total_core_in_orders += op.amount_to_sell.amount;
109  });
110  }
111 
113 
114  const auto& new_order_object = db().create<limit_order_object>([this,&op](limit_order_object& obj){
115  obj.seller = _seller->id;
116  obj.for_sale = op.amount_to_sell.amount;
117  obj.sell_price = op.get_price();
118  obj.expiration = op.expiration;
119  obj.deferred_fee = _deferred_fee;
120  obj.deferred_paid_fee = _deferred_paid_fee;
121  });
122  object_id_type order_id = new_order_object.id; // save this because we may remove the object by filling it
123  bool filled;
124  if( db().get_dynamic_global_properties().next_maintenance_time <= HARDFORK_CORE_625_TIME )
125  filled = db().apply_order_before_hardfork_625( new_order_object );
126  else
127  filled = db().apply_order( new_order_object );
128 
129  GRAPHENE_ASSERT( !op.fill_or_kill || filled,
130  limit_order_create_kill_unfilled,
131  "Killing limit order ${op} due to unable to fill",
132  ("op",op) );
133 
134  return order_id;
135 } FC_CAPTURE_AND_RETHROW( (op) ) }
136 
138 { try {
139  const database& d = db();
140 
141  _order = d.find( o.order );
142 
143  GRAPHENE_ASSERT( _order != nullptr,
144  limit_order_cancel_nonexist_order,
145  "Limit order ${oid} does not exist",
146  ("oid", o.order) );
147 
148  GRAPHENE_ASSERT( _order->seller == o.fee_paying_account,
149  limit_order_cancel_owner_mismatch,
150  "Limit order ${oid} is owned by someone else",
151  ("oid", o.order) );
152 
153  return void_result();
154 } FC_CAPTURE_AND_RETHROW( (o) ) }
155 
157 { try {
158  database& d = db();
159 
160  auto base_asset = _order->sell_price.base.asset_id;
161  auto quote_asset = _order->sell_price.quote.asset_id;
162  auto refunded = _order->amount_for_sale();
163 
164  d.cancel_limit_order( *_order, false ); // don't create a virtual op
165 
166  if( d.get_dynamic_global_properties().next_maintenance_time <= HARDFORK_CORE_606_TIME )
167  {
168  // Possible optimization:
169  // order can be called by canceling a limit order if the canceled order was at the top of the book.
170  // Do I need to check calls in both assets?
171  d.check_call_orders(base_asset(d));
172  d.check_call_orders(quote_asset(d));
173  }
174 
175  return refunded;
176 } FC_CAPTURE_AND_RETHROW( (o) ) }
177 
179 { try {
180  const database& d = db();
181 
182  auto next_maintenance_time = d.get_dynamic_global_properties().next_maintenance_time;
183 
184  // Note: funding_account is the fee payer thus exists in the database
185  _debt_asset = &o.delta_debt.asset_id(d);
186  FC_ASSERT( _debt_asset->is_market_issued(), "Unable to cover ${sym} as it is not a collateralized asset.",
187  ("sym", _debt_asset->symbol) );
188 
189  FC_ASSERT( o.delta_debt.amount <= 0 || _debt_asset->can_create_new_supply(), "Can not create new supply" );
190 
191  _dynamic_data_obj = &_debt_asset->dynamic_asset_data_id(d);
192 
193  /***
194  * There are instances of assets exceeding max_supply before hf 1465, therefore this code must remain.
195  */
196  if (next_maintenance_time > HARDFORK_CORE_1465_TIME)
197  {
198  FC_ASSERT( _dynamic_data_obj->current_supply + o.delta_debt.amount <= _debt_asset->options.max_supply,
199  "Borrowing this quantity would exceed MAX_SUPPLY" );
200  }
201 
202  FC_ASSERT( _dynamic_data_obj->current_supply + o.delta_debt.amount >= 0,
203  "This transaction would bring current supply below zero.");
204 
205  _bitasset_data = &_debt_asset->bitasset_data(d);
206 
209  FC_ASSERT( !_bitasset_data->has_settlement(),
210  "Cannot update debt position when the asset has been globally settled" );
211 
212  FC_ASSERT( o.delta_collateral.asset_id == _bitasset_data->options.short_backing_asset,
213  "Collateral asset type should be same as backing asset of debt asset" );
214 
215  auto& call_idx = d.get_index_type<call_order_index>().indices().get<by_account>();
216  auto itr = call_idx.find( boost::make_tuple(o.funding_account, o.delta_debt.asset_id) );
217  if( itr != call_idx.end() ) // updating or closing debt position
218  {
219  call_ptr = &(*itr);
220  new_collateral = call_ptr->collateral + o.delta_collateral.amount;
221  new_debt = call_ptr->debt + o.delta_debt.amount;
222  if( new_debt == 0 )
223  {
224  FC_ASSERT( new_collateral == 0, "Should claim all collateral when closing debt position" );
225  _closing_order = true;
226  }
227  else
228  {
229  FC_ASSERT( new_collateral > 0 && new_debt > 0,
230  "Both collateral and debt should be positive after updated a debt position if not to close it" );
231  }
232  }
233  else // creating new debt position
234  {
235  FC_ASSERT( o.delta_collateral.amount > 0, "Delta collateral amount of new debt position should be positive" );
236  FC_ASSERT( o.delta_debt.amount > 0, "Delta debt amount of new debt position should be positive" );
237  }
238 
239  if( _bitasset_data->is_prediction_market )
241  "Debt amount and collateral amount should be same when updating debt position in a prediction "
242  "market" );
243  else if( _bitasset_data->current_feed.settlement_price.is_null()
244  && !( HARDFORK_CORE_2467_PASSED( next_maintenance_time ) && _closing_order ) )
245  FC_THROW_EXCEPTION(insufficient_feeds, "Cannot borrow asset with no price feed.");
246 
247  // Since hard fork core-973, check asset authorization limitations
248  if( HARDFORK_CORE_973_PASSED(d.head_block_time()) )
249  {
250  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, *_debt_asset ),
251  "The account is not allowed to transact the debt asset" );
252  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, _bitasset_data->options.short_backing_asset(d) ),
253  "The account is not allowed to transact the collateral asset" );
254  }
255 
256  // Note: there was code here checking whether the account has enough balance to increase delta collateral,
257  // which is now removed since the check is implicitly done later by `adjust_balance()` in `do_apply()`.
258 
259  return void_result();
260 } FC_CAPTURE_AND_RETHROW( (o) ) }
261 
262 
264 { try {
265  database& d = db();
266 
267  if( o.delta_debt.amount != 0 )
268  {
270 
271  // Deduct the debt paid from the total supply of the debt asset.
272  d.modify(*_dynamic_data_obj, [&o](asset_dynamic_data_object& dynamic_asset) {
273  dynamic_asset.current_supply += o.delta_debt.amount;
274  });
275  }
276 
277  if( o.delta_collateral.amount != 0 )
278  {
280 
281  // Adjust the total core in orders accodingly
282  if( o.delta_collateral.asset_id == asset_id_type() )
283  {
286  });
287  }
288  }
289 
290  if( _closing_order ) // closing the debt position
291  {
292  auto call_order_id = call_ptr->id;
293 
294  d.remove( *call_ptr );
295 
296  // Update current_feed if needed
297  const auto bsrm = _bitasset_data->get_black_swan_response_method();
298  if( bitasset_options::black_swan_response_type::no_settlement == bsrm )
299  {
300  auto old_feed_price = _bitasset_data->current_feed.settlement_price;
301  d.update_bitasset_current_feed( *_bitasset_data, true );
302  if( !_bitasset_data->current_feed.settlement_price.is_null()
303  && _bitasset_data->current_feed.settlement_price != old_feed_price )
304  {
305  d.check_call_orders( *_debt_asset, true, false, _bitasset_data );
306  }
307  }
308 
309  return call_order_id;
310  }
311 
312  const auto next_maint_time = d.get_dynamic_global_properties().next_maintenance_time;
313  bool before_core_hardfork_1270 = ( next_maint_time <= HARDFORK_CORE_1270_TIME ); // call price caching issue
314 
315  optional<price> old_collateralization;
316  optional<share_type> old_debt;
317 
318  if( !call_ptr ) // creating new debt position
319  {
320  call_ptr = &d.create<call_order_object>( [&o,this,before_core_hardfork_1270]( call_order_object& call ){
321  call.borrower = o.funding_account;
322  call.collateral = o.delta_collateral.amount;
323  call.debt = o.delta_debt.amount;
324  if( before_core_hardfork_1270 ) // before core-1270 hard fork, calculate call_price here and cache it
325  call.call_price = price::call_price( o.delta_debt, o.delta_collateral,
326  _bitasset_data->current_feed.maintenance_collateral_ratio );
327  else // after core-1270 hard fork, set call_price to 1
328  call.call_price = price( asset( 1, o.delta_collateral.asset_id ), asset( 1, o.delta_debt.asset_id ) );
329  call.target_collateral_ratio = o.extensions.value.target_collateral_ratio;
330  });
331  }
332  else // updating existing debt position
333  {
334  old_collateralization = call_ptr->collateralization();
335  old_debt = call_ptr->debt;
336 
337  d.modify( *call_ptr, [&o,this,before_core_hardfork_1270]( call_order_object& call ){
338  call.collateral = new_collateral;
339  call.debt = new_debt;
340  if( before_core_hardfork_1270 ) // don't update call_price after core-1270 hard fork
341  {
342  call.call_price = price::call_price( call.get_debt(), call.get_collateral(),
343  _bitasset_data->current_feed.maintenance_collateral_ratio );
344  }
345  call.target_collateral_ratio = o.extensions.value.target_collateral_ratio;
346  });
347  }
348 
349  object_id_type call_order_id = call_ptr->id;
350 
351  if( _bitasset_data->is_prediction_market )
352  return call_order_id;
353 
354  // then we must check for margin calls and other issues
355 
356  // After hf core-2481, we do not allow new position's CR to be <= ~max_short_squeeze_price, because
357  // * if there is no force settlement order, it would trigger a blackswan event instantly,
358  // * if there is a force settlement order, they will match at the call order's CR, but it is not fair for the
359  // force settlement order.
360  auto call_collateralization = call_ptr->collateralization();
361  bool increasing_cr = ( old_collateralization.valid() && call_ptr->debt <= *old_debt
362  && call_collateralization > *old_collateralization );
363  if( HARDFORK_CORE_2481_PASSED( next_maint_time ) )
364  {
365  // Note: if it is to increase CR and is not increasing debt amount, it is allowed,
366  // because it implies BSRM == no_settlement
367  FC_ASSERT( increasing_cr
368  || call_collateralization >= ~( _bitasset_data->median_feed.max_short_squeeze_price() ),
369  "Could not create a debt position which would trigger a blackswan event instantly, "
370  "unless it is to increase collateral ratio of an existing debt position and "
371  "is not increasing its debt amount" );
372  }
373  // Update current_feed if needed
374  const auto bsrm = _bitasset_data->get_black_swan_response_method();
375  if( bitasset_options::black_swan_response_type::no_settlement == bsrm )
376  d.update_bitasset_current_feed( *_bitasset_data, true );
377 
378  // check to see if the order needs to be margin called now, but don't allow black swans and require there to be
379  // limit orders available that could be used to fill the order.
380  // Note: due to https://github.com/bitshares/bitshares-core/issues/649, before core-343 hard fork,
381  // the first call order may be unable to be updated if the second one is undercollateralized.
382  // Note: check call orders, don't allow black swan, not for new limit order
383  bool called_some = d.check_call_orders( *_debt_asset, false, false, _bitasset_data );
384  call_ptr = d.find<call_order_object>(call_order_id);
385  if( called_some )
386  {
387  // before hard fork core-583: if we filled at least one call order, we are OK if we totally filled.
388  // after hard fork core-583: we want to allow increasing collateral
389  // Note: increasing collateral won't get the call order itself matched (instantly margin called)
390  // if there is at least a call order get matched but didn't cause a black swan event,
391  // current order must have got matched. in this case, it's OK if it's totally filled.
392  // after hard fork core-2467: when BSRM is no_settlement, it is possible that other call orders are matched
393  // in check_call_orders, also possible that increasing CR will get the call order itself matched
394  if( !HARDFORK_CORE_2467_PASSED( next_maint_time ) ) // before core-2467 hf
395  {
396  GRAPHENE_ASSERT( !call_ptr, call_order_update_unfilled_margin_call,
397  "Updating call order would trigger a margin call that cannot be fully filled" );
398  }
399  // after core-2467 hf
400  else
401  {
402  // if the call order is totally filled, it is OK,
403  // if it is increasing CR, it is always ok, no matter if it or another another call order is called,
404  // otherwise, the remaining call order's CR need to be > ICR
405  // TODO: perhaps it makes sense to allow more cases, e.g.
406  // - when a position has ICR > CR > MCR, allow the owner to sell some collateral to increase CR
407  // - allow owners to sell collateral at price < MSSP (need to update code elsewhere)
408  FC_ASSERT( !call_ptr || increasing_cr
409  || call_ptr->collateralization() > _bitasset_data->current_initial_collateralization,
410  "Could not create a debt position which would trigger a margin call instantly, "
411  "unless the debt position is fully filled, or it is to increase collateral ratio of "
412  "an existing debt position and is not increasing its debt amount, "
413  "or the remaining debt position's collateral ratio is above required "
414  "initial collateral ratio (ICR)" );
415  }
416  }
417  else
418  {
419  // we know no black swan event has occurred
420  FC_ASSERT( call_ptr, "no margin call was executed and yet the call object was deleted" );
421  // this HF must remain as-is, as the assert inside the "if" was triggered during push_proposal()
422  if( d.head_block_time() <= HARDFORK_CORE_583_TIME )
423  {
424  // We didn't fill any call orders. This may be because we
425  // aren't in margin call territory, or it may be because there
426  // were no matching orders. In the latter case, we throw.
428  // we know core-583 hard fork is before core-1270 hard fork, it's ok to use call_price here
429  ~call_ptr->call_price < _bitasset_data->current_feed.settlement_price,
430  call_order_update_unfilled_margin_call,
431  "Updating call order would trigger a margin call that cannot be fully filled",
432  // we know core-583 hard fork is before core-1270 hard fork, it's ok to use call_price here
433  ("a", ~call_ptr->call_price )("b", _bitasset_data->current_feed.settlement_price)
434  );
435  }
436  else // after hard fork core-583, always allow call order to be updated if collateral ratio
437  // is increased and debt is not increased
438  {
439  // We didn't fill any call orders. This may be because we
440  // aren't in margin call territory, or it may be because there
441  // were no matching orders. In the latter case,
442  // if collateral ratio is not increased or debt is increased, we throw.
443  // be here, we know no margin call was executed,
444  // so call_obj's collateral ratio should be set only by op
445  // ------
446  // Before BSIP77, CR of the new/updated position is required to be above MCR.
447  // After BSIP77, CR of the new/updated position is required to be above max(ICR,MCR).
448  // The `current_initial_collateralization` variable has been initialized according to the logic,
449  // so we directly use it here.
450  bool ok = increasing_cr;
451  if( !ok )
452  ok = before_core_hardfork_1270 ?
453  ( ~call_ptr->call_price < _bitasset_data->current_feed.settlement_price )
454  : ( call_collateralization > _bitasset_data->current_initial_collateralization );
455  FC_ASSERT( ok,
456  "Can only increase collateral ratio without increasing debt when the debt position's "
457  "collateral ratio is lower than or equal to required initial collateral ratio (ICR), "
458  "if not to trigger a margin call immediately",
459  ("old_debt", old_debt)
460  ("new_debt", call_ptr->debt)
461  ("old_collateralization", old_collateralization)
462  ("new_collateralization", call_collateralization)
463  );
464  }
465  }
466 
467  return call_order_id;
468 } FC_CAPTURE_AND_RETHROW( (o) ) }
469 
471 { try {
472  const database& d = db();
473 
474  // TODO cleanup: remove the assertion and related test cases after hardfork
475  FC_ASSERT( d.head_block_time() > HARDFORK_CORE_216_TIME, "Not yet!" );
476 
477  // Note: bidder is the fee payer thus exists in the database
478  _debt_asset = &o.debt_covered.asset_id(d);
479  FC_ASSERT( _debt_asset->is_market_issued(), "Unable to cover ${sym} as it is not a collateralized asset.",
480  ("sym", _debt_asset->symbol) );
481 
483  // Note: due to old bugs, an asset can have the flag set before the hardfork, so we need the hardfork check here
484  // TODO review after hardfork to see if we can remove the check
485  if( HARDFORK_CORE_2281_PASSED( next_maint_time ) )
486  FC_ASSERT( _debt_asset->can_bid_collateral(), "Collateral bidding is disabled for this asset" );
487 
488  _bitasset_data = &_debt_asset->bitasset_data(d);
489 
490  FC_ASSERT( _bitasset_data->has_settlement(), "Cannot bid since the asset is not globally settled" );
491 
492  FC_ASSERT( o.additional_collateral.asset_id == _bitasset_data->options.short_backing_asset );
493 
494  FC_ASSERT( !_bitasset_data->is_prediction_market, "Cannot bid on a prediction market!" );
495 
497  const auto& index = bids.indices().get<by_account>();
498  const auto& bid = index.find( boost::make_tuple( o.debt_covered.asset_id, o.bidder ) );
499  if( bid != index.end() )
500  _bid = &(*bid);
501  else
502  FC_ASSERT( o.debt_covered.amount > 0, "Can't find bid to cancel?!");
503 
504  if( o.additional_collateral.amount > 0 )
505  {
506  auto collateral_balance = d.get_balance( o.bidder, _bitasset_data->options.short_backing_asset );
507  if( _bid && d.head_block_time() >= HARDFORK_CORE_1692_TIME ) // TODO: see if HF check can be removed after HF
508  {
509  asset delta = o.additional_collateral - _bid->get_additional_collateral();
510  FC_ASSERT( collateral_balance >= delta,
511  "Cannot increase bid from ${oc} to ${nc} collateral when payer only has ${b}",
512  ("oc", _bid->get_additional_collateral().amount)("nc", o.additional_collateral.amount)
513  ("b", collateral_balance.amount) );
514  } else
515  FC_ASSERT( collateral_balance >= o.additional_collateral,
516  "Cannot bid ${c} collateral when payer only has ${b}", ("c", o.additional_collateral.amount)
517  ("b", collateral_balance.amount) );
518  }
519 
520  // Since hard fork core-973, check asset authorization limitations
521  if( HARDFORK_CORE_973_PASSED(d.head_block_time()) )
522  {
523  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, *_debt_asset ),
524  "The account is not allowed to transact the debt asset" );
525  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, _bitasset_data->options.short_backing_asset(d) ),
526  "The account is not allowed to transact the collateral asset" );
527  }
528 
529  return void_result();
530 } FC_CAPTURE_AND_RETHROW( (o) ) }
531 
532 
534 { try {
535  database& d = db();
536 
537  if( _bid )
538  d.cancel_bid( *_bid, false );
539 
540  if( o.debt_covered.amount == 0 ) return void_result();
541 
543 
545  bid.bidder = o.bidder;
546  bid.inv_swan_price = o.additional_collateral / o.debt_covered;
547  });
548 
549  // Note: CORE asset in collateral_bid_object is not counted in account_stats.total_core_in_orders
550 
551  return void_result();
552 } FC_CAPTURE_AND_RETHROW( (o) ) }
553 
554 } } // graphene::chain
const asset_object * fee_asset
Definition: evaluator.hpp:118
void modify(const T &obj, const Lambda &m)
asset additional_collateral
the amount of collateral to bid for the debt
Definition: market.hpp:186
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account&#39;s balance in a given asset by a delta.
Definition: db_balance.cpp:54
asset do_apply(const limit_order_cancel_operation &o) const
bool fill_or_kill
If this flag is set the entire order must be filled or the operation is rejected. ...
Definition: market.hpp:62
const object * find(object_id_type id) const override
bool is_authorized_asset(const database &d, const account_object &acct, const asset_object &asset_obj)
optional< uint16_t > target_collateral_ratio
maximum CR to maintain when selling collateral on margin call
const index_type & indices() const
void_result do_evaluate(const limit_order_cancel_operation &o)
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
const IndexType & get_index_type() const
void_result do_evaluate(const call_order_update_operation &o)
Definition: api.cpp:48
tracks debt and call price information
bool apply_order_before_hardfork_625(const limit_order_object &new_order_object)
Process a new limit order through the markets.
Definition: db_market.cpp:627
account_id_type bidder
pays fee and additional collateral
Definition: market.hpp:185
const account_object * fee_paying_account
Definition: evaluator.hpp:116
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account&#39;s balance in a given asset.
Definition: db_balance.cpp:35
flat_set< asset_id_type > blacklist_markets
Definition: asset_ops.hpp:86
price call_price
Collateral / Debt.
asset delta_collateral
the amount of collateral to add to the margin position
Definition: market.hpp:127
account_id_type funding_account
pays fee, collateral, and cover
Definition: market.hpp:126
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
bool check_call_orders(const asset_object &mia, bool enable_black_swan=true, bool for_new_limit_order=false, const asset_bitasset_data_object *bitasset_ptr=nullptr, bool mute_exceptions=false, bool skip_matching_settle_orders=false)
Definition: db_market.cpp:1745
share_type debt
call_price.quote.asset_id, access via get_debt
void cancel_bid(const collateral_bid_object &bid, bool create_virtual_op=true)
Definition: db_market.cpp:449
flat_set< asset_id_type > whitelist_markets
Definition: asset_ops.hpp:84
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
object_id_type id
Definition: object.hpp:69
void_result do_evaluate(const limit_order_create_operation &o)
const T * find(const object_id_type &id) const
void_result do_apply(const bid_collateral_operation &o) const
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:108
void cancel_limit_order(const limit_order_object &order, bool create_virtual_op=true, bool skip_cancel_fee=false)
Definition: db_market.cpp:505
bool valid() const
Definition: optional.hpp:186
const object & get(object_id_type id) const
Definition: index.hpp:110
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
instructs the blockchain to attempt to sell one asset for anotherThe blockchain will atempt to sell a...
Definition: market.hpp:48
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
void_result do_evaluate(const bid_collateral_operation &o)
tracks the asset information that changes frequentlyBecause the asset_object is very large it doesn&#39;t...
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
void update_bitasset_current_feed(const asset_bitasset_data_object &bitasset, bool skip_median_update=false)
Definition: db_update.cpp:225
bids of collateral for debt after a black swan
bool apply_order(const limit_order_object &new_order_object)
Definition: db_market.cpp:696
share_type collateral
call_price.base.asset_id, access via get_collateral
asset delta_debt
the amount of the debt to be paid off, may be negative to issue new debt
Definition: market.hpp:128
const account_statistics_object & get_account_stats_by_owner(account_id_type owner) const
Definition: db_getter.cpp:142
asset_id_type asset_id
Definition: asset.hpp:37
account_statistics_id_type statistics
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:70
void remove(const object &obj)
#define GRAPHENE_ASSERT(expr, exc_type, FORMAT,...)
Definition: exceptions.hpp:28
const dynamic_global_property_object & get_dynamic_global_properties() const
Definition: db_getter.cpp:57
const asset_dynamic_data_object * fee_asset_dyn_data
Definition: evaluator.hpp:119
share_type current_supply
The number of shares currently in existence.
static price call_price(const asset &debt, const asset &collateral, uint16_t collateral_ratio)
Definition: asset.cpp:216
const T & create(F &&constructor)
object_id_type do_apply(const limit_order_create_operation &o) const
object_id_type do_apply(const call_order_update_operation &o)
asset debt_covered
the amount of debt to take over
Definition: market.hpp:187
an offer to sell an amount of an asset at a specified exchange rate by a certain timeThe objects are ...
transaction_evaluation_state * trx_state
Definition: evaluator.hpp:120