diff --git a/libraries/chain/asset.cpp b/libraries/chain/asset.cpp index ef73dd73..22a2dd6a 100644 --- a/libraries/chain/asset.cpp +++ b/libraries/chain/asset.cpp @@ -99,12 +99,21 @@ namespace graphene { namespace chain { } price price::max( asset_id_type base, asset_id_type quote ) { return asset( share_type(GRAPHENE_MAX_SHARE_SUPPLY), base ) / asset( share_type(1), quote); } price price::min( asset_id_type base, asset_id_type quote ) { return asset( 1, base ) / asset( GRAPHENE_MAX_SHARE_SUPPLY, quote); } - + + /** + * The black swan price is defined as debt/collateral, we want to perform a margin call + * before debt == collateral. Given a debt/collateral ratio of 1 USD / CORE and + * a maintenance collateral requirement of 2x we can define the call price to be + * 2 USD / CORE. + * + * This method divides the collateral by the maintenance collateral ratio to derive + * a call price for the given black swan ratio. + */ price price::call_price(const asset& debt, const asset& collateral, uint16_t collateral_ratio) { try { fc::uint128 tmp( collateral.amount.value ); - tmp *= collateral_ratio - 1000; - tmp /= 1000; + tmp *= 1000; + tmp /= collateral_ratio; FC_ASSERT( tmp <= GRAPHENE_MAX_SHARE_SUPPLY ); return asset( tmp.to_uint64(), collateral.asset_id) / debt; } FC_CAPTURE_AND_RETHROW( (debt)(collateral)(collateral_ratio) ) } @@ -125,7 +134,8 @@ namespace graphene { namespace chain { FC_ASSERT( maximum_short_squeeze_ratio >= GRAPHENE_MIN_COLLATERAL_RATIO ); FC_ASSERT( maximum_short_squeeze_ratio <= GRAPHENE_MAX_COLLATERAL_RATIO ); FC_ASSERT( maintenance_collateral_ratio >= GRAPHENE_MIN_COLLATERAL_RATIO ); - FC_ASSERT( maintenance_collateral_ratio <= maximum_short_squeeze_ratio ); + FC_ASSERT( maintenance_collateral_ratio <= GRAPHENE_MAX_COLLATERAL_RATIO ); + //FC_ASSERT( maintenance_collateral_ratio >= maximum_short_squeeze_ratio ); } FC_CAPTURE_AND_RETHROW( (*this) ) } price price_feed::max_short_squeeze_price()const @@ -138,6 +148,7 @@ namespace graphene { namespace chain { collateral.amount = tmp.to_uint64(); return settlement_price.base / collateral; } + /* price price_feed::maintenance_price()const { asset collateral = settlement_price.quote; @@ -148,6 +159,7 @@ namespace graphene { namespace chain { collateral.amount = tmp.to_uint64(); return settlement_price.base / collateral; } + */ } } // graphene::chain diff --git a/libraries/chain/call_order_evaluator.cpp b/libraries/chain/call_order_evaluator.cpp index ec6e6638..b508d49f 100644 --- a/libraries/chain/call_order_evaluator.cpp +++ b/libraries/chain/call_order_evaluator.cpp @@ -67,7 +67,6 @@ void_result call_order_update_evaluator::do_evaluate(const call_order_update_ope void_result call_order_update_evaluator::do_apply(const call_order_update_operation& o) { try { database& d = db(); - //wdump( (_bitasset_data->current_feed) ); if( o.delta_debt.amount != 0 ) { @@ -104,11 +103,12 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat FC_ASSERT( o.delta_debt.amount > 0 ); call_obj = &d.create( [&](call_order_object& call ){ - call.borrower = o.funding_account; - call.collateral = o.delta_collateral.amount; - call.debt = o.delta_debt.amount; - call.call_price = ~o.call_price; - }); + call.borrower = o.funding_account; + call.collateral = o.delta_collateral.amount; + call.debt = o.delta_debt.amount; + call.call_price = price::call_price(o.delta_debt, o.delta_collateral, + _bitasset_data->current_feed.maintenance_collateral_ratio); + }); } else { @@ -117,41 +117,32 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat d.modify( *call_obj, [&]( call_order_object& call ){ call.collateral += o.delta_collateral.amount; call.debt += o.delta_debt.amount; - call.call_price = ~o.call_price; + call.call_price = price::call_price(call.get_debt(), call.get_collateral(), + _bitasset_data->current_feed.maintenance_collateral_ratio); }); } auto debt = call_obj->get_debt(); - if( debt.amount == 0 ) + if( debt.amount == 0 ) { FC_ASSERT( call_obj->collateral == 0 ); d.remove( *call_obj ); return void_result(); } - /** then we must check for margin calls and other issues */ + FC_ASSERT(call_obj->collateral > 0 && call_obj->debt > 0); + + // then we must check for margin calls and other issues if( !_bitasset_data->is_prediction_market ) { - auto collateral = call_obj->get_collateral(); - auto mp = _bitasset_data->current_feed.maintenance_price(); - - // edump((debt)(collateral)((debt/collateral).to_real())(mp.to_real()) ); - // edump((debt*mp)); - /// paying off the debt at the user specified call price should require - /// less collateral than paying off the debt at the maitenance price - auto col_at_call_price = debt * o.call_price; - auto col_at_min_callprice = debt * mp; - FC_ASSERT( col_at_call_price <= col_at_min_callprice, "", ("debt*o.callprice",debt*o.call_price)("debt*mp",debt*mp) ); - FC_ASSERT( col_at_call_price <= collateral ); - - //wdump( (o.call_price)(mp)(call_obj->call_price.to_real())(mp.to_real()) ); - //FC_ASSERT( call_obj->call_price <= mp ); + // Check that the order's debt per collateral is less than the system's minimum debt per collateral. + FC_ASSERT( ~call_obj->call_price <= _bitasset_data->current_feed.settlement_price, + "Insufficient collateral for debt.", + ("a", ~call_obj->call_price)("b", _bitasset_data->current_feed.settlement_price)); auto call_order_id = call_obj->id; - //ilog( "checking call orders" ); - - // check to see if the order needs to be margin called now, but don't allow black swans and require there to be + // check to see if the order needs to be margin called now, but don't allow black swans and require there to be // limit orders available that could be used to fill the order. if( d.check_call_orders( *_debt_asset, false ) ) { diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index b9b3bb7c..da0013d7 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -333,10 +333,11 @@ bool database::check_call_orders( const asset_object& mia, bool enable_black_swa auto max_price = price::max( mia.id, bitasset.options.short_backing_asset ); // stop when limit orders are selling too little USD for too much CORE auto min_price = bitasset.current_feed.max_short_squeeze_price(); + /* // edump((bitasset.current_feed)); - // edump((min_price.to_real())(min_price)); + edump((min_price.to_real())(min_price)); + edump((max_price.to_real())(max_price)); //auto min_price = price::min( mia.id, bitasset.options.short_backing_asset ); -/* idump((bitasset.current_feed.settlement_price)(bitasset.current_feed.settlement_price.to_real())); { for( const auto& order : limit_price_index ) @@ -353,7 +354,7 @@ bool database::check_call_orders( const asset_object& mia, bool enable_black_swa */ assert( max_price.base.asset_id == min_price.base.asset_id ); - // wlog( "from ${a} Debt/Col to ${b} Debt/Col ", ("a", max_price.to_real())("b",min_price.to_real()) ); + wlog( "from ${a} Debt/Col to ${b} Debt/Col ", ("a", max_price.to_real())("b",min_price.to_real()) ); // NOTE limit_price_index is sorted from greatest to least auto limit_itr = limit_price_index.lower_bound( max_price ); auto limit_end = limit_price_index.upper_bound( min_price ); diff --git a/libraries/chain/include/graphene/chain/asset.hpp b/libraries/chain/include/graphene/chain/asset.hpp index 576768de..d5f12cba 100644 --- a/libraries/chain/include/graphene/chain/asset.hpp +++ b/libraries/chain/include/graphene/chain/asset.hpp @@ -157,8 +157,8 @@ namespace graphene { namespace chain { * debt * maintenance_price() < collateral * debt * settlement_price < debt * maintenance * debt * maintenance_price() < debt * max_short_squeeze_price() - */ price maintenance_price()const; + */ /** When selling collateral to pay off debt, the least amount of debt to receive should be * min_usd = max_short_squeeze_price() * collateral diff --git a/libraries/chain/include/graphene/chain/call_order_object.hpp b/libraries/chain/include/graphene/chain/call_order_object.hpp index 67fae188..ea00217e 100644 --- a/libraries/chain/include/graphene/chain/call_order_object.hpp +++ b/libraries/chain/include/graphene/chain/call_order_object.hpp @@ -48,7 +48,7 @@ namespace graphene { namespace chain { account_id_type borrower; share_type collateral; ///< call_price.base.asset_id, access via get_collateral share_type debt; ///< call_price.quote.asset_id, access via get_collateral - price call_price; + price call_price; ///< Debt / Collateral }; /** diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 5ff44984..7cb2db1c 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -64,8 +64,8 @@ // These are NOT percentages #define GRAPHENE_MIN_COLLATERAL_RATIO 1001 // lower than this could result in divide by 0 #define GRAPHENE_MAX_COLLATERAL_RATIO 32000 // higher than this is unnecessary and may exceed int16 storage -#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO 1500 // We require collateral of 1.5x or more -#define GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO 1750 // If there is a squeeze you are protected up to 1.75x... but black swan could occur first +#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO 1750 // Call when collateral only pays off 175% the debt +#define GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO 1500 // Stop calling when collateral only pays off 150% of the debt #define GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC (30*60*60*24) #define GRAPHENE_DEFAULT_NUM_WITNESSES (101) diff --git a/libraries/chain/include/graphene/chain/operations.hpp b/libraries/chain/include/graphene/chain/operations.hpp index 39f46a5c..6e9744ac 100644 --- a/libraries/chain/include/graphene/chain/operations.hpp +++ b/libraries/chain/include/graphene/chain/operations.hpp @@ -845,7 +845,6 @@ namespace graphene { namespace chain { account_id_type funding_account; ///< pays fee, collateral, and cover asset delta_collateral; ///< the amount of collateral to add to the margin position asset delta_debt; ///< the amount of the debt to be paid off, may be negative to issue new debt - price call_price; ///< the price at which the collateral will be sold to cover the debt account_id_type fee_payer()const { return funding_account; } void get_required_auth(flat_set& active_auth_set, flat_set&)const; @@ -1504,7 +1503,7 @@ FC_REFLECT( graphene::chain::limit_order_create_operation, ) FC_REFLECT( graphene::chain::fill_order_operation, (fee)(order_id)(account_id)(pays)(receives) ) FC_REFLECT( graphene::chain::limit_order_cancel_operation,(fee)(fee_paying_account)(order) ) -FC_REFLECT( graphene::chain::call_order_update_operation, (fee)(funding_account)(delta_collateral)(delta_debt)(call_price) ) +FC_REFLECT( graphene::chain::call_order_update_operation, (fee)(funding_account)(delta_collateral)(delta_debt) ) FC_REFLECT( graphene::chain::transfer_operation, (fee)(from)(to)(amount)(memo) ) diff --git a/libraries/chain/operations.cpp b/libraries/chain/operations.cpp index c8f8dbb3..73540f23 100644 --- a/libraries/chain/operations.cpp +++ b/libraries/chain/operations.cpp @@ -402,9 +402,7 @@ void call_order_update_operation::validate()const { try { FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( delta_collateral.asset_id != delta_debt.asset_id ); - FC_ASSERT( delta_debt.asset_id == call_price.base.asset_id ); - FC_ASSERT( delta_collateral.asset_id == call_price.quote.asset_id ); - call_price.validate(); + FC_ASSERT( delta_collateral.amount != 0 || delta_debt.amount != 0 ); } FC_CAPTURE_AND_RETHROW((*this)) } share_type call_order_update_operation::calculate_fee(const fee_schedule_type& k) const diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 96b50c9c..e74a34b3 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -716,22 +716,22 @@ void database_fixture::force_settle( const account_object& who, asset what ) trx.operations.clear(); } FC_CAPTURE_AND_RETHROW( (who)(what) ) } -void database_fixture::borrow( const account_object& who, asset what, asset collateral, price call_price ) +void database_fixture::borrow(const account_object& who, asset what, asset collateral) { try { trx.set_expiration(db.head_block_time() + fc::minutes(1)); trx.operations.clear(); - trx.operations.push_back( call_order_update_operation({ asset(), who.id, collateral, what, call_price }));; + trx.operations.push_back(call_order_update_operation({asset(), who.id, collateral, what}));; for( auto& op : trx.operations ) op.visit( operation_set_fee( db.current_fee_schedule() ) ); trx.validate(); db.push_transaction(trx, ~0); trx.operations.clear(); } FC_CAPTURE_AND_RETHROW( (who.name)(what)(collateral) ) } -void database_fixture::cover( const account_object& who, asset what, asset collateral, price call_price ) +void database_fixture::cover(const account_object& who, asset what, asset collateral) { try { trx.set_expiration(db.head_block_time() + fc::minutes(1)); trx.operations.clear(); - trx.operations.push_back( call_order_update_operation({ asset(), who.id, -collateral, -what, call_price })); + trx.operations.push_back( call_order_update_operation({asset(), who.id, -collateral, -what})); for( auto& op : trx.operations ) op.visit( operation_set_fee( db.current_fee_schedule() ) ); trx.validate(); db.push_transaction(trx, ~0); diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index edbead03..827dd081 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -151,10 +151,8 @@ struct database_fixture { void force_settle(const account_object& who, asset what); void update_feed_producers(const asset_object& mia, flat_set producers); void publish_feed(const asset_object& mia, const account_object& by, const price_feed& f); - void borrow(account_id_type who, asset what, asset collateral, price call_price = price()) - { borrow(who(db), what, collateral, call_price); } - void borrow(const account_object& who, asset what, asset collateral, price call_price); - void cover(const account_object& who, asset what, asset collateral_freed, price call_price = price()); + void borrow(const account_object& who, asset what, asset collateral); + void cover(const account_object& who, asset what, asset collateral_freed); const asset_object& get_asset( const string& symbol )const; const account_object& get_account( const string& name )const; diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index ed182860..800fe906 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -42,13 +42,27 @@ BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture ) BOOST_AUTO_TEST_CASE( feed_limit_logic_test ) { try { - asset usd(100,1); - asset core(100,0); + asset usd(1000,1); + asset core(1000,0); price_feed feed; feed.settlement_price = usd / core; - FC_ASSERT( usd * feed.settlement_price < usd * feed.maintenance_price() ); - FC_ASSERT( usd * feed.maintenance_price() < usd * feed.max_short_squeeze_price() ); + // require 3x min collateral + auto swanp = usd / core; + auto callp = ~price::call_price( usd, core, 1750 ); + // 1:1 collateral + wdump((callp.to_real())(callp)); + wdump((swanp.to_real())(swanp)); + FC_ASSERT( callp.to_real() > swanp.to_real() ); + + /* + wdump((feed.settlement_price.to_real())); + wdump((feed.maintenance_price().to_real())); + wdump((feed.max_short_squeeze_price().to_real())); + + BOOST_CHECK( usd * feed.settlement_price < usd * feed.maintenance_price() ); + BOOST_CHECK( usd * feed.maintenance_price() < usd * feed.max_short_squeeze_price() ); + */ } catch (fc::exception& e) { edump((e.to_detail_string())); @@ -70,65 +84,58 @@ BOOST_AUTO_TEST_CASE( call_order_update_test ) FC_ASSERT( bitusd.bitasset_data(db).current_feed.settlement_price == current_feed.settlement_price ); - auto default_call_price = ~price::call_price( bitusd.amount(5000), asset(5000), 1750); - BOOST_TEST_MESSAGE( "attempting to borrow using 2x collateral at 1:1 price now that there is a valid order" ); - borrow( dan, bitusd.amount(5000), asset(10000), default_call_price ); + borrow( dan, bitusd.amount(5000), asset(10000)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 5000 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 10000 ); BOOST_TEST_MESSAGE( "covering 2500 usd and freeing 5000 core..." ); - cover( dan, bitusd.amount(2500), asset(5000), default_call_price ); + cover( dan, bitusd.amount(2500), asset(5000)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 2500 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 10000 + 5000 ); BOOST_TEST_MESSAGE( "verifying that attempting to cover the full amount without claiming the collateral fails" ); - BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(2500), core.amount(0), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(2500), core.amount(0) ), fc::exception ); - cover( dan, bitusd.amount(2500), core.amount(5000), default_call_price ); + cover( dan, bitusd.amount(2500), core.amount(5000)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 0 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 ); - borrow( dan, bitusd.amount(5000), asset(10000), default_call_price ); + borrow( dan, bitusd.amount(5000), asset(10000)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 5000 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 10000 ); // test just increasing collateral BOOST_TEST_MESSAGE( "increasing collateral" ); - borrow( dan, bitusd.amount(0), asset(10000), default_call_price ); + borrow( dan, bitusd.amount(0), asset(10000)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 5000 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 20000 ); // test just decreasing debt BOOST_TEST_MESSAGE( "decreasing debt" ); - cover( dan, bitusd.amount(1000), asset(0), default_call_price ); + cover( dan, bitusd.amount(1000), asset(0)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 4000 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 20000 ); BOOST_TEST_MESSAGE( "increasing debt without increasing collateral" ); - borrow( dan, bitusd.amount(1000), asset(0), default_call_price ); + borrow( dan, bitusd.amount(1000), asset(0)); BOOST_REQUIRE_EQUAL( get_balance( dan, bitusd ), 5000 ); BOOST_REQUIRE_EQUAL( get_balance( dan, core ), 10000000 - 20000 ); BOOST_TEST_MESSAGE( "increasing debt without increasing collateral again" ); - BOOST_REQUIRE_THROW( borrow( dan, bitusd.amount(80000), asset(0), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( borrow( dan, bitusd.amount(80000), asset(0)), fc::exception ); BOOST_TEST_MESSAGE( "attempting to claim all collateral without paying off debt" ); - BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(0), asset(20000), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(0), asset(20000)), fc::exception ); BOOST_TEST_MESSAGE( "attempting reduce collateral without paying off any debt" ); - cover( dan, bitusd.amount(0), asset(1000), default_call_price ); - - BOOST_TEST_MESSAGE( "attempting change call price without changing debt/collateral ratio" ); - default_call_price = ~price::call_price( bitusd.amount(100), asset(50), 1750); - cover( dan, bitusd.amount(0), asset(0), default_call_price ); + cover( dan, bitusd.amount(0), asset(1000)); BOOST_TEST_MESSAGE( "attempting change call price to be below minimum for debt/collateral ratio" ); - default_call_price = ~price::call_price( bitusd.amount(100), asset(500), 1750); - BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(0), asset(0), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( cover( dan, bitusd.amount(0), asset(0)), fc::exception ); } catch (fc::exception& e) { edump((e.to_detail_string())); @@ -166,14 +173,13 @@ BOOST_AUTO_TEST_CASE( margin_call_limit_test ) price_feed current_feed; current_feed.settlement_price = bitusd.amount( 100 ) / core.amount(100); - auto default_call_price = ~price::call_price( bitusd.amount(100), asset(100), 1750); // starting out with price 1:1 publish_feed( bitusd, feedproducer, current_feed ); // start out with 2:1 collateral - borrow( borrower, bitusd.amount(1000), asset(2000), default_call_price ); - borrow( borrower2, bitusd.amount(1000), asset(4000), default_call_price ); + borrow( borrower, bitusd.amount(1000), asset(2000)); + borrow( borrower2, bitusd.amount(1000), asset(4000) ); BOOST_REQUIRE_EQUAL( get_balance( borrower, bitusd ), 1000 ); BOOST_REQUIRE_EQUAL( get_balance( borrower2, bitusd ), 1000 ); @@ -194,8 +200,8 @@ BOOST_AUTO_TEST_CASE( margin_call_limit_test ) BOOST_TEST_MESSAGE( "Creating a margin call that is protected by the max short squeeze price" ); - borrow( borrower, bitusd.amount(1000), asset(2000), default_call_price ); - borrow( borrower2, bitusd.amount(1000), asset(4000), default_call_price ); + borrow( borrower, bitusd.amount(1000), asset(2000) ); + borrow( borrower2, bitusd.amount(1000), asset(4000) ); // this should trigger margin call without protection from the price feed. order = create_sell_order( borrower2, bitusd.amount(1000), core.amount(1800) ); @@ -226,14 +232,13 @@ BOOST_AUTO_TEST_CASE( black_swan ) price_feed current_feed; current_feed.settlement_price = bitusd.amount( 100 ) / core.amount(100); - auto default_call_price = ~price::call_price( bitusd.amount(100), asset(100), 1750); // starting out with price 1:1 publish_feed( bitusd, feedproducer, current_feed ); // start out with 2:1 collateral - borrow( borrower, bitusd.amount(1000), asset(2000), default_call_price ); - borrow( borrower2, bitusd.amount(1000), asset(4000), default_call_price ); + borrow( borrower, bitusd.amount(1000), asset(2000) ); + borrow( borrower2, bitusd.amount(1000), asset(4000) ); BOOST_REQUIRE_EQUAL( get_balance( borrower, bitusd ), 1000 ); BOOST_REQUIRE_EQUAL( get_balance( borrower2, bitusd ), 1000 ); @@ -249,9 +254,9 @@ BOOST_AUTO_TEST_CASE( black_swan ) FC_ASSERT( bitusd.bitasset_data(db).has_settlement() ); force_settle( borrower, bitusd.amount(100) ); - + BOOST_TEST_MESSAGE( "Verify that we cannot borrow after black swan" ); - BOOST_REQUIRE_THROW( borrow( borrower, bitusd.amount(1000), asset(2000), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( borrow( borrower, bitusd.amount(1000), asset(2000) ), fc::exception ); } catch( const fc::exception& e) { edump((e.to_detail_string())); throw; @@ -270,23 +275,21 @@ BOOST_AUTO_TEST_CASE( prediction_market ) transfer(genesis_account, dan_id, asset(init_balance)); transfer(genesis_account, nathan_id, asset(init_balance)); - auto default_call_price = ~price::call_price( pmark.amount(100), asset(100), 1750); - BOOST_TEST_MESSAGE( "Require throw for mismatch collateral amounts" ); - BOOST_REQUIRE_THROW( borrow( dan, pmark.amount(1000), asset(2000), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( borrow( dan, pmark.amount(1000), asset(2000) ), fc::exception ); BOOST_TEST_MESSAGE( "Open position with equal collateral" ); - borrow( dan, pmark.amount(1000), asset(1000), default_call_price ); + borrow( dan, pmark.amount(1000), asset(1000) ); BOOST_TEST_MESSAGE( "Cover position with unequal asset should fail." ); - BOOST_REQUIRE_THROW( cover( dan, pmark.amount(500), asset(1000), default_call_price ), fc::exception ); + BOOST_REQUIRE_THROW( cover( dan, pmark.amount(500), asset(1000) ), fc::exception ); BOOST_TEST_MESSAGE( "Cover half of position with equal ammounts" ); - cover( dan, pmark.amount(500), asset(500), default_call_price ); + cover( dan, pmark.amount(500), asset(500) ); BOOST_TEST_MESSAGE( "Verify that forced settlment fails before global settlement" ); BOOST_REQUIRE_THROW( force_settle( dan, pmark.amount(100) ), fc::exception ); - + BOOST_TEST_MESSAGE( "Shouldn't be allowed to force settle at more than 1 collateral per debt" ); BOOST_REQUIRE_THROW( force_global_settle( pmark, pmark.amount(100) / core.amount(105) ), fc::exception );