32 #include <graphene/chain/hardfork.hpp> 37 namespace graphene {
namespace chain {
52 limit_order_create_market_not_whitelisted,
53 "This market has not been whitelisted by the selling asset", );
59 limit_order_create_market_blacklisted,
60 "This market has been blacklisted by the selling asset", );
64 limit_order_create_selling_asset_unauthorized,
65 "The account is not allowed to transact the selling asset", );
68 limit_order_create_receiving_asset_unauthorized,
69 "The account is not allowed to transact the receiving asset", );
72 limit_order_create_insufficient_balance,
73 "insufficient balance",
81 if(
db().head_block_time() <= HARDFORK_CORE_604_TIME )
93 if(
db().head_block_time() <= HARDFORK_445_TIME )
98 if(
db().head_block_time() > HARDFORK_CORE_604_TIME &&
fee_asset->
get_id() != asset_id_type() )
115 obj.seller = _seller->
id;
119 obj.deferred_fee = _deferred_fee;
120 obj.deferred_paid_fee = _deferred_paid_fee;
130 limit_order_create_kill_unfilled,
131 "Killing limit order ${op} due to unable to fill",
144 limit_order_cancel_nonexist_order,
145 "Limit order ${oid} does not exist",
149 limit_order_cancel_owner_mismatch,
150 "Limit order ${oid} is owned by someone else",
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();
186 FC_ASSERT( _debt_asset->is_market_issued(),
"Unable to cover ${sym} as it is not a collateralized asset.",
187 (
"sym", _debt_asset->symbol) );
191 _dynamic_data_obj = &_debt_asset->dynamic_asset_data_id(d);
196 if (next_maintenance_time > HARDFORK_CORE_1465_TIME)
199 "Borrowing this quantity would exceed MAX_SUPPLY" );
203 "This transaction would bring current supply below zero.");
205 _bitasset_data = &_debt_asset->bitasset_data(d);
209 FC_ASSERT( !_bitasset_data->has_settlement(),
210 "Cannot update debt position when the asset has been globally settled" );
213 "Collateral asset type should be same as backing asset of debt asset" );
217 if( itr != call_idx.end() )
224 FC_ASSERT( new_collateral == 0,
"Should claim all collateral when closing debt position" );
225 _closing_order =
true;
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" );
239 if( _bitasset_data->is_prediction_market )
241 "Debt amount and collateral amount should be same when updating debt position in a prediction " 243 else if( _bitasset_data->current_feed.settlement_price.is_null()
244 && !( HARDFORK_CORE_2467_PASSED( next_maintenance_time ) && _closing_order ) )
251 "The account is not allowed to transact the debt asset" );
253 "The account is not allowed to transact the collateral asset" );
292 auto call_order_id = call_ptr->id;
297 const auto bsrm = _bitasset_data->get_black_swan_response_method();
298 if( bitasset_options::black_swan_response_type::no_settlement == bsrm )
300 auto old_feed_price = _bitasset_data->current_feed.settlement_price;
302 if( !_bitasset_data->current_feed.settlement_price.is_null()
303 && _bitasset_data->current_feed.settlement_price != old_feed_price )
309 return call_order_id;
313 bool before_core_hardfork_1270 = ( next_maint_time <= HARDFORK_CORE_1270_TIME );
321 call.borrower = o.funding_account;
323 call.
debt = o.delta_debt.amount;
324 if( before_core_hardfork_1270 )
326 _bitasset_data->current_feed.maintenance_collateral_ratio );
328 call.call_price =
price(
asset( 1, o.delta_collateral.asset_id ),
asset( 1, o.delta_debt.asset_id ) );
334 old_collateralization = call_ptr->collateralization();
335 old_debt = call_ptr->debt;
339 call.
debt = new_debt;
340 if( before_core_hardfork_1270 )
343 _bitasset_data->current_feed.maintenance_collateral_ratio );
351 if( _bitasset_data->is_prediction_market )
352 return call_order_id;
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 ) )
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" );
374 const auto bsrm = _bitasset_data->get_black_swan_response_method();
375 if( bitasset_options::black_swan_response_type::no_settlement == bsrm )
383 bool called_some = d.
check_call_orders( *_debt_asset,
false,
false, _bitasset_data );
394 if( !HARDFORK_CORE_2467_PASSED( next_maint_time ) )
397 "Updating call order would trigger a margin call that cannot be fully filled" );
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)" );
420 FC_ASSERT( call_ptr,
"no margin call was executed and yet the call object was deleted" );
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",
433 (
"a", ~call_ptr->call_price )(
"b", _bitasset_data->current_feed.settlement_price)
450 bool ok = increasing_cr;
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 );
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)
467 return call_order_id;
479 FC_ASSERT( _debt_asset->is_market_issued(),
"Unable to cover ${sym} as it is not a collateralized asset.",
480 (
"sym", _debt_asset->symbol) );
485 if( HARDFORK_CORE_2281_PASSED( next_maint_time ) )
486 FC_ASSERT( _debt_asset->can_bid_collateral(),
"Collateral bidding is disabled for this asset" );
488 _bitasset_data = &_debt_asset->bitasset_data(d);
490 FC_ASSERT( _bitasset_data->has_settlement(),
"Cannot bid since the asset is not globally settled" );
494 FC_ASSERT( !_bitasset_data->is_prediction_market,
"Cannot bid on a prediction market!" );
499 if( bid != index.end() )
506 auto collateral_balance = d.
get_balance( o.
bidder, _bitasset_data->options.short_backing_asset );
511 "Cannot increase bid from ${oc} to ${nc} collateral when payer only has ${b}",
513 (
"b", collateral_balance.amount) );
517 (
"b", collateral_balance.amount) );
524 "The account is not allowed to transact the debt asset" );
526 "The account is not allowed to transact the collateral asset" );
const asset_object * fee_asset
void modify(const T &obj, const Lambda &m)
asset additional_collateral
the amount of collateral to bid for the debt
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account's balance in a given asset by a delta.
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. ...
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
tracks the blockchain state in an extensible manner
const IndexType & get_index_type() const
void_result do_evaluate(const call_order_update_operation &o)
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.
account_id_type bidder
pays fee and additional collateral
const account_object * fee_paying_account
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account's balance in a given asset.
flat_set< asset_id_type > blacklist_markets
price call_price
Collateral / Debt.
asset delta_collateral
the amount of collateral to add to the margin position
account_id_type funding_account
pays fee, collateral, and cover
provides stack-based nullable value similar to boost::optional
extensions_type extensions
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)
share_type debt
call_price.quote.asset_id, access via get_debt
asset get_collateral() const
void cancel_bid(const collateral_bid_object &bid, bool create_virtual_op=true)
flat_set< asset_id_type > whitelist_markets
object_id< SpaceID, TypeID > get_id() const
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.
void cancel_limit_order(const limit_order_object &order, bool create_virtual_op=true, bool skip_cancel_fee=false)
const object & get(object_id_type id) const
virtual void pay_fee() override
time_point_sec expiration
#define FC_CAPTURE_AND_RETHROW(...)
instructs the blockchain to attempt to sell one asset for anotherThe blockchain will atempt to sell a...
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
void_result do_evaluate(const bid_collateral_operation &o)
tracks the asset information that changes frequentlyBecause the asset_object is very large it doesn't...
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
void update_bitasset_current_feed(const asset_bitasset_data_object &bitasset, bool skip_median_update=false)
bids of collateral for debt after a black swan
time_point_sec next_maintenance_time
bool apply_order(const limit_order_object &new_order_object)
share_type fee_pool
in core asset
virtual void convert_fee()
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
const account_statistics_object & get_account_stats_by_owner(account_id_type owner) const
virtual void convert_fee() override
limit_order_id_type order
account_statistics_id_type statistics
abstract base class for accessing objects indexed in various ways.
void remove(const object &obj)
#define GRAPHENE_ASSERT(expr, exc_type, FORMAT,...)
const dynamic_global_property_object & get_dynamic_global_properties() const
const asset_dynamic_data_object * fee_asset_dyn_data
share_type current_supply
The number of shares currently in existence.
account_id_type fee_paying_account
static price call_price(const asset &debt, const asset &collateral, uint16_t collateral_ratio)
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)
share_type total_core_in_orders
asset debt_covered
the amount of debt to take over
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