BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
liquidity_pool_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Abit More, and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
26 
28 
31 #include <graphene/chain/hardfork.hpp>
33 
35 
36 namespace graphene { namespace chain {
37 
39 { try {
40  const database& d = db();
41  const auto block_time = d.head_block_time();
42 
43  FC_ASSERT( HARDFORK_LIQUIDITY_POOL_PASSED(block_time), "Not allowed until the LP hardfork" );
44 
45  op.asset_a(d); // Make sure it exists
46  op.asset_b(d); // Make sure it exists
47  _share_asset = &op.share_asset(d);
48 
49  FC_ASSERT( _share_asset->issuer == op.account,
50  "Only the asset owner can set an asset as the share asset of a liquidity pool" );
51 
52  FC_ASSERT( !_share_asset->is_market_issued(),
53  "Can not specify a market-issued asset as the share asset of a liquidity pool" );
54 
55  FC_ASSERT( !_share_asset->is_liquidity_pool_share_asset(),
56  "The share asset is already bound to another liquidity pool" );
57 
58  FC_ASSERT( _share_asset->dynamic_data(d).current_supply == 0,
59  "Current supply of the share asset needs to be zero" );
60 
61  return void_result();
62 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
63 
65 { try {
66  database& d = db();
68 
69  const auto& new_liquidity_pool_object = d.create<liquidity_pool_object>([&op](liquidity_pool_object& obj){
70  obj.asset_a = op.asset_a;
71  obj.asset_b = op.asset_b;
72  obj.share_asset = op.share_asset;
73  obj.taker_fee_percent = op.taker_fee_percent;
74  obj.withdrawal_fee_percent = op.withdrawal_fee_percent;
75  });
76  result.new_objects.insert( new_liquidity_pool_object.id );
77 
78  result.updated_objects.insert( _share_asset->id );
79  d.modify( *_share_asset, [&new_liquidity_pool_object](asset_object& ao) {
80  ao.for_liquidity_pool = new_liquidity_pool_object.id;
81  });
82 
83  return result;
84 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
85 
87 { try {
88  const database& d = db();
89 
90  _pool = &op.pool(d);
91 
92  FC_ASSERT( _pool->balance_a == 0 && _pool->balance_b == 0, "Can not delete a non-empty pool" );
93 
94  _share_asset = &_pool->share_asset(d);
95 
96  FC_ASSERT( _share_asset->issuer == op.account, "The account is not the owner of the liquidity pool" );
97 
98  return void_result();
99 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
100 
102 { try {
103  database& d = db();
105 
106  result.updated_objects.insert( _share_asset->id );
107  d.modify( *_share_asset, [](asset_object& ao) {
109  });
110 
111  result.removed_objects.insert( _pool->id );
112  d.remove( *_pool );
113 
114  return result;
115 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
116 
118 { try {
119  const database& d = db();
120  const auto block_time = d.head_block_time();
121 
122  FC_ASSERT( HARDFORK_CORE_2604_PASSED(block_time), "Not allowed until the core-2604 hardfork" );
123 
124  _pool = &op.pool(d);
125 
126  const asset_object* _share_asset = &_pool->share_asset(d);
127 
128  FC_ASSERT( _share_asset->issuer == op.account, "The account is not the owner of the liquidity pool" );
129 
130  if( op.taker_fee_percent.valid() )
131  {
132  FC_ASSERT( 0 == _pool->withdrawal_fee_percent
133  || ( op.withdrawal_fee_percent.valid() && 0 == *op.withdrawal_fee_percent ),
134  "Taker fee percent can only be updated if withdrawal fee percent is zero or "
135  "withdrawal fee percent is to be updated to zero at the same time" );
136  }
137 
138  return void_result();
139 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
140 
142 { try {
143  database& d = db();
144 
145  d.modify( *_pool, [&op](liquidity_pool_object& obj) {
146  if( op.taker_fee_percent.valid() )
148  if( op.withdrawal_fee_percent.valid() )
150  });
151 
152  return void_result();
153 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
154 
156 { try {
157  const database& d = db();
158 
159  _pool = &op.pool(d);
160 
161  FC_ASSERT( op.amount_a.asset_id == _pool->asset_a, "Asset type A mismatch" );
162  FC_ASSERT( op.amount_b.asset_id == _pool->asset_b, "Asset type B mismatch" );
163 
164  FC_ASSERT( (_pool->balance_a == 0) == (_pool->balance_b == 0), "Internal error" );
165 
166  const asset_object& share_asset_obj = _pool->share_asset(d);
167 
168  FC_ASSERT( share_asset_obj.can_create_new_supply(), "Can not create new supply for the share asset" );
169 
170  if( _pool->balance_a == 0 ) // which implies that _pool->balance_b == 0
171  {
172  FC_ASSERT( share_asset_obj.issuer == op.account, "The initial deposit can only be done by the pool owner" );
173  }
174 
175  _share_asset_dyn_data = &share_asset_obj.dynamic_data(d);
176 
177  FC_ASSERT( (_pool->balance_a == 0) == (_share_asset_dyn_data->current_supply == 0), "Internal error" );
178 
179  FC_ASSERT( _share_asset_dyn_data->current_supply < share_asset_obj.options.max_supply,
180  "Can not create new supply for the share asset" );
181 
182  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, share_asset_obj ),
183  "The account is unauthorized by the share asset" );
185  "The account is unauthorized by asset A" );
187  "The account is unauthorized by asset B" );
188 
189  if( _pool->balance_a == 0 )
190  {
191  share_type share_amount = std::max( op.amount_a.amount.value, op.amount_b.amount.value );
192  FC_ASSERT( share_amount <= share_asset_obj.options.max_supply,
193  "For initial deposit, each amount of the two assets in the pool should not be greater than "
194  "the maximum supply of the share asset" );
195  _pool_receives_a = op.amount_a;
196  _pool_receives_b = op.amount_b;
197  _account_receives = asset( share_amount, _pool->share_asset );
198  }
199  else
200  {
201  share_type max_new_supply = share_asset_obj.options.max_supply - _share_asset_dyn_data->current_supply;
202  fc::uint128_t max128( max_new_supply.value );
203  fc::uint128_t supply128( _share_asset_dyn_data->current_supply.value );
204  fc::uint128_t new_supply_if_a = supply128 * op.amount_a.amount.value / _pool->balance_a.value;
205  fc::uint128_t new_supply_if_b = supply128 * op.amount_b.amount.value / _pool->balance_b.value;
206  fc::uint128_t new_supply = std::min( { new_supply_if_a, new_supply_if_b, max128 } );
207 
208  FC_ASSERT( new_supply > 0, "Aborting due to zero outcome" );
209 
210  fc::uint128_t a128 = ( new_supply * _pool->balance_a.value + supply128 - 1 ) / supply128; // round up
211  FC_ASSERT( a128 <= fc::uint128_t( op.amount_a.amount.value ), "Internal error" );
212  _pool_receives_a = asset( static_cast<int64_t>( a128 ), _pool->asset_a );
213 
214  fc::uint128_t b128 = ( new_supply * _pool->balance_b.value + supply128 - 1 ) / supply128; // round up
215  FC_ASSERT( b128 <= fc::uint128_t( op.amount_b.amount.value ), "Internal error" );
216  _pool_receives_b = asset( static_cast<int64_t>( b128 ), _pool->asset_b );
217 
218  _account_receives = asset( static_cast<int64_t>( new_supply ), _pool->share_asset );
219  }
220 
221  return void_result();
222 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
223 
226 { try {
227  database& d = db();
229 
230  d.adjust_balance( op.account, -_pool_receives_a );
231  d.adjust_balance( op.account, -_pool_receives_b );
232  d.adjust_balance( op.account, _account_receives );
233 
234  d.modify( *_pool, [this]( liquidity_pool_object& lpo ){
235  lpo.balance_a += _pool_receives_a.amount;
236  lpo.balance_b += _pool_receives_b.amount;
237  lpo.update_virtual_value();
238  });
239 
240  d.modify( *_share_asset_dyn_data, [this]( asset_dynamic_data_object& data ){
241  data.current_supply += _account_receives.amount;
242  });
243 
244  FC_ASSERT( _pool->balance_a > 0 && _pool->balance_b > 0, "Internal error" );
245  FC_ASSERT( _share_asset_dyn_data->current_supply > 0, "Internal error" );
246 
247  result.paid.emplace_back( _pool_receives_a );
248  result.paid.emplace_back( _pool_receives_b );
249  result.received.emplace_back( _account_receives );
250 
251  return result;
252 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
253 
255 { try {
256  const database& d = db();
257 
258  _pool = &op.pool(d);
259 
260  FC_ASSERT( op.share_amount.asset_id == _pool->share_asset, "Share asset type mismatch" );
261 
262  FC_ASSERT( _pool->balance_a > 0 && _pool->balance_b > 0, "The pool has not been initialized" );
263 
264  const asset_object& share_asset_obj = _pool->share_asset(d);
265 
266  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, share_asset_obj ),
267  "The account is unauthorized by the share asset" );
269  "The account is unauthorized by asset A" );
271  "The account is unauthorized by asset B" );
272 
273  _share_asset_dyn_data = &share_asset_obj.dynamic_data(d);
274 
275  FC_ASSERT( _share_asset_dyn_data->current_supply >= op.share_amount.amount,
276  "Can not withdraw an amount that is more than the current supply" );
277 
278  if( _share_asset_dyn_data->current_supply == op.share_amount.amount )
279  {
280  _pool_pays_a = asset( _pool->balance_a, _pool->asset_a );
281  _pool_pays_b = asset( _pool->balance_b, _pool->asset_b );
282  _fee_a = asset( 0, _pool->asset_a );
283  _fee_b = asset( 0, _pool->asset_b );
284  }
285  else
286  {
287  fc::uint128_t share128( op.share_amount.amount.value );
288  fc::uint128_t a128 = share128 * _pool->balance_a.value / _share_asset_dyn_data->current_supply.value;
289  FC_ASSERT( a128 < fc::uint128_t( _pool->balance_a.value ), "Internal error" );
290  fc::uint128_t fee_a = a128 * _pool->withdrawal_fee_percent / GRAPHENE_100_PERCENT;
291  FC_ASSERT( fee_a <= a128, "Withdrawal fee percent of the pool is too high" );
292  a128 -= fee_a;
293  fc::uint128_t b128 = share128 * _pool->balance_b.value / _share_asset_dyn_data->current_supply.value;
294  FC_ASSERT( b128 < fc::uint128_t( _pool->balance_b.value ), "Internal error" );
295  fc::uint128_t fee_b = b128 * _pool->withdrawal_fee_percent / GRAPHENE_100_PERCENT;
296  FC_ASSERT( fee_b <= b128, "Withdrawal fee percent of the pool is too high" );
297  b128 -= fee_b;
298  FC_ASSERT( a128 > 0 || b128 > 0, "Aborting due to zero outcome" );
299  _pool_pays_a = asset( static_cast<int64_t>( a128 ), _pool->asset_a );
300  _pool_pays_b = asset( static_cast<int64_t>( b128 ), _pool->asset_b );
301  _fee_a = asset( static_cast<int64_t>( fee_a ), _pool->asset_a );
302  _fee_b = asset( static_cast<int64_t>( fee_b ), _pool->asset_b );
303  }
304 
305  return void_result();
306 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
307 
310 { try {
311  database& d = db();
313 
314  d.adjust_balance( op.account, -op.share_amount );
315 
316  if( _pool_pays_a.amount > 0 )
317  d.adjust_balance( op.account, _pool_pays_a );
318  if( _pool_pays_b.amount > 0 )
319  d.adjust_balance( op.account, _pool_pays_b );
320 
321  d.modify( *_share_asset_dyn_data, [&op]( asset_dynamic_data_object& data ){
323  });
324 
325  d.modify( *_pool, [this]( liquidity_pool_object& lpo ){
326  lpo.balance_a -= _pool_pays_a.amount;
327  lpo.balance_b -= _pool_pays_b.amount;
328  lpo.update_virtual_value();
329  });
330 
331  FC_ASSERT( (_pool->balance_a == 0) == (_pool->balance_b == 0), "Internal error" );
332  FC_ASSERT( (_pool->balance_a == 0) == (_share_asset_dyn_data->current_supply == 0), "Internal error" );
333 
334  result.paid.emplace_back( op.share_amount );
335  result.received.emplace_back( _pool_pays_a );
336  result.received.emplace_back( _pool_pays_b );
337  result.fees.emplace_back( _fee_a );
338  result.fees.emplace_back( _fee_b );
339 
340  return result;
341 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
342 
344 { try {
345  const database& d = db();
346 
347  _pool = &op.pool(d);
348 
349  FC_ASSERT( _pool->balance_a > 0 && _pool->balance_b > 0, "The pool has not been initialized" );
350 
351  FC_ASSERT( ( op.amount_to_sell.asset_id == _pool->asset_a && op.min_to_receive.asset_id == _pool->asset_b )
352  || ( op.amount_to_sell.asset_id == _pool->asset_b && op.min_to_receive.asset_id == _pool->asset_a ),
353  "Asset type mismatch" );
354 
355 
356  const asset_object& asset_obj_a = _pool->asset_a(d);
357  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, asset_obj_a ),
358  "The account is unauthorized by asset A" );
359 
360  const asset_object& asset_obj_b = _pool->asset_b(d);
361  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, asset_obj_b ),
362  "The account is unauthorized by asset B" );
363 
364  if( HARDFORK_CORE_2350_PASSED( d.head_block_time() ) )
365  {
366  if( !asset_obj_a.options.whitelist_markets.empty() )
367  {
368  FC_ASSERT( asset_obj_a.options.whitelist_markets.find(_pool->asset_b)
369  != asset_obj_a.options.whitelist_markets.end(),
370  "The ${a}:${b} market has not been whitelisted by asset ${a}",
371  ("a", asset_obj_a.symbol) ("b", asset_obj_b.symbol) );
372  }
373  if( !asset_obj_a.options.blacklist_markets.empty() )
374  {
375  FC_ASSERT( asset_obj_a.options.blacklist_markets.find(_pool->asset_b)
376  == asset_obj_a.options.blacklist_markets.end(),
377  "The ${a}:${b} market has been blacklisted by asset ${a}",
378  ("a", asset_obj_a.symbol) ("b", asset_obj_b.symbol) );
379  }
380  if( !asset_obj_b.options.whitelist_markets.empty() )
381  {
382  FC_ASSERT( asset_obj_b.options.whitelist_markets.find(_pool->asset_a)
383  != asset_obj_b.options.whitelist_markets.end(),
384  "The ${a}:${b} market has not been whitelisted by asset ${b}",
385  ("a", asset_obj_a.symbol) ("b", asset_obj_b.symbol) );
386  }
387  if( !asset_obj_b.options.blacklist_markets.empty() )
388  {
389  FC_ASSERT( asset_obj_b.options.blacklist_markets.find(_pool->asset_a)
390  == asset_obj_b.options.blacklist_markets.end(),
391  "The ${a}:${b} market has been blacklisted by asset ${b}",
392  ("a", asset_obj_a.symbol) ("b", asset_obj_b.symbol) );
393  }
394  }
395 
396  _pool_receives_asset = ( op.amount_to_sell.asset_id == _pool->asset_a ? &asset_obj_a : &asset_obj_b );
397 
398  _maker_market_fee = d.calculate_market_fee( *_pool_receives_asset, op.amount_to_sell, true );
399  FC_ASSERT( _maker_market_fee < op.amount_to_sell,
400  "Aborting since the maker market fee of the selling asset is too high" );
401  _pool_receives = op.amount_to_sell - _maker_market_fee;
402 
403  fc::uint128_t delta;
404  if( op.amount_to_sell.asset_id == _pool->asset_a )
405  {
406  share_type new_balance_a = _pool->balance_a + _pool_receives.amount;
407  // round up
408  fc::uint128_t new_balance_b = ( _pool->virtual_value + new_balance_a.value - 1 ) / new_balance_a.value;
409  FC_ASSERT( new_balance_b <= _pool->balance_b, "Internal error" );
410  delta = fc::uint128_t( _pool->balance_b.value ) - new_balance_b;
411  _pool_pays_asset = &asset_obj_b;
412  }
413  else
414  {
415  share_type new_balance_b = _pool->balance_b + _pool_receives.amount;
416  // round up
417  fc::uint128_t new_balance_a = ( _pool->virtual_value + new_balance_b.value - 1 ) / new_balance_b.value;
418  FC_ASSERT( new_balance_a <= _pool->balance_a, "Internal error" );
419  delta = fc::uint128_t( _pool->balance_a.value ) - new_balance_a;
420  _pool_pays_asset = &asset_obj_a;
421  }
422 
423  fc::uint128_t pool_taker_fee = delta * _pool->taker_fee_percent / GRAPHENE_100_PERCENT;
424  FC_ASSERT( pool_taker_fee <= delta, "Taker fee percent of the pool is too high" );
425 
426  _pool_pays = asset( static_cast<int64_t>( delta - pool_taker_fee ), op.min_to_receive.asset_id );
427 
428  _taker_market_fee = d.calculate_market_fee( *_pool_pays_asset, _pool_pays, false );
429  FC_ASSERT( _taker_market_fee <= _pool_pays, "Market fee should not be greater than the amount to receive" );
430  _account_receives = _pool_pays - _taker_market_fee;
431 
432  GRAPHENE_ASSERT( _account_receives.amount >= op.min_to_receive.amount,
433  liquidity_pool_exchange_unfillable_price,
434  "Unable to exchange at expected price" );
435 
436  _pool_taker_fee = asset( static_cast<int64_t>( pool_taker_fee ), op.min_to_receive.asset_id );
437 
438  return void_result();
439 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
440 
443 { try {
444  database& d = db();
446 
448  d.adjust_balance( op.account, _account_receives );
449 
450  // For _pool_receives_asset, if market fee sharing is enabled,
451  // the share asset owner's registrar and referrer will get the shared maker market fee.
452  // For _pool_pays_asset, if market fee sharing is enabled,
453  // the trader's registrar and referrer will get the shared taker market fee.
454  d.pay_market_fees( &_pool->share_asset(d).issuer(d), *_pool_receives_asset, op.amount_to_sell, true,
455  _maker_market_fee );
456  d.pay_market_fees( fee_paying_account, *_pool_pays_asset, _pool_pays, false, _taker_market_fee );
457 
458  const auto old_virtual_value = _pool->virtual_value;
459  if( op.amount_to_sell.asset_id == _pool->asset_a )
460  {
461  d.modify( *_pool, [this]( liquidity_pool_object& lpo ){
462  lpo.balance_a += _pool_receives.amount;
463  lpo.balance_b -= _pool_pays.amount;
464  lpo.update_virtual_value();
465  });
466  }
467  else
468  {
469  d.modify( *_pool, [this]( liquidity_pool_object& lpo ){
470  lpo.balance_b += _pool_receives.amount;
471  lpo.balance_a -= _pool_pays.amount;
472  lpo.update_virtual_value();
473  });
474  }
475 
476  FC_ASSERT( _pool->balance_a > 0 && _pool->balance_b > 0, "Internal error" );
477  FC_ASSERT( _pool->virtual_value >= old_virtual_value, "Internal error" );
478 
479  result.paid.emplace_back( op.amount_to_sell );
480  result.received.emplace_back( _account_receives );
481  result.fees.emplace_back( _maker_market_fee );
482  result.fees.emplace_back( _taker_market_fee );
483  result.fees.emplace_back( _pool_taker_fee );
484 
485  return result;
486 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
487 
488 } } // graphene::chain
fc::optional::reset
void reset()
Definition: optional.hpp:224
graphene::chain::liquidity_pool_withdraw_evaluator::do_apply
generic_exchange_operation_result do_apply(const liquidity_pool_withdraw_operation &op)
Definition: liquidity_pool_evaluator.cpp:308
graphene::chain::liquidity_pool_create_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_create_operation &op)
Definition: liquidity_pool_evaluator.cpp:38
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
liquidity_pool_object.hpp
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::chain::liquidity_pool_exchange_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_exchange_operation &op)
Definition: liquidity_pool_evaluator.cpp:343
is_authorized_asset.hpp
graphene::protocol::liquidity_pool_exchange_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:144
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::chain::liquidity_pool_object::share_asset
asset_id_type share_asset
Type of the share asset aka the LP token.
Definition: liquidity_pool_object.hpp:51
graphene::chain::asset_object::for_liquidity_pool
optional< liquidity_pool_id_type > for_liquidity_pool
The ID of the liquidity pool if the asset is the share asset of a liquidity pool.
Definition: asset_object.hpp:147
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::protocol::liquidity_pool_withdraw_operation::account
account_id_type account
The account who withdraws from the liquidity pool.
Definition: liquidity_pool.hpp:119
graphene::chain::liquidity_pool_object::asset_a
asset_id_type asset_a
Type of the first asset in the pool.
Definition: liquidity_pool_object.hpp:47
asset_object.hpp
database.hpp
graphene::protocol::liquidity_pool_create_operation::asset_a
asset_id_type asset_a
Type of the first asset in the pool.
Definition: liquidity_pool.hpp:40
graphene::protocol::liquidity_pool_deposit_operation::amount_b
asset amount_b
The amount of the second asset to deposit.
Definition: liquidity_pool.hpp:102
graphene::protocol::liquidity_pool_exchange_operation
Exchange with a liquidity pool.
Definition: liquidity_pool.hpp:138
graphene::chain::liquidity_pool_object::asset_b
asset_id_type asset_b
Type of the second asset in the pool.
Definition: liquidity_pool_object.hpp:48
graphene::chain::database::pay_market_fees
asset pay_market_fees(const account_object *seller, const asset_object &recv_asset, const asset &receives, const bool &is_maker, const optional< asset > &calculated_market_fees={})
Definition: db_market.cpp:2592
graphene::chain::asset_dynamic_data_object::current_supply
share_type current_supply
The number of shares currently in existence.
Definition: asset_object.hpp:61
graphene::chain::asset_object::is_liquidity_pool_share_asset
bool is_liquidity_pool_share_asset() const
Definition: asset_object.hpp:86
graphene::protocol::asset_options::whitelist_markets
flat_set< asset_id_type > whitelist_markets
Definition: asset_ops.hpp:84
graphene::chain::asset_object
tracks the parameters of an asset
Definition: asset_object.hpp:75
graphene::chain::liquidity_pool_update_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_update_operation &op)
Definition: liquidity_pool_evaluator.cpp:117
graphene::db::object_database::create
const T & create(F &&constructor)
Definition: object_database.hpp:63
graphene::chain::database::adjust_balance
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account's balance in a given asset by a delta.
Definition: db_balance.cpp:54
graphene::protocol::liquidity_pool_create_operation::asset_b
asset_id_type asset_b
Type of the second asset in the pool.
Definition: liquidity_pool.hpp:41
graphene::chain::asset_object::symbol
string symbol
Ticker symbol for this asset, i.e. "USD".
Definition: asset_object.hpp:131
graphene::protocol::liquidity_pool_create_operation
Create a new liquidity pool.
Definition: liquidity_pool.hpp:34
graphene::protocol::asset_options::blacklist_markets
flat_set< asset_id_type > blacklist_markets
Definition: asset_ops.hpp:86
graphene::chain::liquidity_pool_create_evaluator::do_apply
generic_operation_result do_apply(const liquidity_pool_create_operation &op)
Definition: liquidity_pool_evaluator.cpp:64
graphene::protocol::liquidity_pool_update_operation::withdrawal_fee_percent
optional< uint16_t > withdrawal_fee_percent
Withdrawal fee percent.
Definition: liquidity_pool.hpp:82
graphene::protocol::liquidity_pool_delete_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:62
graphene::protocol::liquidity_pool_deposit_operation::account
account_id_type account
The account who deposits to the liquidity pool.
Definition: liquidity_pool.hpp:99
graphene::chain::liquidity_pool_delete_evaluator::do_apply
generic_operation_result do_apply(const liquidity_pool_delete_operation &op) const
Definition: liquidity_pool_evaluator.cpp:101
graphene::chain::liquidity_pool_object::balance_a
share_type balance_a
The balance of the first asset in the pool.
Definition: liquidity_pool_object.hpp:49
graphene::protocol::liquidity_pool_create_operation::withdrawal_fee_percent
uint16_t withdrawal_fee_percent
Withdrawal fee percent.
Definition: liquidity_pool.hpp:44
graphene::protocol::liquidity_pool_withdraw_operation
Withdraw from a liquidity pool.
Definition: liquidity_pool.hpp:114
graphene::protocol::liquidity_pool_withdraw_operation::share_amount
asset share_amount
The amount of the share asset to use.
Definition: liquidity_pool.hpp:121
graphene::protocol::asset_options::max_supply
share_type max_supply
Definition: asset_ops.hpp:50
graphene::chain::liquidity_pool_update_evaluator::do_apply
void_result do_apply(const liquidity_pool_update_operation &op) const
Definition: liquidity_pool_evaluator.cpp:141
fc::optional::valid
bool valid() const
Definition: optional.hpp:186
graphene::chain::asset_dynamic_data_object
tracks the asset information that changes frequently
Definition: asset_object.hpp:56
graphene::chain::liquidity_pool_object::taker_fee_percent
uint16_t taker_fee_percent
Taker fee percent.
Definition: liquidity_pool_object.hpp:52
liquidity_pool.hpp
graphene::chain::liquidity_pool_object::balance_b
share_type balance_b
The balance of the second asset in the pool.
Definition: liquidity_pool_object.hpp:50
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::protocol::generic_exchange_operation_result
Definition: base.hpp:95
graphene::chain::liquidity_pool_delete_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_delete_operation &op)
Definition: liquidity_pool_evaluator.cpp:86
graphene::chain::asset_object::can_create_new_supply
bool can_create_new_supply() const
Definition: asset_object.hpp:101
graphene::protocol::liquidity_pool_deposit_operation
Deposit to a liquidity pool.
Definition: liquidity_pool.hpp:94
graphene::chain::liquidity_pool_object::withdrawal_fee_percent
uint16_t withdrawal_fee_percent
Withdrawal fee percent.
Definition: liquidity_pool_object.hpp:53
graphene::chain::liquidity_pool_withdraw_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_withdraw_operation &op)
Definition: liquidity_pool_evaluator.cpp:254
graphene::chain::is_authorized_asset
bool is_authorized_asset(const database &d, const account_object &acct, const asset_object &asset_obj)
Definition: is_authorized_asset.hpp:43
graphene::protocol::liquidity_pool_withdraw_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:120
graphene::chain::liquidity_pool_object::update_virtual_value
void update_virtual_value()
Definition: liquidity_pool_object.hpp:56
graphene::protocol::generic_exchange_operation_result::received
vector< asset > received
Definition: base.hpp:98
graphene::chain::liquidity_pool_object::virtual_value
fc::uint128_t virtual_value
Virtual value of the pool.
Definition: liquidity_pool_object.hpp:54
graphene::protocol::liquidity_pool_exchange_operation::min_to_receive
asset min_to_receive
The minimum amount of the other asset type to receive.
Definition: liquidity_pool.hpp:146
graphene::protocol::generic_operation_result::updated_objects
flat_set< object_id_type > updated_objects
Definition: base.hpp:91
graphene::protocol::liquidity_pool_exchange_operation::amount_to_sell
asset amount_to_sell
The amount of one asset type to sell.
Definition: liquidity_pool.hpp:145
graphene::protocol::liquidity_pool_delete_operation::account
account_id_type account
The account who owns the liquidity pool.
Definition: liquidity_pool.hpp:61
graphene::protocol::liquidity_pool_update_operation::taker_fee_percent
optional< uint16_t > taker_fee_percent
Taker fee percent.
Definition: liquidity_pool.hpp:81
graphene::chain::asset_object::dynamic_data
const asset_dynamic_data_object & dynamic_data(const DB &db) const
Definition: asset_object.hpp:175
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::protocol::liquidity_pool_deposit_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:100
graphene::protocol::liquidity_pool_create_operation::share_asset
asset_id_type share_asset
Type of the share asset aka the LP token.
Definition: liquidity_pool.hpp:42
graphene::chain::asset_object::issuer
account_id_type issuer
ID of the account which issued this asset.
Definition: asset_object.hpp:135
graphene::protocol::liquidity_pool_update_operation
Update a liquidity pool.
Definition: liquidity_pool.hpp:74
graphene::protocol::liquidity_pool_deposit_operation::amount_a
asset amount_a
The amount of the first asset to deposit.
Definition: liquidity_pool.hpp:101
graphene::chain::liquidity_pool_object
A liquidity pool.
Definition: liquidity_pool_object.hpp:44
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
graphene::protocol::generic_exchange_operation_result::paid
vector< asset > paid
Definition: base.hpp:97
graphene::protocol::generic_operation_result::new_objects
flat_set< object_id_type > new_objects
Definition: base.hpp:90
graphene::protocol::liquidity_pool_delete_operation
Delete a liquidity pool.
Definition: liquidity_pool.hpp:56
liquidity_pool_evaluator.hpp
graphene::chain::liquidity_pool_deposit_evaluator::do_evaluate
void_result do_evaluate(const liquidity_pool_deposit_operation &op)
Definition: liquidity_pool_evaluator.cpp:155
graphene::protocol::generic_exchange_operation_result::fees
vector< asset > fees
Definition: base.hpp:99
graphene::chain::liquidity_pool_deposit_evaluator::do_apply
generic_exchange_operation_result do_apply(const liquidity_pool_deposit_operation &op)
Definition: liquidity_pool_evaluator.cpp:224
graphene::protocol::liquidity_pool_exchange_operation::account
account_id_type account
The account who exchanges with the liquidity pool.
Definition: liquidity_pool.hpp:143
graphene::protocol::liquidity_pool_create_operation::account
account_id_type account
The account who creates the liquidity pool.
Definition: liquidity_pool.hpp:39
graphene::chain::generic_evaluator::fee_paying_account
const account_object * fee_paying_account
Definition: evaluator.hpp:116
graphene::protocol::liquidity_pool_update_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:80
graphene::protocol::asset
Definition: asset.hpp:31
graphene::chain::asset_object::options
asset_options options
Definition: asset_object.hpp:137
GRAPHENE_ASSERT
#define GRAPHENE_ASSERT(expr, exc_type, FORMAT,...)
Definition: exceptions.hpp:28
graphene::protocol::void_result
Definition: base.hpp:86
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
graphene::chain::asset_object::is_market_issued
bool is_market_issued() const
Definition: asset_object.hpp:84
fc::safe::value
T value
Definition: safe.hpp:28
graphene::protocol::liquidity_pool_create_operation::taker_fee_percent
uint16_t taker_fee_percent
Taker fee percent.
Definition: liquidity_pool.hpp:43
graphene::chain::database::calculate_market_fee
asset calculate_market_fee(const asset_object &trade_asset, const asset &trade_amount, const bool &is_maker) const
Calculate the market fee that is to be taken.
Definition: db_market.cpp:2557
graphene::protocol::generic_operation_result
Definition: base.hpp:88
GRAPHENE_100_PERCENT
#define GRAPHENE_100_PERCENT
Definition: config.hpp:102
graphene
Definition: api.cpp:48
graphene::chain::liquidity_pool_exchange_evaluator::do_apply
generic_exchange_operation_result do_apply(const liquidity_pool_exchange_operation &op)
Definition: liquidity_pool_evaluator.cpp:441
exceptions.hpp
graphene::protocol::generic_operation_result::removed_objects
flat_set< object_id_type > removed_objects
Definition: base.hpp:92
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
graphene::protocol::liquidity_pool_update_operation::account
account_id_type account
The account who owns the liquidity pool.
Definition: liquidity_pool.hpp:79
fc::safe
Definition: safe.hpp:26