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

Add operation to update liquidity pools #2720

Merged
merged 4 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ void database::initialize_evaluators()
register_evaluator<ticket_update_evaluator>();
register_evaluator<liquidity_pool_create_evaluator>();
register_evaluator<liquidity_pool_delete_evaluator>();
register_evaluator<liquidity_pool_update_evaluator>();
register_evaluator<liquidity_pool_deposit_evaluator>();
register_evaluator<liquidity_pool_withdraw_evaluator>();
register_evaluator<liquidity_pool_exchange_evaluator>();
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/db_notify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ struct get_impacted_account_visitor
{
_impacted.insert( op.fee_payer() ); // account
}
void operator()( const liquidity_pool_update_operation& op )
{
_impacted.insert( op.fee_payer() ); // account
}
void operator()( const liquidity_pool_deposit_operation& op )
{
_impacted.insert( op.fee_payer() ); // account
Expand Down
6 changes: 6 additions & 0 deletions libraries/chain/hardfork.d/CORE_2604.hf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// bitshares-core issue #2604 Allow updating liquidity pool fee rates with certain restrictions
#ifndef HARDFORK_CORE_2604_TIME
// Jan 1 2030, midnight; this is a dummy date until a hardfork date is scheduled
#define HARDFORK_CORE_2604_TIME (fc::time_point_sec( 1893456000 ))
#define HARDFORK_CORE_2604_PASSED(head_block_time) (head_block_time >= HARDFORK_CORE_2604_TIME)
#endif
4 changes: 4 additions & 0 deletions libraries/chain/include/graphene/chain/hardfork_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct hardfork_visitor {
protocol::liquidity_pool_deposit_operation,
protocol::liquidity_pool_withdraw_operation,
protocol::liquidity_pool_exchange_operation >;
using liquidity_pool_update_op = fc::typelist::list< protocol::liquidity_pool_update_operation >;
using samet_fund_ops = fc::typelist::list< protocol::samet_fund_create_operation,
protocol::samet_fund_delete_operation,
protocol::samet_fund_update_operation,
Expand Down Expand Up @@ -90,6 +91,9 @@ struct hardfork_visitor {
template<typename Op>
std::enable_if_t<fc::typelist::contains<credit_offer_ops, Op>(), bool>
visit() { return HARDFORK_CORE_2362_PASSED(now); }
template<typename Op>
std::enable_if_t<fc::typelist::contains<liquidity_pool_update_op, Op>(), bool>
visit() { return HARDFORK_CORE_2604_PASSED(now); }
/// @}

/// typelist::runtime::dispatch adaptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ namespace graphene { namespace chain {
const asset_object* _share_asset = nullptr;
};

class liquidity_pool_update_evaluator : public evaluator<liquidity_pool_update_evaluator>
{
public:
using operation_type = liquidity_pool_update_operation;

void_result do_evaluate( const liquidity_pool_update_operation& op );
void_result do_apply( const liquidity_pool_update_operation& op ) const;

const liquidity_pool_object* _pool = nullptr;
};

class liquidity_pool_deposit_evaluator : public evaluator<liquidity_pool_deposit_evaluator>
{
public:
Expand Down
38 changes: 38 additions & 0 deletions libraries/chain/liquidity_pool_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,44 @@ generic_operation_result liquidity_pool_delete_evaluator::do_apply(const liquidi
return result;
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result liquidity_pool_update_evaluator::do_evaluate(const liquidity_pool_update_operation& op)
{ try {
const database& d = db();
const auto block_time = d.head_block_time();

FC_ASSERT( HARDFORK_CORE_2604_PASSED(block_time), "Not allowed until the core-2604 hardfork" );

_pool = &op.pool(d);

const asset_object* _share_asset = &_pool->share_asset(d);

FC_ASSERT( _share_asset->issuer == op.account, "The account is not the owner of the liquidity pool" );

if( op.taker_fee_percent.valid() )
{
FC_ASSERT( 0 == _pool->withdrawal_fee_percent
|| ( op.withdrawal_fee_percent.valid() && 0 == *op.withdrawal_fee_percent ),
"Taker fee percent can only be updated if withdrawal fee percent is zero or "
"withdrawal fee percent is to be updated to zero at the same time" );
}

return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result liquidity_pool_update_evaluator::do_apply(const liquidity_pool_update_operation& op) const
{ try {
database& d = db();

d.modify( *_pool, [&op](liquidity_pool_object& obj) {
if( op.taker_fee_percent.valid() )
obj.taker_fee_percent = *op.taker_fee_percent;
if( op.withdrawal_fee_percent.valid() )
obj.withdrawal_fee_percent = *op.withdrawal_fee_percent;
});

return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

void_result liquidity_pool_deposit_evaluator::do_evaluate(const liquidity_pool_deposit_operation& op)
{ try {
const database& d = db();
Expand Down
7 changes: 7 additions & 0 deletions libraries/chain/proposal_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ struct proposal_operation_hardfork_visitor
FC_ASSERT(!op.new_parameters.current_fees->exists<credit_deal_expired_operation>(),
"Unable to define fees for credit offer operations prior to the core-2362 hardfork");
}
if (!HARDFORK_CORE_2604_PASSED(block_time)) {
FC_ASSERT(!op.new_parameters.current_fees->exists<liquidity_pool_update_operation>(),
"Unable to define fees for liquidity pool update operation prior to the core-2604 hardfork");
}
}
void operator()(const graphene::chain::htlc_create_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_CORE_1468_TIME, "Not allowed until hardfork 1468" );
Expand Down Expand Up @@ -246,6 +250,9 @@ struct proposal_operation_hardfork_visitor
void operator()(const graphene::chain::liquidity_pool_delete_operation&) const {
FC_ASSERT( HARDFORK_LIQUIDITY_POOL_PASSED(block_time), "Not allowed until the LP hardfork" );
}
void operator()(const graphene::chain::liquidity_pool_update_operation&) const {
FC_ASSERT( HARDFORK_CORE_2604_PASSED(block_time), "Not allowed until the core-2604 hardfork" );
}
void operator()(const graphene::chain::liquidity_pool_deposit_operation&) const {
FC_ASSERT( HARDFORK_LIQUIDITY_POOL_PASSED(block_time), "Not allowed until the LP hardfork" );
}
Expand Down
5 changes: 5 additions & 0 deletions libraries/plugins/market_history/market_history_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,11 @@ struct get_liquidity_pool_id_visitor
return o.pool;
}

result_type operator()( const liquidity_pool_update_operation& o )const
{
return o.pool;
}

result_type operator()( const liquidity_pool_deposit_operation& o )const
{
return o.pool;
Expand Down
25 changes: 25 additions & 0 deletions libraries/protocol/include/graphene/protocol/liquidity_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ namespace graphene { namespace protocol {
void validate()const;
};

/**
* @brief Update a liquidity pool
* @ingroup operations
*/
struct liquidity_pool_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 1 * GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee; ///< Operation fee
account_id_type account; ///< The account who owns the liquidity pool
liquidity_pool_id_type pool; ///< ID of the liquidity pool
optional<uint16_t> taker_fee_percent; ///< Taker fee percent
optional<uint16_t> withdrawal_fee_percent; ///< Withdrawal fee percent

extensions_type extensions; ///< Unused. Reserved for future use.

account_id_type fee_payer()const { return account; }
void validate()const;
};

/**
* @brief Deposit to a liquidity pool
* @ingroup operations
Expand Down Expand Up @@ -135,6 +155,7 @@ namespace graphene { namespace protocol {

FC_REFLECT( graphene::protocol::liquidity_pool_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::protocol::liquidity_pool_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::protocol::liquidity_pool_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::protocol::liquidity_pool_deposit_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::protocol::liquidity_pool_withdraw_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::protocol::liquidity_pool_exchange_operation::fee_parameters_type, (fee) )
Expand All @@ -144,6 +165,8 @@ FC_REFLECT( graphene::protocol::liquidity_pool_create_operation,
(taker_fee_percent)(withdrawal_fee_percent)(extensions) )
FC_REFLECT( graphene::protocol::liquidity_pool_delete_operation,
(fee)(account)(pool)(extensions) )
FC_REFLECT( graphene::protocol::liquidity_pool_update_operation,
(fee)(account)(pool)(taker_fee_percent)(withdrawal_fee_percent)(extensions) )
FC_REFLECT( graphene::protocol::liquidity_pool_deposit_operation,
(fee)(account)(pool)(amount_a)(amount_b)(extensions) )
FC_REFLECT( graphene::protocol::liquidity_pool_withdraw_operation,
Expand All @@ -153,12 +176,14 @@ FC_REFLECT( graphene::protocol::liquidity_pool_exchange_operation,

GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_create_operation::fee_parameters_type )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_delete_operation::fee_parameters_type )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_update_operation::fee_parameters_type )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_deposit_operation::fee_parameters_type )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_withdraw_operation::fee_parameters_type )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_exchange_operation::fee_parameters_type )

GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_create_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_delete_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_update_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_deposit_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_withdraw_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_exchange_operation )
3 changes: 2 additions & 1 deletion libraries/protocol/include/graphene/protocol/operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ namespace graphene { namespace protocol {
/* 71 */ credit_offer_update_operation,
/* 72 */ credit_offer_accept_operation,
/* 73 */ credit_deal_repay_operation,
/* 74 */ credit_deal_expired_operation // VIRTUAL
/* 74 */ credit_deal_expired_operation, // VIRTUAL
/* 75 */ liquidity_pool_update_operation
>;

/// @} // operations group
Expand Down
12 changes: 12 additions & 0 deletions libraries/protocol/liquidity_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ void liquidity_pool_delete_operation::validate()const
FC_ASSERT( fee.amount >= 0, "Fee should not be negative" );
}

void liquidity_pool_update_operation::validate()const
{
FC_ASSERT( fee.amount >= 0, "Fee should not be negative" );
FC_ASSERT( taker_fee_percent.valid() || withdrawal_fee_percent.valid(), "Should update something" );
if( taker_fee_percent.valid() )
FC_ASSERT( *taker_fee_percent <= GRAPHENE_100_PERCENT, "Taker fee percent should not exceed 100%" );
if( withdrawal_fee_percent.valid() )
FC_ASSERT( 0 == *withdrawal_fee_percent, "Withdrawal fee percent can only be updated to zero" );
}

void liquidity_pool_deposit_operation::validate()const
{
FC_ASSERT( fee.amount >= 0, "Fee should not be negative" );
Expand Down Expand Up @@ -69,12 +79,14 @@ void liquidity_pool_exchange_operation::validate()const

GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_create_operation::fee_parameters_type )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_delete_operation::fee_parameters_type )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_update_operation::fee_parameters_type )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_deposit_operation::fee_parameters_type )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_withdraw_operation::fee_parameters_type )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_exchange_operation::fee_parameters_type )

GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_create_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_delete_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_update_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_deposit_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_withdraw_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::liquidity_pool_exchange_operation )
29 changes: 29 additions & 0 deletions tests/common/database_fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,35 @@ generic_operation_result database_fixture_base::delete_liquidity_pool( account_i
return op_result.get<generic_operation_result>();
}

liquidity_pool_update_operation database_fixture_base::make_liquidity_pool_update_op( account_id_type account,
liquidity_pool_id_type pool,
optional<uint16_t> taker_fee_percent,
optional<uint16_t> withdrawal_fee_percent )const
{
liquidity_pool_update_operation op;
op.account = account;
op.pool = pool;
op.taker_fee_percent = taker_fee_percent;
op.withdrawal_fee_percent = withdrawal_fee_percent;
return op;
}

void database_fixture_base::update_liquidity_pool( account_id_type account,
liquidity_pool_id_type pool,
optional<uint16_t> taker_fee_percent,
optional<uint16_t> withdrawal_fee_percent )
{
liquidity_pool_update_operation op = make_liquidity_pool_update_op( account, pool, taker_fee_percent,
withdrawal_fee_percent );
trx.operations.clear();
trx.operations.push_back( op );

for( auto& o : trx.operations ) db.current_fee_schedule().set_fee(o);
trx.validate();
set_expiration( db, trx );
PUSH_TX(db, trx, ~0);
}

liquidity_pool_deposit_operation database_fixture_base::make_liquidity_pool_deposit_op( account_id_type account,
liquidity_pool_id_type pool, const asset& amount_a,
const asset& amount_b )const
Expand Down
7 changes: 7 additions & 0 deletions tests/common/database_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,13 @@ struct database_fixture_base {
liquidity_pool_delete_operation make_liquidity_pool_delete_op( account_id_type account,
liquidity_pool_id_type pool )const;
generic_operation_result delete_liquidity_pool( account_id_type account, liquidity_pool_id_type pool );
liquidity_pool_update_operation make_liquidity_pool_update_op( account_id_type account,
liquidity_pool_id_type pool,
optional<uint16_t> taker_fee_percent,
optional<uint16_t> withdrawal_fee_percent )const;
void update_liquidity_pool( account_id_type account, liquidity_pool_id_type pool,
optional<uint16_t> taker_fee_percent,
optional<uint16_t> withdrawal_fee_percent );
liquidity_pool_deposit_operation make_liquidity_pool_deposit_op( account_id_type account,
liquidity_pool_id_type pool, const asset& amount_a,
const asset& amount_b )const;
Expand Down
Loading