BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
credit_offer_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 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_CORE_2362_PASSED(block_time), "Not allowed until the core-2362 hardfork" );
44 
45  if( op.enabled )
46  {
47  FC_ASSERT( op.auto_disable_time > block_time, "Auto-disable time should be in the future" );
49  "Auto-disable time should not be later than ${d} days in the future",
51  }
52 
53  // Make sure all the collateral asset types exist
54  for( const auto& collateral : op.acceptable_collateral )
55  {
56  collateral.first(d);
57  }
58 
59  // Make sure all the accounts exist
60  for( const auto& borrower : op.acceptable_borrowers )
61  {
62  borrower.first(d);
63  }
64 
66  "The account is unauthorized by the asset" );
67 
68  return void_result();
69 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
70 
72 { try {
73  database& d = db();
74 
76 
77  const auto& new_credit_offer_object = d.create<credit_offer_object>([&op](credit_offer_object& obj){
78  obj.owner_account = op.owner_account;
79  obj.asset_type = op.asset_type;
80  obj.total_balance = op.balance;
81  obj.current_balance = op.balance;
82  obj.fee_rate = op.fee_rate;
83  obj.max_duration_seconds = op.max_duration_seconds;
84  obj.min_deal_amount = op.min_deal_amount;
85  obj.enabled = op.enabled;
86  obj.auto_disable_time = op.auto_disable_time;
87  obj.acceptable_collateral = op.acceptable_collateral;
88  obj.acceptable_borrowers = op.acceptable_borrowers;
89  });
90  return new_credit_offer_object.id;
91 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
92 
94 { try {
95  const database& d = db();
96 
97  _offer = &op.offer_id(d);
98 
99  FC_ASSERT( _offer->owner_account == op.owner_account, "The account is not the owner of the credit offer" );
100 
102  "Can only delete a credit offer when the unpaid amount is zero" );
103 
104  // Note: no asset authorization check here, allow funds to be moved to account balance
105 
106  return void_result();
107 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
108 
110 { try {
111  database& d = db();
112 
114 
115  if( _offer->current_balance != 0 )
116  {
117  d.adjust_balance( op.owner_account, released );
118  }
119 
120  d.remove( *_offer );
121 
122  return released;
123 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
124 
126 { try {
127  const database& d = db();
128  const auto block_time = d.head_block_time();
129 
130  _offer = &op.offer_id(d);
131 
132  FC_ASSERT( _offer->owner_account == op.owner_account, "The account is not the owner of the credit offer" );
133 
134  if( op.delta_amount.valid() )
135  {
136  FC_ASSERT( _offer->asset_type == op.delta_amount->asset_id, "Asset type mismatch" );
137 
138  if( op.delta_amount->amount > 0 )
139  {
140  // Check asset authorization only when moving funds from account balance to somewhere else
142  "The account is unauthorized by the asset" );
143  }
144  else
145  {
146  FC_ASSERT( _offer->total_balance > -op.delta_amount->amount,
147  "Should leave some funds in the credit offer when updating" );
148  FC_ASSERT( _offer->current_balance >= -op.delta_amount->amount, "Insufficient balance in the credit offer" );
149  }
150  }
151 
152  bool enabled = op.enabled.valid() ? *op.enabled : _offer->enabled;
153  if( enabled )
154  {
155  auto auto_disable_time = op.auto_disable_time.valid() ? *op.auto_disable_time : _offer->auto_disable_time;
156  FC_ASSERT( auto_disable_time > block_time, "Auto-disable time should be in the future" );
157  FC_ASSERT( auto_disable_time - block_time <= fc::days(GRAPHENE_MAX_CREDIT_OFFER_DAYS),
158  "Auto-disable time should not be later than ${d} days in the future",
160  }
161 
162  // Make sure all the collateral asset types exist
163  if( op.acceptable_collateral.valid() )
164  {
165  for( const auto& collateral : *op.acceptable_collateral )
166  {
167  collateral.first(d);
168  FC_ASSERT( _offer->asset_type == collateral.second.base.asset_id,
169  "Asset type mismatch in a price of acceptable collateral" );
170  }
171  }
172 
173  // Make sure all the accounts exist
174  if( op.acceptable_borrowers.valid() )
175  {
176  for( const auto& borrower : *op.acceptable_borrowers )
177  {
178  borrower.first(d);
179  }
180  }
181 
182  return void_result();
183 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
184 
186 { try {
187  database& d = db();
188 
189  if( op.delta_amount.valid() )
190  d.adjust_balance( op.owner_account, -(*op.delta_amount) );
191 
192  d.modify( *_offer, [&op]( credit_offer_object& coo ){
193  if( op.delta_amount.valid() ) {
194  coo.total_balance += op.delta_amount->amount;
195  coo.current_balance += op.delta_amount->amount;
196  }
197  if( op.fee_rate.valid() )
198  coo.fee_rate = *op.fee_rate;
199  if( op.max_duration_seconds.valid() )
201  if( op.min_deal_amount.valid() )
203  if( op.enabled.valid() )
204  coo.enabled = *op.enabled;
205  if( op.auto_disable_time.valid() )
207  if( op.acceptable_collateral.valid() )
209  if( op.acceptable_borrowers.valid() )
211  });
212 
213  // Defensive checks
214  FC_ASSERT( _offer->total_balance > 0, "Total balance in the credit offer should be positive" );
215  FC_ASSERT( _offer->current_balance >= 0, "Current balance in the credit offer should not be negative" );
217  "Total balance in the credit offer should not be less than current balance" );
218  if( _offer->enabled )
219  {
221  "Auto-disable time should be in the future if the credit offer is enabled" );
223  "Auto-disable time should not be too late in the future" );
224  }
225 
226  return void_result();
227 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
228 
230 { try {
231  const database& d = db();
232  const auto block_time = d.head_block_time();
233 
234  if( !HARDFORK_CORE_2595_PASSED(block_time) )
235  {
236  FC_ASSERT( !op.extensions.value.auto_repay.valid(),
237  "auto_repay unavailable until the core-2595 hardfork");
238  }
239 
240  _offer = &op.offer_id(d);
241 
242  FC_ASSERT( _offer->enabled, "The credit offer is not enabled" );
243 
244  FC_ASSERT( _offer->asset_type == op.borrow_amount.asset_id, "Asset type mismatch" );
245 
247  "Insufficient balance in the credit offer thus unable to borrow" );
248 
250  "Borrowing amount should not be less than minimum deal amount" );
251 
253  "The maximum accceptable fee rate is lower than offered" );
254 
256  "The minimum accceptable duration is longer than offered" );
257 
258  auto coll_itr = _offer->acceptable_collateral.find( op.collateral.asset_id );
259  FC_ASSERT( coll_itr != _offer->acceptable_collateral.end(),
260  "Collateral asset type is not acceptable by the credit offer" );
261 
262  const asset_object& debt_asset_obj = _offer->asset_type(d);
263  const asset_object& collateral_asset_obj = op.collateral.asset_id(d);
264 
265  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, debt_asset_obj ),
266  "The borrower is unauthorized by the borrowing asset" );
267  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, collateral_asset_obj ),
268  "The borrower is unauthorized by the collateral asset" );
269 
270  const account_object& offer_owner = _offer->owner_account(d);
271 
272  FC_ASSERT( is_authorized_asset( d, offer_owner, debt_asset_obj ),
273  "The owner of the credit offer is unauthorized by the borrowing asset" );
274  FC_ASSERT( is_authorized_asset( d, offer_owner, collateral_asset_obj ),
275  "The owner of the credit offer is unauthorized by the collateral asset" );
276 
277  auto required_collateral = op.borrow_amount.multiply_and_round_up( coll_itr->second );
278  FC_ASSERT( required_collateral.amount <= op.collateral.amount,
279  "Insufficient collateral provided, requires ${r}, provided ${p}",
280  ("r", required_collateral.amount) ("p", op.collateral.amount) );
281 
282  optional<share_type> max_allowed;
283  if( !_offer->acceptable_borrowers.empty() )
284  {
285  auto itr = _offer->acceptable_borrowers.find( op.borrower );
286  FC_ASSERT( itr != _offer->acceptable_borrowers.end(), "Account is not in acceptable borrowers" );
287  max_allowed = itr->second;
288  }
289 
290  share_type already_borrowed = 0;
291  const auto& deal_summary_idx = d.get_index_type<credit_deal_summary_index>().indices().get<by_offer_borrower>();
292  auto summ_itr = deal_summary_idx.find( boost::make_tuple( op.offer_id, op.borrower ) );
293  if( summ_itr != deal_summary_idx.end() )
294  {
295  _deal_summary = &(*summ_itr);
296  already_borrowed = _deal_summary->total_debt_amount;
297  }
298 
299  if( max_allowed.valid() )
300  {
301  FC_ASSERT( already_borrowed + op.borrow_amount.amount <= *max_allowed,
302  "Unable to borrow ${b}, already borrowed ${a}, maximum allowed ${m}",
303  ("b", op.borrow_amount.amount) ("a", already_borrowed) ("m", max_allowed) );
304  }
305 
306  return void_result();
307 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
308 
310 { try {
311  database& d = db();
312 
313  d.adjust_balance( op.borrower, -op.collateral );
315 
316  d.modify( *_offer, [&op]( credit_offer_object& coo ){
318  });
319 
320  const auto block_time = d.head_block_time();
321  auto repay_time = ( fc::time_point_sec::maximum() - block_time ) >= fc::seconds(_offer->max_duration_seconds)
322  ? ( block_time + _offer->max_duration_seconds )
324 
325  const auto& new_deal = d.create<credit_deal_object>([&op,this,&repay_time](credit_deal_object& obj){
326  obj.borrower = op.borrower;
327  obj.offer_id = op.offer_id;
328  obj.offer_owner = _offer->owner_account;
329  obj.debt_asset = _offer->asset_type;
330  obj.debt_amount = op.borrow_amount.amount;
331  obj.collateral_asset = op.collateral.asset_id;
332  obj.collateral_amount = op.collateral.amount;
333  obj.fee_rate = _offer->fee_rate;
334  obj.latest_repay_time = repay_time;
335  obj.auto_repay = ( op.extensions.value.auto_repay.valid() ? *op.extensions.value.auto_repay : 0 );
336  });
337 
338  if( _deal_summary != nullptr )
339  {
341  obj.total_debt_amount += op.borrow_amount.amount;
342  });
343  }
344  else
345  {
347  obj.borrower = op.borrower;
348  obj.offer_id = op.offer_id;
349  obj.offer_owner = _offer->owner_account;
350  obj.debt_asset = _offer->asset_type;
351  obj.total_debt_amount = op.borrow_amount.amount;
352  });
353  }
354 
355  // Defensive check
356  FC_ASSERT( _offer->total_balance > 0, "Total balance in the credit offer should be positive" );
357  FC_ASSERT( _offer->current_balance >= 0, "Current balance in the credit offer should not be negative" );
359  "Total balance in the credit offer should not be less than current balance" );
360  FC_ASSERT( new_deal.latest_repay_time > block_time,
361  "Latest repayment time should be in the future" );
362  FC_ASSERT( new_deal.latest_repay_time - block_time <= fc::days(GRAPHENE_MAX_CREDIT_DEAL_DAYS),
363  "Latest repayment time should not be too late in the future" );
364 
366  // Note: only return the deal here, deal summary is impl so we do not return it
367  result.value.new_objects = flat_set<object_id_type>({ new_deal.id });
368  result.value.impacted_accounts = flat_set<account_id_type>({ _offer->owner_account });
369 
370  return result;
371 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
372 
374 { try {
375  const database& d = db();
376 
377  _deal = &op.deal_id(d);
378 
379  FC_ASSERT( _deal->borrower == op.account, "A credit deal can only be repaid by the borrower" );
380 
381  FC_ASSERT( _deal->debt_asset == op.repay_amount.asset_id, "Asset type mismatch" );
382 
384  "Repay amount should not be greater than unpaid amount" );
385 
386  // Note: the result can be larger than 64 bit, but since we don't store it, it is allowed
387  auto required_fee = ( ( ( fc::uint128_t( op.repay_amount.amount.value ) * _deal->fee_rate )
388  + GRAPHENE_FEE_RATE_DENOM ) - 1 ) / GRAPHENE_FEE_RATE_DENOM; // Round up
389 
390  FC_ASSERT( fc::uint128_t(op.credit_fee.amount.value) >= required_fee,
391  "Insuffient credit fee, requires ${r}, offered ${p}",
392  ("r", required_fee) ("p", op.credit_fee.amount) );
393 
394  const asset_object& debt_asset_obj = _deal->debt_asset(d);
395  // Note: allow collateral to be moved to account balance regardless of collateral asset authorization
396 
397  FC_ASSERT( is_authorized_asset( d, *fee_paying_account, debt_asset_obj ),
398  "The account is unauthorized by the repaying asset" );
399  FC_ASSERT( is_authorized_asset( d, _deal->offer_owner(d), debt_asset_obj ),
400  "The owner of the credit offer is unauthorized by the repaying asset" );
401 
402  return void_result();
403 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
404 
406 { try {
407  database& d = db();
408 
409  share_type total_amount = op.repay_amount.amount + op.credit_fee.amount;
410 
411  d.adjust_balance( op.account, asset( -total_amount, op.repay_amount.asset_id ) );
412 
413  // Update offer
414  const credit_offer_object& offer = _deal->offer_id(d);
415  d.modify( offer, [&op,&total_amount]( credit_offer_object& obj ){
416  obj.total_balance += op.credit_fee.amount;
417  obj.current_balance += total_amount;
418  });
419  // Defensive check
420  FC_ASSERT( offer.total_balance >= offer.current_balance,
421  "Total balance in the credit offer should not be less than current balance" );
422 
424  result.value.impacted_accounts = flat_set<account_id_type>({ offer.owner_account });
425  result.value.updated_objects = flat_set<object_id_type>({ offer.id });
426 
427  // Process deal summary
428  const auto& deal_summary_idx = d.get_index_type<credit_deal_summary_index>().indices().get<by_offer_borrower>();
429  auto summ_itr = deal_summary_idx.find( boost::make_tuple( _deal->offer_id, op.account ) );
430  FC_ASSERT( summ_itr != deal_summary_idx.end(), "Internal error" );
431 
432  const credit_deal_summary_object& summ_obj = *summ_itr;
433  if( summ_obj.total_debt_amount == op.repay_amount.amount )
434  {
435  d.remove( summ_obj );
436  }
437  else
438  {
439  d.modify( summ_obj, [&op]( credit_deal_summary_object& obj ){
441  });
442  }
443 
444  // Process deal
445  asset collateral_released( _deal->collateral_amount, _deal->collateral_asset );
446  if( _deal->debt_amount == op.repay_amount.amount ) // to fully repay
447  {
448  result.value.removed_objects = flat_set<object_id_type>({ _deal->id });
449  d.remove( *_deal );
450  }
451  else // to partially repay
452  {
453  // Note:
454  // Due to rounding, it is possible that the account is paying too much debt asset for too little collateral,
455  // in extreme cases, the amount to release can be zero.
456  auto amount_to_release = ( fc::uint128_t( op.repay_amount.amount.value ) * _deal->collateral_amount.value )
457  / _deal->debt_amount.value; // Round down
458  FC_ASSERT( amount_to_release < fc::uint128_t( _deal->collateral_amount.value ), "Internal error" );
459  collateral_released.amount = static_cast<int64_t>( amount_to_release );
460 
461  d.modify( *_deal, [&op,&collateral_released]( credit_deal_object& obj ){
462  obj.debt_amount -= op.repay_amount.amount;
463  obj.collateral_amount -= collateral_released.amount;
464  });
465 
466  result.value.updated_objects->insert( _deal->id );
467  }
468 
469  d.adjust_balance( op.account, collateral_released );
470  result.value.received = vector<asset>({ collateral_released });
471 
472  return result;
473 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
474 
476 { try {
477  const database& d = db();
478  const auto block_time = d.head_block_time();
479 
480  FC_ASSERT( HARDFORK_CORE_2595_PASSED(block_time), "Not allowed until the core-2595 hardfork" );
481 
482  _deal = &op.deal_id(d);
483 
484  FC_ASSERT( _deal->borrower == op.account, "A credit deal can only be updated by the borrower" );
485 
486  FC_ASSERT( _deal->auto_repay != op.auto_repay, "The automatic repayment type does not change" );
487 
488  return void_result();
489 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
490 
492 { try {
493  database& d = db();
494 
495  d.modify( *_deal, [&op]( credit_deal_object& obj ){
496  obj.auto_repay = op.auto_repay;
497  });
498 
499  return void_result();
500 } FC_CAPTURE_AND_RETHROW( (op) ) } // GCOVR_EXCL_LINE
501 
502 } } // graphene::chain
graphene::chain::credit_offer_accept_evaluator::do_apply
extendable_operation_result do_apply(const credit_offer_accept_operation &op) const
Definition: credit_offer_evaluator.cpp:309
GRAPHENE_MAX_CREDIT_OFFER_DAYS
constexpr int64_t GRAPHENE_MAX_CREDIT_OFFER_DAYS
How long a credit offer will be kept active, in days.
Definition: config.hpp:124
graphene::protocol::credit_offer_accept_operation::borrower
account_id_type borrower
The account who accepts the offer.
Definition: credit_offer.hpp:146
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::protocol::credit_offer_accept_operation::extensions
extension< ext > extensions
Extensions.
Definition: credit_offer.hpp:153
graphene::chain::credit_deal_repay_evaluator::do_apply
extendable_operation_result do_apply(const credit_deal_repay_operation &op) const
Definition: credit_offer_evaluator.cpp:405
graphene::protocol::extension
Definition: ext.hpp:36
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
is_authorized_asset.hpp
graphene::protocol::credit_offer_update_operation::owner_account
account_id_type owner_account
Owner of the credit offer.
Definition: credit_offer.hpp:96
graphene::chain::credit_deal_object::collateral_amount
share_type collateral_amount
How much funds in collateral.
Definition: credit_offer_object.hpp:113
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::protocol::credit_offer_create_operation::auto_disable_time
time_point_sec auto_disable_time
The time when this offer will be disabled automatically.
Definition: credit_offer.hpp:51
graphene::protocol::credit_offer_create_operation::balance
share_type balance
Usable amount in the credit offer.
Definition: credit_offer.hpp:46
graphene::chain::credit_deal_object
A credit deal describes the details of a borrower's borrowing of funds from a credit offer.
Definition: credit_offer_object.hpp:104
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::chain::credit_offer_object
A credit offer is a fund that can be used by other accounts who provide certain collateral.
Definition: credit_offer_object.hpp:39
graphene::chain::credit_offer_object::total_balance
share_type total_balance
Total size of the fund.
Definition: credit_offer_object.hpp:44
graphene::protocol::credit_offer_update_operation::acceptable_borrowers
optional< flat_map< account_id_type, share_type > > acceptable_borrowers
New allowed borrowers and their maximum amounts to borrow, optional.
Definition: credit_offer.hpp:109
graphene::protocol::credit_deal_repay_operation::deal_id
credit_deal_id_type deal_id
ID of the credit deal.
Definition: credit_offer.hpp:169
graphene::protocol::credit_deal_update_operation::auto_repay
uint8_t auto_repay
The specified automatic repayment type.
Definition: credit_offer.hpp:222
asset_object.hpp
graphene::chain::credit_offer_object::asset_type
asset_id_type asset_type
Asset type in the fund.
Definition: credit_offer_object.hpp:43
database.hpp
graphene::protocol::credit_deal_repay_operation
Repay a credit deal.
Definition: credit_offer.hpp:163
graphene::protocol::credit_offer_create_operation
Create a new credit offer.
Definition: credit_offer.hpp:36
graphene::protocol::credit_offer_create_operation::acceptable_borrowers
flat_map< account_id_type, share_type > acceptable_borrowers
Allowed borrowers and their maximum amounts to borrow. No limitation if empty.
Definition: credit_offer.hpp:57
graphene::chain::credit_deal_update_evaluator::do_evaluate
void_result do_evaluate(const credit_deal_update_operation &op)
Definition: credit_offer_evaluator.cpp:475
graphene::chain::credit_offer_delete_evaluator::_offer
const credit_offer_object * _offer
Definition: credit_offer_evaluator.hpp:50
graphene::chain::credit_deal_summary_object::total_debt_amount
share_type total_debt_amount
How much funds borrowed.
Definition: credit_offer_object.hpp:192
graphene::protocol::credit_offer_update_operation::min_deal_amount
optional< share_type > min_deal_amount
Minimum amount to borrow for each new deal, optional.
Definition: credit_offer.hpp:101
graphene::chain::asset_object
tracks the parameters of an asset
Definition: asset_object.hpp:75
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::chain::credit_offer_create_evaluator::do_evaluate
void_result do_evaluate(const credit_offer_create_operation &op) const
Definition: credit_offer_evaluator.cpp:38
graphene::protocol::credit_offer_delete_operation
Delete a credit offer.
Definition: credit_offer.hpp:70
graphene::chain::credit_offer_object::owner_account
account_id_type owner_account
Owner of the fund.
Definition: credit_offer_object.hpp:42
fc::time_point_sec::maximum
static time_point_sec maximum()
Definition: time.hpp:86
graphene::protocol::credit_offer_update_operation::enabled
optional< bool > enabled
Whether this offer is available, optional.
Definition: credit_offer.hpp:102
graphene::protocol::credit_offer_create_operation::min_deal_amount
share_type min_deal_amount
Minimum amount to borrow for each new deal.
Definition: credit_offer.hpp:49
graphene::chain::credit_offer_delete_evaluator::do_apply
asset do_apply(const credit_offer_delete_operation &op) const
Definition: credit_offer_evaluator.cpp:109
fc::seconds
microseconds seconds(int64_t s)
Definition: time.hpp:34
graphene::chain::credit_offer_object::acceptable_collateral
flat_map< asset_id_type, price > acceptable_collateral
Types and rates of acceptable collateral.
Definition: credit_offer_object.hpp:53
graphene::chain::credit_offer_object::enabled
bool enabled
Whether this offer is available.
Definition: credit_offer_object.hpp:49
graphene::protocol::credit_offer_create_operation::enabled
bool enabled
Whether this offer is available.
Definition: credit_offer.hpp:50
graphene::protocol::credit_deal_repay_operation::repay_amount
asset repay_amount
The amount to repay.
Definition: credit_offer.hpp:170
graphene::chain::credit_deal_summary_object::offer_id
credit_offer_id_type offer_id
ID of the credit offer.
Definition: credit_offer_object.hpp:189
graphene::chain::credit_offer_object::fee_rate
uint32_t fee_rate
Fee rate, the demominator is GRAPHENE_FEE_RATE_DENOM.
Definition: credit_offer_object.hpp:46
graphene::protocol::credit_offer_update_operation::fee_rate
optional< uint32_t > fee_rate
New fee rate, optional.
Definition: credit_offer.hpp:99
graphene::chain::credit_offer_accept_evaluator::do_evaluate
void_result do_evaluate(const credit_offer_accept_operation &op)
Definition: credit_offer_evaluator.cpp:229
graphene::protocol::credit_deal_repay_operation::credit_fee
asset credit_fee
The credit fee relative to the amount to repay.
Definition: credit_offer.hpp:171
graphene::chain::credit_deal_object::borrower
account_id_type borrower
Borrower.
Definition: credit_offer_object.hpp:107
fc::days
microseconds days(int64_t d)
Definition: time.hpp:38
graphene::chain::credit_offer_delete_evaluator::do_evaluate
void_result do_evaluate(const credit_offer_delete_operation &op)
Definition: credit_offer_evaluator.cpp:93
graphene::db::index::get
const object & get(object_id_type id) const
Definition: index.hpp:110
graphene::protocol::asset::multiply_and_round_up
asset multiply_and_round_up(const price &p) const
Multiply and round up.
Definition: asset.cpp:77
fc::optional::valid
bool valid() const
Definition: optional.hpp:186
graphene::protocol::credit_offer_delete_operation::offer_id
credit_offer_id_type offer_id
ID of the credit offer.
Definition: credit_offer.hpp:76
graphene::chain::account_object
This class represents an account on the object graph.
Definition: account_object.hpp:180
graphene::chain::credit_deal_object::auto_repay
uint8_t auto_repay
The specified automatic repayment type.
Definition: credit_offer_object.hpp:116
graphene::protocol::credit_offer_accept_operation
Accept a credit offer, thereby creating a credit deal.
Definition: credit_offer.hpp:135
graphene::protocol::credit_offer_update_operation::acceptable_collateral
optional< flat_map< asset_id_type, price > > acceptable_collateral
New types and rates of acceptable collateral, optional.
Definition: credit_offer.hpp:106
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::chain::credit_deal_summary_object
A credit deal summary describes the summary of a borrower's borrowing of funds from a credit offer.
Definition: credit_offer_object.hpp:184
graphene::protocol::credit_offer_create_operation::acceptable_collateral
flat_map< asset_id_type, price > acceptable_collateral
Types and rates of acceptable collateral.
Definition: credit_offer.hpp:54
GRAPHENE_MAX_CREDIT_DEAL_DAYS
constexpr int64_t GRAPHENE_MAX_CREDIT_DEAL_DAYS
How long a credit deal will be kept, in days.
Definition: config.hpp:128
graphene::chain::credit_deal_repay_evaluator::_deal
const credit_deal_object * _deal
Definition: credit_offer_evaluator.hpp:84
graphene::protocol::credit_offer_update_operation::offer_id
credit_offer_id_type offer_id
ID of the credit offer.
Definition: credit_offer.hpp:97
graphene::chain::credit_deal_object::debt_asset
asset_id_type debt_asset
Asset type of the debt, redundant info for ease of querying.
Definition: credit_offer_object.hpp:110
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::chain::credit_deal_summary_object::borrower
account_id_type borrower
Borrower.
Definition: credit_offer_object.hpp:188
graphene::chain::credit_offer_object::auto_disable_time
time_point_sec auto_disable_time
The time when this offer will be disabled automatically.
Definition: credit_offer_object.hpp:50
graphene::chain::credit_offer_create_evaluator::do_apply
object_id_type do_apply(const credit_offer_create_operation &op) const
Definition: credit_offer_evaluator.cpp:71
graphene::protocol::credit_offer_create_operation::asset_type
asset_id_type asset_type
Asset type in the credit offer.
Definition: credit_offer.hpp:45
GRAPHENE_FEE_RATE_DENOM
constexpr uint32_t GRAPHENE_FEE_RATE_DENOM
Denominator for SameT Fund fee calculation.
Definition: config.hpp:121
graphene::chain::credit_deal_object::offer_id
credit_offer_id_type offer_id
ID of the credit offer.
Definition: credit_offer_object.hpp:108
graphene::protocol::credit_offer_accept_operation::offer_id
credit_offer_id_type offer_id
ID of the credit offer.
Definition: credit_offer.hpp:147
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
graphene::protocol::credit_offer_accept_operation::borrow_amount
asset borrow_amount
The amount to borrow.
Definition: credit_offer.hpp:148
credit_offer_object.hpp
graphene::chain::credit_deal_object::debt_amount
share_type debt_amount
How much funds borrowed.
Definition: credit_offer_object.hpp:111
graphene::chain::credit_offer_update_evaluator::do_evaluate
void_result do_evaluate(const credit_offer_update_operation &op)
Definition: credit_offer_evaluator.cpp:125
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::credit_offer_create_operation::max_duration_seconds
uint32_t max_duration_seconds
The time limit that borrowed funds should be repaid.
Definition: credit_offer.hpp:48
graphene::chain::credit_offer_update_evaluator::_offer
const credit_offer_object * _offer
Definition: credit_offer_evaluator.hpp:61
credit_offer.hpp
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::protocol::credit_deal_update_operation
Update a credit deal.
Definition: credit_offer.hpp:215
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
credit_offer_evaluator.hpp
graphene::chain::credit_offer_object::acceptable_borrowers
flat_map< account_id_type, share_type > acceptable_borrowers
Allowed borrowers and their maximum amounts to borrow. No limitation if empty.
Definition: credit_offer_object.hpp:56
graphene::chain::credit_deal_object::fee_rate
uint32_t fee_rate
Fee rate, the demominator is GRAPHENE_FEE_RATE_DENOM.
Definition: credit_offer_object.hpp:114
graphene::chain::credit_offer_accept_evaluator::_offer
const credit_offer_object * _offer
Definition: credit_offer_evaluator.hpp:72
graphene::protocol::credit_deal_update_operation::deal_id
credit_deal_id_type deal_id
ID of the credit deal.
Definition: credit_offer.hpp:221
graphene::protocol::credit_offer_create_operation::fee_rate
uint32_t fee_rate
Fee rate, the demominator is GRAPHENE_FEE_RATE_DENOM.
Definition: credit_offer.hpp:47
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::protocol::credit_offer_update_operation::delta_amount
optional< asset > delta_amount
Delta amount, optional.
Definition: credit_offer.hpp:98
graphene::protocol::credit_deal_update_operation::account
account_id_type account
The account who owns the credit deal.
Definition: credit_offer.hpp:220
graphene::chain::credit_offer_update_evaluator::do_apply
void_result do_apply(const credit_offer_update_operation &op) const
Definition: credit_offer_evaluator.cpp:185
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::chain::credit_deal_repay_evaluator::do_evaluate
void_result do_evaluate(const credit_deal_repay_operation &op)
Definition: credit_offer_evaluator.cpp:373
graphene::protocol::credit_offer_accept_operation::max_fee_rate
uint32_t max_fee_rate
The maximum acceptable fee rate.
Definition: credit_offer.hpp:150
graphene::protocol::credit_offer_update_operation::auto_disable_time
optional< time_point_sec > auto_disable_time
New time to disable automatically, optional.
Definition: credit_offer.hpp:103
graphene::chain::credit_deal_object::collateral_asset
asset_id_type collateral_asset
Asset type of the collateral.
Definition: credit_offer_object.hpp:112
graphene::chain::generic_evaluator::fee_paying_account
const account_object * fee_paying_account
Definition: evaluator.hpp:116
graphene::chain::credit_offer_object::max_duration_seconds
uint32_t max_duration_seconds
The time limit that borrowed funds should be repaid.
Definition: credit_offer_object.hpp:47
graphene::protocol::asset
Definition: asset.hpp:31
graphene::protocol::credit_offer_accept_operation::collateral
asset collateral
The collateral.
Definition: credit_offer.hpp:149
graphene::chain::credit_deal_update_evaluator::_deal
const credit_deal_object * _deal
Definition: credit_offer_evaluator.hpp:95
graphene::chain::credit_deal_object::offer_owner
account_id_type offer_owner
Owner of the credit offer, redundant info for ease of querying.
Definition: credit_offer_object.hpp:109
graphene::protocol::void_result
Definition: base.hpp:86
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
graphene::db::object_database::get_index_type
const IndexType & get_index_type() const
Definition: object_database.hpp:77
graphene::protocol::credit_offer_accept_operation::min_duration_seconds
uint32_t min_duration_seconds
The minimum acceptable duration.
Definition: credit_offer.hpp:151
graphene::chain::credit_deal_update_evaluator::do_apply
void_result do_apply(const credit_deal_update_operation &op) const
Definition: credit_offer_evaluator.cpp:491
graphene::protocol::credit_offer_create_operation::owner_account
account_id_type owner_account
Owner of the credit offer.
Definition: credit_offer.hpp:44
graphene::chain::credit_offer_object::current_balance
share_type current_balance
Usable amount in the fund.
Definition: credit_offer_object.hpp:45
fc::safe::value
T value
Definition: safe.hpp:28
graphene::chain::credit_offer_object::min_deal_amount
share_type min_deal_amount
Minimum amount to borrow for each new deal.
Definition: credit_offer_object.hpp:48
graphene::protocol::credit_offer_delete_operation::owner_account
account_id_type owner_account
The account who owns the credit offer.
Definition: credit_offer.hpp:75
graphene::chain::credit_offer_accept_evaluator::_deal_summary
const credit_deal_summary_object * _deal_summary
Definition: credit_offer_evaluator.hpp:73
graphene::protocol::credit_offer_update_operation
Update a credit offer.
Definition: credit_offer.hpp:88
graphene::protocol::credit_offer_update_operation::max_duration_seconds
optional< uint32_t > max_duration_seconds
New repayment time limit, optional.
Definition: credit_offer.hpp:100
graphene
Definition: api.cpp:48
graphene::protocol::extension::value
T value
Definition: ext.hpp:40
exceptions.hpp
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
graphene::protocol::credit_deal_repay_operation::account
account_id_type account
The account who repays to the credit offer.
Definition: credit_offer.hpp:168
fc::safe
Definition: safe.hpp:26