From 73321cad4393cb20350efdd6971292da71d0a394 Mon Sep 17 00:00:00 2001 From: Alexey Frolov Date: Mon, 8 Jul 2019 17:31:10 +0300 Subject: [PATCH 1/2] Added settle orders to market fee sharing program --- libraries/chain/db_market.cpp | 6 +- libraries/chain/hardfork.d/CORE_1780.hf | 4 + tests/tests/market_fee_sharing_tests.cpp | 1 - tests/tests/settle_tests.cpp | 189 +++++++++++++++++++++++ 4 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 libraries/chain/hardfork.d/CORE_1780.hf diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index c009d0b830..e309aec4b2 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -932,7 +932,11 @@ bool database::fill_settle_order( const force_settlement_object& settle, const a { try { bool filled = false; - auto issuer_fees = pay_market_fees(get(receives.asset_id), receives); + const account_object& owner = settle.owner(*this); + + auto issuer_fees = ( head_block_time() < HARDFORK_CORE_1780_TIME ) ? + pay_market_fees(get(receives.asset_id), receives) : + pay_market_fees(owner, get(receives.asset_id), receives); if( pays < settle.balance ) { diff --git a/libraries/chain/hardfork.d/CORE_1780.hf b/libraries/chain/hardfork.d/CORE_1780.hf new file mode 100644 index 0000000000..8e1358b15b --- /dev/null +++ b/libraries/chain/hardfork.d/CORE_1780.hf @@ -0,0 +1,4 @@ +// Market fees of settle orders aren't shared to referral program +#ifndef HARDFORK_CORE_1780_TIME +#define HARDFORK_CORE_1780_TIME (fc::time_point_sec( 1600000000 ) ) // September 13, 2020 3:26:40 PM (GMT) +#endif diff --git a/tests/tests/market_fee_sharing_tests.cpp b/tests/tests/market_fee_sharing_tests.cpp index 2ba95b2c5b..a267a3b9b5 100644 --- a/tests/tests/market_fee_sharing_tests.cpp +++ b/tests/tests/market_fee_sharing_tests.cpp @@ -426,7 +426,6 @@ BOOST_AUTO_TEST_CASE(create_actors) price price(asset(1, asset_id_type(1)), asset(1)); uint16_t market_fee_percent = 20 * GRAPHENE_1_PERCENT; - auto obj = jill_id(db); const asset_object jillcoin = create_user_issued_asset( "JCOIN", jill, charge_market_fee, price, 2, market_fee_percent ); const account_object alice = create_account("alice", izzyregistrar, izzyreferrer, 50/*0.5%*/); diff --git a/tests/tests/settle_tests.cpp b/tests/tests/settle_tests.cpp index f64719e613..1249c03eb9 100644 --- a/tests/tests/settle_tests.cpp +++ b/tests/tests/settle_tests.cpp @@ -1501,4 +1501,193 @@ BOOST_AUTO_TEST_CASE( global_settle_rounding_test_after_hf_184 ) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( create_bitassets ) +{ + try { + generate_blocks( HARDFORK_1268_TIME ); + generate_blocks( db.get_dynamic_global_properties().next_maintenance_time ); + set_expiration( db, trx ); + + ACTORS((paul)(rachelregistrar)(rachelreferrer)); + + upgrade_to_lifetime_member(rachelregistrar); + upgrade_to_lifetime_member(rachelreferrer); + + constexpr auto market_fee_percent = 50 * GRAPHENE_1_PERCENT; + constexpr auto biteur_reward_percent = 90 * GRAPHENE_1_PERCENT; + constexpr auto referrer_reward_percent = 10 * GRAPHENE_1_PERCENT; + + const auto& biteur = create_bitasset( "EURBIT", paul_id, market_fee_percent, charge_market_fee, 2 ); + asset_id_type biteur_id = biteur.id; + + const auto& bitusd = create_bitasset( "USDBIT", paul_id, market_fee_percent, charge_market_fee, 2, biteur_id ); + + const account_object rachel = create_account( "rachel", rachelregistrar, rachelreferrer, referrer_reward_percent ); + + transfer( committee_account, rachelregistrar_id, asset( 10000000 ) ); + transfer( committee_account, rachelreferrer_id, asset( 10000000 ) ); + transfer( committee_account, rachel.get_id(), asset( 10000000) ); + transfer( committee_account, paul_id, asset( 10000000000 ) ); + + asset_update_operation op; + op.issuer = biteur.issuer; + op.asset_to_update = biteur_id; + op.new_options.issuer_permissions = charge_market_fee; + op.new_options.extensions.value.reward_percent = biteur_reward_percent; + op.new_options.flags = bitusd.options.flags | charge_market_fee; + op.new_options.core_exchange_rate = price( asset(20,biteur_id), asset(1,asset_id_type()) ); + op.new_options.market_fee_percent = market_fee_percent; + trx.operations.push_back(op); + sign(trx, paul_private_key); + PUSH_TX(db, trx); + generate_block(); + trx.clear(); + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE( market_fee_of_settle_order_before_hardfork_1780 ) +{ + try { + INVOKE(create_bitassets); + + GET_ACTOR(paul); + GET_ACTOR(rachelregistrar); + GET_ACTOR(rachelreferrer); + + const asset_object &biteur = get_asset( "EURBIT" ); + asset_id_type biteur_id = biteur.id; + const asset_object &bitusd = get_asset( "USDBIT" ); + asset_id_type bitusd_id = bitusd.id; + + const auto& core = asset_id_type()(db); + + const account_object& rachel = get_account( "rachel" ); + + {// add a feed to asset bitusd + update_feed_producers( bitusd, {paul_id} ); + price_feed feed; + feed.settlement_price = price( bitusd.amount(100), biteur.amount(5) ); + feed.core_exchange_rate = price( bitusd.amount(100), asset(1) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 110 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( bitusd_id, paul_id, feed ); + } + + {// add a feed to asset biteur + update_feed_producers( biteur, {paul_id} ); + price_feed feed; + feed.settlement_price = price( biteur.amount(100), core.amount(5) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 110 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( biteur_id, paul_id, feed ); + } + + enable_fees(); + + // paul gets some bitusd and biteur + borrow( paul_id, biteur.amount(20000), core.amount(2000) ); + borrow( paul_id, bitusd.amount(10000), biteur.amount(1000) ); + + // and transfer some bitusd to rachel + constexpr auto rachel_bitusd_count = 1000; + transfer( paul_id, rachel.get_id(), asset(rachel_bitusd_count, bitusd_id) ); + + force_settle( rachel, bitusd.amount(rachel_bitusd_count) ); + generate_block(); + generate_blocks( db.head_block_time() + fc::hours(24) ); + + // 1 biteur = 20 bitusd see publish_feed + const auto biteur_expected_result = rachel_bitusd_count/20; + BOOST_CHECK_EQUAL( get_balance(rachel, biteur), biteur_expected_result/2/*market fee percent = 50%*/ ); + BOOST_CHECK_EQUAL( get_balance(rachel, bitusd), 0 ); + + const auto rachelregistrar_reward = get_market_fee_reward( rachelregistrar, biteur ); + const auto rachelreferrer_reward = get_market_fee_reward( rachelreferrer, biteur ); + + BOOST_CHECK_EQUAL( rachelregistrar_reward, 0 ); + BOOST_CHECK_EQUAL( rachelreferrer_reward, 0 ); + + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE( market_fee_of_settle_order_after_hardfork_1780 ) +{ + try { + INVOKE(create_bitassets); + + GET_ACTOR(paul); + GET_ACTOR(rachelregistrar); + GET_ACTOR(rachelreferrer); + + const asset_object &biteur = get_asset( "EURBIT" ); + asset_id_type biteur_id = biteur.id; + const asset_object &bitusd = get_asset( "USDBIT" ); + asset_id_type bitusd_id = bitusd.id; + + const auto& core = asset_id_type()(db); + + const account_object& rachel = get_account( "rachel" ); + + generate_blocks( HARDFORK_CORE_1780_TIME ); + + {// add a feed to asset bitusd + update_feed_producers( bitusd, {paul_id} ); + price_feed feed; + feed.settlement_price = price( bitusd.amount(100), biteur.amount(5) ); + feed.core_exchange_rate = price( bitusd.amount(100), asset(1) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 110 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( bitusd_id, paul_id, feed ); + } + + {// add a feed to asset biteur + update_feed_producers( biteur, {paul_id} ); + price_feed feed; + feed.settlement_price = price( biteur.amount(100), core.amount(5) ); + feed.maintenance_collateral_ratio = 175 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + feed.maximum_short_squeeze_ratio = 110 * GRAPHENE_COLLATERAL_RATIO_DENOM / 100; + publish_feed( biteur_id, paul_id, feed ); + } + + enable_fees(); + + // paul gets some bitusd and biteur + borrow( paul_id, biteur.amount(20000), core.amount(2000) ); + borrow( paul_id, bitusd.amount(10000), biteur.amount(1000) ); + + // and transfer some bitusd to rachel + constexpr auto rachel_bitusd_count = 1000; + transfer( paul_id, rachel.get_id(), asset(rachel_bitusd_count, bitusd_id) ); + + force_settle( rachel, bitusd.amount(rachel_bitusd_count) ); + generate_block(); + generate_blocks( db.head_block_time() + fc::hours(24) ); + + // 1 biteur = 20 bitusd see publish_feed + const auto biteur_expected_result = rachel_bitusd_count/20; + BOOST_CHECK_EQUAL( get_balance(rachel, biteur), biteur_expected_result/2/*market fee percent = 50%*/ ); + BOOST_CHECK_EQUAL( get_balance(rachel, bitusd), 0 ); + + const auto rachelregistrar_reward = get_market_fee_reward( rachelregistrar, biteur ); + const auto rachelreferrer_reward = get_market_fee_reward( rachelreferrer, biteur ); + + BOOST_CHECK_GT( rachelregistrar_reward, 0 ); + BOOST_CHECK_GT( rachelreferrer_reward, 0 ); + + auto calculate_percent = [](const share_type& value, uint16_t percent) + { + auto a(value.value); + a *= percent; + a /= GRAPHENE_100_PERCENT; + return a; + }; + + const auto biteur_market_fee = calculate_percent( biteur_expected_result, 50 * GRAPHENE_1_PERCENT ); + const auto biteur_reward = calculate_percent( biteur_market_fee, 90*GRAPHENE_1_PERCENT ); + BOOST_CHECK_EQUAL( biteur_reward, rachelregistrar_reward + rachelreferrer_reward ); + + } FC_LOG_AND_RETHROW() +} + + BOOST_AUTO_TEST_SUITE_END() From c2b28e9917e9d4e11aef7e754f98ea0e283cc3a5 Mon Sep 17 00:00:00 2001 From: Alexey Frolov Date: Thu, 11 Jul 2019 16:46:36 +0300 Subject: [PATCH 2/2] optimize access to graphene database --- libraries/chain/db_market.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index e309aec4b2..53f6d97c8d 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -932,11 +932,9 @@ bool database::fill_settle_order( const force_settlement_object& settle, const a { try { bool filled = false; - const account_object& owner = settle.owner(*this); - auto issuer_fees = ( head_block_time() < HARDFORK_CORE_1780_TIME ) ? pay_market_fees(get(receives.asset_id), receives) : - pay_market_fees(owner, get(receives.asset_id), receives); + pay_market_fees(settle.owner(*this), get(receives.asset_id), receives); if( pays < settle.balance ) {