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>
42 TAmounts<TIn, TOut> cur{};
46 cur.out =
swapAssetIn(initialBalances_, cur.in, tradingFee_);
48 if (ammContext_.curIters() == 0)
53 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,
54 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
55 196418, 317811, 514229, 832040, 1346269};
58 XRPL_ASSERT(!ammContext_.maxItersReached(),
"xrpl::AMMLiquidity::generateFibSeqOffer : maximum iterations");
60 cur.out = toAmount<TOut>(
63 if (cur.out >= balances.out)
64 Throw<std::overflow_error>(
"AMMLiquidity: generateFibSeqOffer exceeds the balance");
86maxOut(T
const&
out, Issue
const& iss)
88 Number
const res =
out * Number{99, -2};
93template <
typename TIn,
typename TOut>
97 if (!rules.
enabled(fixAMMOverflowOffer))
101 {maxAmount<TIn>(),
swapAssetIn(balances, maxAmount<TIn>(), tradingFee_)},
107 auto const out = maxOut<TOut>(balances.out, issueOut());
108 if (
out <= TOut{0} ||
out >= balances.out)
114template <
typename TIn,
typename TOut>
119 if (ammContext_.maxItersReached())
122 auto const balances = fetchBalances(view);
125 if (balances.in == beast::zero || balances.out == beast::zero)
127 JLOG(j_.debug()) <<
"AMMLiquidity::getOffer, frozen accounts";
131 JLOG(j_.trace()) <<
"AMMLiquidity::getOffer balances " <<
to_string(initialBalances_.in) <<
" "
132 <<
to_string(initialBalances_.out) <<
" new balances " <<
to_string(balances.in) <<
" "
143 if (
auto const spotPriceQ = Quality{balances};
146 JLOG(j_.trace()) <<
"AMMLiquidity::getOffer, higher clob quality";
153 if (ammContext_.multiPath())
155 auto const amounts = generateFibSeqOffer(balances);
156 if (clobQuality && Quality{amounts} < clobQuality)
160 else if (!clobQuality)
167 return maxOffer(balances, view.
rules());
175 if (
auto const maxAMMOffer = maxOffer(balances, view.
rules());
176 maxAMMOffer && Quality{maxAMMOffer->amount()} > *clobQuality)
182 JLOG(j_.error()) <<
"AMMLiquidity::getOffer overflow " << e.
what();
184 return maxOffer(balances, view.
rules());
190 JLOG(j_.error()) <<
"AMMLiquidity::getOffer exception " << e.
what();
197 if (offer->amount().in > beast::zero && offer->amount().out > beast::zero)
199 JLOG(j_.trace()) <<
"AMMLiquidity::getOffer, created " <<
to_string(offer->amount().in) <<
"/" << issueIn_
200 <<
" " <<
to_string(offer->amount().out) <<
"/" << issueOut_;
204 JLOG(j_.debug()) <<
"AMMLiquidity::getOffer, no valid offer " << ammContext_.multiPath() <<
" "
205 << ammContext_.curIters() <<
" " << (clobQuality ? clobQuality->rate() :
STAmount{}) <<
" "
A generic endpoint for log messages.
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.
TAmounts< TIn, TOut > generateFibSeqOffer(TAmounts< TIn, TOut > const &balances) const
Generate AMM offers with the offer size based on Fibonacci sequence.
std::optional< AMMOffer< TIn, TOut > > maxOffer(TAmounts< TIn, TOut > const &balances, Rules const &rules) const
Generate max 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 > > getOffer(ReadView const &view, std::optional< Quality > const &clobQuality) const
Generate AMM offer.
Represents synthetic AMM offer in BookStep.
Floating point representation of amounts with high dynamic range.
A currency issued by an account.
Number is a floating point type that can represent a wide range of values.
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 constexpr std::uint64_t cMaxValue
static int const cMaxOffset
static constexpr std::uint64_t cMaxNative
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
STAmount ammAccountHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue)
Returns total amount held by AMM for the given token.
std::string to_string(base_uint< Bits, Tag > const &a)
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...
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.
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
Issue getIssue(T const &amt)