BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
asset_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2018 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  */
30 #include <graphene/chain/hardfork.hpp>
32 
33 #include <functional>
34 
35 namespace graphene { namespace chain {
36 namespace detail {
37 
38  // TODO review and remove code below and links to it after hf_1774
39  void check_asset_options_hf_1774(const fc::time_point_sec& block_time, const asset_options& options)
40  {
41  if( block_time < HARDFORK_1774_TIME )
42  {
45  "Asset extension reward percent must be less than 100% till HARDFORK_1774_TIME!");
46  }
47  }
48 
49  void check_bitasset_options_hf_bsip74( const fc::time_point_sec& block_time, const bitasset_options& options)
50  {
51  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
52  FC_ASSERT( block_time >= HARDFORK_CORE_BSIP74_TIME
53  || !options.extensions.value.margin_call_fee_ratio.valid(),
54  "A BitAsset's MCFR cannot be set before Hardfork BSIP74" );
55  }
56 
57  // TODO review and remove code below and links to it after HARDFORK_BSIP_81_TIME
58  void check_asset_options_hf_bsip81(const fc::time_point_sec& block_time, const asset_options& options)
59  {
60  if (block_time < HARDFORK_BSIP_81_TIME) {
61  // Taker fees should not be set until activation of BSIP81
63  "Taker fee percent should not be defined before HARDFORK_BSIP_81_TIME");
64  }
65  }
66 
67  // TODO review and remove code below and links to it after HARDFORK_BSIP_48_75_TIME
68  void check_asset_options_hf_bsip_48_75(const fc::time_point_sec& block_time, const asset_options& options)
69  {
70  if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
71  {
72  // new issuer permissions should not be set until activation of BSIP_48_75
73  FC_ASSERT( 0 == (options.issuer_permissions & (uint16_t)(~ASSET_ISSUER_PERMISSION_ENABLE_BITS_MASK)),
74  "New asset issuer permission bits should not be set before HARDFORK_BSIP_48_75_TIME" );
75  // Note: no check for flags here because we didn't check in the past
76  }
77  }
78 
79  // TODO review and remove code below and links to it after HARDFORK_BSIP_48_75_TIME
81  {
82  if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
83  {
84  // new params should not be set until activation of BSIP_48_75
85  FC_ASSERT( !options.extensions.value.maintenance_collateral_ratio.valid(),
86  "Maintenance collateral ratio should not be defined by asset owner "
87  "before HARDFORK_BSIP_48_75_TIME" );
88  FC_ASSERT( !options.extensions.value.maximum_short_squeeze_ratio.valid(),
89  "Maximum short squeeze ratio should not be defined by asset owner "
90  "before HARDFORK_BSIP_48_75_TIME" );
91  }
92  }
93 
94  // TODO review and remove code below and links to it after HARDFORK_BSIP_48_75_TIME
96  const asset_update_operation::ext& extensions )
97  {
98  if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
99  {
100  // new extensions should not be set until activation of BSIP_48_75
101  FC_ASSERT( !extensions.new_precision.valid(),
102  "new_precision should not be set before HARDFORK_BSIP_48_75_TIME" );
103  FC_ASSERT( !extensions.skip_core_exchange_rate.valid(),
104  "skip_core_exchange_rate should not be set before HARDFORK_BSIP_48_75_TIME" );
105  }
106  }
107 
108  // TODO review and remove code below and links to it after HARDFORK_BSIP_77_TIME
110  const asset_publish_feed_operation::ext& extensions )
111  {
112  if ( !HARDFORK_BSIP_77_PASSED( block_time ) )
113  {
114  // new extensions should not be set until activation of BSIP_77
116  "Initial collateral ratio should not be defined before HARDFORK_BSIP_77_TIME" );
117  }
118  }
119 
120  // TODO review and remove code below and links to it after HARDFORK_BSIP_77_TIME
122  {
123  if ( !HARDFORK_BSIP_77_PASSED( block_time ) ) {
124  // ICR should not be set until activation of BSIP77
125  FC_ASSERT(!options.extensions.value.initial_collateral_ratio.valid(),
126  "Initial collateral ratio should not be defined before HARDFORK_BSIP_77_TIME");
127  }
128  }
129 
131  {
132  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
133  FC_ASSERT( !options.extensions.value.force_settle_fee_percent.valid()
134  || block_time >= HARDFORK_CORE_BSIP87_TIME,
135  "A BitAsset's FSFP cannot be set before Hardfork BSIP87" );
136  }
137 
139  const asset_claim_fees_operation& op)
140  {
141  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
142  FC_ASSERT( !op.extensions.value.claim_from_asset_id.valid() ||
143  block_time >= HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME,
144  "Collateral-denominated fees are not yet active and therefore cannot be claimed." );
145  }
146 
147  void check_asset_options_hf_core2281( const fc::time_point_sec& next_maint_time, const asset_options& options)
148  {
149  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
150  if ( !HARDFORK_CORE_2281_PASSED(next_maint_time) )
151  {
152  // new issuer permissions should not be set until activation of the hardfork
154  "New asset issuer permission bit 'disable_collateral_bidding' should not be set "
155  "before Hardfork core-2281" );
156  // Note: checks about flags are more complicated due to old bugs,
157  // and likely can not be removed after hardfork, so do not put them here
158  }
159  }
160 
161  void check_asset_options_hf_core2467(const fc::time_point_sec& next_maint_time, const asset_options& options)
162  {
163  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
164  if ( !HARDFORK_CORE_2467_PASSED(next_maint_time) )
165  {
166  // new issuer permissions should not be set until activation of the hardfork
168  "New asset issuer permission bit 'disable_bsrm_update' should not be set "
169  "before Hardfork core-2467" );
170  }
171  }
172 
173  void check_bitasset_opts_hf_core2467(const fc::time_point_sec& next_maint_time, const bitasset_options& options)
174  {
175  // HF_REMOVABLE: Following hardfork check should be removable after hardfork date passes:
176  if ( !HARDFORK_CORE_2467_PASSED(next_maint_time) )
177  {
178  FC_ASSERT( !options.extensions.value.black_swan_response_method.valid(),
179  "A BitAsset's black swan response method cannot be set before Hardfork core-2467" );
180  }
181  }
182 
183 } // graphene::chain::detail
184 
186 { try {
187 
188  const database& d = db();
189  const time_point_sec now = d.head_block_time();
191 
192  // Hardfork Checks:
196  detail::check_asset_options_hf_core2281( next_maint_time, op.common_options ); // HF_REMOVABLE
197  detail::check_asset_options_hf_core2467( next_maint_time, op.common_options ); // HF_REMOVABLE
198  if( op.bitasset_opts ) {
200  detail::check_bitasset_options_hf_bsip74( now, *op.bitasset_opts ); // HF_REMOVABLE
201  detail::check_bitasset_options_hf_bsip77( now, *op.bitasset_opts ); // HF_REMOVABLE
202  detail::check_bitasset_options_hf_bsip87( now, *op.bitasset_opts ); // HF_REMOVABLE
203  detail::check_bitasset_opts_hf_core2467( next_maint_time, *op.bitasset_opts ); // HF_REMOVABLE
204  }
205 
206  // TODO move as many validations as possible to validate() if not triggered before hardfork
207  if( HARDFORK_CORE_2281_PASSED( next_maint_time ) )
208  {
210  }
211  else if( HARDFORK_BSIP_48_75_PASSED( now ) )
212  {
213  // do not allow the 'disable_collateral_bidding' bit
214  op.common_options.validate_flags( op.bitasset_opts.valid(), false );
215  }
216 
220 
221  // Check that all authorities do exist
222  for( auto id : op.common_options.whitelist_authorities )
223  d.get(id);
224  for( auto id : op.common_options.blacklist_authorities )
225  d.get(id);
226 
227  auto& asset_indx = d.get_index_type<asset_index>().indices().get<by_symbol>();
228  auto asset_symbol_itr = asset_indx.find( op.symbol );
229  FC_ASSERT( asset_symbol_itr == asset_indx.end() );
230 
231  // This must remain due to "BOND.CNY" being allowed before this HF
232  if( now > HARDFORK_385_TIME )
233  {
234  auto dotpos = op.symbol.rfind( '.' );
235  if( dotpos != std::string::npos )
236  {
237  auto prefix = op.symbol.substr( 0, dotpos );
238  auto asset_prefix_itr = asset_indx.find( prefix );
239  FC_ASSERT( asset_prefix_itr != asset_indx.end(),
240  "Asset ${s} may only be created by issuer of asset ${p}, but asset ${p} has not been created",
241  ("s",op.symbol)("p",prefix) );
242  FC_ASSERT( asset_prefix_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
243  ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
244  }
245  }
246 
247  if( op.bitasset_opts )
248  {
249  const asset_object& backing = op.bitasset_opts->short_backing_asset(d);
250  if( backing.is_market_issued() )
251  {
252  const asset_bitasset_data_object& backing_bitasset_data = backing.bitasset_data(d);
253  const asset_object& backing_backing = backing_bitasset_data.options.short_backing_asset(d);
254  FC_ASSERT( !backing_backing.is_market_issued(),
255  "May not create a bitasset backed by a bitasset backed by a bitasset." );
256  FC_ASSERT( op.issuer != GRAPHENE_COMMITTEE_ACCOUNT || backing_backing.get_id() == asset_id_type(),
257  "May not create a blockchain-controlled market asset which is not backed by CORE.");
258  } else
259  FC_ASSERT( op.issuer != GRAPHENE_COMMITTEE_ACCOUNT || backing.get_id() == asset_id_type(),
260  "May not create a blockchain-controlled market asset which is not backed by CORE.");
261  FC_ASSERT( op.bitasset_opts->feed_lifetime_sec > chain_parameters.block_interval &&
262  op.bitasset_opts->force_settlement_delay_sec > chain_parameters.block_interval );
263  }
264 
265  if( op.is_prediction_market )
266  {
267  FC_ASSERT( op.bitasset_opts );
268  FC_ASSERT( op.precision == op.bitasset_opts->short_backing_asset(d).precision );
269  }
270 
271  return void_result();
272 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
273 
275 {
276  constexpr int64_t two = 2;
277  fee_is_odd = ( ( core_fee_paid.value % two ) != 0 );
280 }
281 
283 { try {
284  database& d = db();
285 
286  bool hf_429 = fee_is_odd && d.head_block_time() > HARDFORK_CORE_429_TIME;
287 
288  const asset_dynamic_data_object& dyn_asset =
290  a.current_supply = 0;
291  a.fee_pool = core_fee_paid - (hf_429 ? 1 : 0);
292  });
293 
294  if( fee_is_odd && !hf_429 )
295  {
297  ++dd.current_supply;
298  });
299  }
300 
301  asset_bitasset_data_id_type bit_asset_id;
302 
303  auto next_asset_id = d.get_index_type<asset_index>().get_next_id();
304 
305  if( op.bitasset_opts.valid() )
306  bit_asset_id = d.create<asset_bitasset_data_object>( [&op,next_asset_id]( asset_bitasset_data_object& a ) {
307  a.options = *op.bitasset_opts;
309  a.asset_id = next_asset_id;
310  }).id;
311 
312  const asset_object& new_asset =
313  d.create<asset_object>( [&op,next_asset_id,&dyn_asset,bit_asset_id,&d]( asset_object& a ) {
314  a.issuer = op.issuer;
315  a.symbol = op.symbol;
316  a.precision = op.precision;
317  a.options = op.common_options;
318  if( 0 == a.options.core_exchange_rate.base.asset_id.instance.value )
319  a.options.core_exchange_rate.quote.asset_id = next_asset_id;
320  else
321  a.options.core_exchange_rate.base.asset_id = next_asset_id;
322  a.dynamic_asset_data_id = dyn_asset.id;
323  if( op.bitasset_opts.valid() )
324  a.bitasset_data_id = bit_asset_id;
326  a.creation_time = d._current_block_time;
327  });
328  FC_ASSERT( new_asset.id == next_asset_id, "Unexpected object database error, object id mismatch" );
329 
330  return new_asset.id;
331 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
332 
334 { try {
335  const database& d = db();
336 
337  const asset_object& a = o.asset_to_issue.asset_id(d);
338  FC_ASSERT( o.issuer == a.issuer );
339  FC_ASSERT( !a.is_market_issued(), "Cannot manually issue a market-issued asset." );
340 
341  FC_ASSERT( !a.is_liquidity_pool_share_asset(), "Cannot manually issue a liquidity pool share asset." );
342 
343  FC_ASSERT( a.can_create_new_supply(), "Can not create new supply" );
344 
345  to_account = &o.issue_to_account(d);
346  FC_ASSERT( is_authorized_asset( d, *to_account, a ) );
347 
348  asset_dyn_data = &a.dynamic_asset_data_id(d);
349  FC_ASSERT( (asset_dyn_data->current_supply + o.asset_to_issue.amount) <= a.options.max_supply );
350 
351  return void_result();
352 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
353 
355 { try {
357 
358  db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
360  });
361 
362  return void_result();
363 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
364 
366 { try {
367  const database& d = db();
368 
369  const asset_object& a = o.amount_to_reserve.asset_id(d);
371  !a.is_market_issued(),
372  asset_reserve_invalid_on_mia,
373  "Cannot reserve ${sym} because it is a market-issued asset",
374  ("sym", a.symbol)
375  );
376 
377  from_account = fee_paying_account;
378  FC_ASSERT( is_authorized_asset( d, *from_account, a ) );
379 
380  asset_dyn_data = &a.dynamic_asset_data_id(d);
382  {
383  FC_ASSERT( asset_dyn_data->current_supply >= o.amount_to_reserve.amount,
384  "Can not reserve an amount that is more than the current supply" );
385  }
386  else
387  {
388  FC_ASSERT( asset_dyn_data->current_supply > o.amount_to_reserve.amount,
389  "The asset is a liquidity pool share asset thus can only reserve an amount "
390  "that is less than the current supply" );
391  }
392 
393  return void_result();
394 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
395 
397 { try {
399 
400  db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
402  });
403 
404  return void_result();
405 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
406 
408 { try {
409  const database& d = db();
410 
411  const asset_object& a = o.asset_id(d);
412 
413  asset_dyn_data = &a.dynamic_asset_data_id(d);
414 
415  return void_result();
416 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
417 
419 { try {
421 
422  db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ) {
423  data.fee_pool += o.amount;
424  });
425 
426  return void_result();
427 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
428 
429 static void validate_new_issuer( const database& d, const asset_object& a, account_id_type new_issuer )
430 { try {
431  FC_ASSERT(d.find(new_issuer), "New issuer account does not exist");
432  if( a.is_market_issued() && new_issuer == GRAPHENE_COMMITTEE_ACCOUNT )
433  {
434  const asset_object& backing = a.bitasset_data(d).options.short_backing_asset(d);
435  if( backing.is_market_issued() )
436  {
437  const asset_object& backing_backing = backing.bitasset_data(d).options.short_backing_asset(d);
438  FC_ASSERT( backing_backing.get_id() == asset_id_type(),
439  "May not create a blockchain-controlled market asset which is not backed by CORE.");
440  } else
441  FC_ASSERT( backing.get_id() == asset_id_type(),
442  "May not create a blockchain-controlled market asset which is not backed by CORE.");
443  }
444 } FC_CAPTURE_AND_RETHROW( (a)(new_issuer) ) } // GCOVR_EXCL_LINE
445 
447 { try {
448  const database& d = db();
449  const time_point_sec now = d.head_block_time();
451 
452  // Hardfork Checks:
456  detail::check_asset_options_hf_core2281( next_maint_time, o.new_options ); // HF_REMOVABLE
457  detail::check_asset_options_hf_core2467( next_maint_time, o.new_options ); // HF_REMOVABLE
459 
460  bool hf_bsip_48_75_passed = ( HARDFORK_BSIP_48_75_PASSED( now ) );
461  bool hf_core_2281_passed = ( HARDFORK_CORE_2281_PASSED( next_maint_time ) );
462  bool hf_core_2467_passed = ( HARDFORK_CORE_2467_PASSED( next_maint_time ) );
463 
464  const asset_object& a = o.asset_to_update(d);
465  auto a_copy = a;
466  a_copy.options = o.new_options;
467  a_copy.validate();
468 
469  if( o.new_issuer )
470  {
471  FC_ASSERT( now < HARDFORK_CORE_199_TIME,
472  "Since Hardfork #199, updating issuer requires the use of asset_update_issuer_operation.");
473  validate_new_issuer( d, a, *o.new_issuer );
474  }
475 
476  if( a.is_market_issued() )
477  bitasset_data = &a.bitasset_data(d);
478 
479  if( hf_core_2467_passed )
480  {
481  // Unable to set non-UIA issuer permission bits on UIA
482  if( !a.is_market_issued() )
483  FC_ASSERT( 0 == ( o.new_options.issuer_permissions & NON_UIA_ONLY_ISSUER_PERMISSION_MASK ),
484  "Unable to set non-UIA issuer permission bits on UIA" );
485  // Unable to set disable_bsrm_update issuer permission bit on PM
486  else if( bitasset_data->is_prediction_market )
488  "Unable to set disable_bsrm_update issuer permission bit on PM" );
489  // else do nothing
490  }
491 
492  uint16_t enabled_issuer_permissions_mask = a.options.get_enabled_issuer_permissions_mask();
493  if( hf_bsip_48_75_passed && a.is_market_issued() && bitasset_data->is_prediction_market )
494  {
495  // Note: if the global_settle permission was unset, it should be corrected
496  FC_ASSERT( a_copy.can_global_settle(),
497  "The global_settle permission should be enabled for prediction markets" );
498  enabled_issuer_permissions_mask |= global_settle;
499  }
500 
501  const auto& dyn_data = a.dynamic_asset_data_id(d);
502  if( dyn_data.current_supply != 0 )
503  {
504  // new issuer_permissions must be subset of old issuer permissions
505  if( hf_core_2467_passed && !a.is_market_issued() ) // for UIA, ignore non-UIA bits
507  & (uint16_t)(~enabled_issuer_permissions_mask) ) & UIA_ASSET_ISSUER_PERMISSION_MASK ),
508  "Cannot reinstate previously revoked issuer permissions on a UIA if current supply is non-zero, "
509  "unless to unset non-UIA issuer permission bits.");
510  else if( hf_core_2467_passed && bitasset_data->is_prediction_market ) // for PM, ignore disable_bsrm_update
512  & (uint16_t)(~enabled_issuer_permissions_mask) ) & (uint16_t)(~disable_bsrm_update) ),
513  "Cannot reinstate previously revoked issuer permissions on a PM if current supply is non-zero, "
514  "unless to unset the disable_bsrm_update issuer permission bit.");
515  else
517  & (uint16_t)(~enabled_issuer_permissions_mask) ),
518  "Cannot reinstate previously revoked issuer permissions on an asset if current supply is non-zero.");
519  // precision can not be changed
520  FC_ASSERT( !o.extensions.value.new_precision.valid(),
521  "Cannot update precision if current supply is non-zero" );
522 
523  if( hf_bsip_48_75_passed ) // TODO review after hard fork, probably can assert unconditionally
524  {
525  FC_ASSERT( dyn_data.current_supply <= o.new_options.max_supply,
526  "Max supply should not be smaller than current supply" );
527  }
528  }
529 
530  // If an invalid bit was set in flags, it should be unset
531  // TODO move as many validations as possible to validate() if not triggered before hardfork
532  if( hf_core_2281_passed )
533  {
535  }
536  else if( hf_bsip_48_75_passed )
537  {
538  // do not allow the 'disable_collateral_bidding' bit
540  }
541 
542  // changed flags must be subset of old issuer permissions
543  if( hf_bsip_48_75_passed )
544  {
545  // Note: if an invalid bit was set, it can be unset regardless of the permissions
546  uint16_t valid_flags_mask = hf_core_2281_passed ? VALID_FLAGS_MASK
547  : (VALID_FLAGS_MASK & (uint16_t)(~disable_collateral_bidding));
548  uint16_t check_bits = a.is_market_issued() ? valid_flags_mask : UIA_VALID_FLAGS_MASK;
549 
550  FC_ASSERT( 0 == ( (o.new_options.flags ^ a.options.flags) & check_bits
551  & (uint16_t)(~enabled_issuer_permissions_mask) ),
552  "Flag change is forbidden by issuer permissions" );
553  }
554  else
555  {
556  FC_ASSERT( 0 == ( (o.new_options.flags ^ a.options.flags) & (uint16_t)(~a.options.issuer_permissions) ),
557  "Flag change is forbidden by issuer permissions" );
558  }
559 
560  asset_to_update = &a;
561  FC_ASSERT( o.issuer == a.issuer,
562  "Incorrect issuer for asset! (${o.issuer} != ${a.issuer})",
563  ("o.issuer", o.issuer)("a.issuer", a.issuer) );
564 
566  "Can not update max supply" );
567 
568  if( o.extensions.value.new_precision.valid() )
569  {
570  FC_ASSERT( *o.extensions.value.new_precision != a.precision,
571  "Specified a new precision but it does not change" );
572 
573  if( a.is_market_issued() )
574  FC_ASSERT( !bitasset_data->is_prediction_market, "Can not update precision of a prediction market" );
575 
576  // If any other asset is backed by this asset, this asset's precision can't be updated
578  .indices().get<by_short_backing_asset>();
579  auto itr = idx.lower_bound( o.asset_to_update );
580  bool backing_another_asset = ( itr != idx.end() && itr->options.short_backing_asset == o.asset_to_update );
581  FC_ASSERT( !backing_another_asset,
582  "Asset ${a} is backed by this asset, can not update precision",
583  ("a",itr->asset_id) );
584  }
585 
587 
589  for( auto id : o.new_options.whitelist_authorities )
590  d.get(id);
592  for( auto id : o.new_options.blacklist_authorities )
593  d.get(id);
594 
595  return void_result();
596 } FC_CAPTURE_AND_RETHROW((o)) } // GCOVR_EXCL_LINE
597 
599 { try {
600  database& d = db();
601 
602  // If we are now disabling force settlements, cancel all open force settlement orders
603  if( 0 != (o.new_options.flags & disable_force_settle) && asset_to_update->can_force_settle() )
604  {
605  const auto& idx = d.get_index_type<force_settlement_index>().indices().get<by_expiration>();
606  // Funky iteration code because we're removing objects as we go. We have to re-initialize itr every loop instead
607  // of simply incrementing it.
608  for( auto itr = idx.lower_bound(o.asset_to_update);
609  itr != idx.end() && itr->settlement_asset_id() == o.asset_to_update;
610  itr = idx.lower_bound(o.asset_to_update) )
611  d.cancel_settle_order(*itr);
612  }
613 
614  // If we are now disabling collateral bidding, cancel all open collateral bids
615  if( 0 != (o.new_options.flags & disable_collateral_bidding) && asset_to_update->can_bid_collateral() )
616  {
617  const auto& bid_idx = d.get_index_type< collateral_bid_index >().indices().get<by_price>();
618  auto itr = bid_idx.lower_bound( o.asset_to_update );
619  const auto end = bid_idx.upper_bound( o.asset_to_update );
620  while( itr != end )
621  {
622  const collateral_bid_object& bid = *itr;
623  ++itr;
624  d.cancel_bid( bid );
625  }
626  }
627 
628  // For market-issued assets, if core exchange rate changed, update flag in bitasset data
629  if( !o.extensions.value.skip_core_exchange_rate.valid() && asset_to_update->is_market_issued()
630  && asset_to_update->options.core_exchange_rate != o.new_options.core_exchange_rate )
631  {
632  const auto& bitasset = ( bitasset_data ? *bitasset_data : asset_to_update->bitasset_data(d) );
633  if( !bitasset.asset_cer_updated )
634  {
635  d.modify( bitasset, [](asset_bitasset_data_object& b)
636  {
637  b.asset_cer_updated = true;
638  });
639  }
640  }
641 
642  d.modify(*asset_to_update, [&o](asset_object& a) {
643  if( o.new_issuer )
644  a.issuer = *o.new_issuer;
645  if( o.extensions.value.new_precision.valid() )
646  a.precision = *o.extensions.value.new_precision;
647  if( o.extensions.value.skip_core_exchange_rate.valid() )
648  {
649  const auto old_cer = a.options.core_exchange_rate;
650  a.options = o.new_options;
651  a.options.core_exchange_rate = old_cer;
652  }
653  else
654  a.options = o.new_options;
655  });
656 
657  return void_result();
658 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
659 
661 { try {
662  database& d = db();
663 
664  const asset_object& a = o.asset_to_update(d);
665 
666  validate_new_issuer( d, a, o.new_issuer );
667 
668  asset_to_update = &a;
669  FC_ASSERT( o.issuer == a.issuer,
670  "Incorrect issuer for asset! (${o.issuer} != ${a.issuer})",
671  ("o.issuer", o.issuer)("a.issuer", a.issuer) );
672 
673  return void_result();
674 } FC_CAPTURE_AND_RETHROW((o)) } // GCOVR_EXCL_LINE
675 
677 { try {
678  database& d = db();
679  d.modify(*asset_to_update, [&](asset_object& a) {
680  a.issuer = o.new_issuer;
681  });
682 
683  return void_result();
684 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
685 
686 /****************
687  * Loop through assets, looking for ones that are backed by the asset being changed. When found,
688  * perform checks to verify validity
689  *
690  * @param d the database
691  * @param op the bitasset update operation being performed
692  * @param new_backing_asset
693  * @param true if after hf 922/931 (if nothing triggers, this and the logic that depends on it
694  * should be removed).
695  */
697  const asset_object& new_backing_asset)
698 {
699  // no need to do these checks if the new backing asset is CORE
700  if ( new_backing_asset.get_id() == asset_id_type() )
701  return;
702 
703  // loop through all assets that have this asset as a backing asset
705  .indices()
706  .get<by_short_backing_asset>();
707  auto backed_range = idx.equal_range(op.asset_to_update);
708  std::for_each( backed_range.first, backed_range.second,
709  [&new_backing_asset, &d, &op](const asset_bitasset_data_object& bitasset_data)
710  {
711  const auto& child = bitasset_data.asset_id(d);
712  FC_ASSERT( child.get_id() != op.new_options.short_backing_asset,
713  "A BitAsset would be invalidated by changing this backing asset "
714  "('A' backed by 'B' backed by 'A')." );
715 
716  FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT,
717  "A blockchain-controlled market asset would be invalidated by changing this backing asset." );
718 
719  FC_ASSERT( !new_backing_asset.is_market_issued(),
720  "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset.");
721  } ); // end of lambda and std::for_each()
722 } // check_children_of_bitasset
723 
725 { try {
726  const database& d = db();
727  const time_point_sec now = d.head_block_time();
729 
730  // Hardfork Checks:
732  detail::check_bitasset_options_hf_bsip74( now, op.new_options ); // HF_REMOVABLE
733  detail::check_bitasset_options_hf_bsip77( now, op.new_options ); // HF_REMOVABLE
734  detail::check_bitasset_options_hf_bsip87( now, op.new_options ); // HF_REMOVABLE
735  detail::check_bitasset_opts_hf_core2467( next_maint_time, op.new_options ); // HF_REMOVABLE
736 
737  const asset_object& asset_obj = op.asset_to_update(d);
738 
739  FC_ASSERT( asset_obj.is_market_issued(), "Cannot update BitAsset-specific settings on a non-BitAsset." );
740 
741  FC_ASSERT( op.issuer == asset_obj.issuer, "Only asset issuer can update bitasset_data of the asset." );
742 
743  const asset_bitasset_data_object& current_bitasset_data = asset_obj.bitasset_data(d);
744 
745  if( !HARDFORK_CORE_2282_PASSED( next_maint_time ) )
746  FC_ASSERT( !current_bitasset_data.is_globally_settled(),
747  "Cannot update a bitasset after a global settlement has executed" );
748 
749  if( current_bitasset_data.is_prediction_market )
750  FC_ASSERT( !op.new_options.extensions.value.black_swan_response_method.valid(),
751  "Can not set black_swan_response_method for Prediction Markets" );
752 
753  // TODO simplify code below when made sure operator==(optional,optional) works
754  if( !asset_obj.can_owner_update_mcr() )
755  {
756  // check if MCR will change
757  const auto& old_mcr = current_bitasset_data.options.extensions.value.maintenance_collateral_ratio;
758  const auto& new_mcr = op.new_options.extensions.value.maintenance_collateral_ratio;
759  bool mcr_changed = ( ( old_mcr.valid() != new_mcr.valid() )
760  || ( old_mcr.valid() && *old_mcr != *new_mcr ) );
761  FC_ASSERT( !mcr_changed, "No permission to update MCR" );
762  }
763  if( !asset_obj.can_owner_update_icr() )
764  {
765  // check if ICR will change
766  const auto& old_icr = current_bitasset_data.options.extensions.value.initial_collateral_ratio;
767  const auto& new_icr = op.new_options.extensions.value.initial_collateral_ratio;
768  bool icr_changed = ( ( old_icr.valid() != new_icr.valid() )
769  || ( old_icr.valid() && *old_icr != *new_icr ) );
770  FC_ASSERT( !icr_changed, "No permission to update ICR" );
771  }
772  if( !asset_obj.can_owner_update_mssr() )
773  {
774  // check if MSSR will change
775  const auto& old_mssr = current_bitasset_data.options.extensions.value.maximum_short_squeeze_ratio;
776  const auto& new_mssr = op.new_options.extensions.value.maximum_short_squeeze_ratio;
777  bool mssr_changed = ( ( old_mssr.valid() != new_mssr.valid() )
778  || ( old_mssr.valid() && *old_mssr != *new_mssr ) );
779  FC_ASSERT( !mssr_changed, "No permission to update MSSR" );
780  }
781  // check if BSRM will change
782  const auto old_bsrm = current_bitasset_data.get_black_swan_response_method();
783  const auto new_bsrm = op.new_options.get_black_swan_response_method();
784  if( old_bsrm != new_bsrm )
785  {
786  FC_ASSERT( asset_obj.can_owner_update_bsrm(), "No permission to update BSRM" );
787  FC_ASSERT( !current_bitasset_data.is_globally_settled(),
788  "Unable to update BSRM when the asset has been globally settled" );
789 
790  // Note: it is probably OK to allow BSRM update, be conservative here so far
792  if( bsrm_type::individual_settlement_to_fund == old_bsrm )
793  FC_ASSERT( !current_bitasset_data.is_individually_settled_to_fund(),
794  "Unable to update BSRM when the individual settlement pool (for force-settlements) is not empty" );
795  else if( bsrm_type::individual_settlement_to_order == old_bsrm )
797  "Unable to update BSRM when there exists an individual settlement order" );
798 
799  // Since we do not allow updating in some cases (above), only check no_settlement here
800  if( bsrm_type::no_settlement == old_bsrm || bsrm_type::no_settlement == new_bsrm )
801  update_feeds_due_to_bsrm_change = true;
802  }
803 
804 
805  // hf 922_931 is a consensus/logic change. This hf cannot be removed.
806  bool after_hf_core_922_931 = ( next_maint_time > HARDFORK_CORE_922_931_TIME );
807 
808  // Are we changing the backing asset?
809  if( op.new_options.short_backing_asset != current_bitasset_data.options.short_backing_asset )
810  {
811  FC_ASSERT( !current_bitasset_data.is_globally_settled(),
812  "Cannot change backing asset after a global settlement has executed" );
813 
814  const asset_dynamic_data_object& dyn = asset_obj.dynamic_asset_data_id(d);
815  FC_ASSERT( dyn.current_supply == 0,
816  "Cannot change backing asset if there is already a current supply." );
817 
819  "Must claim collateral-denominated fees before changing backing asset." );
820 
821  const asset_object& new_backing_asset = op.new_options.short_backing_asset(d); // check if the asset exists
822 
823  if( after_hf_core_922_931 )
824  {
825  FC_ASSERT( op.new_options.short_backing_asset != asset_obj.get_id(),
826  "Cannot update an asset to be backed by itself." );
827 
828  if( current_bitasset_data.is_prediction_market )
829  {
830  FC_ASSERT( asset_obj.precision == new_backing_asset.precision,
831  "The precision of the asset and backing asset must be equal." );
832  }
833 
834  if( asset_obj.issuer == GRAPHENE_COMMITTEE_ACCOUNT )
835  {
836  if( new_backing_asset.is_market_issued() )
837  {
838  FC_ASSERT( new_backing_asset.bitasset_data(d).options.short_backing_asset == asset_id_type(),
839  "May not modify a blockchain-controlled market asset to be backed by an asset which is not "
840  "backed by CORE." );
841 
842  check_children_of_bitasset( d, op, new_backing_asset );
843  }
844  else
845  {
846  FC_ASSERT( new_backing_asset.get_id() == asset_id_type(),
847  "May not modify a blockchain-controlled market asset to be backed by an asset which is not "
848  "market issued asset nor CORE." );
849  }
850  }
851  else
852  {
853  // not a committee issued asset
854 
855  // If we're changing to a backing_asset that is not CORE, we need to look at any
856  // asset ( "CHILD" ) that has this one as a backing asset. If CHILD is committee-owned,
857  // the change is not allowed. If CHILD is user-owned, then this asset's backing
858  // asset must be either CORE or a UIA.
859  if ( new_backing_asset.get_id() != asset_id_type() ) // not backed by CORE
860  {
861  check_children_of_bitasset( d, op, new_backing_asset );
862  }
863 
864  }
865 
866  // Check if the new backing asset is itself backed by something. It must be CORE or a UIA
867  if ( new_backing_asset.is_market_issued() )
868  {
869  asset_id_type backing_backing_asset_id = new_backing_asset.bitasset_data(d).options.short_backing_asset;
870  FC_ASSERT( (backing_backing_asset_id == asset_id_type()
871  || !backing_backing_asset_id(d).is_market_issued()),
872  "A BitAsset cannot be backed by a BitAsset that itself is backed by a BitAsset.");
873  }
874  }
875  }
876 
878  if( after_hf_core_922_931 )
879  {
881  "Feed lifetime must exceed block interval." );
883  "Force settlement delay must exceed block interval." );
884  }
885 
886  bitasset_to_update = &current_bitasset_data;
887  asset_to_update = &asset_obj;
888 
889  return void_result();
890 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
891 
892 /*******
893  * @brief Apply requested changes to bitasset options
894  *
895  * This applies the requested changes to the bitasset object. It also cleans up the
896  * releated feeds, and checks conditions that might necessitate a call to check_call_orders.
897  * Called from asset_update_bitasset_evaluator::do_apply().
898  *
899  * @param op the requested operation
900  * @param db the database
901  * @param bdo the actual database object
902  * @param asset_to_update the asset_object related to this bitasset_data_object
903  *
904  * @returns true if we should check call orders, such as if if the feed price is changed, or some
905  * cases after hf core-868-890, or if the margin_call_fee_ratio has changed, which affects the
906  * matching price of margin call orders.
907  */
908 static bool update_bitasset_object_options(
910  asset_bitasset_data_object& bdo, const asset_object& asset_to_update,
911  bool update_feeds_due_to_bsrm_change )
912 {
914  bool after_hf_core_868_890 = ( next_maint_time > HARDFORK_CORE_868_890_TIME );
915 
916  const auto& head_time = db.head_block_time();
917  bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time ); // Price feed issues
918 
919  // If the minimum number of feeds to calculate a median has changed, we need to recalculate the median
920  bool should_update_feeds = false;
922  should_update_feeds = true;
923 
924  // after hardfork core-868-890, we also should call update_bitasset_current_feed if the feed_lifetime_sec changed
925  if( after_hf_core_868_890
927  {
928  should_update_feeds = true;
929  }
930 
931  // feeds must be reset if the backing asset is changed after hardfork core-868-890
932  bool backing_asset_changed = false;
933  bool is_witness_or_committee_fed = false;
934  if( after_hf_core_868_890
936  {
937  backing_asset_changed = true;
938  should_update_feeds = true;
939  if( 0 != ( asset_to_update.options.flags & ( witness_fed_asset | committee_fed_asset ) ) )
940  is_witness_or_committee_fed = true;
941  }
942 
943  // TODO simplify code below when made sure operator==(optional,optional) works
944  // check if ICR will change
945  if( !should_update_feeds )
946  {
947  const auto& old_icr = bdo.options.extensions.value.initial_collateral_ratio;
948  const auto& new_icr = op.new_options.extensions.value.initial_collateral_ratio;
949  bool icr_changed = ( ( old_icr.valid() != new_icr.valid() )
950  || ( old_icr.valid() && *old_icr != *new_icr ) );
951  should_update_feeds = icr_changed;
952  }
953  // check if MCR will change
954  if( !should_update_feeds )
955  {
956  const auto& old_mcr = bdo.options.extensions.value.maintenance_collateral_ratio;
957  const auto& new_mcr = op.new_options.extensions.value.maintenance_collateral_ratio;
958  bool mcr_changed = ( ( old_mcr.valid() != new_mcr.valid() )
959  || ( old_mcr.valid() && *old_mcr != *new_mcr ) );
960  should_update_feeds = mcr_changed;
961  }
962  // check if MSSR will change
963  if( !should_update_feeds )
964  {
965  const auto& old_mssr = bdo.options.extensions.value.maximum_short_squeeze_ratio;
966  const auto& new_mssr = op.new_options.extensions.value.maximum_short_squeeze_ratio;
967  bool mssr_changed = ( ( old_mssr.valid() != new_mssr.valid() )
968  || ( old_mssr.valid() && *old_mssr != *new_mssr ) );
969  should_update_feeds = mssr_changed;
970  }
971 
972  // check if MCFR will change
973  const auto& old_mcfr = bdo.options.extensions.value.margin_call_fee_ratio;
974  const auto& new_mcfr = op.new_options.extensions.value.margin_call_fee_ratio;
975  const bool mcfr_changed = ( ( old_mcfr.valid() != new_mcfr.valid() )
976  || ( old_mcfr.valid() && *old_mcfr != *new_mcfr ) );
977 
978  // Apply changes to bitasset options
979  bdo.options = op.new_options;
980 
981  // are we modifying the underlying? If so, reset the feeds
982  if( backing_asset_changed )
983  {
984  if( is_witness_or_committee_fed )
985  {
986  bdo.feeds.clear();
987  }
988  else
989  {
990  // for non-witness-feeding and non-committee-feeding assets, modify all feeds
991  // published by producers to nothing, since we can't simply remove them. For more information:
992  // https://github.com/bitshares/bitshares-core/pull/832#issuecomment-384112633
993  for( auto& current_feed : bdo.feeds )
994  {
995  current_feed.second.second.settlement_price = price();
996  }
997  }
998  }
999 
1000  bool feed_actually_changed = false;
1001  if( should_update_feeds || update_feeds_due_to_bsrm_change )
1002  {
1003  const auto old_feed = bdo.current_feed;
1004  const auto old_median_feed = bdo.median_feed;
1005  // skip recalculating median feed if it is not needed
1006  db.update_bitasset_current_feed( bdo, !should_update_feeds );
1007  // Note: we don't try to revive the bitasset here if it was GSed // TODO probably we should do it
1008 
1009  // TODO potential optimization: check only when should_update_feeds == true
1010 
1011  // We need to call check_call_orders if the settlement price changes after hardfork core-868-890
1012  feed_actually_changed = ( after_hf_core_868_890 && !old_feed.margin_call_params_equal( bdo.current_feed ) );
1013 
1014  if( !feed_actually_changed && after_core_hardfork_2582
1015  && !old_median_feed.margin_call_params_equal( bdo.median_feed ) )
1016  feed_actually_changed = true;
1017  }
1018 
1019  // Conditions under which a call to check_call_orders is needed in response to the updates applied here:
1020  const bool retval = feed_actually_changed || mcfr_changed;
1021 
1022  return retval;
1023 }
1024 
1026 {
1027  try
1028  {
1029  auto& db_conn = db();
1030  bool to_check_call_orders = false;
1031 
1032  db_conn.modify( *bitasset_to_update,
1033  [&op, &to_check_call_orders, &db_conn, this]( asset_bitasset_data_object& bdo )
1034  {
1035  to_check_call_orders = update_bitasset_object_options( op, db_conn, bdo, *asset_to_update,
1036  update_feeds_due_to_bsrm_change );
1037  });
1038 
1039  if( to_check_call_orders )
1040  // Process margin calls, allow black swan, not for a new limit order
1041  db_conn.check_call_orders( *asset_to_update, true, false, bitasset_to_update );
1042 
1043  return void_result();
1044 
1045  } FC_CAPTURE_AND_RETHROW( (op) ) // GCOVR_EXCL_LINE
1046 }
1047 
1049 { try {
1050  database& d = db();
1051 
1053  "Cannot specify more feed producers than maximum allowed" );
1054 
1055  const asset_object& a = o.asset_to_update(d);
1056 
1057  FC_ASSERT(a.is_market_issued(), "Cannot update feed producers on a non-BitAsset.");
1058  FC_ASSERT(0 == (a.options.flags & committee_fed_asset), "Cannot set feed producers on a committee-fed asset.");
1059  FC_ASSERT(0 == (a.options.flags & witness_fed_asset), "Cannot set feed producers on a witness-fed asset.");
1060 
1061  FC_ASSERT( a.issuer == o.issuer, "Only asset issuer can update feed producers of an asset" );
1062 
1063  asset_to_update = &a;
1064 
1065  // Make sure all producers exist. Check these after asset because account lookup is more expensive
1066  for( auto id : o.new_feed_producers )
1067  d.get(id);
1068 
1069  return void_result();
1070 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1071 
1073 { try {
1074  database& d = db();
1075  const asset_bitasset_data_object& bitasset_to_update = asset_to_update->bitasset_data(d);
1076  d.modify( bitasset_to_update, [&o](asset_bitasset_data_object& a) {
1077  //This is tricky because I have a set of publishers coming in, but a map of publisher to feed is stored.
1078  //I need to update the map such that the keys match the new publishers, but not munge the old price feeds from
1079  //publishers who are being kept.
1080 
1081  // TODO possible performance optimization:
1082  // Since both the map and the set are ordered by account already, we can iterate through them only once
1083  // and avoid lookups while iterating by maintaining two iterators at same time.
1084  // However, this operation is not used much, and both the set and the map are small,
1085  // so likely we won't gain much with the optimization.
1086 
1087  //First, remove any old publishers who are no longer publishers
1088  for( auto itr = a.feeds.begin(); itr != a.feeds.end(); )
1089  {
1090  if( o.new_feed_producers.count(itr->first) == 0 )
1091  itr = a.feeds.erase(itr);
1092  else
1093  ++itr;
1094  }
1095  //Now, add any new publishers
1096  for( const account_id_type& acc : o.new_feed_producers )
1097  {
1098  a.feeds[acc];
1099  }
1100  });
1101  d.update_bitasset_current_feed( bitasset_to_update );
1102  // Note: we don't try to revive the bitasset here if it was GSed // TODO probably we should do it
1103 
1104  // Process margin calls, allow black swan, not for a new limit order
1105  d.check_call_orders( *asset_to_update, true, false, &bitasset_to_update );
1106 
1107  return void_result();
1108 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1109 
1111 { try {
1112  const database& d = db();
1113  asset_to_settle = &op.asset_to_settle(d);
1114  FC_ASSERT( asset_to_settle->is_market_issued(), "Can only globally settle market-issued assets" );
1115  FC_ASSERT( asset_to_settle->can_global_settle(), "The global_settle permission of this asset is disabled" );
1116  FC_ASSERT( asset_to_settle->issuer == op.issuer, "Only asset issuer can globally settle an asset" );
1117  FC_ASSERT( asset_to_settle->dynamic_data(d).current_supply > 0,
1118  "Can not globally settle an asset with zero supply" );
1119 
1120  const asset_bitasset_data_object& _bitasset_data = asset_to_settle->bitasset_data(d);
1121  // if there is a settlement for this asset, then no further global settle may be taken
1122  FC_ASSERT( !_bitasset_data.is_globally_settled(),
1123  "This asset has been globally settled, cannot globally settle again" );
1124 
1125  // Note: after core-2467 hard fork, there can be no debt position due to individual settlements, so we check here
1126  const call_order_object* least_collateralized_short = d.find_least_collateralized_short( _bitasset_data, true );
1127  if( least_collateralized_short )
1128  {
1129  FC_ASSERT( ( least_collateralized_short->get_debt() * op.settle_price )
1130  <= least_collateralized_short->get_collateral(),
1131  "Cannot globally settle at supplied price: least collateralized short lacks "
1132  "sufficient collateral to settle." );
1133  }
1134 
1135  return void_result();
1136 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
1137 
1139 { try {
1140  database& d = db();
1141  d.globally_settle_asset( *asset_to_settle, op.settle_price );
1142  return void_result();
1143 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
1144 
1146 { try {
1147  const database& d = db();
1148  asset_to_settle = &op.amount.asset_id(d);
1149  FC_ASSERT( asset_to_settle->is_market_issued(),
1150  "Can only force settle a predition market or a market issued asset" );
1151 
1152  const auto& bitasset = asset_to_settle->bitasset_data(d);
1153  FC_ASSERT( asset_to_settle->can_force_settle() || bitasset.is_globally_settled()
1154  || bitasset.is_individually_settled_to_fund(),
1155  "Either the asset need to have the force_settle flag enabled, or it need to be globally settled, "
1156  "or the individual settlement pool (for force-settlements) is not empty" );
1157 
1158  if( bitasset.is_prediction_market )
1159  {
1160  FC_ASSERT( bitasset.is_globally_settled(),
1161  "Global settlement must occur before force settling a prediction market" );
1162  }
1163  else if( bitasset.current_feed.settlement_price.is_null() )
1164  {
1165  // TODO check whether the HF check can be removed
1166  if( d.head_block_time() <= HARDFORK_CORE_216_TIME )
1167  {
1168  FC_THROW_EXCEPTION( insufficient_feeds,
1169  "Before the core-216 hard fork, unable to force settle when there is no sufficient "
1170  " price feeds, no matter if the asset has been globally settled" );
1171  }
1172  if( !bitasset.is_globally_settled() && !bitasset.is_individually_settled_to_fund() )
1173  {
1174  FC_THROW_EXCEPTION( insufficient_feeds,
1175  "Cannot force settle with no price feed if the asset is not globally settled and the "
1176  "individual settlement pool (for force-settlements) is not empty" );
1177  }
1178  }
1179 
1180  FC_ASSERT( d.get_balance( op.account, op.amount.asset_id ) >= op.amount, "Insufficient balance" );
1181 
1182  // Since hard fork core-973, check asset authorization limitations
1183  if( HARDFORK_CORE_973_PASSED(d.head_block_time()) )
1184  {
1185  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, *asset_to_settle ),
1186  "The account is not allowed to settle the asset" );
1187  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, bitasset.options.short_backing_asset(d) ),
1188  "The account is not allowed to receive the backing asset" );
1189  }
1190 
1191  bitasset_ptr = &bitasset;
1192 
1193  return void_result();
1194 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
1195 
1196 static optional<asset> pay_collateral_fees( database& d,
1197  const asset& pays,
1198  const asset& settled_amount,
1199  const asset_object& asset_to_settle,
1200  const asset_bitasset_data_object& bitasset )
1201 {
1202  const auto& head_time = d.head_block_time();
1203  bool after_core_hardfork_2591 = HARDFORK_CORE_2591_PASSED( head_time ); // Tighter peg (fill settlement at MCOP)
1204  if( after_core_hardfork_2591 && !bitasset.is_prediction_market
1205  && !bitasset.current_feed.settlement_price.is_null() )
1206  {
1207  price fill_price = bitasset.get_margin_call_order_price();
1208  try
1209  {
1210  asset settled_amount_by_mcop = pays.multiply_and_round_up( fill_price ); // Throws fc::exception if overflow
1211  if( settled_amount_by_mcop < settled_amount )
1212  {
1213  asset collateral_fees = settled_amount - settled_amount_by_mcop;
1214  asset_to_settle.accumulate_fee( d, collateral_fees );
1215  return collateral_fees;
1216  }
1217  } FC_CAPTURE_AND_LOG( (pays)(settled_amount)(fill_price) ) // Catch and log the exception // GCOVR_EXCL_LINE
1218  }
1219  return optional<asset>();
1220 }
1221 
1222 static extendable_operation_result pay_settle_from_gs_fund( database& d,
1224  const account_object* fee_paying_account,
1225  const asset_object& asset_to_settle,
1226  const asset_bitasset_data_object& bitasset )
1227 {
1228  const auto& head_time = d.head_block_time();
1229  const auto& maint_time = d.get_dynamic_global_properties().next_maintenance_time;
1230 
1231  const auto& mia_dyn = asset_to_settle.dynamic_asset_data_id(d);
1232 
1233  asset settled_amount = ( op.amount.amount == mia_dyn.current_supply )
1234  ? asset( bitasset.settlement_fund, bitasset.options.short_backing_asset )
1235  : ( op.amount * bitasset.settlement_price ); // round down, favors global settlement fund
1236  if( op.amount.amount != mia_dyn.current_supply )
1237  {
1238  // should be strictly < except for PM with zero outcome since in that case bitasset.settlement_fund is zero
1239  FC_ASSERT( settled_amount.amount <= bitasset.settlement_fund,
1240  "Internal error: amount in the global settlement fund is not sufficient to pay the settlement" );
1241  }
1242 
1243  if( 0 == settled_amount.amount && !bitasset.is_prediction_market && maint_time > HARDFORK_CORE_184_TIME )
1244  FC_THROW( "Settle amount is too small to receive anything due to rounding" );
1245  // else do nothing. Before the hf, something for nothing issue (#184, variant F) could occur
1246 
1247  asset pays = op.amount;
1248  if( op.amount.amount != mia_dyn.current_supply
1249  && settled_amount.amount != 0
1250  && maint_time > HARDFORK_CORE_342_TIME )
1251  {
1252  pays = settled_amount.multiply_and_round_up( bitasset.settlement_price );
1253  }
1254 
1255  d.adjust_balance( op.account, -pays );
1256 
1257  asset issuer_fees( 0, bitasset.options.short_backing_asset );
1258  optional<asset> collateral_fees;
1259 
1260  if( settled_amount.amount > 0 )
1261  {
1262  d.modify( bitasset, [&settled_amount]( asset_bitasset_data_object& obj ){
1263  obj.settlement_fund -= settled_amount.amount;
1264  });
1265 
1266  // Calculate and pay collateral fees after HF core-2591
1267  collateral_fees = pay_collateral_fees( d, pays, settled_amount, asset_to_settle, bitasset );
1268  if( collateral_fees.valid() )
1269  settled_amount -= *collateral_fees;
1270 
1271  // The account who settles pays market fees to the issuer of the collateral asset after HF core-1780
1272  //
1273  // TODO Check whether the HF check can be removed after the HF.
1274  // Note: even if logically it can be removed, perhaps the removal will lead to a small
1275  // performance loss. Needs testing.
1276  if( head_time >= HARDFORK_CORE_1780_TIME )
1277  {
1278  issuer_fees = d.pay_market_fees( fee_paying_account, settled_amount.asset_id(d), settled_amount, false );
1279  settled_amount -= issuer_fees;
1280  }
1281 
1282  if( settled_amount.amount > 0 )
1283  d.adjust_balance( op.account, settled_amount );
1284  }
1285 
1286  d.modify( mia_dyn, [&pays]( asset_dynamic_data_object& obj ){
1287  obj.current_supply -= pays.amount;
1288  });
1289  // Note: we don't revive the asset here if current_supply become zero, but only do it on a new feed
1290 
1292 
1293  result.value.paid = vector<asset>({ pays });
1294  result.value.received = vector<asset>({ settled_amount });
1295  result.value.fees = collateral_fees.valid() ? vector<asset>({ *collateral_fees, issuer_fees })
1296  : vector<asset>({ issuer_fees });
1297 
1298  return result;
1299 }
1300 
1301 static extendable_operation_result pay_settle_from_individual_pool( database& d,
1303  const account_object* fee_paying_account,
1304  const asset_object& asset_to_settle,
1305  const asset_bitasset_data_object& bitasset )
1306 {
1307  asset pays( bitasset.individual_settlement_debt, bitasset.asset_id );
1308  asset settled_amount( bitasset.individual_settlement_fund, bitasset.options.short_backing_asset );
1309  if( op.amount.amount < bitasset.individual_settlement_debt )
1310  {
1311  auto settlement_price = bitasset.get_individual_settlement_price();
1312  settled_amount = op.amount * settlement_price; // round down, in favor of settlement fund
1313  FC_ASSERT( settled_amount.amount > 0, "Settle amount is too small to receive anything due to rounding" );
1314  pays = settled_amount.multiply_and_round_up( settlement_price );
1315  }
1316 
1317  d.adjust_balance( op.account, -pays );
1318  d.modify( bitasset, [&pays,&settled_amount]( asset_bitasset_data_object& obj ){
1319  obj.individual_settlement_debt -= pays.amount;
1320  obj.individual_settlement_fund -= settled_amount.amount;
1321  });
1322  d.modify( asset_to_settle.dynamic_asset_data_id(d), [&pays]( asset_dynamic_data_object& obj ){
1323  obj.current_supply -= pays.amount;
1324  });
1325 
1326  // Calculate and pay collateral fees after HF core-2591
1327  optional<asset> collateral_fees = pay_collateral_fees( d, pays, settled_amount, asset_to_settle, bitasset );
1328  if( collateral_fees.valid() )
1329  settled_amount -= *collateral_fees;
1330 
1331  auto issuer_fees = d.pay_market_fees( fee_paying_account, settled_amount.asset_id(d), settled_amount, false );
1332  settled_amount -= issuer_fees;
1333 
1334  if( settled_amount.amount > 0 )
1335  d.adjust_balance( op.account, settled_amount );
1336 
1337  // Update current_feed since fund price changed
1338  auto old_feed_price = bitasset.current_feed.settlement_price;
1339  d.update_bitasset_current_feed( bitasset, true );
1340 
1341  // When current_feed is updated, it is possible that there are limit orders able to get filled,
1342  // so we need to call check_call_orders()
1343  // Note: theoretically, if the fund is still not empty, its new CR should be >= old CR,
1344  // in this case, calling check_call_orders() should not change anything.
1345  // Note: there should be no existing force settlements
1346  if( 0 == bitasset.individual_settlement_debt && old_feed_price != bitasset.current_feed.settlement_price )
1347  d.check_call_orders( asset_to_settle, true, false, &bitasset );
1348 
1350 
1351  result.value.paid = vector<asset>({ pays });
1352  result.value.received = vector<asset>({ settled_amount });
1353  result.value.fees = collateral_fees.valid() ? vector<asset>({ *collateral_fees, issuer_fees })
1354  : vector<asset>({ issuer_fees });
1355 
1356  return result;
1357 }
1358 
1360 { try {
1361  database& d = db();
1362 
1363  const auto& bitasset = *bitasset_ptr;
1364 
1365  // Process global settlement fund
1366  if( bitasset.is_globally_settled() )
1367  return pay_settle_from_gs_fund( d, op, fee_paying_account, *asset_to_settle, bitasset );
1368 
1369  // Process individual settlement pool
1371  asset to_settle = op.amount;
1372  if( bitasset.is_individually_settled_to_fund() )
1373  {
1374  result = pay_settle_from_individual_pool( d, op, fee_paying_account, *asset_to_settle, bitasset );
1375 
1376  // If the amount to settle is too small, or force settlement is disabled, we return
1377  if( bitasset.is_individually_settled_to_fund() || !asset_to_settle->can_force_settle() )
1378  return result;
1379 
1380  to_settle -= result.value.paid->front();
1381  }
1382 
1383  // Process the rest
1384  const auto& head_time = d.head_block_time();
1385 
1386  bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time ); // Price feed issues
1387  if( after_core_hardfork_2582 && 0 == to_settle.amount )
1388  return result;
1389 
1390  bool after_core_hardfork_2587 = HARDFORK_CORE_2587_PASSED( head_time );
1391  if( after_core_hardfork_2587 && bitasset.current_feed.settlement_price.is_null() )
1392  return result;
1393 
1394  d.adjust_balance( op.account, -to_settle );
1395  const auto& settle = d.create<force_settlement_object>(
1396  [&op,&to_settle,&head_time,&bitasset](force_settlement_object& s) {
1397  s.owner = op.account;
1398  s.balance = to_settle;
1399  s.settlement_date = head_time + bitasset.options.force_settlement_delay_sec;
1400  });
1401 
1402  result.value.new_objects = flat_set<object_id_type>({ settle.id });
1403 
1404  const auto& maint_time = d.get_dynamic_global_properties().next_maintenance_time;
1405  if( HARDFORK_CORE_2481_PASSED( maint_time ) )
1406  {
1407  d.apply_force_settlement( settle, bitasset, *asset_to_settle );
1408  }
1409 
1410  return result;
1411 
1412 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
1413 
1415 { try {
1416  const database& d = db();
1417  const time_point_sec now = d.head_block_time();
1418 
1419  // TODO remove check after hard fork
1421 
1422  const asset_object& base = o.asset_id(d);
1423  //Verify that this feed is for a market-issued asset and that asset is backed by the base
1424  FC_ASSERT( base.is_market_issued(), "Can only publish price feeds for market-issued assets" );
1425 
1426  const asset_bitasset_data_object& bitasset = base.bitasset_data(d);
1427  if( bitasset.is_prediction_market || now <= HARDFORK_CORE_216_TIME )
1428  {
1429  FC_ASSERT( !bitasset.is_globally_settled(), "No further feeds may be published after a settlement event" );
1430  }
1431 
1432  // the settlement price must be quoted in terms of the backing asset
1434  "Quote asset type in settlement price should be same as backing asset of this asset" );
1435 
1436  if( now > HARDFORK_480_TIME )
1437  {
1438  if( !o.feed.core_exchange_rate.is_null() )
1439  {
1440  FC_ASSERT( o.feed.core_exchange_rate.quote.asset_id == asset_id_type(),
1441  "Quote asset in core exchange rate should be CORE asset" );
1442  }
1443  }
1444  else
1445  {
1447  {
1448  // Old buggy code, but we have to live with it
1450  }
1451  }
1452 
1453  //Verify that the publisher is authoritative to publish a feed
1454  if( 0 != ( base.options.flags & witness_fed_asset ) )
1455  {
1456  FC_ASSERT( d.get(GRAPHENE_WITNESS_ACCOUNT).active.account_auths.count(o.publisher) > 0,
1457  "Only active witnesses are allowed to publish price feeds for this asset" );
1458  }
1459  else if( 0 != ( base.options.flags & committee_fed_asset ) )
1460  {
1461  FC_ASSERT( d.get(GRAPHENE_COMMITTEE_ACCOUNT).active.account_auths.count(o.publisher) > 0,
1462  "Only active committee members are allowed to publish price feeds for this asset" );
1463  }
1464  else
1465  {
1466  FC_ASSERT( bitasset.feeds.count(o.publisher) > 0,
1467  "The account is not in the set of allowed price feed producers of this asset" );
1468  }
1469 
1470  asset_ptr = &base;
1471  bitasset_ptr = &bitasset;
1472 
1473  return void_result();
1474 } FC_CAPTURE_AND_RETHROW((o)) } // GCOVR_EXCL_LINE
1475 
1477 { try {
1478 
1479  database& d = db();
1480  const auto head_time = d.head_block_time();
1481  const auto next_maint_time = d.get_dynamic_global_properties().next_maintenance_time;
1482 
1483  const asset_object& base = *asset_ptr;
1484  const asset_bitasset_data_object& bad = *bitasset_ptr;
1485 
1486  auto old_feed = bad.current_feed;
1487  auto old_median_feed = bad.median_feed;
1488  // Store medians for this asset
1489  d.modify( bad , [&o,&head_time](asset_bitasset_data_object& a) {
1490  a.feeds[o.publisher] = make_pair( head_time, price_feed_with_icr( o.feed,
1491  o.extensions.value.initial_collateral_ratio ) );
1492  });
1494 
1495  bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time ); // Price feed issues
1496 
1497  if( !after_core_hardfork_2582 && old_feed.margin_call_params_equal(bad.current_feed) )
1498  return void_result();
1499  if( after_core_hardfork_2582 && old_median_feed.margin_call_params_equal(bad.median_feed) )
1500  return void_result();
1501 
1502  // Feed changed, check whether need to revive the asset and proceed if need
1503  if( bad.is_globally_settled() // has globally settled, implies head_block_time > HARDFORK_CORE_216_TIME
1504  && !bad.current_feed.settlement_price.is_null() ) // has a valid feed
1505  {
1506  bool should_revive = false;
1507  const auto& mia_dyn = base.dynamic_asset_data_id(d);
1508  if( mia_dyn.current_supply == 0 ) // if current supply is zero, revive the asset
1509  should_revive = true;
1510  // if current supply is not zero, revive the asset when collateral ratio of settlement fund
1511  // is greater than ( MCR if before HF core-2290, ICR if after)
1512  else if( next_maint_time <= HARDFORK_CORE_1270_TIME )
1513  {
1514  // before core-1270 hard fork, calculate call_price and compare to median feed
1515  auto fund_call_price = ~price::call_price( asset(mia_dyn.current_supply, o.asset_id),
1518  should_revive = ( fund_call_price < bad.current_feed.settlement_price );
1519  }
1520  else
1521  {
1522  // after core-1270 hard fork, calculate collateralization and compare to maintenance_collateralization
1523  price fund_collateralization( asset( bad.settlement_fund, bad.options.short_backing_asset ),
1524  asset( mia_dyn.current_supply, o.asset_id ) );
1525  should_revive = HARDFORK_CORE_2290_PASSED( next_maint_time ) ?
1526  ( fund_collateralization > bad.current_initial_collateralization )
1527  : ( fund_collateralization > bad.current_maintenance_collateralization );
1528  }
1529  if( should_revive )
1530  d.revive_bitasset( base, bad );
1531  }
1532 
1533  // Process margin calls, allow black swan, not for a new limit order
1534  d.check_call_orders( base, true, false, bitasset_ptr );
1535 
1536  return void_result();
1537 } FC_CAPTURE_AND_RETHROW((o)) } // GCOVR_EXCL_LINE
1538 
1539 
1540 /***
1541  * @brief evaluator for asset_claim_fees operation
1542  *
1543  * Checks that we are able to claim fees denominated in asset Y (the amount_to_claim asset),
1544  * from some container asset X which is presumed to have accumulated the fees we wish to claim.
1545  * The container asset is either explicitly named in the extensions, or else assumed as the same
1546  * asset as the amount_to_claim asset. Evaluation fails if either (a) operation issuer is not
1547  * the same as the container_asset issuer, or (b) container_asset has no fee bucket for
1548  * amount_to_claim asset, or (c) accumulated fees are insufficient to cover amount claimed.
1549  */
1551 { try {
1552  const database& d = db();
1553 
1555 
1556  container_asset = o.extensions.value.claim_from_asset_id.valid() ?
1557  &(*o.extensions.value.claim_from_asset_id)(d) : &o.amount_to_claim.asset_id(d);
1558 
1559  FC_ASSERT( container_asset->issuer == o.issuer, "Asset fees may only be claimed by the issuer" );
1560  FC_ASSERT( container_asset->can_accumulate_fee(d,o.amount_to_claim),
1561  "Asset ${a} (${id}) is not backed by asset (${fid}) and does not hold it as fees.",
1562  ("a",container_asset->symbol)("id",container_asset->id)("fid",o.amount_to_claim.asset_id) );
1563 
1564  container_ddo = &container_asset->dynamic_asset_data_id(d);
1565 
1566  if (container_asset->get_id() == o.amount_to_claim.asset_id) {
1567  FC_ASSERT( o.amount_to_claim.amount <= container_ddo->accumulated_fees,
1568  "Attempt to claim more fees than have accumulated within asset ${a} (${id}). "
1569  "Asset DDO: ${ddo}. Fee claim: ${claim}.", ("a",container_asset->symbol)
1570  ("id",container_asset->id)("ddo",*container_ddo)("claim",o.amount_to_claim) );
1571  } else {
1573  "Attempt to claim more backing-asset fees than have accumulated within asset ${a} (${id}) "
1574  "backed by (${fid}). Asset DDO: ${ddo}. Fee claim: ${claim}.", ("a",container_asset->symbol)
1575  ("id",container_asset->id)("fid",o.amount_to_claim.asset_id)("ddo",*container_ddo)
1576  ("claim",o.amount_to_claim) );
1577  // Note: asset authorization check on (account, collateral asset) is skipped here,
1578  // because it is fine to allow the funds to be moved to account balance
1579  }
1580 
1581  return void_result();
1582 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1583 
1584 
1585 /***
1586  * @brief apply asset_claim_fees operation
1587  */
1589 { try {
1590  database& d = db();
1591 
1592  if ( container_asset->get_id() == o.amount_to_claim.asset_id ) {
1593  d.modify( *container_ddo, [&o]( asset_dynamic_data_object& _addo ) {
1595  });
1596  } else {
1597  d.modify( *container_ddo, [&o]( asset_dynamic_data_object& _addo ) {
1599  });
1600  }
1601 
1603 
1604  return void_result();
1605 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1606 
1607 
1609 { try {
1610  FC_ASSERT( o.asset_id(db()).issuer == o.issuer, "Asset fee pool may only be claimed by the issuer" );
1611 
1612  return void_result();
1613 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1614 
1616 { try {
1617  database& d = db();
1618 
1619  const asset_object& a = o.asset_id(d);
1621  FC_ASSERT( o.amount_to_claim.amount <= addo.fee_pool, "Attempt to claim more fees than is available", ("addo",addo) );
1622 
1623  d.modify( addo, [&o]( asset_dynamic_data_object& _addo ) {
1624  _addo.fee_pool -= o.amount_to_claim.amount;
1625  });
1626 
1628 
1629  return void_result();
1630 } FC_CAPTURE_AND_RETHROW( (o) ) } // GCOVR_EXCL_LINE
1631 
1632 
1633 } } // graphene::chain
graphene::chain::database::apply_force_settlement
void apply_force_settlement(const force_settlement_object &new_settlement, const asset_bitasset_data_object &bitasset, const asset_object &asset_obj)
Process a new force-settlement request.
Definition: db_market.cpp:943
graphene::chain::asset_dynamic_data_object::fee_pool
share_type fee_pool
in core asset
Definition: asset_object.hpp:65
graphene::protocol::asset_create_operation::issuer
account_id_type issuer
This account must sign and pay the fee for this operation. Later, this account may update the asset.
Definition: asset_ops.hpp:203
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::protocol::extension
Definition: ext.hpp:36
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::chain::asset_claim_pool_evaluator::do_apply
void_result do_apply(const asset_claim_pool_operation &o)
Definition: asset_evaluator.cpp:1615
is_authorized_asset.hpp
graphene::chain::asset_fund_fee_pool_evaluator::do_apply
void_result do_apply(const asset_fund_fee_pool_operation &op) const
Definition: asset_evaluator.cpp:418
graphene::chain::asset_bitasset_data_object::settlement_fund
share_type settlement_fund
Amount of collateral which is available for force settlement due to global settlement.
Definition: asset_object.hpp:313
graphene::chain::detail::check_bitasset_options_hf_bsip77
void check_bitasset_options_hf_bsip77(const fc::time_point_sec &block_time, const bitasset_options &options)
Definition: asset_evaluator.cpp:121
graphene::chain::asset_fund_fee_pool_evaluator::do_evaluate
void_result do_evaluate(const asset_fund_fee_pool_operation &op)
Definition: asset_evaluator.cpp:407
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::chain::database::find_settled_debt_order
const limit_order_object * find_settled_debt_order(const asset_id_type &a) const
Definition: db_getter.cpp:152
graphene::protocol::asset_update_issuer_operation::issuer
account_id_type issuer
Definition: asset_ops.hpp:572
graphene::chain::detail::check_asset_options_hf_core2467
void check_asset_options_hf_core2467(const fc::time_point_sec &next_maint_time, const asset_options &options)
Definition: asset_evaluator.cpp:161
graphene::chain::detail::check_bitasset_options_hf_bsip87
void check_bitasset_options_hf_bsip87(const fc::time_point_sec &block_time, const bitasset_options &options)
Definition: asset_evaluator.cpp:130
graphene::chain::check_children_of_bitasset
void check_children_of_bitasset(const database &d, const asset_update_bitasset_operation &op, const asset_object &new_backing_asset)
Definition: asset_evaluator.cpp:696
graphene::chain::detail::check_asset_update_extensions_hf_bsip_48_75
void check_asset_update_extensions_hf_bsip_48_75(const fc::time_point_sec &block_time, const asset_update_operation::ext &extensions)
Definition: asset_evaluator.cpp:95
graphene::chain::asset_publish_feeds_evaluator::do_evaluate
void_result do_evaluate(const asset_publish_feed_operation &o)
Definition: asset_evaluator.cpp:1414
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::chain::detail::check_asset_claim_fees_hardfork_87_74_collatfee
void check_asset_claim_fees_hardfork_87_74_collatfee(const fc::time_point_sec &block_time, const asset_claim_fees_operation &op)
Definition: asset_evaluator.cpp:138
graphene::protocol::price_feed::core_exchange_rate
price core_exchange_rate
Price at which automatically exchanging this asset for CORE from fee pool occurs (used for paying fee...
Definition: asset.hpp:183
graphene::chain::database::_current_block_time
fc::time_point_sec _current_block_time
Definition: database.hpp:799
graphene::chain::asset_update_evaluator::do_apply
void_result do_apply(const asset_update_operation &o)
Definition: asset_evaluator.cpp:598
asset_object.hpp
graphene::db::object_database::get
const T & get(const object_id_type &id) const
Definition: object_database.hpp:119
graphene::chain::database::get_balance
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account's balance in a given asset.
Definition: db_balance.cpp:35
graphene::protocol::witness_fed_asset
@ witness_fed_asset
the bitasset is to be fed by witnesses
Definition: types.hpp:201
graphene::protocol::price
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:108
graphene::chain::asset_bitasset_data_object::is_prediction_market
bool is_prediction_market
True if this asset implements a Prediction Market.
Definition: asset_object.hpp:291
graphene::protocol::bitasset_options::black_swan_response_type
black_swan_response_type
Defines how a BitAsset would respond to black swan events.
Definition: asset_ops.hpp:112
database.hpp
graphene::chain::dynamic_global_property_object::next_maintenance_time
time_point_sec next_maintenance_time
Definition: global_property_object.hpp:70
graphene::chain::asset_object::bitasset_data
const asset_bitasset_data_object & bitasset_data(const DB &db) const
Definition: asset_object.hpp:166
fc::static_variant< void_result, object_id_type, asset, generic_operation_result, generic_exchange_operation_result, extendable_operation_result >
graphene::chain::asset_update_bitasset_evaluator::do_evaluate
void_result do_evaluate(const asset_update_bitasset_operation &o)
Definition: asset_evaluator.cpp:724
graphene::protocol::bitasset_options::get_black_swan_response_method
black_swan_response_type get_black_swan_response_method() const
Get the effective black swan response method.
Definition: asset_ops.hpp:180
graphene::chain::detail::check_asset_options_hf_core2281
void check_asset_options_hf_core2281(const fc::time_point_sec &next_maint_time, const asset_options &options)
Definition: asset_evaluator.cpp:147
graphene::protocol::asset_options::whitelist_authorities
flat_set< account_id_type > whitelist_authorities
Definition: asset_ops.hpp:76
graphene::chain::call_order_object::get_collateral
asset get_collateral() const
Definition: market_object.hpp:143
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
graphene::protocol::asset_claim_fees_operation
used to transfer accumulated fees back to the issuer's balance.
Definition: asset_ops.hpp:529
graphene::protocol::asset_create_operation::is_prediction_market
bool is_prediction_market
For BitAssets, set this to true if the asset implements a prediction market; false otherwise.
Definition: asset_ops.hpp:219
graphene::protocol::asset_publish_feed_operation::ext::initial_collateral_ratio
fc::optional< uint16_t > initial_collateral_ratio
After BSIP77, price feed producers can feed ICR too.
Definition: asset_ops.hpp:467
FC_THROW
#define FC_THROW( ...)
Definition: exception.hpp:366
graphene::protocol::asset_claim_fees_operation::amount_to_claim
asset amount_to_claim
Definition: asset_ops.hpp:547
graphene::protocol::asset_update_issuer_operation::asset_to_update
asset_id_type asset_to_update
Definition: asset_ops.hpp:573
graphene::chain::asset_dynamic_data_object::current_supply
share_type current_supply
The number of shares currently in existence.
Definition: asset_object.hpp:61
graphene::chain::asset_object::is_liquidity_pool_share_asset
bool is_liquidity_pool_share_asset() const
Definition: asset_object.hpp:86
graphene::chain::asset_object::can_force_settle
bool can_force_settle() const
Definition: asset_object.hpp:88
graphene::protocol::asset_reserve_operation::payer
account_id_type payer
Definition: asset_ops.hpp:518
graphene::protocol::asset_options::core_exchange_rate
price core_exchange_rate
Definition: asset_ops.hpp:72
graphene::chain::asset_update_issuer_evaluator::do_evaluate
void_result do_evaluate(const asset_update_issuer_operation &o)
Definition: asset_evaluator.cpp:660
graphene::protocol::asset_create_operation::bitasset_opts
optional< bitasset_options > bitasset_opts
Options only available for BitAssets. MUST be non-null if and only if the asset is market-issued.
Definition: asset_ops.hpp:217
graphene::protocol::asset_update_issuer_operation
Update issuer of an asset.
Definition: asset_ops.hpp:565
graphene::chain::asset_object::can_owner_update_mssr
bool can_owner_update_mssr() const
Definition: asset_object.hpp:107
graphene::chain::asset_object
tracks the parameters of an asset
Definition: asset_object.hpp:75
graphene::protocol::bitasset_options::feed_lifetime_sec
uint32_t feed_lifetime_sec
Time before a price feed expires.
Definition: asset_ops.hpp:156
graphene::chain::asset_bitasset_data_object::current_maintenance_collateralization
price current_maintenance_collateralization
Definition: asset_object.hpp:283
graphene::db::object_database::create
const T & create(F &&constructor)
Definition: object_database.hpp:63
graphene::chain::database::adjust_balance
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account's balance in a given asset by a delta.
Definition: db_balance.cpp:54
graphene::chain::asset_settle_evaluator::do_evaluate
void_result do_evaluate(const operation_type &op)
Definition: asset_evaluator.cpp:1145
graphene::protocol::price_feed::settlement_price
price settlement_price
Definition: asset.hpp:180
graphene::protocol::asset_options::blacklist_authorities
flat_set< account_id_type > blacklist_authorities
Definition: asset_ops.hpp:81
graphene::chain::database::_current_block_num
uint32_t _current_block_num
Definition: database.hpp:800
graphene::chain::asset_create_evaluator::pay_fee
void pay_fee() override
Definition: asset_evaluator.cpp:274
graphene::chain::database::check_call_orders
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:2079
graphene::protocol::asset_publish_feed_operation::asset_id
asset_id_type asset_id
asset for which the feed is published
Definition: asset_ops.hpp:474
graphene::chain::asset_object::symbol
string symbol
Ticker symbol for this asset, i.e. "USD".
Definition: asset_object.hpp:131
graphene::chain::call_order_object::get_debt
asset get_debt() const
Definition: market_object.hpp:144
graphene::chain::detail::check_asset_options_hf_bsip81
void check_asset_options_hf_bsip81(const fc::time_point_sec &block_time, const asset_options &options)
Definition: asset_evaluator.cpp:58
graphene::chain::asset_object::dynamic_asset_data_id
asset_dynamic_data_id_type dynamic_asset_data_id
Current supply, fee pool, and collected fees are stored in a separate object as they change frequentl...
Definition: asset_object.hpp:140
graphene::protocol::asset_options
The asset_options struct contains options available on all assets in the network.
Definition: asset_ops.hpp:47
graphene::chain::generic_evaluator::pay_fee
virtual void pay_fee()
Definition: evaluator.cpp:91
graphene::chain::asset_object::can_global_settle
bool can_global_settle() const
Definition: asset_object.hpp:90
graphene::chain::asset_update_evaluator::do_evaluate
void_result do_evaluate(const asset_update_operation &o)
Definition: asset_evaluator.cpp:446
graphene::protocol::asset_update_operation::asset_to_update
asset_id_type asset_to_update
Definition: asset_ops.hpp:372
graphene::protocol::asset_options::extensions
additional_asset_options_t extensions
Definition: asset_ops.hpp:93
graphene::protocol::bitasset_options
The bitasset_options struct contains configurable options available only to BitAssets.
Definition: asset_ops.hpp:109
graphene::chain::asset_update_feed_producers_evaluator::do_apply
void_result do_apply(const operation_type &o) const
Definition: asset_evaluator.cpp:1072
graphene::protocol::asset_update_operation::extensions
extension< ext > extensions
Definition: asset_ops.hpp:377
graphene::protocol::committee_fed_asset
@ committee_fed_asset
the bitasset is to be fed by the committee
Definition: types.hpp:202
graphene::protocol::asset_claim_pool_operation::asset_id
asset_id_type asset_id
Definition: asset_ops.hpp:609
graphene::db::object_database::find
const T * find(const object_id_type &id) const
Definition: object_database.hpp:126
graphene::chain::asset_dynamic_data_object::accumulated_fees
share_type accumulated_fees
fees accumulate to be paid out over time
Definition: asset_object.hpp:63
graphene::chain::database::revive_bitasset
void revive_bitasset(const asset_object &bitasset, const asset_bitasset_data_object &bad)
Definition: db_market.cpp:422
graphene::protocol::asset_issue_operation::issuer
account_id_type issuer
Must be asset_to_issue->asset_id->issuer.
Definition: asset_ops.hpp:493
asset_evaluator.hpp
graphene::chain::asset_bitasset_data_object::asset_cer_updated
bool asset_cer_updated
Track whether core_exchange_rate in corresponding asset_object has updated.
Definition: asset_object.hpp:373
graphene::protocol::asset_options::max_supply
share_type max_supply
Definition: asset_ops.hpp:50
graphene::protocol::asset_publish_feed_operation::extensions
extension< ext > extensions
Definition: asset_ops.hpp:476
graphene::protocol::asset_update_bitasset_operation::new_options
bitasset_options new_options
Definition: asset_ops.hpp:406
graphene::protocol::asset_update_operation::ext
Definition: asset_ops.hpp:353
graphene::chain::account_object::options
account_options options
Definition: account_object.hpp:222
graphene::chain::force_settlement_object::settlement_date
time_point_sec settlement_date
Definition: market_object.hpp:193
graphene::chain::detail::check_bitasset_options_hf_bsip_48_75
void check_bitasset_options_hf_bsip_48_75(const fc::time_point_sec &block_time, const bitasset_options &options)
Definition: asset_evaluator.cpp:80
graphene::protocol::asset_update_operation::ext::new_precision
fc::optional< uint8_t > new_precision
Definition: asset_ops.hpp:357
graphene::chain::asset_object::precision
uint8_t precision
Maximum number of digits after the decimal point (must be <= 12)
Definition: asset_object.hpp:133
graphene::protocol::asset_reserve_operation
used to take an asset out of circulation, returning to the issuer
Definition: asset_ops.hpp:513
graphene::protocol::asset_update_operation
Update options common to all assets.
Definition: asset_ops.hpp:351
graphene::protocol::disable_force_settle
@ disable_force_settle
disable force settling
Definition: types.hpp:198
graphene::db::index::get
const object & get(object_id_type id) const
Definition: index.hpp:110
graphene::protocol::asset::multiply_and_round_up
asset multiply_and_round_up(const price &p) const
Multiply and round up.
Definition: asset.cpp:77
graphene::chain::database::update_bitasset_current_feed
void update_bitasset_current_feed(const asset_bitasset_data_object &bitasset, bool skip_median_update=false)
Definition: db_update.cpp:270
FC_CAPTURE_AND_LOG
#define FC_CAPTURE_AND_LOG(...)
Definition: exception.hpp:438
fc::optional::valid
bool valid() const
Definition: optional.hpp:186
graphene::chain::database::cancel_bid
void cancel_bid(const collateral_bid_object &bid, bool create_virtual_op=true)
Definition: db_market.cpp:477
graphene::chain::asset_dynamic_data_object
tracks the asset information that changes frequently
Definition: asset_object.hpp:56
graphene::chain::database::get_core_dynamic_data
const asset_dynamic_data_object & get_core_dynamic_data() const
Definition: db_getter.cpp:42
graphene::protocol::asset_settle_operation::account
account_id_type account
Account requesting the force settlement. This account pays the fee.
Definition: asset_ops.hpp:281
graphene::protocol::asset_global_settle_operation::asset_to_settle
asset_id_type asset_to_settle
Definition: asset_ops.hpp:244
graphene::protocol::asset_create_operation::precision
uint8_t precision
Number of digits to the right of decimal point, must be less than or equal to 12.
Definition: asset_ops.hpp:207
fc::time_point_sec
Definition: time.hpp:74
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::chain::detail::check_asset_publish_feed_extensions_hf_bsip77
void check_asset_publish_feed_extensions_hf_bsip77(const fc::time_point_sec &block_time, const asset_publish_feed_operation::ext &extensions)
Definition: asset_evaluator.cpp:109
graphene::chain::detail::check_asset_options_hf_bsip_48_75
void check_asset_options_hf_bsip_48_75(const fc::time_point_sec &block_time, const asset_options &options)
Definition: asset_evaluator.cpp:68
account_object.hpp
graphene::protocol::asset_claim_pool_operation::issuer
account_id_type issuer
Definition: asset_ops.hpp:608
graphene::chain::asset_update_issuer_evaluator::do_apply
void_result do_apply(const asset_update_issuer_operation &o)
Definition: asset_evaluator.cpp:676
graphene::chain::by_expiration
Definition: proposal_object.hpp:86
graphene::chain::asset_object::can_create_new_supply
bool can_create_new_supply() const
Definition: asset_object.hpp:101
graphene::protocol::asset_issue_operation::asset_to_issue
asset asset_to_issue
Definition: asset_ops.hpp:494
graphene::protocol::asset_options::issuer_permissions
uint16_t issuer_permissions
The flags which the issuer has permission to update. See asset_issuer_permission_flags.
Definition: asset_ops.hpp:61
graphene::protocol::asset_claim_fees_operation::issuer
account_id_type issuer
must match issuer of asset from which we claim fees
Definition: asset_ops.hpp:546
graphene::protocol::price::is_null
bool is_null() const
Definition: asset.cpp:229
graphene::chain::force_settlement_object::balance
asset balance
Definition: market_object.hpp:192
graphene::chain::database::globally_settle_asset
void globally_settle_asset(const asset_object &bitasset, const price &settle_price, bool check_margin_calls=false)
Definition: db_market.cpp:221
graphene::chain::asset_bitasset_data_object
contains properties that only apply to bitassets (market issued assets)
Definition: asset_object.hpp:255
graphene::chain::is_authorized_asset
bool is_authorized_asset(const database &d, const account_object &acct, const asset_object &asset_obj)
Definition: is_authorized_asset.hpp:43
graphene::chain::asset_object::accumulate_fee
void accumulate_fee(DB &db, const asset &fee) const
Definition: asset_object.hpp:201
graphene::chain::asset_bitasset_data_object::current_feed
price_feed_with_icr current_feed
This is the currently active price feed, calculated from median_feed and other parameters.
Definition: asset_object.hpp:272
graphene::chain::collateral_bid_object
bids of collateral for debt after a black swan
Definition: market_object.hpp:206
graphene::chain::asset_bitasset_data_object::median_feed
price_feed_with_icr median_feed
This is the median of values from the currently active feeds.
Definition: asset_object.hpp:270
graphene::protocol::asset_update_operation::ext::skip_core_exchange_rate
fc::optional< bool > skip_core_exchange_rate
Definition: asset_ops.hpp:360
graphene::chain::asset_bitasset_data_object::get_margin_call_order_price
price get_margin_call_order_price() const
Get margin call order price (MCOP) of this bitasset.
Definition: asset_object.hpp:355
graphene::chain::asset_bitasset_data_object::is_individually_settled_to_fund
bool is_individually_settled_to_fund() const
Definition: asset_object.hpp:334
graphene::chain::asset_update_feed_producers_evaluator::do_evaluate
void_result do_evaluate(const operation_type &o)
Definition: asset_evaluator.cpp:1048
graphene::protocol::asset_options::validate
void validate() const
Definition: asset_ops.cpp:273
graphene::protocol::asset_publish_feed_operation::publisher
account_id_type publisher
Definition: asset_ops.hpp:473
graphene::protocol::asset_update_bitasset_operation
Update options specific to BitAssets.
Definition: asset_ops.hpp:398
graphene::chain::asset_object::can_bid_collateral
bool can_bid_collateral() const
Definition: asset_object.hpp:111
graphene::protocol::chain_parameters
Definition: chain_parameters.hpp:46
graphene::protocol::asset_create_operation::symbol
string symbol
The ticker symbol of this asset.
Definition: asset_ops.hpp:205
graphene::protocol::global_settle
@ global_settle
allow the bitasset owner to force a global settlement, permission only
Definition: types.hpp:199
graphene::protocol::extendable_operation_result
extension< extendable_operation_result_dtl > extendable_operation_result
Definition: base.hpp:113
graphene::chain::asset_object::can_update_max_supply
bool can_update_max_supply() const
Definition: asset_object.hpp:99
graphene::protocol::asset_publish_feed_operation
Publish price feeds for market-issued assets.
Definition: asset_ops.hpp:462
graphene::protocol::additional_asset_options::reward_percent
fc::optional< uint16_t > reward_percent
Definition: asset_ops.hpp:33
graphene::protocol::asset_options::flags
uint16_t flags
The currently active flags on this permission. See asset_issuer_permission_flags.
Definition: asset_ops.hpp:63
GRAPHENE_COMMITTEE_ACCOUNT
#define GRAPHENE_COMMITTEE_ACCOUNT
Definition: config.hpp:140
graphene::protocol::chain_parameters::maximum_asset_whitelist_authorities
uint8_t maximum_asset_whitelist_authorities
maximum number of accounts which an asset may list as authorities for its whitelist OR blacklist
Definition: chain_parameters.hpp:61
graphene::protocol::bitasset_options::force_settlement_delay_sec
uint32_t force_settlement_delay_sec
This is the delay between the time a long requests settlement and the chain evaluates the settlement.
Definition: asset_ops.hpp:160
graphene::chain::asset_claim_fees_evaluator::do_evaluate
void_result do_evaluate(const asset_claim_fees_operation &o)
Definition: asset_evaluator.cpp:1550
graphene::chain::asset_object::dynamic_data
const asset_dynamic_data_object & dynamic_data(const DB &db) const
Definition: asset_object.hpp:175
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
graphene::chain::asset_reserve_evaluator::do_evaluate
void_result do_evaluate(const asset_reserve_operation &o)
Definition: asset_evaluator.cpp:365
graphene::chain::detail::check_asset_options_hf_1774
void check_asset_options_hf_1774(const fc::time_point_sec &block_time, const asset_options &options)
Definition: asset_evaluator.cpp:39
graphene::protocol::asset_issue_operation::issue_to_account
account_id_type issue_to_account
Definition: asset_ops.hpp:495
graphene::protocol::asset_claim_fees_operation::extensions
extension< additional_options_type > extensions
Definition: asset_ops.hpp:549
graphene::chain::asset_create_evaluator::do_apply
object_id_type do_apply(const asset_create_operation &o) const
Definition: asset_evaluator.cpp:282
graphene::protocol::asset_update_operation::new_options
asset_options new_options
Definition: asset_ops.hpp:376
graphene::chain::asset_dynamic_data_object::accumulated_collateral_fees
share_type accumulated_collateral_fees
accumulated collateral-denominated fees (for bitassets)
Definition: asset_object.hpp:64
graphene::protocol::asset_reserve_operation::amount_to_reserve
asset amount_to_reserve
Definition: asset_ops.hpp:519
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::chain::asset_object::issuer
account_id_type issuer
ID of the account which issued this asset.
Definition: asset_object.hpp:135
graphene::protocol::asset_update_operation::issuer
account_id_type issuer
Definition: asset_ops.hpp:371
graphene::protocol::asset_update_feed_producers_operation
Update the set of feed-producing accounts for a BitAsset.
Definition: asset_ops.hpp:430
graphene::chain::asset_global_settle_evaluator::do_evaluate
void_result do_evaluate(const operation_type &op)
Definition: asset_evaluator.cpp:1110
graphene::chain::asset_settle_evaluator::do_apply
operation_result do_apply(const operation_type &op)
Definition: asset_evaluator.cpp:1359
graphene::protocol::asset_settle_operation
Schedules a market-issued asset for automatic settlement.
Definition: asset_ops.hpp:267
graphene::chain::asset_object::can_owner_update_mcr
bool can_owner_update_mcr() const
Definition: asset_object.hpp:103
GRAPHENE_WITNESS_ACCOUNT
#define GRAPHENE_WITNESS_ACCOUNT
Represents the current witnesses.
Definition: config.hpp:142
graphene::protocol::asset_options::validate_flags
void validate_flags(bool is_market_issued, bool allow_disable_collateral_bid=true) const
Definition: asset_ops.cpp:312
graphene::protocol::asset_update_feed_producers_operation::asset_to_update
asset_id_type asset_to_update
Definition: asset_ops.hpp:436
graphene::protocol::asset_create_operation::common_options
asset_options common_options
Definition: asset_ops.hpp:215
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::chain::asset_claim_pool_evaluator::do_evaluate
void_result do_evaluate(const asset_claim_pool_operation &o)
Definition: asset_evaluator.cpp:1608
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
graphene::protocol::price_feed::maintenance_collateral_ratio
uint16_t maintenance_collateral_ratio
Definition: asset.hpp:186
graphene::chain::asset_claim_fees_evaluator::do_apply
void_result do_apply(const asset_claim_fees_operation &o)
Definition: asset_evaluator.cpp:1588
graphene::protocol::asset_global_settle_operation::settle_price
price settle_price
Definition: asset_ops.hpp:245
graphene::protocol::asset_update_feed_producers_operation::new_feed_producers
flat_set< account_id_type > new_feed_producers
Definition: asset_ops.hpp:438
graphene::protocol::asset_update_bitasset_operation::asset_to_update
asset_id_type asset_to_update
Definition: asset_ops.hpp:404
graphene::chain::asset_global_settle_evaluator::do_apply
void_result do_apply(const operation_type &op)
Definition: asset_evaluator.cpp:1138
graphene::chain::asset_bitasset_data_object::get_black_swan_response_method
bitasset_options::black_swan_response_type get_black_swan_response_method() const
Get the effective black swan response method of this bitasset.
Definition: asset_object.hpp:349
graphene::chain::force_settlement_object
tracks bitassets scheduled for force settlement at some point in the future.
Definition: market_object.hpp:187
graphene::protocol::asset_fund_fee_pool_operation::amount
share_type amount
core asset
Definition: asset_ops.hpp:329
graphene::chain::asset_issue_evaluator::do_apply
void_result do_apply(const asset_issue_operation &o) const
Definition: asset_evaluator.cpp:354
graphene::chain::call_order_object
tracks debt and call price information
Definition: market_object.hpp:140
graphene::protocol::price::base
asset base
Definition: asset.hpp:113
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::protocol::asset_fund_fee_pool_operation
Definition: asset_ops.hpp:322
graphene::protocol::asset_update_bitasset_operation::issuer
account_id_type issuer
Definition: asset_ops.hpp:403
graphene::db::abstract_object::get_id
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
graphene::chain::asset_publish_feeds_evaluator::do_apply
void_result do_apply(const asset_publish_feed_operation &o)
Definition: asset_evaluator.cpp:1476
graphene::protocol::asset_fund_fee_pool_operation::from_account
account_id_type from_account
Definition: asset_ops.hpp:327
graphene::chain::asset_create_evaluator::do_evaluate
void_result do_evaluate(const asset_create_operation &o) const
Definition: asset_evaluator.cpp:185
graphene::protocol::chain_parameters::maximum_asset_feed_publishers
uint8_t maximum_asset_feed_publishers
the maximum number of feed publishers for a given asset
Definition: chain_parameters.hpp:62
graphene::chain::database::get_global_properties
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:47
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::protocol::disable_collateral_bidding
@ disable_collateral_bidding
Can not bid collateral after a global settlement.
Definition: types.hpp:223
graphene::chain::price_feed_with_icr
defines market parameters for margin positions, extended with an initial_collateral_ratio field
Definition: asset_object.hpp:229
graphene::chain::asset_issue_evaluator::do_evaluate
void_result do_evaluate(const asset_issue_operation &o)
Definition: asset_evaluator.cpp:333
graphene::chain::asset_object::can_accumulate_fee
bool can_accumulate_fee(const DB &db, const asset &fee) const
Definition: asset_object.hpp:187
graphene::chain::generic_evaluator::fee_paying_account
const account_object * fee_paying_account
Definition: evaluator.hpp:116
graphene::protocol::asset_global_settle_operation::issuer
account_id_type issuer
must equal issuer of asset_to_settle
Definition: asset_ops.hpp:243
graphene::protocol::asset_update_feed_producers_operation::issuer
account_id_type issuer
Definition: asset_ops.hpp:435
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
graphene::protocol::asset
Definition: asset.hpp:31
graphene::chain::asset_object::options
asset_options options
Definition: asset_object.hpp:137
graphene::chain::asset_update_bitasset_evaluator::do_apply
void_result do_apply(const asset_update_bitasset_operation &o)
Definition: asset_evaluator.cpp:1025
market_object.hpp
graphene::chain::database::cancel_settle_order
void cancel_settle_order(const force_settlement_object &order)
Definition: db_market.cpp:524
graphene::chain::generic_evaluator::core_fee_paid
share_type core_fee_paid
Definition: evaluator.hpp:115
GRAPHENE_ASSERT
#define GRAPHENE_ASSERT(expr, exc_type, FORMAT,...)
Definition: exceptions.hpp:28
graphene::chain::asset_reserve_evaluator::do_apply
void_result do_apply(const asset_reserve_operation &o) const
Definition: asset_evaluator.cpp:396
graphene::protocol::asset_update_operation::new_issuer
optional< account_id_type > new_issuer
If the asset is to be given a new issuer, specify his ID here.
Definition: asset_ops.hpp:375
graphene::protocol::void_result
Definition: base.hpp:86
graphene::chain::asset_object::is_market_issued
bool is_market_issued() const
Definition: asset_object.hpp:84
graphene::chain::asset_bitasset_data_object::feeds
flat_map< account_id_type, pair< time_point_sec, price_feed_with_icr > > feeds
Definition: asset_object.hpp:268
graphene::db::object_database::get_index_type
const IndexType & get_index_type() const
Definition: object_database.hpp:77
graphene::chain::database::get_dynamic_global_properties
const dynamic_global_property_object & get_dynamic_global_properties() const
Definition: db_getter.cpp:57
graphene::chain::detail::check_bitasset_options_hf_bsip74
void check_bitasset_options_hf_bsip74(const fc::time_point_sec &block_time, const bitasset_options &options)
Definition: asset_evaluator.cpp:49
graphene::chain::asset_object::can_owner_update_bsrm
bool can_owner_update_bsrm() const
Definition: asset_object.hpp:109
fc::safe::value
T value
Definition: safe.hpp:28
graphene::protocol::asset_publish_feed_operation::ext
Definition: asset_ops.hpp:464
graphene::chain::database::find_least_collateralized_short
const call_order_object * find_least_collateralized_short(const asset_bitasset_data_object &bitasset, bool force_by_collateral_index) const
Definition: db_getter.cpp:161
graphene::protocol::asset_options::get_enabled_issuer_permissions_mask
uint16_t get_enabled_issuer_permissions_mask() const
Definition: asset_ops.cpp:336
graphene::chain::asset_bitasset_data_object::current_initial_collateralization
price current_initial_collateralization
Definition: asset_object.hpp:288
graphene::protocol::asset_issue_operation
Definition: asset_ops.hpp:485
graphene::protocol::asset_update_issuer_operation::new_issuer
account_id_type new_issuer
Definition: asset_ops.hpp:574
graphene::chain::asset_object::can_owner_update_icr
bool can_owner_update_icr() const
Definition: asset_object.hpp:105
graphene::protocol::bitasset_options::short_backing_asset
asset_id_type short_backing_asset
Definition: asset_ops.hpp:171
graphene::protocol::disable_bsrm_update
@ disable_bsrm_update
the bitasset owner can not update BSRM, permission only
Definition: types.hpp:222
graphene::protocol::asset_global_settle_operation
allows global settling of bitassets (black swan or prediction markets)
Definition: asset_ops.hpp:238
graphene::protocol::price::quote
asset quote
Definition: asset.hpp:114
GRAPHENE_100_PERCENT
#define GRAPHENE_100_PERCENT
Definition: config.hpp:102
graphene
Definition: api.cpp:48
graphene::protocol::extension::value
T value
Definition: ext.hpp:40
graphene::protocol::asset_create_operation
Definition: asset_ops.hpp:192
graphene::chain::asset_object::creation_block_num
uint32_t creation_block_num
The block number when the asset object was created.
Definition: asset_object.hpp:150
exceptions.hpp
graphene::protocol::bitasset_options::extensions
extension< ext > extensions
Definition: asset_ops.hpp:173
graphene::protocol::asset_claim_pool_operation::amount_to_claim
asset amount_to_claim
fee.asset_id must != asset_id
Definition: asset_ops.hpp:610
graphene::chain::asset_bitasset_data_object::options
bitasset_options options
The tunable options for BitAssets are stored in this field.
Definition: asset_object.hpp:263
graphene::protocol::asset_claim_pool_operation
Transfers BTS from the fee pool of a specified asset back to the issuer's balance.
Definition: asset_ops.hpp:601
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
fc::typelist::runtime::for_each
void for_each(list< Types... >, Callable c)
Invoke the provided callable with an argument wrapper<Type>() for each type in the list.
Definition: typelist.hpp:257
graphene::protocol::asset_fund_fee_pool_operation::asset_id
asset_id_type asset_id
Definition: asset_ops.hpp:328
graphene::protocol::chain_parameters::block_interval
uint8_t block_interval
interval in seconds between blocks
Definition: chain_parameters.hpp:53
graphene::protocol::additional_asset_options::taker_fee_percent
fc::optional< uint16_t > taker_fee_percent
Definition: asset_ops.hpp:36
graphene::protocol::asset_settle_operation::amount
asset amount
Amount of asset to force settle. This must be a market-issued asset.
Definition: asset_ops.hpp:283
graphene::chain::asset_bitasset_data_object::is_globally_settled
bool is_globally_settled() const
Definition: asset_object.hpp:299
graphene::chain::detail::check_bitasset_opts_hf_core2467
void check_bitasset_opts_hf_core2467(const fc::time_point_sec &next_maint_time, const bitasset_options &options)
Definition: asset_evaluator.cpp:173
graphene::chain::asset_settle_evaluator::operation_type
asset_settle_operation operation_type
Definition: asset_evaluator.hpp:153
graphene::protocol::asset_publish_feed_operation::feed
price_feed feed
Definition: asset_ops.hpp:475
graphene::protocol::bitasset_options::minimum_feeds
uint8_t minimum_feeds
Minimum number of unexpired feeds required to extract a median feed from.
Definition: asset_ops.hpp:158