implementing rake fee in resolve_betting_market_group #1
improving net profit calculation
This commit is contained in:
parent
32433ef29f
commit
c18094abd8
5 changed files with 71 additions and 16 deletions
|
|
@ -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
|
// walking through bettors' positions and collecting winings and fees respecting asset_id
|
||||||
for (const auto& bettor_positions_pair: bettor_positions_map)
|
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> payout_amounts;
|
||||||
std::map<asset_id_type, share_type> fees_collected;
|
std::map<asset_id_type, share_type> fees_collected;
|
||||||
account_id_type bettor_id = bettor_positions_pair.first;
|
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_payout_condition;
|
||||||
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
|
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
|
||||||
fees_collected[betting_market.asset_id] += position->fees_collected;
|
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;
|
break;
|
||||||
case betting_market_resolution_type::not_win:
|
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_payout_condition;
|
||||||
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
|
payout_amounts[betting_market.asset_id] += position->pay_if_not_canceled;
|
||||||
fees_collected[betting_market.asset_id] += position->fees_collected;
|
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;
|
break;
|
||||||
case betting_market_resolution_type::cancel:
|
case betting_market_resolution_type::cancel:
|
||||||
payout_amounts[betting_market.asset_id] += position->pay_if_canceled;
|
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;
|
std::vector<asset> fees;
|
||||||
for (const auto& payout_amount_pair: payout_amounts)
|
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);
|
adjust_balance(bettor_id, payout);
|
||||||
|
|
||||||
winnings.push_back(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);
|
fees.push_back(fee);
|
||||||
}
|
}
|
||||||
push_applied_operation(betting_market_group_resolved_operation(bettor_id,
|
push_applied_operation(betting_market_group_resolved_operation(bettor_id,
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
||||||
a.membership_expiration_date = time_point_sec::maximum();
|
a.membership_expiration_date = time_point_sec::maximum();
|
||||||
a.network_fee_percentage = 0;
|
a.network_fee_percentage = 0;
|
||||||
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT;
|
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
|
// Create more special accounts
|
||||||
while( true )
|
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.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
|
||||||
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
|
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
|
||||||
a.options.payout_interval = 7*24*60*60;
|
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 =
|
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.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
|
||||||
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
|
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
|
||||||
a.options.payout_interval = 7*24*60*60;
|
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 =
|
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.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
|
||||||
a.options.flags = 0;
|
a.options.flags = 0;
|
||||||
a.options.issuer_permissions = 79;
|
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.amount = 1;
|
||||||
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
|
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
|
||||||
a.options.core_exchange_rate.quote.amount = 1;
|
a.options.core_exchange_rate.quote.amount = 1;
|
||||||
|
|
|
||||||
|
|
@ -165,13 +165,15 @@
|
||||||
/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy)
|
/// 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 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.
|
/// Sentinel value used in the scheduler.
|
||||||
#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0))
|
#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0))
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743))
|
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743))
|
||||||
|
|
||||||
|
#define GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE (3*GRAPHENE_1_PERCENT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Betting-related constants.
|
* Betting-related constants.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
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 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;
|
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 min_bet_multiplier = GRAPHENE_DEFAULT_MIN_BET_MULTIPLIER;
|
||||||
bet_multiplier_type max_bet_multiplier = GRAPHENE_DEFAULT_MAX_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;
|
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)
|
(max_authority_depth)
|
||||||
(min_bet_multiplier)
|
(min_bet_multiplier)
|
||||||
(max_bet_multiplier)
|
(max_bet_multiplier)
|
||||||
|
(betting_rake_fee_percentage)
|
||||||
(permitted_betting_odds_increments)
|
(permitted_betting_odds_increments)
|
||||||
(extensions)
|
(extensions)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,11 @@ BOOST_AUTO_TEST_CASE( peerplays_sport_create_test )
|
||||||
{{capitals_win_market.id, betting_market_resolution_type::win},
|
{{capitals_win_market.id, betting_market_resolution_type::win},
|
||||||
{blackhawks_win_market.id, betting_market_resolution_type::cancel}});
|
{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);
|
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000);
|
||||||
|
|
||||||
} FC_LOG_AND_RETHROW()
|
} FC_LOG_AND_RETHROW()
|
||||||
|
|
@ -294,10 +298,16 @@ BOOST_AUTO_TEST_CASE( win )
|
||||||
GET_ACTOR(alice);
|
GET_ACTOR(alice);
|
||||||
GET_ACTOR(bob);
|
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
|
// 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);
|
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
|
// 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()
|
} FC_LOG_AND_RETHROW()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,8 +322,13 @@ BOOST_AUTO_TEST_CASE( not_win )
|
||||||
GET_ACTOR(alice);
|
GET_ACTOR(alice);
|
||||||
GET_ACTOR(bob);
|
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
|
// 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
|
// 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);
|
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000 - 1000 - 20 + 1100 - 1100 - 22 + 0);
|
||||||
} FC_LOG_AND_RETHROW()
|
} FC_LOG_AND_RETHROW()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue