Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distribute Asset Market Fees to Referral Program #1419

Merged
merged 17 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
vector<balance_object> get_balance_objects( const vector<address>& addrs )const;
vector<asset> get_vested_balances( const vector<balance_id_type>& objs )const;
vector<vesting_balance_object> get_vesting_balances( const std::string account_id_or_name )const;
vector<vesting_balance_object> get_mfs_vesting_balances( const std::string account_id_or_name )const;

// Assets
vector<optional<asset_object>> get_assets(const vector<asset_id_type>& asset_ids)const;
Expand Down Expand Up @@ -1026,6 +1027,11 @@ vector<vesting_balance_object> database_api::get_vesting_balances( const std::st
return my->get_vesting_balances( account_id_or_name );
}

vector<vesting_balance_object> database_api::get_mfs_vesting_balances( const std::string account_id_or_name )const
{
return my->get_mfs_vesting_balances( account_id_or_name );
}

vector<vesting_balance_object> database_api_impl::get_vesting_balances( const std::string account_id_or_name )const
{
try
Expand All @@ -1042,6 +1048,27 @@ vector<vesting_balance_object> database_api_impl::get_vesting_balances( const st
FC_CAPTURE_AND_RETHROW( (account_id_or_name) );
}

vector<vesting_balance_object> database_api_impl::get_mfs_vesting_balances( const std::string account_id_or_name )const
{
try
{
const account_id_type account_id = get_account_from_string(account_id_or_name)->id;
vector<vesting_balance_object> result;

auto& vesting_balances = _db.get_index_type<vesting_balance_index>().indices().get<by_vesting_type>();
auto key = boost::make_tuple(account_id, vesting_balance_type::market_fee_sharing);
auto mfs_vesting_range = vesting_balances.equal_range(key);

std::for_each(mfs_vesting_range.first, mfs_vesting_range.second,
[&result](const vesting_balance_object& balance) {
result.emplace_back(balance);
});

return result;
}
FC_CAPTURE_AND_RETHROW( (account_id_or_name) );
}

//////////////////////////////////////////////////////////////////////
// //
// Assets //
Expand Down
3 changes: 3 additions & 0 deletions libraries/app/include/graphene/app/database_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ class database_api

vector<vesting_balance_object> get_vesting_balances( const std::string account_id_or_name )const;

vector<vesting_balance_object> get_mfs_vesting_balances( const std::string account_id_or_name )const;

/**
* @brief Get the total number of accounts registered with the blockchain
*/
Expand Down Expand Up @@ -784,6 +786,7 @@ FC_API(graphene::app::database_api,
(get_balance_objects)
(get_vested_balances)
(get_vesting_balances)
(get_mfs_vesting_balances)

// Assets
(get_assets)
Expand Down
12 changes: 12 additions & 0 deletions libraries/chain/asset_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
FC_ASSERT( op.common_options.whitelist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );
FC_ASSERT( op.common_options.blacklist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );

if( d.head_block_time() < HARDFORK_1268_TIME )
{
FC_ASSERT(!op.common_options.additional_options.value.null_ext.valid());
FC_ASSERT(!op.common_options.additional_options.value.reward_percent.valid());
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
}

// Check that all authorities do exist
for( auto id : op.common_options.whitelist_authorities )
d.get_object(id);
Expand Down Expand Up @@ -277,6 +283,12 @@ void_result asset_update_evaluator::do_evaluate(const asset_update_operation& o)
validate_new_issuer( d, a, *o.new_issuer );
}

if ( o.new_options.additional_options.value.reward_percent.valid() )
{
FC_ASSERT( d.head_block_time() >= HARDFORK_1268_TIME,
"Referrer percent is only available after HARDFORK_1268_TIME!");
}

if( (d.head_block_time() < HARDFORK_572_TIME) || (a.dynamic_asset_data_id(d).current_supply != 0) )
{
// new issuer_permissions must be subset of old issuer permissions
Expand Down
35 changes: 35 additions & 0 deletions libraries/chain/db_balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <boost/range/algorithm.hpp>

namespace graphene { namespace chain {

Expand Down Expand Up @@ -80,6 +81,40 @@ void database::adjust_balance(account_id_type account, asset delta )

} FC_CAPTURE_AND_RETHROW( (account)(delta) ) }

void database::deposit_market_fee_vesting_balance(const account_id_type &account_id, const asset &delta)
{ try {
FC_ASSERT( delta.amount > 0, "Invalid negative value for balance");
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved

if( delta.amount == 0 )
return;

auto& vesting_balances = get_index_type<vesting_balance_index>().indices().get<by_vesting_type>();
auto market_vesting_balances = vesting_balances.equal_range(boost::make_tuple(account_id, vesting_balance_type::market_fee_sharing));
auto market_balance = boost::range::find_if(market_vesting_balances,
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
[&delta](const vesting_balance_object& vbo) { return vbo.balance.asset_id == delta.asset_id;}
);

if(market_balance == boost::end(market_vesting_balances) )
{
create<vesting_balance_object>([&](vesting_balance_object &vbo) {
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
vbo.owner = account_id;
vbo.balance = delta;
vbo.balance_type = vesting_balance_type::market_fee_sharing;
cdd_vesting_policy policy;
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
policy.vesting_seconds = { 0 };
policy.coin_seconds_earned = vbo.balance.amount.value;
policy.coin_seconds_earned_last_update = head_block_time();
vbo.policy = policy;
});
} else {
modify( *market_balance, [&]( vesting_balance_object& vbo )
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
{
vbo.deposit_vested(head_block_time(), delta);
});
}

} FC_CAPTURE_AND_RETHROW( (account_id)(delta) ) }

optional< vesting_balance_id_type > database::deposit_lazy_vesting(
const optional< vesting_balance_id_type >& ovbid,
share_type amount, uint32_t req_vesting_seconds,
Expand Down
74 changes: 68 additions & 6 deletions libraries/chain/db_market.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@

#include <fc/uint128.hpp>

namespace graphene { namespace chain {
namespace graphene { namespace chain { namespace detail {

fc::uint128 calculate_percent(const share_type& value, uint16_t percent)
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
{
fc::uint128 a(value.value);
a *= percent;
a /= GRAPHENE_100_PERCENT;
return a;
}

} //detail

/**
* All margin positions are force closed at the swan price
Expand Down Expand Up @@ -775,7 +785,12 @@ bool database::fill_limit_order( const limit_order_object& order, const asset& p
const account_object& seller = order.seller(*this);
const asset_object& recv_asset = receives.asset_id(*this);

auto issuer_fees = pay_market_fees( recv_asset, receives );
//auto issuer_fees = pay_market_fees( recv_asset, receives );
//auto issuer_fees = pay_market_fees(seller, recv_asset, receives);
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
auto issuer_fees = ( head_block_time() < HARDFORK_1268_TIME ) ?
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
pay_market_fees(recv_asset, receives) :
pay_market_fees(seller, recv_asset, receives);

pay_order( seller, receives - issuer_fees, pays );

assert( pays.asset_id != receives.asset_id );
Expand Down Expand Up @@ -1109,10 +1124,8 @@ asset database::calculate_market_fee( const asset_object& trade_asset, const ass
if( trade_asset.options.market_fee_percent == 0 )
return trade_asset.amount(0);

fc::uint128 a(trade_amount.amount.value);
a *= trade_asset.options.market_fee_percent;
a /= GRAPHENE_100_PERCENT;
asset percent_fee = trade_asset.amount(a.to_uint64());
auto value = detail::calculate_percent(trade_amount.amount, trade_asset.options.market_fee_percent);
asset percent_fee = trade_asset.amount(value.to_uint64());

if( percent_fee.amount > trade_asset.options.max_market_fee )
percent_fee.amount = trade_asset.options.max_market_fee;
Expand All @@ -1138,4 +1151,53 @@ asset database::pay_market_fees( const asset_object& recv_asset, const asset& re
return issuer_fees;
}

asset database::pay_market_fees(const account_object& seller, const asset_object& recv_asset, const asset& receives )
{
FC_ASSERT( head_block_time() >= HARDFORK_1268_TIME );
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved

const auto issuer_fees = calculate_market_fee( recv_asset, receives );

assert(issuer_fees <= receives );
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved

//Don't dirty undo state if not actually collecting any fees
if( issuer_fees.amount > 0 )
{
// calculate and pay rewards
asset reward = recv_asset.amount(0);

const auto reward_percent = recv_asset.options.additional_options.value.reward_percent;

if ( reward_percent && *reward_percent )
{
const auto reward_value = detail::calculate_percent(issuer_fees.amount, *reward_percent);

if ( reward_value > 0 )
{
reward = recv_asset.amount(reward_value.to_uint64());

assert( reward < issuer_fees );
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
// cut referrer percent from reward
const auto referrer_rewards_percentage = seller.referrer_rewards_percentage;
const auto referrer_rewards_value = detail::calculate_percent(reward.amount, referrer_rewards_percentage);

OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
auto registrar_reward = reward;
if ( referrer_rewards_value > 0 )
{
const asset referrer_reward = recv_asset.amount(referrer_rewards_value.to_uint64());
registrar_reward -= referrer_reward;
deposit_market_fee_vesting_balance(seller.referrer, referrer_reward);
}
deposit_market_fee_vesting_balance(seller.registrar, registrar_reward);
}
}

const auto& recv_dyn_data = recv_asset.dynamic_asset_data_id(*this);
modify( recv_dyn_data, [&]( asset_dynamic_data_object& obj ){
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
obj.accumulated_fees += issuer_fees.amount - reward.amount;
});
}

return issuer_fees;
}

} }
4 changes: 4 additions & 0 deletions libraries/chain/hardfork.d/CORE_1268.hf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// #1268 Distribute Asset Market Fees to Referral Program
#ifndef HARDFORK_1268_TIME
#define HARDFORK_1268_TIME (fc::time_point_sec( 1530705600 )) // Wednesday, July 4, 2018 12:00:00 PM
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
#endif
3 changes: 3 additions & 0 deletions libraries/chain/include/graphene/chain/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ namespace graphene { namespace chain {
*/
void adjust_balance(account_id_type account, asset delta);

void deposit_market_fee_vesting_balance(const account_id_type &account, const asset &delta);

/**
* @brief Helper to make lazy deposit to CDD VBO.
*
Expand Down Expand Up @@ -395,6 +397,7 @@ namespace graphene { namespace chain {

asset calculate_market_fee(const asset_object& recv_asset, const asset& trade_amount);
asset pay_market_fees( const asset_object& recv_asset, const asset& receives );
asset pay_market_fees( const account_object& seller, const asset_object& recv_asset, const asset& receives );


///@{
Expand Down
13 changes: 10 additions & 3 deletions libraries/chain/include/graphene/chain/protocol/asset_ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@

namespace graphene { namespace chain {

struct additional_asset_options
{
fc::optional<void_t> null_ext;
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
fc::optional<uint16_t> reward_percent;
};
typedef extension<additional_asset_options> additional_asset_options_t;

bool is_valid_symbol( const string& symbol );

/**
Expand Down Expand Up @@ -75,7 +82,7 @@ namespace graphene { namespace chain {
* size of description.
*/
string description;
extensions_type extensions;
additional_asset_options_t additional_options;

/// Perform internal consistency checks.
/// @throws fc::exception if any check fails
Expand Down Expand Up @@ -523,7 +530,7 @@ FC_REFLECT( graphene::chain::asset_options,
(whitelist_markets)
(blacklist_markets)
(description)
(extensions)
(additional_options)
)
FC_REFLECT( graphene::chain::bitasset_options,
(feed_lifetime_sec)
Expand All @@ -535,7 +542,7 @@ FC_REFLECT( graphene::chain::bitasset_options,
(extensions)
)


FC_REFLECT( graphene::chain::additional_asset_options, (null_ext)(reward_percent) )
FC_REFLECT( graphene::chain::asset_create_operation::fee_parameters_type, (symbol3)(symbol4)(long_symbol)(price_per_kbyte) )
FC_REFLECT( graphene::chain::asset_global_settle_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::asset_settle_operation::fee_parameters_type, (fee) )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp>

#include <fc/static_variant.hpp>
#include <fc/uint128.hpp>
Expand Down Expand Up @@ -124,6 +125,9 @@ namespace graphene { namespace chain {
cdd_vesting_policy
> vesting_policy;

enum class vesting_balance_type { unspecified,
worker,
market_fee_sharing };
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
/**
* Vesting balance object is a balance that is locked by the blockchain for a period of time.
*/
Expand All @@ -140,6 +144,8 @@ namespace graphene { namespace chain {
asset balance;
/// The vesting policy stores details on when funds vest, and controls when they may be withdrawn
vesting_policy policy;
/// type of the vesting balance
vesting_balance_type balance_type = vesting_balance_type::unspecified;

vesting_balance_object() {}

Expand Down Expand Up @@ -171,12 +177,22 @@ namespace graphene { namespace chain {
* @ingroup object_index
*/
struct by_account;
struct by_vesting_type;
pmconrad marked this conversation as resolved.
Show resolved Hide resolved

typedef multi_index_container<
vesting_balance_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id >
>,
ordered_non_unique< tag<by_account>,
member<vesting_balance_object, account_id_type, &vesting_balance_object::owner>
>,
ordered_non_unique< tag<by_vesting_type>,
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
composite_key<
vesting_balance_object,
member<vesting_balance_object, account_id_type, &vesting_balance_object::owner>,
member<vesting_balance_object, vesting_balance_type, &vesting_balance_object::balance_type>
OpenLedgerApp marked this conversation as resolved.
Show resolved Hide resolved
>
>
>
> vesting_balance_multi_index_type;
Expand Down
8 changes: 8 additions & 0 deletions libraries/wallet/include/graphene/wallet/wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,13 @@ class wallet_api
*/
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name );

/** List account's market fee sharing vesting balances.
* Each account can have multiple market fee sharing vesting balances.
* @param account_name_or_id the name or id of the account whose balances you want
* @returns a list of the given account's market fee sharing vesting balances
*/
vector< vesting_balance_object_with_info > get_mfs_vesting_balances(string account_name_or_id);

/**
* Withdraw a vesting balance.
*
Expand Down Expand Up @@ -1799,6 +1806,7 @@ FC_API( graphene::wallet::wallet_api,
(create_worker)
(update_worker_votes)
(get_vesting_balances)
(get_mfs_vesting_balances)
(withdraw_vesting)
(vote_for_committee_member)
(vote_for_witness)
Expand Down
Loading