220 lines
8.3 KiB
C++
220 lines
8.3 KiB
C++
/*
|
|
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
|
|
*
|
|
* The MIT License
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
#pragma once
|
|
#include <graphene/chain/protocol/config.hpp>
|
|
#include <graphene/chain/protocol/types.hpp>
|
|
|
|
namespace graphene { namespace chain {
|
|
|
|
extern const int64_t scaled_precision_lut[];
|
|
|
|
struct asset
|
|
{
|
|
asset( share_type a = 0, asset_id_type id = asset_id_type() )
|
|
:amount(a),asset_id(id){}
|
|
|
|
share_type amount;
|
|
asset_id_type asset_id;
|
|
|
|
asset& operator += ( const asset& o )
|
|
{
|
|
FC_ASSERT( asset_id == o.asset_id );
|
|
amount += o.amount;
|
|
return *this;
|
|
}
|
|
asset& operator -= ( const asset& o )
|
|
{
|
|
FC_ASSERT( asset_id == o.asset_id );
|
|
amount -= o.amount;
|
|
return *this;
|
|
}
|
|
asset operator -()const { return asset( -amount, asset_id ); }
|
|
|
|
friend bool operator == ( const asset& a, const asset& b )
|
|
{
|
|
return std::tie( a.asset_id, a.amount ) == std::tie( b.asset_id, b.amount );
|
|
}
|
|
friend bool operator < ( const asset& a, const asset& b )
|
|
{
|
|
FC_ASSERT( a.asset_id == b.asset_id );
|
|
return a.amount < b.amount;
|
|
}
|
|
friend bool operator <= ( const asset& a, const asset& b )
|
|
{
|
|
return (a == b) || (a < b);
|
|
}
|
|
|
|
friend bool operator != ( const asset& a, const asset& b )
|
|
{
|
|
return !(a == b);
|
|
}
|
|
friend bool operator > ( const asset& a, const asset& b )
|
|
{
|
|
return !(a <= b);
|
|
}
|
|
friend bool operator >= ( const asset& a, const asset& b )
|
|
{
|
|
return !(a < b);
|
|
}
|
|
|
|
friend asset operator - ( const asset& a, const asset& b )
|
|
{
|
|
FC_ASSERT( a.asset_id == b.asset_id );
|
|
return asset( a.amount - b.amount, a.asset_id );
|
|
}
|
|
friend asset operator + ( const asset& a, const asset& b )
|
|
{
|
|
FC_ASSERT( a.asset_id == b.asset_id );
|
|
return asset( a.amount + b.amount, a.asset_id );
|
|
}
|
|
|
|
static share_type scaled_precision( uint8_t precision )
|
|
{
|
|
FC_ASSERT( precision < 19 );
|
|
return scaled_precision_lut[ precision ];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief The price struct stores asset prices in the Graphene system.
|
|
*
|
|
* A price is defined as a ratio between two assets, and represents a possible exchange rate between those two
|
|
* assets. prices are generally not stored in any simplified form, i.e. a price of (1000 CORE)/(20 USD) is perfectly
|
|
* normal.
|
|
*
|
|
* The assets within a price are labeled base and quote. Throughout the Graphene code base, the convention used is
|
|
* that the base asset is the asset being sold, and the quote asset is the asset being purchased, where the price is
|
|
* represented as base/quote, so in the example price above the seller is looking to sell CORE asset and get USD in
|
|
* return.
|
|
*/
|
|
struct price
|
|
{
|
|
price(const asset& base = asset(), const asset quote = asset())
|
|
: base(base),quote(quote){}
|
|
|
|
asset base;
|
|
asset quote;
|
|
|
|
static price max(asset_id_type base, asset_id_type quote );
|
|
static price min(asset_id_type base, asset_id_type quote );
|
|
|
|
static price call_price(const asset& debt, const asset& collateral, uint16_t collateral_ratio);
|
|
|
|
/// The unit price for an asset type A is defined to be a price such that for any asset m, m*A=m
|
|
static price unit_price(asset_id_type a = asset_id_type()) { return price(asset(1, a), asset(1, a)); }
|
|
|
|
price max()const { return price::max( base.asset_id, quote.asset_id ); }
|
|
price min()const { return price::min( base.asset_id, quote.asset_id ); }
|
|
|
|
double to_real()const { return double(base.amount.value)/double(quote.amount.value); }
|
|
|
|
bool is_null()const;
|
|
void validate()const;
|
|
};
|
|
|
|
price operator / ( const asset& base, const asset& quote );
|
|
inline price operator~( const price& p ) { return price{p.quote,p.base}; }
|
|
|
|
bool operator < ( const asset& a, const asset& b );
|
|
bool operator <= ( const asset& a, const asset& b );
|
|
bool operator < ( const price& a, const price& b );
|
|
bool operator <= ( const price& a, const price& b );
|
|
bool operator > ( const price& a, const price& b );
|
|
bool operator >= ( const price& a, const price& b );
|
|
bool operator == ( const price& a, const price& b );
|
|
bool operator != ( const price& a, const price& b );
|
|
asset operator * ( const asset& a, const price& b );
|
|
|
|
/**
|
|
* @class price_feed
|
|
* @brief defines market parameters for margin positions
|
|
*/
|
|
struct price_feed
|
|
{
|
|
/**
|
|
* Required maintenance collateral is defined
|
|
* as a fixed point number with a maximum value of 10.000
|
|
* and a minimum value of 1.000. (denominated in GRAPHENE_COLLATERAL_RATIO_DENOM)
|
|
*
|
|
* A black swan event occurs when value_of_collateral equals
|
|
* value_of_debt, to avoid a black swan a margin call is
|
|
* executed when value_of_debt * required_maintenance_collateral
|
|
* equals value_of_collateral using rate.
|
|
*
|
|
* Default requirement is $1.75 of collateral per $1 of debt
|
|
*
|
|
* BlackSwan ---> SQR ---> MCR ----> SP
|
|
*/
|
|
///@{
|
|
/**
|
|
* Forced settlements will evaluate using this price, defined as BITASSET / COLLATERAL
|
|
*/
|
|
price settlement_price;
|
|
|
|
/// Price at which automatically exchanging this asset for CORE from fee pool occurs (used for paying fees)
|
|
price core_exchange_rate;
|
|
|
|
/** Fixed point between 1.000 and 10.000, implied fixed point denominator is GRAPHENE_COLLATERAL_RATIO_DENOM */
|
|
uint16_t maintenance_collateral_ratio = GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO;
|
|
|
|
/** Fixed point between 1.000 and 10.000, implied fixed point denominator is GRAPHENE_COLLATERAL_RATIO_DENOM */
|
|
uint16_t maximum_short_squeeze_ratio = GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO;
|
|
|
|
/**
|
|
* When updating a call order the following condition must be maintained:
|
|
*
|
|
* 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
|
|
*
|
|
* This is provided to ensure that a black swan cannot be trigged due to poor liquidity alone, it
|
|
* must be confirmed by having the max_short_squeeze_price() move below the black swan price.
|
|
*/
|
|
price max_short_squeeze_price()const;
|
|
///@}
|
|
|
|
friend bool operator == ( const price_feed& a, const price_feed& b )
|
|
{
|
|
return std::tie( a.settlement_price, a.maintenance_collateral_ratio, a.maximum_short_squeeze_ratio ) ==
|
|
std::tie( b.settlement_price, b.maintenance_collateral_ratio, b.maximum_short_squeeze_ratio );
|
|
}
|
|
|
|
void validate() const;
|
|
bool is_for( asset_id_type asset_id ) const;
|
|
};
|
|
|
|
} }
|
|
|
|
FC_REFLECT( graphene::chain::asset, (amount)(asset_id) )
|
|
FC_REFLECT( graphene::chain::price, (base)(quote) )
|
|
|
|
#define GRAPHENE_PRICE_FEED_FIELDS (settlement_price)(maintenance_collateral_ratio)(maximum_short_squeeze_ratio) \
|
|
(core_exchange_rate)
|
|
|
|
FC_REFLECT( graphene::chain::price_feed, GRAPHENE_PRICE_FEED_FIELDS )
|