30 #include <graphene/chain/hardfork.hpp>
35 namespace graphene {
namespace chain {
41 if( block_time < HARDFORK_1774_TIME )
45 "Asset extension reward percent must be less than 100% till HARDFORK_1774_TIME!");
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" );
60 if (block_time < HARDFORK_BSIP_81_TIME) {
63 "Taker fee percent should not be defined before HARDFORK_BSIP_81_TIME");
70 if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
74 "New asset issuer permission bits should not be set before HARDFORK_BSIP_48_75_TIME" );
82 if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
86 "Maintenance collateral ratio should not be defined by asset owner "
87 "before HARDFORK_BSIP_48_75_TIME" );
89 "Maximum short squeeze ratio should not be defined by asset owner "
90 "before HARDFORK_BSIP_48_75_TIME" );
98 if ( !HARDFORK_BSIP_48_75_PASSED( block_time ) )
102 "new_precision should not be set before HARDFORK_BSIP_48_75_TIME" );
104 "skip_core_exchange_rate should not be set before HARDFORK_BSIP_48_75_TIME" );
112 if ( !HARDFORK_BSIP_77_PASSED( block_time ) )
116 "Initial collateral ratio should not be defined before HARDFORK_BSIP_77_TIME" );
123 if ( !HARDFORK_BSIP_77_PASSED( block_time ) ) {
126 "Initial collateral ratio should not be defined before HARDFORK_BSIP_77_TIME");
134 || block_time >= HARDFORK_CORE_BSIP87_TIME,
135 "A BitAsset's FSFP cannot be set before Hardfork BSIP87" );
143 block_time >= HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME,
144 "Collateral-denominated fees are not yet active and therefore cannot be claimed." );
150 if ( !HARDFORK_CORE_2281_PASSED(next_maint_time) )
154 "New asset issuer permission bit 'disable_collateral_bidding' should not be set "
155 "before Hardfork core-2281" );
164 if ( !HARDFORK_CORE_2467_PASSED(next_maint_time) )
168 "New asset issuer permission bit 'disable_bsrm_update' should not be set "
169 "before Hardfork core-2467" );
176 if ( !HARDFORK_CORE_2467_PASSED(next_maint_time) )
179 "A BitAsset's black swan response method cannot be set before Hardfork core-2467" );
207 if( HARDFORK_CORE_2281_PASSED( next_maint_time ) )
211 else if( HARDFORK_BSIP_48_75_PASSED( now ) )
228 auto asset_symbol_itr = asset_indx.find( op.
symbol );
229 FC_ASSERT( asset_symbol_itr == asset_indx.end() );
232 if( now > HARDFORK_385_TIME )
234 auto dotpos = op.
symbol.rfind(
'.' );
235 if( dotpos != std::string::npos )
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}",
255 "May not create a bitasset backed by a bitasset backed by a bitasset." );
257 "May not create a blockchain-controlled market asset which is not backed by CORE.");
260 "May not create a blockchain-controlled market asset which is not backed by CORE.");
276 constexpr int64_t two = 2;
286 bool hf_429 = fee_is_odd && d.
head_block_time() > HARDFORK_CORE_429_TIME;
290 a.current_supply = 0;
294 if( fee_is_odd && !hf_429 )
301 asset_bitasset_data_id_type bit_asset_id;
307 a.options = *op.bitasset_opts;
309 a.asset_id = next_asset_id;
317 a.options = op.common_options;
318 if( 0 == a.options.core_exchange_rate.base.asset_id.instance.value )
323 if( op.bitasset_opts.valid() )
324 a.bitasset_data_id = bit_asset_id;
328 FC_ASSERT( new_asset.id == next_asset_id,
"Unexpected object database error, object id mismatch" );
372 asset_reserve_invalid_on_mia,
373 "Cannot reserve ${sym} because it is a market-issued asset",
384 "Can not reserve an amount that is more than the current supply" );
389 "The asset is a liquidity pool share asset thus can only reserve an amount "
390 "that is less than the current supply" );
429 static void validate_new_issuer(
const database& d,
const asset_object& a, account_id_type new_issuer )
431 FC_ASSERT(d.
find(new_issuer),
"New issuer account does not exist");
439 "May not create a blockchain-controlled market asset which is not backed by CORE.");
442 "May not create a blockchain-controlled market asset which is not backed by CORE.");
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 ) );
472 "Since Hardfork #199, updating issuer requires the use of asset_update_issuer_operation.");
479 if( hf_core_2467_passed )
484 "Unable to set non-UIA issuer permission bits on UIA" );
488 "Unable to set disable_bsrm_update issuer permission bit on PM" );
497 "The global_settle permission should be enabled for prediction markets" );
502 if( dyn_data.current_supply != 0 )
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.");
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.");
517 & (uint16_t)(~enabled_issuer_permissions_mask) ),
518 "Cannot reinstate previously revoked issuer permissions on an asset if current supply is non-zero.");
521 "Cannot update precision if current supply is non-zero" );
523 if( hf_bsip_48_75_passed )
526 "Max supply should not be smaller than current supply" );
532 if( hf_core_2281_passed )
536 else if( hf_bsip_48_75_passed )
543 if( hf_bsip_48_75_passed )
546 uint16_t valid_flags_mask = hf_core_2281_passed ? VALID_FLAGS_MASK
548 uint16_t check_bits = a.
is_market_issued() ? valid_flags_mask : UIA_VALID_FLAGS_MASK;
551 & (uint16_t)(~enabled_issuer_permissions_mask) ),
552 "Flag change is forbidden by issuer permissions" );
557 "Flag change is forbidden by issuer permissions" );
560 asset_to_update = &a;
562 "Incorrect issuer for asset! (${o.issuer} != ${a.issuer})",
566 "Can not update max supply" );
568 if( o.
extensions.value.new_precision.valid() )
571 "Specified a new precision but it does not change" );
578 .indices().
get<by_short_backing_asset>();
580 bool backing_another_asset = ( itr != idx.end() && itr->options.short_backing_asset == o.
asset_to_update );
582 "Asset ${a} is backed by this asset, can not update precision",
583 (
"a",itr->asset_id) );
632 const auto& bitasset = ( bitasset_data ? *bitasset_data : asset_to_update->
bitasset_data(d) );
633 if( !bitasset.asset_cer_updated )
645 if( o.
extensions.value.new_precision.valid() )
647 if( o.
extensions.value.skip_core_exchange_rate.valid() )
668 asset_to_update = &a;
670 "Incorrect issuer for asset! (${o.issuer} != ${a.issuer})",
700 if ( new_backing_asset.
get_id() == asset_id_type() )
706 .
get<by_short_backing_asset>();
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')." );
716 FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT,
717 "A blockchain-controlled market asset would be invalidated by changing this backing asset." );
719 FC_ASSERT( !new_backing_asset.is_market_issued(),
720 "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset.");
741 FC_ASSERT( op.
issuer == asset_obj.
issuer,
"Only asset issuer can update bitasset_data of the asset." );
745 if( !HARDFORK_CORE_2282_PASSED( next_maint_time ) )
747 "Cannot update a bitasset after a global settlement has executed" );
751 "Can not set black_swan_response_method for Prediction Markets" );
757 const auto& old_mcr = current_bitasset_data.
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" );
766 const auto& old_icr = current_bitasset_data.
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" );
775 const auto& old_mssr = current_bitasset_data.
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" );
784 if( old_bsrm != new_bsrm )
788 "Unable to update BSRM when the asset has been globally settled" );
792 if( bsrm_type::individual_settlement_to_fund == old_bsrm )
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" );
800 if( bsrm_type::no_settlement == old_bsrm || bsrm_type::no_settlement == new_bsrm )
801 update_feeds_due_to_bsrm_change =
true;
806 bool after_hf_core_922_931 = ( next_maint_time > HARDFORK_CORE_922_931_TIME );
812 "Cannot change backing asset after a global settlement has executed" );
816 "Cannot change backing asset if there is already a current supply." );
819 "Must claim collateral-denominated fees before changing backing asset." );
823 if( after_hf_core_922_931 )
826 "Cannot update an asset to be backed by itself." );
831 "The precision of the asset and backing asset must be equal." );
839 "May not modify a blockchain-controlled market asset to be backed by an asset which is not "
847 "May not modify a blockchain-controlled market asset to be backed by an asset which is not "
848 "market issued asset nor CORE." );
859 if ( new_backing_asset.
get_id() != asset_id_type() )
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.");
878 if( after_hf_core_922_931 )
881 "Feed lifetime must exceed block interval." );
883 "Force settlement delay must exceed block interval." );
886 bitasset_to_update = ¤t_bitasset_data;
887 asset_to_update = &asset_obj;
908 static bool update_bitasset_object_options(
911 bool update_feeds_due_to_bsrm_change )
914 bool after_hf_core_868_890 = ( next_maint_time > HARDFORK_CORE_868_890_TIME );
917 bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time );
920 bool should_update_feeds =
false;
922 should_update_feeds =
true;
925 if( after_hf_core_868_890
928 should_update_feeds =
true;
932 bool backing_asset_changed =
false;
933 bool is_witness_or_committee_fed =
false;
934 if( after_hf_core_868_890
937 backing_asset_changed =
true;
938 should_update_feeds =
true;
940 is_witness_or_committee_fed =
true;
945 if( !should_update_feeds )
949 bool icr_changed = ( ( old_icr.valid() != new_icr.valid() )
950 || ( old_icr.valid() && *old_icr != *new_icr ) );
951 should_update_feeds = icr_changed;
954 if( !should_update_feeds )
958 bool mcr_changed = ( ( old_mcr.valid() != new_mcr.valid() )
959 || ( old_mcr.valid() && *old_mcr != *new_mcr ) );
960 should_update_feeds = mcr_changed;
963 if( !should_update_feeds )
967 bool mssr_changed = ( ( old_mssr.valid() != new_mssr.valid() )
968 || ( old_mssr.valid() && *old_mssr != *new_mssr ) );
969 should_update_feeds = mssr_changed;
975 const bool mcfr_changed = ( ( old_mcfr.valid() != new_mcfr.valid() )
976 || ( old_mcfr.valid() && *old_mcfr != *new_mcfr ) );
982 if( backing_asset_changed )
984 if( is_witness_or_committee_fed )
993 for(
auto& current_feed : bdo.
feeds )
995 current_feed.second.second.settlement_price = price();
1000 bool feed_actually_changed =
false;
1001 if( should_update_feeds || update_feeds_due_to_bsrm_change )
1012 feed_actually_changed = ( after_hf_core_868_890 && !old_feed.margin_call_params_equal( bdo.
current_feed ) );
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;
1020 const bool retval = feed_actually_changed || mcfr_changed;
1029 auto& db_conn =
db();
1030 bool to_check_call_orders =
false;
1032 db_conn.modify( *bitasset_to_update,
1035 to_check_call_orders = update_bitasset_object_options( op, db_conn, bdo, *asset_to_update,
1036 update_feeds_due_to_bsrm_change );
1039 if( to_check_call_orders )
1041 db_conn.check_call_orders( *asset_to_update,
true,
false, bitasset_to_update );
1053 "Cannot specify more feed producers than maximum allowed" );
1063 asset_to_update = &a;
1088 for(
auto itr = a.
feeds.begin(); itr != a.
feeds.end(); )
1090 if( o.new_feed_producers.count(itr->first) == 0 )
1091 itr = a.feeds.erase(itr);
1116 FC_ASSERT( asset_to_settle->
issuer == op.
issuer,
"Only asset issuer can globally settle an asset" );
1118 "Can not globally settle an asset with zero supply" );
1123 "This asset has been globally settled, cannot globally settle again" );
1127 if( least_collateralized_short )
1131 "Cannot globally settle at supplied price: least collateralized short lacks "
1132 "sufficient collateral to settle." );
1150 "Can only force settle a predition market or a market issued asset" );
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" );
1158 if( bitasset.is_prediction_market )
1160 FC_ASSERT( bitasset.is_globally_settled(),
1161 "Global settlement must occur before force settling a prediction market" );
1163 else if( bitasset.current_feed.settlement_price.is_null() )
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" );
1172 if( !bitasset.is_globally_settled() && !bitasset.is_individually_settled_to_fund() )
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" );
1186 "The account is not allowed to settle the asset" );
1188 "The account is not allowed to receive the backing asset" );
1191 bitasset_ptr = &bitasset;
1198 const asset& settled_amount,
1203 bool after_core_hardfork_2591 = HARDFORK_CORE_2591_PASSED( head_time );
1211 if( settled_amount_by_mcop < settled_amount )
1213 asset collateral_fees = settled_amount - settled_amount_by_mcop;
1215 return collateral_fees;
1219 return optional<asset>();
1224 const account_object* fee_paying_account,
1225 const asset_object& asset_to_settle,
1226 const asset_bitasset_data_object& bitasset )
1228 const auto& head_time = d.head_block_time();
1229 const auto& maint_time = d.get_dynamic_global_properties().next_maintenance_time;
1231 const auto& mia_dyn = asset_to_settle.dynamic_asset_data_id(d);
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 );
1236 if( op.amount.amount != mia_dyn.current_supply )
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" );
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" );
1248 if( op.amount.amount != mia_dyn.current_supply
1249 && settled_amount.amount != 0
1250 && maint_time > HARDFORK_CORE_342_TIME )
1252 pays = settled_amount.multiply_and_round_up( bitasset.settlement_price );
1255 d.adjust_balance( op.account, -pays );
1257 asset issuer_fees( 0, bitasset.options.short_backing_asset );
1258 optional<asset> collateral_fees;
1260 if( settled_amount.amount > 0 )
1262 d.modify( bitasset, [&settled_amount]( asset_bitasset_data_object& obj ){
1263 obj.settlement_fund -= settled_amount.amount;
1267 collateral_fees = pay_collateral_fees( d, pays, settled_amount, asset_to_settle, bitasset );
1268 if( collateral_fees.valid() )
1269 settled_amount -= *collateral_fees;
1276 if( head_time >= HARDFORK_CORE_1780_TIME )
1278 issuer_fees = d.pay_market_fees( fee_paying_account, settled_amount.asset_id(d), settled_amount,
false );
1279 settled_amount -= issuer_fees;
1282 if( settled_amount.amount > 0 )
1283 d.adjust_balance( op.account, settled_amount );
1286 d.modify( mia_dyn, [&pays]( asset_dynamic_data_object& obj ){
1287 obj.current_supply -= pays.amount;
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 });
1303 const account_object* fee_paying_account,
1304 const asset_object& asset_to_settle,
1305 const asset_bitasset_data_object& bitasset )
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 )
1311 auto settlement_price = bitasset.get_individual_settlement_price();
1312 settled_amount = op.amount * settlement_price;
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 );
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;
1322 d.modify( asset_to_settle.dynamic_asset_data_id(d), [&pays]( asset_dynamic_data_object& obj ){
1323 obj.current_supply -= pays.amount;
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;
1331 auto issuer_fees = d.pay_market_fees( fee_paying_account, settled_amount.asset_id(d), settled_amount,
false );
1332 settled_amount -= issuer_fees;
1334 if( settled_amount.amount > 0 )
1335 d.adjust_balance( op.account, settled_amount );
1338 auto old_feed_price = bitasset.current_feed.settlement_price;
1339 d.update_bitasset_current_feed( bitasset,
true );
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 );
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 });
1363 const auto& bitasset = *bitasset_ptr;
1366 if( bitasset.is_globally_settled() )
1367 return pay_settle_from_gs_fund( d, op,
fee_paying_account, *asset_to_settle, bitasset );
1372 if( bitasset.is_individually_settled_to_fund() )
1374 result = pay_settle_from_individual_pool( d, op,
fee_paying_account, *asset_to_settle, bitasset );
1377 if( bitasset.is_individually_settled_to_fund() || !asset_to_settle->can_force_settle() )
1380 to_settle -= result.
value.paid->front();
1386 bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time );
1387 if( after_core_hardfork_2582 && 0 == to_settle.
amount )
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() )
1397 s.owner = op.account;
1399 s.
settlement_date = head_time + bitasset.options.force_settlement_delay_sec;
1402 result.
value.new_objects = flat_set<object_id_type>({ settle.id });
1405 if( HARDFORK_CORE_2481_PASSED( maint_time ) )
1434 "Quote asset type in settlement price should be same as backing asset of this asset" );
1436 if( now > HARDFORK_480_TIME )
1441 "Quote asset in core exchange rate should be CORE asset" );
1457 "Only active witnesses are allowed to publish price feeds for this asset" );
1462 "Only active committee members are allowed to publish price feeds for this asset" );
1467 "The account is not in the set of allowed price feed producers of this asset" );
1471 bitasset_ptr = &bitasset;
1491 o.
extensions.value.initial_collateral_ratio ) );
1495 bool after_core_hardfork_2582 = HARDFORK_CORE_2582_PASSED( head_time );
1497 if( !after_core_hardfork_2582 && old_feed.margin_call_params_equal(bad.
current_feed) )
1499 if( after_core_hardfork_2582 && old_median_feed.margin_call_params_equal(bad.
median_feed) )
1506 bool should_revive =
false;
1508 if( mia_dyn.current_supply == 0 )
1509 should_revive =
true;
1512 else if( next_maint_time <= HARDFORK_CORE_1270_TIME )
1515 auto fund_call_price = ~
price::call_price(
asset(mia_dyn.current_supply, o.
asset_id),
1525 should_revive = HARDFORK_CORE_2290_PASSED( next_maint_time ) ?
1556 container_asset = o.
extensions.value.claim_from_asset_id.valid() ?
1561 "Asset ${a} (${id}) is not backed by asset (${fid}) and does not hold it as 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)
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)