implementing rake fee in resolve_betting_market_group #1

improving net profit calculation
This commit is contained in:
Roman Olearski 2017-07-07 14:23:02 +02:00
parent 32433ef29f
commit c18094abd8
5 changed files with 71 additions and 16 deletions

View file

@ -92,6 +92,8 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
// walking through bettors' positions and collecting winings and fees respecting asset_id
for (const auto& bettor_positions_pair: bettor_positions_map)
{
uint16_t rake_fee_percentage = get_global_properties().parameters.betting_rake_fee_percentage;
std::map<asset_id_type, share_type> net_profits;
std::map<asset_id_type, share_type> payout_amounts;
std::map<asset_id_type, share_type> fees_collected;
account_id_type bettor_id = bettor_positions_pair.first;
@ -118,11 +120,17 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
payout_amounts[betting_market.asset_id] += position->pay_if_payout_condition;
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
fees_collected[betting_market.asset_id] += position->fees_collected;
net_profits[betting_market.asset_id] += position->pay_if_payout_condition;
net_profits[betting_market.asset_id] += position->pay_if_not_canceled;
net_profits[betting_market.asset_id] -= position->pay_if_canceled;
break;
case betting_market_resolution_type::not_win:
payout_amounts[betting_market.asset_id] += position->pay_if_not_payout_condition;
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
fees_collected[betting_market.asset_id] += position->fees_collected;
net_profits[betting_market.asset_id] += position->pay_if_not_payout_condition;
net_profits[betting_market.asset_id] += position->pay_if_not_canceled;
net_profits[betting_market.asset_id] -= position->pay_if_canceled;
break;
case betting_market_resolution_type::cancel:
payout_amounts[betting_market.asset_id] += position->pay_if_canceled;
@ -138,15 +146,44 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
std::vector<asset> fees;
for (const auto& payout_amount_pair: payout_amounts)
{
asset payout = asset(payout_amount_pair.second, payout_amount_pair.first);
// pay the fees to the correct (dividend-distribution) account if net profit
asset_id_type asset_id = payout_amount_pair.first;
const asset_object & asset_obj = asset_id(*this);
optional<asset_dividend_data_id_type> dividend_id = asset_obj.dividend_data_id;
account_id_type rake_account_id;
if (dividend_id.valid())
{
const asset_dividend_data_id_type& asset_dividend_data_id_= *dividend_id;
const asset_dividend_data_object& dividend_obj = asset_dividend_data_id_(*this);
rake_account_id = dividend_obj.dividend_distribution_account;
}
asset fee = fees_collected[asset_id];
share_type net_profit = net_profits[asset_id];
share_type payout_amount = payout_amount_pair.second;
share_type rake_amount = 0;
if (dividend_id.valid())
{
if (net_profit.value > 0)
{
rake_amount = (fc::uint128_t(net_profit.value) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100).to_uint64();
if (rake_amount.value)
{
// adjusting balance of dividend_distribution_account
asset rake(rake_amount, asset_id);
adjust_balance(rake_account_id, rake);
}
}
adjust_balance(rake_account_id, fee);
}
else
{
adjust_balance(account_id_type(), fee);
}
// pay winning - rake
asset payout = asset(payout_amount - rake_amount, asset_id);
adjust_balance(bettor_id, payout);
winnings.push_back(payout);
}
for (const auto& fee_collected_pair: fees_collected)
{
// TODO : pay the fees to the correct (dividend-distribution) account
asset fee = asset(fee_collected_pair.second, fee_collected_pair.first);
adjust_balance(account_id_type(), fee);
fees.push_back(fee);
}
push_applied_operation(betting_market_group_resolved_operation(bettor_id,

View file

@ -381,7 +381,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.membership_expiration_date = time_point_sec::maximum();
a.network_fee_percentage = 0;
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT;
}).get_id() == TOURNAMENT_RAKE_FEE_ACCOUNT_ID);
}).get_id() == GRAPHENE_RAKE_FEE_ACCOUNT_ID);
// Create more special accounts
while( true )
@ -415,7 +415,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
a.options.payout_interval = 7*24*60*60;
a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
a.dividend_distribution_account = GRAPHENE_RAKE_FEE_ACCOUNT_ID;
});
const asset_object& core_asset =
@ -447,7 +447,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
a.options.payout_interval = 7*24*60*60;
a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
a.dividend_distribution_account = GRAPHENE_RAKE_FEE_ACCOUNT_ID;
});
const asset_object& default_asset =
@ -458,7 +458,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
a.options.flags = 0;
a.options.issuer_permissions = 79;
a.issuer = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
a.issuer = GRAPHENE_RAKE_FEE_ACCOUNT_ID;
a.options.core_exchange_rate.base.amount = 1;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 1;

View file

@ -165,13 +165,15 @@
/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy)
#define GRAPHENE_PROXY_TO_SELF_ACCOUNT (graphene::chain::account_id_type(5))
///
#define TOURNAMENT_RAKE_FEE_ACCOUNT_ID (graphene::chain::account_id_type(6))
#define GRAPHENE_RAKE_FEE_ACCOUNT_ID (graphene::chain::account_id_type(6))
/// Sentinel value used in the scheduler.
#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0))
///@}
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743))
#define GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE (3*GRAPHENE_1_PERCENT)
/**
* Betting-related constants.
*

View file

@ -69,7 +69,7 @@ namespace graphene { namespace chain {
uint16_t accounts_per_fee_scale = GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE; ///< number of accounts between fee scalings
uint8_t account_fee_scale_bitshifts = GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS; ///< number of times to left bitshift account registration fee at each scaling
uint8_t max_authority_depth = GRAPHENE_MAX_SIG_CHECK_DEPTH;
uint16_t betting_rake_fee_percentage = GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE; ///< part of prize paid into the dividend account for the core token holders
bet_multiplier_type min_bet_multiplier = GRAPHENE_DEFAULT_MIN_BET_MULTIPLIER;
bet_multiplier_type max_bet_multiplier = GRAPHENE_DEFAULT_MAX_BET_MULTIPLIER;
flat_map<bet_multiplier_type, bet_multiplier_type> permitted_betting_odds_increments = GRAPHENE_DEFAULT_PERMITTED_BETTING_ODDS_INCREMENTS;
@ -113,6 +113,7 @@ FC_REFLECT( graphene::chain::chain_parameters,
(max_authority_depth)
(min_bet_multiplier)
(max_bet_multiplier)
(betting_rake_fee_percentage)
(permitted_betting_odds_increments)
(extensions)
)

View file

@ -118,7 +118,11 @@ BOOST_AUTO_TEST_CASE( peerplays_sport_create_test )
{{capitals_win_market.id, betting_market_resolution_type::win},
{blackhawks_win_market.id, betting_market_resolution_type::cancel}});
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000);
uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage;
uint32_t rake_value = (-1000000 + 2000000) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
BOOST_TEST_MESSAGE("Rake value " + std::to_string(rake_value));
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000 - rake_value);
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000);
} FC_LOG_AND_RETHROW()
@ -294,10 +298,16 @@ BOOST_AUTO_TEST_CASE( win )
GET_ACTOR(alice);
GET_ACTOR(bob);
uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage;
uint32_t rake_value;
//rake_value = (-100 + 1100 - 1100) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
// alice starts with 10000, pays 100 (bet) + 2 (fee), wins 1100, then pays 1100 (bet) + 22 (fee), wins 0
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000 - 100 - 2 + 1100 - 1100 - 22 + 0);
rake_value = (-1000 - 1100 + 2200) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
// bob starts with 10000, pays 1000 (bet) + 20 (fee), wins 0, then pays 1100 (bet) + 22 (fee), wins 2200
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000 - 1000 - 20 + 0 - 1100 - 22 + 2200);
BOOST_TEST_MESSAGE("Rake value " + std::to_string(rake_value));
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000 - 1000 - 20 + 0 - 1100 - 22 + 2200 - rake_value);
} FC_LOG_AND_RETHROW()
}
@ -312,8 +322,13 @@ BOOST_AUTO_TEST_CASE( not_win )
GET_ACTOR(alice);
GET_ACTOR(bob);
uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage;
uint32_t rake_value = (-100 - 1100 + 2200) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
// alice starts with 10000, pays 100 (bet) + 2 (fee), wins 0, then pays 1100 (bet) + 22 (fee), wins 2200
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000 - 100 - 2 + 0 - 1100 - 22 + 2200);
BOOST_TEST_MESSAGE("Rake value " + std::to_string(rake_value));
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000 - 100 - 2 + 0 - 1100 - 22 + 2200 - rake_value);
//rake_value = (-1000 + 1100 - 1100) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
// bob starts with 10000, pays 1000 (bet) + 20 (fee), wins 1100, then pays 1100 (bet) + 22 (fee), wins 0
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000 - 1000 - 20 + 1100 - 1100 - 22 + 0);
} FC_LOG_AND_RETHROW()