#ifndef XRPL_PROTOCOL_QUALITYFUNCTION_H_INCLUDED #define XRPL_PROTOCOL_QUALITYFUNCTION_H_INCLUDED #include #include #include 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_; 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 QualityFunction( TAmounts 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 outFromAvgQ(Quality const& quality); /** Return true if the quality function is constant */ bool isConst() const { return quality_.has_value(); } std::optional const& quality() const { return quality_; } }; template QualityFunction::QualityFunction( TAmounts const& amounts, std::uint32_t tfee, QualityFunction::AMMTag) { if (amounts.in <= beast::zero || amounts.out <= beast::zero) Throw("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