205 lines
8.3 KiB
C++
205 lines
8.3 KiB
C++
/*
|
|
* Copyright (c) 2015, Cryptonomex, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
|
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted until September 8, 2015, provided that the following conditions are met:
|
|
*
|
|
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#pragma once
|
|
#include <graphene/chain/protocol/config.hpp>
|
|
#include <graphene/chain/protocol/types.hpp>
|
|
|
|
namespace graphene { namespace chain {
|
|
|
|
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 );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @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;
|
|
};
|
|
|
|
} }
|
|
|
|
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 )
|