Skip to content

Commit

Permalink
Merge pull request #1842 from openledger/issue-1780
Browse files Browse the repository at this point in the history
Fix: Market fees of settle orders aren't shared to referral program
  • Loading branch information
abitmore authored Apr 5, 2020
2 parents d98c38a + c2b28e9 commit 4cb30cd
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 2 deletions.
4 changes: 3 additions & 1 deletion libraries/chain/db_market.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,9 @@ 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);
auto issuer_fees = ( head_block_time() < HARDFORK_CORE_1780_TIME ) ?
pay_market_fees(get(receives.asset_id), receives) :
pay_market_fees(settle.owner(*this), get(receives.asset_id), receives);

if( pays < settle.balance )
{
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/hardfork.d/CORE_1780.hf
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion tests/tests/market_fee_sharing_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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%*/);
Expand Down
189 changes: 189 additions & 0 deletions tests/tests/settle_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 4cb30cd

Please sign in to comment.