1#include <xrpld/app/paths/AMMLiquidity.h> 
    2#include <xrpld/app/paths/AMMOffer.h> 
    6template <
typename TIn, 
typename TOut>
 
   15    : ammContext_(ammContext)
 
   16    , ammAccountID_(ammAccountID)
 
   17    , tradingFee_(tradingFee)
 
   20    , initialBalances_{fetchBalances(view)}
 
 
   25template <
typename TIn, 
typename TOut>
 
   32    if (assetIn < beast::zero || assetOut < beast::zero)
 
   33        Throw<std::runtime_error>(
"AMMLiquidity: invalid balances");
 
   35    return TAmounts{get<TIn>(assetIn), get<TOut>(assetOut)};
 
 
   38template <
typename TIn, 
typename TOut>
 
   41    TAmounts<TIn, TOut> 
const& balances)
 const 
   43    TAmounts<TIn, TOut> cur{};
 
   45    cur.in = toAmount<TIn>(
 
   47        InitialFibSeqPct * initialBalances_.in,
 
   49    cur.out = 
swapAssetIn(initialBalances_, cur.in, tradingFee_);
 
   51    if (ammContext_.curIters() == 0)
 
   56        1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,
 
   57        1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
 
   58        196418, 317811, 514229, 832040, 1346269};
 
   62        !ammContext_.maxItersReached(),
 
   63        "ripple::AMMLiquidity::generateFibSeqOffer : maximum iterations");
 
   65    cur.out = toAmount<TOut>(
 
   67        cur.out * fib[ammContext_.curIters() - 1],
 
   70    if (cur.out >= balances.out)
 
   71        Throw<std::overflow_error>(
 
   72            "AMMLiquidity: generateFibSeqOffer exceeds the balance");
 
 
   94maxOut(T 
const& 
out, Issue 
const& iss)
 
   96    Number 
const res = 
out * Number{99, -2};
 
  101template <
typename TIn, 
typename TOut>
 
  104    TAmounts<TIn, TOut> 
const& balances,
 
  105    Rules const& rules)
 const 
  107    if (!rules.
enabled(fixAMMOverflowOffer))
 
  112             swapAssetIn(balances, maxAmount<TIn>(), tradingFee_)},
 
  118        auto const out = maxOut<TOut>(balances.out, issueOut());
 
  119        if (
out <= TOut{0} || 
out >= balances.out)
 
 
  129template <
typename TIn, 
typename TOut>
 
  136    if (ammContext_.maxItersReached())
 
  139    auto const balances = fetchBalances(view);
 
  142    if (balances.in == beast::zero || balances.out == beast::zero)
 
  144        JLOG(j_.
debug()) << 
"AMMLiquidity::getOffer, frozen accounts";
 
  148    JLOG(j_.
trace()) << 
"AMMLiquidity::getOffer balances " 
  150                     << 
to_string(initialBalances_.out) << 
" new balances " 
  162    if (
auto const spotPriceQ = Quality{balances}; clobQuality &&
 
  163        (spotPriceQ <= clobQuality ||
 
  166        JLOG(j_.
trace()) << 
"AMMLiquidity::getOffer, higher clob quality";
 
  173            if (ammContext_.multiPath())
 
  175                auto const amounts = generateFibSeqOffer(balances);
 
  176                if (clobQuality && Quality{amounts} < clobQuality)
 
  179                    *
this, amounts, balances, Quality{amounts});
 
  181            else if (!clobQuality)
 
  188                return maxOffer(balances, view.
rules());
 
  192                    balances, *clobQuality, tradingFee_, view.
rules(), j_))
 
  195                    *
this, *amounts, balances, Quality{*amounts});
 
  199                if (
auto const maxAMMOffer = maxOffer(balances, view.
rules());
 
  201                    Quality{maxAMMOffer->amount()} > *clobQuality)
 
  207            JLOG(j_.
error()) << 
"AMMLiquidity::getOffer overflow " << e.
what();
 
  209                return maxOffer(balances, view.
rules());
 
  215            JLOG(j_.
error()) << 
"AMMLiquidity::getOffer exception " << e.
what();
 
  222        if (offer->amount().in > beast::zero &&
 
  223            offer->amount().out > beast::zero)
 
  226                << 
"AMMLiquidity::getOffer, created " 
  227                << 
to_string(offer->amount().in) << 
"/" << issueIn_ << 
" " 
  228                << 
to_string(offer->amount().out) << 
"/" << issueOut_;
 
  232        JLOG(j_.
debug()) << 
"AMMLiquidity::getOffer, no valid offer " 
  233                         << ammContext_.multiPath() << 
" " 
  234                         << ammContext_.curIters() << 
" " 
  235                         << (clobQuality ? clobQuality->rate() : 
STAmount{})
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
Maintains AMM info per overall payment engine execution and individual iteration.
 
static constexpr std::uint8_t MaxIterations
 
AMMLiquidity class provides AMM offers to BookStep class.
 
std::optional< AMMOffer< TIn, TOut > > getOffer(ReadView const &view, std::optional< Quality > const &clobQuality) const
Generate AMM offer.
 
TAmounts< TIn, TOut > fetchBalances(ReadView const &view) const
Fetches current AMM balances.
 
AMMLiquidity(ReadView const &view, AccountID const &ammAccountID, std::uint32_t tradingFee, Issue const &in, Issue const &out, AMMContext &ammContext, beast::Journal j)
 
std::optional< AMMOffer< TIn, TOut > > maxOffer(TAmounts< TIn, TOut > const &balances, Rules const &rules) const
Generate max offer.
 
TAmounts< TIn, TOut > generateFibSeqOffer(TAmounts< TIn, TOut > const &balances) const
Generate AMM offers with the offer size based on Fibonacci sequence.
 
Represents synthetic AMM offer in BookStep.
 
Floating point representation of amounts with high dynamic range.
 
A currency issued by an account.
 
virtual Rules const & rules() const =0
Returns the tx processing rules.
 
Rules controlling protocol behavior.
 
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
 
static int const cMaxOffset
 
static std::uint64_t const cMaxValue
 
static std::uint64_t const cMaxNative
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Issue getIssue(T const &amt)
 
TOut swapAssetIn(TAmounts< TIn, TOut > const &pool, TIn const &assetIn, std::uint16_t tfee)
AMM pool invariant - the product (A * B) after swap in/out has to remain at least the same: (A + in) ...
 
std::optional< TAmounts< TIn, TOut > > changeSpotPriceQuality(TAmounts< TIn, TOut > const &pool, Quality const &quality, std::uint16_t tfee, Rules const &rules, beast::Journal j)
Generate AMM offer so that either updated Spot Price Quality (SPQ) is equal to LOB quality (in this c...
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
STAmount ammAccountHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue)
Returns total amount held by AMM for the given token.
 
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
 
TIn swapAssetOut(TAmounts< TIn, TOut > const &pool, TOut const &assetOut, std::uint16_t tfee)
Swap assetOut out of the pool and swap in a proportional amount of the other asset.