price operator/(const asset &base, const asset "e) { try { FC_ASSERT(base.symbol_name() != quote.symbol_name()); return price{base, quote}; } FC_CAPTURE_AND_RETHROW((base)(quote)) }
void block_evaluation_state::add_output_delegate_votes( int32_t did, const asset& votes ) { auto itr = _output_votes.find(did); if( itr == _output_votes.end() ) _output_votes[did] = votes.get_rounded_amount(); else itr->second += votes.get_rounded_amount(); }
void token::issue( account_name to, asset quantity, string memo ) { auto sym = quantity.symbol; eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); auto sym_name = sym.name(); stats statstable( _self, sym_name ); auto existing = statstable.find( sym_name ); eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; require_auth( st.issuer ); eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must issue positive quantity" ); eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); statstable.modify( st, 0, [&]( auto& s ) { s.supply += quantity; }); add_balance( st.issuer, quantity, st.issuer ); if( to != st.issuer ) { SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); } }
string database_fixture::pretty( const asset& a )const { std::stringstream ss; ss << a.amount.value << " "; ss << a.asset_id(db).symbol; return ss.str(); }
void database_fixture::issue_uia( const account_object& recipient, asset amount ) { asset_issue_operation op({asset(),amount.asset_id(db).issuer, amount, recipient.id}); trx.validate(); trx.operations.push_back(op); return; }
uint16_t trx_validation_state::find_unused_sig_output( const address& owner, const asset& bal ) { auto rounded_amount = asset(bal.get_rounded_amount(),bal.unit); ilog( "find unused sig output ${o} ${bal}", ("o", owner)("bal",bal) ); for( uint32_t i = 0; i < trx.outputs.size(); ++i ) { if( used_outputs.find(i) == used_outputs.end() ) { ilog( "out: ${i}", ("i",trx.outputs[i]) ); if( trx.outputs[i].claim_func == claim_by_signature ) { ilog( "amount: ${i} ==? ${r} ", ("i",trx.outputs[i].get_amount())("r",rounded_amount) ); ilog( "round down amount: ${i} ==? ${r} ", ("i",trx.outputs[i].amount/5)("r",rounded_amount.amount.high_bits()/5) ); if( trx.outputs[i].amount/5 == rounded_amount.amount.high_bits()/5 && trx.outputs[i].unit == bal.unit ) { if( trx.outputs[i].as<claim_by_signature_output>().owner == owner ) { return i; } } } } } return output_not_found; }
uint64_t database_fixture::fund( const account_object& account, const asset& amount /* = asset(500000) */ ) { transfer(account_id_type()(db), account, amount); return get_balance(account, amount.asset_id(db)); }
asset operator*(const asset &a, const price &b) { if (a.symbol_name() == b.base.symbol_name()) { FC_ASSERT(b.base.amount.value > 0); uint128_t result = (uint128_t(a.amount.value) * b.quote.amount.value) / b.base.amount.value; FC_ASSERT(result.hi == 0); return asset(result.to_uint64(), b.quote.symbol); } else if (a.symbol_name() == b.quote.symbol_name()) { FC_ASSERT(b.quote.amount.value > 0); uint128_t result = (uint128_t(a.amount.value) * b.base.amount.value) / b.quote.amount.value; FC_ASSERT(result.hi == 0); return asset(result.to_uint64(), b.base.symbol); } FC_THROW_EXCEPTION(fc::assert_exception, "invalid asset * price", ("asset", a)("price", b)); }
asset operator * ( const asset& a, const price& b ) { if( a.symbol_name() == b.base.symbol_name() ) { FC_ASSERT( b.base.amount.value > 0 ); uint128_t result = (uint128_t(a.amount.value) * b.quote.amount.value)/b.base.amount.value; FC_ASSERT( result <= uint64_t(-1) ); return asset( result.to_uint64(), b.quote.symbol ); } else if( a.symbol_name() == b.quote.symbol_name() ) { FC_ASSERT( b.quote.amount.value > 0 ); uint128_t result = (uint128_t(a.amount.value) * b.base.amount.value)/b.quote.amount.value; //FC_ASSERT( result <= STEEMIT_MAX_SHARE_SUPPLY, "${result}", ("result",result)("max",STEEMIT_MAX_SHARE_SUPPLY)("asset",a)("price",b) ); FC_ASSERT( result <= uint64_t(-1) ); return asset( result.to_uint64(), b.base.symbol ); } FC_THROW_EXCEPTION( fc::assert_exception, "invalid asset * price", ("asset",a)("price",b) ); }
void database_fixture::issue_uia( const account_object& recipient, asset amount ) { BOOST_TEST_MESSAGE( "Issuing UIA" ); asset_issue_operation op; op.issuer = amount.asset_id(db).issuer; op.asset_to_issue = amount; op.issue_to_account = recipient.id; trx.operations.push_back(op); db.push_transaction( trx, ~0 ); trx.operations.clear(); }
bool database::fill_order( const call_order_object& order, const asset& pays, const asset& receives ) { try { //idump((pays)(receives)(order)); FC_ASSERT( order.get_debt().asset_id == receives.asset_id ); FC_ASSERT( order.get_collateral().asset_id == pays.asset_id ); FC_ASSERT( order.get_collateral() >= pays ); optional<asset> collateral_freed; modify( order, [&]( call_order_object& o ){ o.debt -= receives.amount; o.collateral -= pays.amount; if( o.debt == 0 ) { collateral_freed = o.get_collateral(); o.collateral = 0; } }); const asset_object& mia = receives.asset_id(*this); assert( mia.is_market_issued() ); const asset_dynamic_data_object& mia_ddo = mia.dynamic_asset_data_id(*this); modify( mia_ddo, [&]( asset_dynamic_data_object& ao ){ //idump((receives)); ao.current_supply -= receives.amount; }); const account_object& borrower = order.borrower(*this); if( collateral_freed || pays.asset_id == asset_id_type() ) { const account_statistics_object& borrower_statistics = borrower.statistics(*this); if( collateral_freed ) adjust_balance(borrower.get_id(), *collateral_freed); modify( borrower_statistics, [&]( account_statistics_object& b ){ if( collateral_freed && collateral_freed->amount > 0 ) b.total_core_in_orders -= collateral_freed->amount; if( pays.asset_id == asset_id_type() ) b.total_core_in_orders -= pays.amount; assert( b.total_core_in_orders >= 0 ); }); } assert( pays.asset_id != receives.asset_id ); push_applied_operation( fill_order_operation{ order.id, order.borrower, pays, receives, asset(0, pays.asset_id) } ); if( collateral_freed ) remove( order ); return collateral_freed.valid(); } FC_CAPTURE_AND_RETHROW( (order)(pays)(receives) ) }
bool database::fill_order( const limit_order_object& order, const asset& pays, const asset& receives ) { try { FC_ASSERT( order.amount_for_sale().asset_id == pays.asset_id ); FC_ASSERT( pays.asset_id != receives.asset_id ); const account_object& seller = order.seller(*this); const asset_object& recv_asset = receives.asset_id(*this); auto issuer_fees = pay_market_fees( recv_asset, receives ); pay_order( seller, receives - issuer_fees, pays ); assert( pays.asset_id != receives.asset_id ); push_applied_operation( fill_order_operation( order.id, order.seller, pays, receives, issuer_fees ) ); // conditional because cheap integer comparison may allow us to avoid two expensive modify() and object lookups if( order.deferred_fee > 0 ) { modify( seller.statistics(*this), [&]( account_statistics_object& statistics ) { statistics.pay_fee( order.deferred_fee, get_global_properties().parameters.cashback_vesting_threshold ); } ); } if( pays == order.amount_for_sale() ) { remove( order ); return true; } else { modify( order, [&]( limit_order_object& b ) { b.for_sale -= pays.amount; b.deferred_fee = 0; }); /** * There are times when the AMOUNT_FOR_SALE * SALE_PRICE == 0 which means that we * have hit the limit where the seller is asking for nothing in return. When this * happens we must refund any balance back to the seller, it is too small to be * sold at the sale price. */ if( order.amount_to_receive().amount == 0 ) { cancel_order(order); return true; } return false; } } FC_CAPTURE_AND_RETHROW( (order)(pays)(receives) ) }
void deposit( const account_name from, const asset& quantity ) { eosio_assert( quantity.is_valid(), "invalid quantiy" ); eosio_assert( quantity.amount > 0, "must deposit positive quantity" ); action ( permission_level { from, N( active ) }, N( eosio.token ), N( transfer ), std::make_tuple( from, _self, quantity, std::string("") ) ).send(); return; }
void token::create( account_name issuer, asset maximum_supply ) { require_auth( _self ); auto sym = maximum_supply.symbol; eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( maximum_supply.is_valid(), "invalid supply"); eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); stats statstable( _self, sym.name() ); auto existing = statstable.find( sym.name() ); eosio_assert( existing == statstable.end(), "token with symbol already exists" ); statstable.emplace( _self, [&]( auto& s ) { s.supply.symbol = maximum_supply.symbol; s.max_supply = maximum_supply; s.issuer = issuer; }); }
bool database::fill_order( const limit_order_object& order, const asset& pays, const asset& receives, bool cull_if_small ) { try { cull_if_small |= (head_block_time() < HARDFORK_555_TIME); FC_ASSERT( order.amount_for_sale().asset_id == pays.asset_id ); FC_ASSERT( pays.asset_id != receives.asset_id ); const account_object& seller = order.seller(*this); const asset_object& recv_asset = receives.asset_id(*this); auto issuer_fees = pay_market_fees( recv_asset, receives ); pay_order( seller, receives - issuer_fees, pays ); assert( pays.asset_id != receives.asset_id ); push_applied_operation( fill_order_operation( order.id, order.seller, pays, receives, issuer_fees ) ); // conditional because cheap integer comparison may allow us to avoid two expensive modify() and object lookups if( order.deferred_fee > 0 ) { modify( seller.statistics(*this), [&]( account_statistics_object& statistics ) { statistics.pay_fee( order.deferred_fee, get_global_properties().parameters.cashback_vesting_threshold ); } ); } if( pays == order.amount_for_sale() ) { remove( order ); return true; } else { modify( order, [&]( limit_order_object& b ) { b.for_sale -= pays.amount; b.deferred_fee = 0; }); if( cull_if_small ) return maybe_cull_small_order( *this, order ); return false; } } FC_CAPTURE_AND_RETHROW( (order)(pays)(receives) ) }
//@abi action void deposit( const account_name from, const asset& quantity ) { eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must deposit positive quantity" ); auto itr = accounts.find(from); if( itr == accounts.end() ) { itr = accounts.emplace(_self, [&](auto& acnt){ acnt.owner = from; }); } action( permission_level{ from, N(active) }, N(eosio.token), N(transfer), std::make_tuple(from, _self, quantity, std::string("")) ).send(); accounts.modify( itr, 0, [&]( auto& acnt ) { acnt.eos_balance += quantity; }); }
bool database::fill_order( const limit_order_object& order, const asset& pays, const asset& receives ) { assert( order.amount_for_sale().asset_id == pays.asset_id ); assert( pays.asset_id != receives.asset_id ); const account_object& seller = order.seller(*this); const asset_object& recv_asset = receives.asset_id(*this); auto issuer_fees = pay_market_fees( recv_asset, receives ); pay_order( seller, receives - issuer_fees, pays ); assert( pays.asset_id != receives.asset_id ); push_applied_operation( fill_order_operation( order.id, order.seller, pays, receives, issuer_fees ) ); if( pays == order.amount_for_sale() ) { remove( order ); return true; } else { modify( order, [&]( limit_order_object& b ) { b.for_sale -= pays.amount; }); /** * There are times when the AMOUNT_FOR_SALE * SALE_PRICE == 0 which means that we * have hit the limit where the seller is asking for nothing in return. When this * happens we must refund any balance back to the seller, it is too small to be * sold at the sale price. */ if( order.amount_to_receive().amount == 0 ) { cancel_order(order); return true; } return false; } }
//@abi action void withdraw( const account_name to, const asset& quantity ) { require_auth( to ); eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must withdraw positive quantity" ); auto itr = accounts.find( to ); eosio_assert(itr != accounts.end(), "unknown account"); accounts.modify( itr, 0, [&]( auto& acnt ) { eosio_assert( acnt.eos_balance >= quantity, "insufficient balance" ); acnt.eos_balance -= quantity; }); action( permission_level{ _self, N(active) }, N(eosio.token), N(transfer), std::make_tuple(_self, to, quantity, std::string("")) ).send(); if( itr->is_empty() ) { accounts.erase(itr); } }
void token::transfer( account_name from, account_name to, asset quantity, string memo ) { eosio_assert( from != to, "cannot transfer to self" ); require_auth( from ); eosio_assert( is_account( to ), "to account does not exist"); auto sym = quantity.symbol.name(); stats statstable( _self, sym ); const auto& st = statstable.get( sym ); require_recipient( from ); require_recipient( to ); eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); sub_balance( from, quantity ); add_balance( to, quantity, from ); }
friend asset operator + (const asset& a, const asset& b) { EOS_ASSERT(a.get_symbol() == b.get_symbol(), asset_type_exception, "addition between two different asset is not allowed"); return asset(a.amount + b.amount, a.get_symbol()); }
friend bool operator < (const asset& a, const asset& b) { EOS_ASSERT(a.get_symbol() == b.get_symbol(), asset_type_exception, "logical operation between two different asset is not allowed"); return std::tie(a.amount,a.get_symbol()) < std::tie(b.amount,b.get_symbol()); }
friend bool operator == (const asset& a, const asset& b) { return std::tie(a.get_symbol(), a.amount) == std::tie(b.get_symbol(), b.amount); }
trx_output( const ClaimType& t, const asset& a ) :amount(a.get_rounded_amount()),unit(a.unit) { claim_func = ClaimType::type; claim_data = fc::raw::pack(t); }
void transaction_evaluation_state::add_output_asset( asset a ) { auto itr = total.find( a.unit ); if( itr == total.end() ) total[a.unit].out = a.get_rounded_amount(); else itr->second.out += a.get_rounded_amount(); }
double to_real()const { return base.to_real() / quote.to_real(); }
void transaction_evaluation_state::add_required_fees( asset a ) { auto itr = total.find( a.unit ); if( itr == total.end() ) total[a.unit].required_fees = a.get_rounded_amount(); else itr->second.required_fees += a.get_rounded_amount(); }