Skip to content

Commit

Permalink
Move deferred fee processing code into a function
Browse files Browse the repository at this point in the history
  • Loading branch information
abitmore committed May 12, 2023
1 parent 032f125 commit 0ab1d1f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 82 deletions.
5 changes: 4 additions & 1 deletion libraries/chain/include/graphene/chain/market_evaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace graphene { namespace chain {
using operation_type = limit_order_update_operation;

void_result do_evaluate(const limit_order_update_operation& o);
void_result do_apply(const limit_order_update_operation& o) const;
void_result do_apply(const limit_order_update_operation& o);

/** override the default behavior defined by generic_evaluator
*/
Expand All @@ -77,9 +77,12 @@ namespace graphene { namespace chain {
void pay_fee() override;

private:
void process_deferred_fee();

share_type _deferred_fee;
asset _deferred_paid_fee;
const limit_order_object* _order = nullptr;
const account_statistics_object* _seller_acc_stats = nullptr;
};

class limit_order_cancel_evaluator : public evaluator<limit_order_cancel_evaluator>
Expand Down
168 changes: 87 additions & 81 deletions libraries/chain/market_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,104 +243,110 @@ void_result limit_order_update_evaluator::do_evaluate(const limit_order_update_o
return {};
}

void_result limit_order_update_evaluator::do_apply(const limit_order_update_operation& o) const
void limit_order_update_evaluator::process_deferred_fee()
{
database& d = db();
// Attempt to deduct a possibly discounted order cancellation fee, and refund the remainder.
// Only deduct fee if there is any fee deferred.
// TODO fix duplicate code (see database::cancel_limit_order())
if( _order->deferred_fee <= 0 )
return;

const account_statistics_object* seller_acc_stats = nullptr;
database& d = db();

// Adjust account balance
if( o.delta_amount_to_sell )
share_type deferred_fee = _order->deferred_fee;
asset deferred_paid_fee = _order->deferred_paid_fee;
const asset_dynamic_data_object* fee_asset_dyn_data = nullptr;
const auto& current_fees = d.current_fee_schedule();
asset core_cancel_fee = current_fees.calculate_fee( limit_order_cancel_operation() );
if( core_cancel_fee.amount > 0 )
{
d.adjust_balance( o.seller, -*o.delta_amount_to_sell );
if( o.delta_amount_to_sell->asset_id == asset_id_type() )
// maybe-discounted cancel_fee calculation:
// limit_order_cancel_fee * limit_order_update_fee / limit_order_create_fee
asset core_create_fee = current_fees.calculate_fee( limit_order_create_operation() );
fc::uint128_t fee128( core_cancel_fee.amount.value );
if( core_create_fee.amount > 0 )
{
seller_acc_stats = &d.get_account_stats_by_owner( o.seller );
d.modify( *seller_acc_stats, [&o]( account_statistics_object& bal ) {
bal.total_core_in_orders += o.delta_amount_to_sell->amount;
});
asset core_update_fee = current_fees.calculate_fee( limit_order_update_operation() );
fee128 *= core_update_fee.amount.value;
fee128 /= core_create_fee.amount.value;
}
// cap the fee
if( fee128 > static_cast<uint64_t>( deferred_fee.value ) )
fee128 = deferred_fee.value;
core_cancel_fee.amount = static_cast<int64_t>( fee128 );
}

// Process deferred fee in the order.
// Attempt to deduct a possibly discounted order cancellation fee, and refund the remainder.
// Only deduct fee if there is any fee deferred.
// TODO fix duplicate code (see database::cancel_limit_order())
if( _order->deferred_fee > 0 )
// if there is any CORE fee to deduct, redirect it to referral program
if( core_cancel_fee.amount > 0 )
{
share_type deferred_fee = _order->deferred_fee;
asset deferred_paid_fee = _order->deferred_paid_fee;
const asset_dynamic_data_object* fee_asset_dyn_data = nullptr;
const auto& current_fees = d.current_fee_schedule();
asset core_cancel_fee = current_fees.calculate_fee( limit_order_cancel_operation() );
if( core_cancel_fee.amount > 0 )
if( !_seller_acc_stats )
_seller_acc_stats = &d.get_account_stats_by_owner( _order->seller );
d.modify( *_seller_acc_stats, [&core_cancel_fee, &d]( account_statistics_object& obj ) {
obj.pay_fee( core_cancel_fee.amount, d.get_global_properties().parameters.cashback_vesting_threshold );
} );
deferred_fee -= core_cancel_fee.amount;
// handle originally paid fee if any:
// to_deduct = round_up( paid_fee * core_cancel_fee / deferred_core_fee_before_deduct )
if( deferred_paid_fee.amount > 0 )
{
// maybe-discounted cancel_fee calculation:
// limit_order_cancel_fee * limit_order_update_fee / limit_order_create_fee
asset core_create_fee = current_fees.calculate_fee( limit_order_create_operation() );
fc::uint128_t fee128( core_cancel_fee.amount.value );
if( core_create_fee.amount > 0 )
{
asset core_update_fee = current_fees.calculate_fee( limit_order_update_operation() );
fee128 *= core_update_fee.amount.value;
fee128 /= core_create_fee.amount.value;
}
// cap the fee
if( fee128 > static_cast<uint64_t>( deferred_fee.value ) )
fee128 = deferred_fee.value;
core_cancel_fee.amount = static_cast<int64_t>( fee128 );
}
// if there is any CORE fee to deduct, redirect it to referral program
if( core_cancel_fee.amount > 0 )
{
if( !seller_acc_stats )
seller_acc_stats = &d.get_account_stats_by_owner( o.seller );
d.modify( *seller_acc_stats, [&core_cancel_fee, &d]( account_statistics_object& obj ) {
obj.pay_fee( core_cancel_fee.amount, d.get_global_properties().parameters.cashback_vesting_threshold );
} );
deferred_fee -= core_cancel_fee.amount;
// handle originally paid fee if any:
// to_deduct = round_up( paid_fee * core_cancel_fee / deferred_core_fee_before_deduct )
if( deferred_paid_fee.amount > 0 )
{
fc::uint128_t fee128( deferred_paid_fee.amount.value );
fee128 *= core_cancel_fee.amount.value;
// to round up
fee128 += _order->deferred_fee.value;
fee128 -= 1;
fee128 /= _order->deferred_fee.value;
share_type cancel_fee_amount = static_cast<int64_t>(fee128);
// cancel_fee should be positive, pay it to asset's accumulated_fees
fee_asset_dyn_data = &deferred_paid_fee.asset_id(d).dynamic_asset_data_id(d);
d.modify( *fee_asset_dyn_data, [&cancel_fee_amount](asset_dynamic_data_object& addo) {
addo.accumulated_fees += cancel_fee_amount;
});
// cancel_fee should be no more than deferred_paid_fee
deferred_paid_fee.amount -= cancel_fee_amount;
}
fc::uint128_t fee128( deferred_paid_fee.amount.value );
fee128 *= core_cancel_fee.amount.value;
// to round up
fee128 += _order->deferred_fee.value;
fee128 -= 1;
fee128 /= _order->deferred_fee.value;
share_type cancel_fee_amount = static_cast<int64_t>(fee128);
// cancel_fee should be positive, pay it to asset's accumulated_fees
fee_asset_dyn_data = &deferred_paid_fee.asset_id(d).dynamic_asset_data_id(d);
d.modify( *fee_asset_dyn_data, [&cancel_fee_amount](asset_dynamic_data_object& addo) {
addo.accumulated_fees += cancel_fee_amount;
});
// cancel_fee should be no more than deferred_paid_fee
deferred_paid_fee.amount -= cancel_fee_amount;
}
}

// refund fee
if( 0 == _order->deferred_paid_fee.amount )
{
// be here, order.create_time <= HARDFORK_CORE_604_TIME, or fee paid in CORE, or no fee to refund.
// if order was created before hard fork 604 then cancelled no matter before or after hard fork 604,
// see it as fee paid in CORE, deferred_fee should be refunded to order owner but not fee pool
d.adjust_balance( _order->seller, deferred_fee );
}
else // need to refund fee in originally paid asset
// refund fee
if( 0 == _order->deferred_paid_fee.amount )
{
// be here, order.create_time <= HARDFORK_CORE_604_TIME, or fee paid in CORE, or no fee to refund.
// if order was created before hard fork 604 then cancelled no matter before or after hard fork 604,
// see it as fee paid in CORE, deferred_fee should be refunded to order owner but not fee pool
d.adjust_balance( _order->seller, deferred_fee );
}
else // need to refund fee in originally paid asset
{
d.adjust_balance( _order->seller, deferred_paid_fee );
// be here, must have: fee_asset != CORE
if( !fee_asset_dyn_data )
fee_asset_dyn_data = &deferred_paid_fee.asset_id(d).dynamic_asset_data_id(d);
d.modify( *fee_asset_dyn_data, [&deferred_fee](asset_dynamic_data_object& addo) {
addo.fee_pool += deferred_fee;
});
}

}

void_result limit_order_update_evaluator::do_apply(const limit_order_update_operation& o)
{
database& d = db();

// Adjust account balance
if( o.delta_amount_to_sell )
{
d.adjust_balance( o.seller, -*o.delta_amount_to_sell );
if( o.delta_amount_to_sell->asset_id == asset_id_type() )
{
d.adjust_balance( _order->seller, deferred_paid_fee );
// be here, must have: fee_asset != CORE
if( !fee_asset_dyn_data )
fee_asset_dyn_data = &deferred_paid_fee.asset_id(d).dynamic_asset_data_id(d);
d.modify( *fee_asset_dyn_data, [&deferred_fee](asset_dynamic_data_object& addo) {
addo.fee_pool += deferred_fee;
_seller_acc_stats = &d.get_account_stats_by_owner( o.seller );
d.modify( *_seller_acc_stats, [&o]( account_statistics_object& bal ) {
bal.total_core_in_orders += o.delta_amount_to_sell->amount;
});
}

}

// Process deferred fee in the order.
process_deferred_fee();

// Update order
d.modify(*_order, [&o,this](limit_order_object& loo) {
if (o.new_price)
Expand Down

0 comments on commit 0ab1d1f

Please sign in to comment.