19 #include <ripple/app/paths/AMMLiquidity.h>
21 #include <ripple/app/paths/AMMOffer.h>
25 template <
typename TIn,
typename TOut>
34 : ammContext_(ammContext)
36 , tradingFee_(tradingFee)
44 template <
typename TIn,
typename TOut>
51 if (assetIn < beast::zero || assetOut < beast::zero)
52 Throw<std::runtime_error>(
"AMMLiquidity: invalid balances");
54 return TAmounts{get<TIn>(assetIn), get<TOut>(assetOut)};
57 template <
typename TIn,
typename TOut>
60 TAmounts<TIn, TOut>
const& balances)
const
62 TAmounts<TIn, TOut> cur{};
64 cur.in = toAmount<TIn>(
66 InitialFibSeqPct * initialBalances_.in,
67 Number::rounding_mode::upward);
68 cur.out = swapAssetIn(initialBalances_, cur.in, tradingFee_);
70 if (ammContext_.curIters() == 0)
75 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,
76 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
77 196418, 317811, 514229, 832040, 1346269};
80 assert(!ammContext_.maxItersReached());
82 cur.out = toAmount<TOut>(
84 cur.out * fib[ammContext_.curIters() - 1],
85 Number::rounding_mode::downward);
87 if (cur.out >= balances.out)
88 Throw<std::overflow_error>(
89 "AMMLiquidity: generateFibSeqOffer exceeds the balance");
91 cur.in = swapAssetOut(balances, cur.out, tradingFee_);
100 if constexpr (std::is_same_v<T, XRPAmount>)
102 else if constexpr (std::is_same_v<T, IOUAmount>)
104 else if constexpr (std::is_same_v<T, STAmount>)
108 template <
typename TIn,
typename TOut>
115 swapAssetIn(balances, maxAmount<TIn>(), tradingFee_)},
120 template <
typename TIn,
typename TOut>
127 if (ammContext_.maxItersReached())
130 auto const balances = fetchBalances(view);
133 if (balances.in == beast::zero || balances.out == beast::zero)
135 JLOG(j_.
debug()) <<
"AMMLiquidity::getOffer, frozen accounts";
139 JLOG(j_.
trace()) <<
"AMMLiquidity::getOffer balances "
141 <<
to_string(initialBalances_.out) <<
" new balances "
153 if (
auto const spotPriceQ = Quality{balances}; clobQuality &&
154 (spotPriceQ <= clobQuality ||
155 withinRelativeDistance(spotPriceQ, *clobQuality,
Number(1, -7))))
157 JLOG(j_.
trace()) <<
"AMMLiquidity::getOffer, higher clob quality";
164 if (ammContext_.multiPath())
166 auto const amounts = generateFibSeqOffer(balances);
167 if (clobQuality && Quality{amounts} < clobQuality)
170 *
this, amounts, std::nullopt, Quality{amounts});
172 else if (!clobQuality)
178 return maxOffer(balances);
182 changeSpotPriceQuality(balances, *clobQuality, tradingFee_))
185 *
this, *amounts, balances, Quality{*amounts});
190 JLOG(j_.
error()) <<
"AMMLiquidity::getOffer overflow " << e.
what();
191 return maxOffer(balances);
195 JLOG(j_.
error()) <<
"AMMLiquidity::getOffer exception " << e.
what();
202 if (offer->amount().in > beast::zero &&
203 offer->amount().out > beast::zero)
206 <<
"AMMLiquidity::getOffer, created "
207 <<
to_string(offer->amount().in) <<
"/" << issueIn_ <<
" "
208 <<
to_string(offer->amount().out) <<
"/" << issueOut_;
212 JLOG(j_.
error()) <<
"AMMLiquidity::getOffer, failed";