int cancel_order_helper() { int x; printf("Please enter the order id: "); scanf("%d", &x); return cancel_order(x); }
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) ) }
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; } }
void database::clear_expired_orders() { detail::with_skip_flags( *this, get_node_properties().skip_flags | skip_authority_check, [&](){ transaction_evaluation_state cancel_context(this); //Cancel expired limit orders auto& limit_index = get_index_type<limit_order_index>().indices().get<by_expiration>(); while( !limit_index.empty() && limit_index.begin()->expiration <= head_block_time() ) { limit_order_cancel_operation canceler; const limit_order_object& order = *limit_index.begin(); canceler.fee_paying_account = order.seller; canceler.order = order.id; apply_operation(cancel_context, canceler); } }); //Process expired force settlement orders auto& settlement_index = get_index_type<force_settlement_index>().indices().get<by_expiration>(); if( !settlement_index.empty() ) { asset_id_type current_asset = settlement_index.begin()->settlement_asset_id(); asset max_settlement_volume; auto next_asset = [¤t_asset, &settlement_index] { auto bound = settlement_index.upper_bound(current_asset); if( bound == settlement_index.end() ) return false; current_asset = bound->settlement_asset_id(); return true; }; // At each iteration, we either consume the current order and remove it, or we move to the next asset for( auto itr = settlement_index.lower_bound(current_asset); itr != settlement_index.end(); itr = settlement_index.lower_bound(current_asset) ) { const force_settlement_object& order = *itr; auto order_id = order.id; current_asset = order.settlement_asset_id(); const asset_object& mia_object = get(current_asset); const asset_bitasset_data_object mia = mia_object.bitasset_data(*this); // Has this order not reached its settlement date? if( order.settlement_date > head_block_time() ) { if( next_asset() ) continue; break; } // Can we still settle in this asset? if( mia.current_feed.settlement_price.is_null() ) { ilog("Canceling a force settlement in ${asset} because settlement price is null", ("asset", mia_object.symbol)); cancel_order(order); continue; } if( max_settlement_volume.asset_id != current_asset ) max_settlement_volume = mia_object.amount(mia.max_force_settlement_volume(mia_object.dynamic_data(*this).current_supply)); if( mia.force_settled_volume >= max_settlement_volume.amount ) { /* ilog("Skipping force settlement in ${asset}; settled ${settled_volume} / ${max_volume}", ("asset", mia_object.symbol)("settlement_price_null",mia.current_feed.settlement_price.is_null()) ("settled_volume", mia.force_settled_volume)("max_volume", max_settlement_volume)); */ if( next_asset() ) continue; break; } auto& pays = order.balance; auto receives = (order.balance * mia.current_feed.settlement_price); receives.amount = (fc::uint128_t(receives.amount.value) * (GRAPHENE_100_PERCENT - mia.options.force_settlement_offset_percent) / GRAPHENE_100_PERCENT).to_uint64(); assert(receives <= order.balance * mia.current_feed.settlement_price); price settlement_price = pays / receives; auto& call_index = get_index_type<call_order_index>().indices().get<by_collateral>(); asset settled = mia_object.amount(mia.force_settled_volume); // Match against the least collateralized short until the settlement is finished or we reach max settlements while( settled < max_settlement_volume && find_object(order_id) ) { auto itr = call_index.lower_bound(boost::make_tuple(price::min(mia_object.bitasset_data(*this).options.short_backing_asset, mia_object.get_id()))); // There should always be a call order, since asset exists! assert(itr != call_index.end() && itr->debt_type() == mia_object.get_id()); asset max_settlement = max_settlement_volume - settled; settled += match(*itr, order, settlement_price, max_settlement); } modify(mia, [settled](asset_bitasset_data_object& b) { b.force_settled_volume = settled.amount; }); } } }