diff --git a/libraries/chain/market_evaluator.cpp b/libraries/chain/market_evaluator.cpp index 10709563..801d6d9c 100644 --- a/libraries/chain/market_evaluator.cpp +++ b/libraries/chain/market_evaluator.cpp @@ -184,7 +184,6 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat call.call_price = price::call_price(o.delta_debt, o.delta_collateral, _bitasset_data->current_feed.maintenance_collateral_ratio); - auto swan_price = call.get_debt()/ call.get_collateral(); }); } else @@ -196,7 +195,6 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat call.debt += o.delta_debt.amount; if( call.debt > 0 ) { - auto swan_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/protocol/asset.cpp b/libraries/chain/protocol/asset.cpp index 251e0824..1d1f8546 100644 --- a/libraries/chain/protocol/asset.cpp +++ b/libraries/chain/protocol/asset.cpp @@ -16,18 +16,20 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -#include #include +#include namespace graphene { namespace chain { + typedef boost::multiprecision::uint128_t uint128_t; + typedef boost::multiprecision::int128_t int128_t; bool operator == ( const price& a, const price& b ) { if( std::tie( a.base.asset_id, a.quote.asset_id ) != std::tie( b.base.asset_id, b.quote.asset_id ) ) return false; - const auto amult = fc::uint128( b.quote.amount.value ) * a.base.amount.value; - const auto bmult = fc::uint128( a.quote.amount.value ) * b.base.amount.value; + const auto amult = uint128_t( b.quote.amount.value ) * a.base.amount.value; + const auto bmult = uint128_t( a.quote.amount.value ) * b.base.amount.value; return amult == bmult; } @@ -39,8 +41,8 @@ namespace graphene { namespace chain { if( a.quote.asset_id < b.quote.asset_id ) return true; if( a.quote.asset_id > b.quote.asset_id ) return false; - const auto amult = fc::uint128( b.quote.amount.value ) * a.base.amount.value; - const auto bmult = fc::uint128( a.quote.amount.value ) * b.base.amount.value; + const auto amult = uint128_t( b.quote.amount.value ) * a.base.amount.value; + const auto bmult = uint128_t( a.quote.amount.value ) * b.base.amount.value; return amult < bmult; } @@ -70,16 +72,16 @@ namespace graphene { namespace chain { if( a.asset_id == b.base.asset_id ) { FC_ASSERT( b.base.amount.value > 0 ); - auto result = (fc::uint128(a.amount.value) * b.quote.amount.value)/b.base.amount.value; + auto result = (uint128_t(a.amount.value) * b.quote.amount.value)/b.base.amount.value; FC_ASSERT( result <= GRAPHENE_MAX_SHARE_SUPPLY ); - return asset( result.to_uint64(), b.quote.asset_id ); + return asset( result, b.quote.asset_id ); } else if( a.asset_id == b.quote.asset_id ) { FC_ASSERT( b.quote.amount.value > 0 ); - auto result = (fc::uint128(a.amount.value) * b.base.amount.value)/b.quote.amount.value; + auto result = (uint128_t(a.amount.value) * b.base.amount.value)/b.quote.amount.value; FC_ASSERT( result <= GRAPHENE_MAX_SHARE_SUPPLY ); - return asset( result.to_uint64(), b.base.asset_id ); + return asset( result, b.base.asset_id ); } FC_THROW_EXCEPTION( fc::assert_exception, "invalid asset * price", ("asset",a)("price",b) ); } @@ -112,9 +114,13 @@ namespace graphene { namespace chain { price price::call_price( const asset& debt, const asset& collateral, uint16_t collateral_ratio) { try { //wdump((debt)(collateral)(collateral_ratio)); - boost::rational swan(debt.amount.value,collateral.amount.value); - boost::rational ratio( collateral_ratio, GRAPHENE_COLLATERAL_RATIO_DENOM ); + boost::rational swan(debt.amount.value,collateral.amount.value); + boost::rational ratio( collateral_ratio, GRAPHENE_COLLATERAL_RATIO_DENOM ); auto cp = swan * ratio; + + while( cp.numerator() > GRAPHENE_MAX_SHARE_SUPPLY || cp.denominator() > GRAPHENE_MAX_SHARE_SUPPLY ) + cp = boost::rational( (cp.numerator() >> 1)+1, (cp.denominator() >> 1)+1 ); + return ~(asset( cp.numerator(), debt.asset_id ) / asset( cp.denominator(), collateral.asset_id )); } FC_CAPTURE_AND_RETHROW( (debt)(collateral)(collateral_ratio) ) } @@ -135,6 +141,8 @@ namespace graphene { namespace chain { FC_ASSERT( maximum_short_squeeze_ratio <= GRAPHENE_MAX_COLLATERAL_RATIO ); FC_ASSERT( maintenance_collateral_ratio >= GRAPHENE_MIN_COLLATERAL_RATIO ); FC_ASSERT( maintenance_collateral_ratio <= GRAPHENE_MAX_COLLATERAL_RATIO ); + max_short_squeeze_price(); // make sure that it doesn't overflow + //FC_ASSERT( maintenance_collateral_ratio >= maximum_short_squeeze_ratio ); } FC_CAPTURE_AND_RETHROW( (*this) ) } @@ -154,9 +162,13 @@ namespace graphene { namespace chain { price price_feed::max_short_squeeze_price()const { - boost::rational sp( settlement_price.base.amount.value, settlement_price.quote.amount.value ); //debt.amount.value,collateral.amount.value); - boost::rational ratio( GRAPHENE_COLLATERAL_RATIO_DENOM, maximum_short_squeeze_ratio ); + boost::rational sp( settlement_price.base.amount.value, settlement_price.quote.amount.value ); //debt.amount.value,collateral.amount.value); + boost::rational ratio( GRAPHENE_COLLATERAL_RATIO_DENOM, maximum_short_squeeze_ratio ); auto cp = sp * ratio; + + while( cp.numerator() > GRAPHENE_MAX_SHARE_SUPPLY || cp.denominator() > GRAPHENE_MAX_SHARE_SUPPLY ) + cp = boost::rational( (cp.numerator() >> 1)+(cp.numerator()&1), (cp.denominator() >> 1)+(cp.denominator()&1) ); + return (asset( cp.numerator(), settlement_price.base.asset_id ) / asset( cp.denominator(), settlement_price.quote.asset_id )); }