BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
samet_fund_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_2351_PASSED(block_time), "Not allowed until the core-2351 hardfork" );
44 
46  "The account is unauthorized by the asset" );
47 
48  return void_result();
49 } FC_CAPTURE_AND_RETHROW( (op) ) }
50 
52 { try {
53  database& d = db();
54 
56 
57  const auto& new_samet_fund_object = d.create<samet_fund_object>([&op](samet_fund_object& obj){
58  obj.owner_account = op.owner_account;
59  obj.asset_type = op.asset_type;
60  obj.balance = op.balance;
61  obj.fee_rate = op.fee_rate;
62  // unpaid amount is 0 by default
63  });
64  return new_samet_fund_object.id;
65 } FC_CAPTURE_AND_RETHROW( (op) ) }
66 
68 { try {
69  const database& d = db();
70 
71  _fund = &op.fund_id(d);
72 
73  FC_ASSERT( _fund->owner_account == op.owner_account, "The account is not the owner of the SameT Fund" );
74 
75  FC_ASSERT( _fund->unpaid_amount == 0, "Can only delete a SameT Fund when the unpaid amount is zero" );
76 
77  // Note: no asset authorization check here, allow funds to be moved to account balance
78 
79  return void_result();
80 } FC_CAPTURE_AND_RETHROW( (op) ) }
81 
83 { try {
84  database& d = db();
85 
86  asset released( _fund->balance, _fund->asset_type );
87 
88  d.adjust_balance( op.owner_account, released );
89 
90  d.remove( *_fund );
91 
92  return released;
93 } FC_CAPTURE_AND_RETHROW( (op) ) }
94 
96 { try {
97  const database& d = db();
98 
99  _fund = &op.fund_id(d);
100 
101  FC_ASSERT( _fund->owner_account == op.owner_account, "The account is not the owner of the SameT Fund" );
102 
103  if( op.delta_amount.valid() )
104  {
105  FC_ASSERT( _fund->asset_type == op.delta_amount->asset_id, "Asset type mismatch" );
107  "Can only update the balance of a SameT Fund when the unpaid amount is zero" );
108 
109  if( op.delta_amount->amount > 0 )
110  {
111  // Check asset authorization only when moving funds from account balance to somewhere else
113  "The account is unauthorized by the asset" );
114  }
115  else
116  {
117  FC_ASSERT( _fund->balance > -op.delta_amount->amount, "Insufficient balance in the SameT Fund" );
118  }
119  }
120 
121  if( op.new_fee_rate.valid() )
122  {
124  "New fee rate should not be the same as the original fee rate" );
125  }
126 
127  return void_result();
128 } FC_CAPTURE_AND_RETHROW( (op) ) }
129 
131 { try {
132  database& d = db();
133 
134  if( op.delta_amount.valid() )
135  d.adjust_balance( op.owner_account, -(*op.delta_amount) );
136 
137  d.modify( *_fund, [&op]( samet_fund_object& sfo ){
138  if( op.delta_amount.valid() )
139  sfo.balance += op.delta_amount->amount;
140  if( op.new_fee_rate.valid() )
141  sfo.fee_rate = *op.new_fee_rate;
142  });
143 
144  // Defensive check
145  FC_ASSERT( _fund->balance > 0, "Balance in the SameT Fund should be positive" );
146 
147  return void_result();
148 } FC_CAPTURE_AND_RETHROW( (op) ) }
149 
151 { try {
152  const database& d = db();
153 
154  _fund = &op.fund_id(d);
155 
156  FC_ASSERT( _fund->asset_type == op.borrow_amount.asset_id, "Asset type mismatch" );
157 
159  "Insufficient balance in the SameT Fund thus unable to borrow" );
160 
162  "The account is unauthorized by the asset" );
163 
164  return void_result();
165 } FC_CAPTURE_AND_RETHROW( (op) ) }
166 
168 { try {
169  database& d = db();
170 
171  d.modify( *_fund, [&op]( samet_fund_object& sfo ){
173  });
174 
176 
177  // Defensive check
178  FC_ASSERT( _fund->balance >= _fund->unpaid_amount, "Should not borrow more than available" );
179 
181  result.value.impacted_accounts = flat_set<account_id_type>({ _fund->owner_account });
182 
183  return result;
184 } FC_CAPTURE_AND_RETHROW( (op) ) }
185 
187 { try {
188  const database& d = db();
189 
190  _fund = &op.fund_id(d);
191 
192  FC_ASSERT( _fund->asset_type == op.repay_amount.asset_id, "Asset type mismatch" );
193 
195  "The account is unauthorized by the asset" );
196 
198  "Repay amount should not be greater than unpaid amount" );
199 
200  // Note: the result can be larger than 64 bit, but since we don't store it, it is allowed
201  auto required_fee = ( ( ( fc::uint128_t( op.repay_amount.amount.value ) * _fund->fee_rate )
202  + GRAPHENE_FEE_RATE_DENOM ) - 1 ) / GRAPHENE_FEE_RATE_DENOM; // Round up
203 
204  FC_ASSERT( fc::uint128_t(op.fund_fee.amount.value) >= required_fee,
205  "Insuffient fund fee, requires ${r}, offered ${p}",
206  ("r", required_fee) ("p", op.fund_fee.amount) );
207 
208  return void_result();
209 } FC_CAPTURE_AND_RETHROW( (op) ) }
210 
212 { try {
213  database& d = db();
214 
215  d.adjust_balance( op.account, -( op.repay_amount + op.fund_fee ) );
216 
217  d.modify( *_fund, [op]( samet_fund_object& sfo ){
218  sfo.balance += op.fund_fee.amount;
220  });
221 
223  result.value.impacted_accounts = flat_set<account_id_type>({ _fund->owner_account });
224 
225  return result;
226 } FC_CAPTURE_AND_RETHROW( (op) ) }
227 
228 } } // graphene::chain
graphene::chain::samet_fund_create_evaluator::do_apply
object_id_type do_apply(const samet_fund_create_operation &op) const
Definition: samet_fund_evaluator.cpp:51
graphene::protocol::samet_fund_update_operation::new_fee_rate
optional< uint32_t > new_fee_rate
New fee rate, optional.
Definition: samet_fund.hpp:82
graphene::chain::samet_fund_update_evaluator::do_evaluate
void_result do_evaluate(const samet_fund_update_operation &op)
Definition: samet_fund_evaluator.cpp:95
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
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::samet_fund_repay_operation::fund_id
samet_fund_id_type fund_id
ID of the SameT Fund.
Definition: samet_fund.hpp:119
samet_fund_object.hpp
graphene::chain::samet_fund_borrow_evaluator::_fund
const samet_fund_object * _fund
Definition: samet_fund_evaluator.hpp:72
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::protocol::samet_fund_create_operation::fee_rate
uint32_t fee_rate
Fee rate, the demominator is GRAPHENE_FEE_RATE_DENOM.
Definition: samet_fund.hpp:44
graphene::protocol::samet_fund_delete_operation
Delete a SameT Fund object.
Definition: samet_fund.hpp:56
graphene::protocol::samet_fund_update_operation::fund_id
samet_fund_id_type fund_id
ID of the SameT Fund object.
Definition: samet_fund.hpp:80
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
asset_object.hpp
graphene::chain::samet_fund_update_evaluator::_fund
const samet_fund_object * _fund
Definition: samet_fund_evaluator.hpp:61
database.hpp
graphene::chain::samet_fund_object
A SameT Fund is a fund which can be used by a borrower and have to be repaid in the same transaction.
Definition: samet_fund_object.hpp:39
graphene::protocol::samet_fund_create_operation::balance
share_type balance
Usable amount in the fund.
Definition: samet_fund.hpp:43
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::samet_fund_update_operation::delta_amount
optional< asset > delta_amount
Delta amount, optional.
Definition: samet_fund.hpp:81
graphene::chain::samet_fund_delete_evaluator::do_evaluate
void_result do_evaluate(const samet_fund_delete_operation &op)
Definition: samet_fund_evaluator.cpp:67
graphene::chain::samet_fund_borrow_evaluator::do_apply
extendable_operation_result do_apply(const samet_fund_borrow_operation &op) const
Definition: samet_fund_evaluator.cpp:167
graphene::protocol::samet_fund_borrow_operation::borrower
account_id_type borrower
The account who borrows from the fund.
Definition: samet_fund.hpp:99
samet_fund.hpp
graphene::chain::samet_fund_object::unpaid_amount
share_type unpaid_amount
Unpaid amount.
Definition: samet_fund_object.hpp:46
graphene::chain::samet_fund_repay_evaluator::do_apply
extendable_operation_result do_apply(const samet_fund_repay_operation &op) const
Definition: samet_fund_evaluator.cpp:211
graphene::protocol::samet_fund_borrow_operation
Borrow from a SameT Fund.
Definition: samet_fund.hpp:94
graphene::protocol::samet_fund_create_operation
Create a new SameT Fund object.
Definition: samet_fund.hpp:36
graphene::protocol::samet_fund_update_operation
Update a SameT Fund object.
Definition: samet_fund.hpp:74
graphene::chain::samet_fund_delete_evaluator::do_apply
asset do_apply(const samet_fund_delete_operation &op) const
Definition: samet_fund_evaluator.cpp:82
graphene::protocol::samet_fund_update_operation::owner_account
account_id_type owner_account
Owner of the fund.
Definition: samet_fund.hpp:79
graphene::protocol::samet_fund_borrow_operation::fund_id
samet_fund_id_type fund_id
ID of the SameT Fund.
Definition: samet_fund.hpp:100
graphene::chain::samet_fund_object::fee_rate
uint32_t fee_rate
Fee rate, the demominator is GRAPHENE_FEE_RATE_DENOM.
Definition: samet_fund_object.hpp:45
fc::optional::valid
bool valid() const
Definition: optional.hpp:186
graphene::protocol::samet_fund_repay_operation::account
account_id_type account
The account who repays to the SameT Fund.
Definition: samet_fund.hpp:118
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
samet_fund_evaluator.hpp
graphene::chain::samet_fund_update_evaluator::do_apply
void_result do_apply(const samet_fund_update_operation &op) const
Definition: samet_fund_evaluator.cpp:130
graphene::chain::samet_fund_repay_evaluator::do_evaluate
void_result do_evaluate(const samet_fund_repay_operation &op)
Definition: samet_fund_evaluator.cpp:186
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_FEE_RATE_DENOM
constexpr uint32_t GRAPHENE_FEE_RATE_DENOM
Denominator for SameT Fund fee calculation.
Definition: config.hpp:121
graphene::chain::samet_fund_delete_evaluator::_fund
const samet_fund_object * _fund
Definition: samet_fund_evaluator.hpp:50
graphene::protocol::samet_fund_repay_operation::repay_amount
asset repay_amount
The amount to repay.
Definition: samet_fund.hpp:120
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
graphene::chain::samet_fund_repay_evaluator::_fund
const samet_fund_object * _fund
Definition: samet_fund_evaluator.hpp:83
graphene::chain::samet_fund_object::balance
share_type balance
Usable amount in the fund.
Definition: samet_fund_object.hpp:44
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
graphene::protocol::samet_fund_repay_operation::fund_fee
asset fund_fee
Fee for using the fund.
Definition: samet_fund.hpp:121
graphene::protocol::samet_fund_create_operation::asset_type
asset_id_type asset_type
Asset type in the fund.
Definition: samet_fund.hpp:42
graphene::protocol::samet_fund_create_operation::owner_account
account_id_type owner_account
Owner of the fund.
Definition: samet_fund.hpp:41
graphene::chain::samet_fund_borrow_evaluator::do_evaluate
void_result do_evaluate(const samet_fund_borrow_operation &op)
Definition: samet_fund_evaluator.cpp:150
graphene::chain::samet_fund_object::asset_type
asset_id_type asset_type
Asset type in the fund.
Definition: samet_fund_object.hpp:43
graphene::protocol::samet_fund_repay_operation
Repay to a SameT Fund.
Definition: samet_fund.hpp:113
graphene::protocol::samet_fund_delete_operation::owner_account
account_id_type owner_account
The account who owns the SameT Fund object.
Definition: samet_fund.hpp:61
graphene::chain::samet_fund_create_evaluator::do_evaluate
void_result do_evaluate(const samet_fund_create_operation &op) const
Definition: samet_fund_evaluator.cpp:38
graphene::chain::generic_evaluator::fee_paying_account
const account_object * fee_paying_account
Definition: evaluator.hpp:116
graphene::protocol::asset
Definition: asset.hpp:31
graphene::chain::samet_fund_object::owner_account
account_id_type owner_account
Owner of the fund.
Definition: samet_fund_object.hpp:42
graphene::protocol::void_result
Definition: base.hpp:86
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
fc::safe::value
T value
Definition: safe.hpp:28
graphene::protocol::samet_fund_borrow_operation::borrow_amount
asset borrow_amount
The amount to borrow.
Definition: samet_fund.hpp:101
graphene
Definition: api.cpp:48
graphene::protocol::extension::value
T value
Definition: ext.hpp:40
exceptions.hpp
graphene::protocol::samet_fund_delete_operation::fund_id
samet_fund_id_type fund_id
ID of the SameT Fund object.
Definition: samet_fund.hpp:62
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99