Files
rippled/include/xrpl/protocol/QualityFunction.h
2025-10-23 11:04:30 -04:00

89 lines
2.3 KiB
C++

#ifndef XRPL_PROTOCOL_QUALITYFUNCTION_H_INCLUDED
#define XRPL_PROTOCOL_QUALITYFUNCTION_H_INCLUDED
#include <xrpl/basics/Number.h>
#include <xrpl/protocol/AMMCore.h>
#include <xrpl/protocol/Quality.h>
namespace ripple {
/** Average quality of a path as a function of `out`: q(out) = m * out + b,
* where m = -1 / poolGets, b = poolPays / poolGets. If CLOB offer then
* `m` is equal to 0 `b` is equal to the offer's quality. The function
* is derived by substituting `in` in q = out / in with the swap out formula
* for `in`:
* in = [(poolGets * poolPays) / (poolGets - out) - poolPays] / (1 - tfee)
* and combining the function for multiple steps. The function is used
* to limit required output amount when quality limit is provided in one
* path optimization.
*/
class QualityFunction
{
private:
// slope
Number m_;
// intercept
Number b_;
// seated if QF is for CLOB offer.
std::optional<Quality> quality_;
public:
struct AMMTag
{
};
// AMMOffer for multi-path is like CLOB, i.e. the offer size
// changes proportionally to its quality.
struct CLOBLikeTag
{
};
QualityFunction(Quality const& quality, CLOBLikeTag);
template <typename TIn, typename TOut>
QualityFunction(
TAmounts<TIn, TOut> const& amounts,
std::uint32_t tfee,
AMMTag);
/** Combines QF with the next step QF
*/
void
combine(QualityFunction const& qf);
/** Find output to produce the requested
* average quality.
* @param quality requested average quality (quality limit)
*/
std::optional<Number>
outFromAvgQ(Quality const& quality);
/** Return true if the quality function is constant
*/
bool
isConst() const
{
return quality_.has_value();
}
std::optional<Quality> const&
quality() const
{
return quality_;
}
};
template <typename TIn, typename TOut>
QualityFunction::QualityFunction(
TAmounts<TIn, TOut> const& amounts,
std::uint32_t tfee,
QualityFunction::AMMTag)
{
if (amounts.in <= beast::zero || amounts.out <= beast::zero)
Throw<std::runtime_error>("QualityFunction amounts are 0.");
Number const cfee = feeMult(tfee);
m_ = -cfee / amounts.in;
b_ = amounts.out * cfee / amounts.in;
}
} // namespace ripple
#endif // XRPL_PROTOCOL_QUALITYFUNCTION_H_INCLUDED