diff --git a/libraries/chain/asset.cpp b/libraries/chain/asset.cpp index 80874c72..22a2dd6a 100644 --- a/libraries/chain/asset.cpp +++ b/libraries/chain/asset.cpp @@ -99,26 +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 call price is defined so that the collateral is able to purchase debt * collateral ratio. + * 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. * - * Give a margin order with @ref debt and @ref collateral we can infer the market price that - * would be necessary to maintain the invariant that the collateral can purchase debt * collateral ratio - * - * (debt / collateral_ratio) / collateral == fair market price - * - * Stated another way: - * - * C * R / D - * - * This method only works if attempting to calculate the call price from a margin position. + * 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) ) } diff --git a/libraries/chain/call_order_evaluator.cpp b/libraries/chain/call_order_evaluator.cpp index 517473d4..b508d49f 100644 --- a/libraries/chain/call_order_evaluator.cpp +++ b/libraries/chain/call_order_evaluator.cpp @@ -106,7 +106,7 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat 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, + call.call_price = price::call_price(o.delta_debt, o.delta_collateral, _bitasset_data->current_feed.maintenance_collateral_ratio); }); } @@ -117,7 +117,7 @@ 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 = ~price::call_price(call.get_debt(), call.get_collateral(), + call.call_price = price::call_price(call.get_debt(), call.get_collateral(), _bitasset_data->current_feed.maintenance_collateral_ratio); }); } diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index 1cc21373..da0013d7 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -333,6 +333,7 @@ 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((max_price.to_real())(max_price)); @@ -350,6 +351,7 @@ bool database::check_call_orders( const asset_object& mia, bool enable_black_swa wdump((max_price)(max_price.to_real())); wdump((min_price)(min_price.to_real())); } + */ 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()) ); diff --git a/libraries/fc b/libraries/fc index dde8ed9d..c09035db 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit dde8ed9d7ab49807f2556488c0815f3741b11e00 +Subproject commit c09035dba0cdab7fcb2c11bf81aaeaffaa981f66 diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index a1b57a8a..800fe906 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -42,11 +42,19 @@ 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; + // 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()));