rippled
Loading...
Searching...
No Matches
AMMHelpers.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2023 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_APP_MISC_AMMHELPERS_H_INCLUDED
21#define RIPPLE_APP_MISC_AMMHELPERS_H_INCLUDED
22
23#include <xrpl/basics/Log.h>
24#include <xrpl/basics/Number.h>
25#include <xrpl/beast/utility/Journal.h>
26#include <xrpl/protocol/AMMCore.h>
27#include <xrpl/protocol/AmountConversions.h>
28#include <xrpl/protocol/Feature.h>
29#include <xrpl/protocol/IOUAmount.h>
30#include <xrpl/protocol/Issue.h>
31#include <xrpl/protocol/Quality.h>
32#include <xrpl/protocol/Rules.h>
33#include <xrpl/protocol/STAmount.h>
34
35namespace ripple {
36
37namespace detail {
38
39Number
40reduceOffer(auto const& amount)
41{
42 static Number const reducedOfferPct(9999, -4);
43
44 // Make sure the result is always less than amount or zero.
46 return amount * reducedOfferPct;
47}
48
49} // namespace detail
50
51enum class IsDeposit : bool { No = false, Yes = true };
52
58STAmount
60 STAmount const& asset1,
61 STAmount const& asset2,
62 Issue const& lptIssue);
63
71STAmount
73 STAmount const& asset1Balance,
74 STAmount const& asset1Deposit,
75 STAmount const& lptAMMBalance,
76 std::uint16_t tfee);
77
85STAmount
87 STAmount const& asset1Balance,
88 STAmount const& lptAMMBalance,
89 STAmount const& lpTokens,
90 std::uint16_t tfee);
91
100STAmount
102 STAmount const& asset1Balance,
103 STAmount const& asset1Withdraw,
104 STAmount const& lptAMMBalance,
105 std::uint16_t tfee);
106
114STAmount
116 STAmount const& assetBalance,
117 STAmount const& lptAMMBalance,
118 STAmount const& lpTokens,
119 std::uint16_t tfee);
120
128inline bool
130 Quality const& calcQuality,
131 Quality const& reqQuality,
132 Number const& dist)
133{
134 if (calcQuality == reqQuality)
135 return true;
136 auto const [min, max] = std::minmax(calcQuality, reqQuality);
137 // Relative distance is (max - min)/max. Can't use basic operations
138 // on Quality. Have to use Quality::rate() instead, which
139 // is inverse of quality: (1/max.rate - 1/min.rate)/(1/max.rate)
140 return ((min.rate() - max.rate()) / min.rate()) < dist;
141}
142
150// clang-format off
151template <typename Amt>
152 requires(
155bool
156withinRelativeDistance(Amt const& calc, Amt const& req, Number const& dist)
157{
158 if (calc == req)
159 return true;
160 auto const [min, max] = std::minmax(calc, req);
161 return ((max - min) / max) < dist;
162}
163// clang-format on
164
169solveQuadraticEqSmallest(Number const& a, Number const& b, Number const& c);
170
194template <typename TIn, typename TOut>
197 TAmounts<TIn, TOut> const& pool,
198 Quality const& targetQuality,
199 std::uint16_t const& tfee)
200{
201 if (targetQuality.rate() == beast::zero)
202 return std::nullopt;
203
205 auto const f = feeMult(tfee);
206 auto const a = 1;
207 auto const b = pool.in * (1 - 1 / f) / targetQuality.rate() - 2 * pool.out;
208 auto const c =
209 pool.out * pool.out - (pool.in * pool.out) / targetQuality.rate();
210
211 auto nTakerGets = solveQuadraticEqSmallest(a, b, c);
212 if (!nTakerGets || *nTakerGets <= 0)
213 return std::nullopt; // LCOV_EXCL_LINE
214
215 auto const nTakerGetsConstraint =
216 pool.out - pool.in / (targetQuality.rate() * f);
217 if (nTakerGetsConstraint <= 0)
218 return std::nullopt;
219
220 // Select the smallest to maximize the quality
221 if (nTakerGetsConstraint < *nTakerGets)
222 nTakerGets = nTakerGetsConstraint;
223
224 auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
225 // Round downward to minimize the offer and to maximize the quality.
226 // This has the most impact when takerGets is XRP.
227 auto const takerGets = toAmount<TOut>(
228 getIssue(pool.out), nTakerGetsProposed, Number::downward);
229 return TAmounts<TIn, TOut>{
230 swapAssetOut(pool, takerGets, tfee), takerGets};
231 };
232
233 // Try to reduce the offer size to improve the quality.
234 // The quality might still not match the targetQuality for a tiny offer.
235 if (auto const amounts = getAmounts(*nTakerGets);
236 Quality{amounts} < targetQuality)
237 return getAmounts(detail::reduceOffer(amounts.out));
238 else
239 return amounts;
240}
241
265template <typename TIn, typename TOut>
268 TAmounts<TIn, TOut> const& pool,
269 Quality const& targetQuality,
270 std::uint16_t tfee)
271{
272 if (targetQuality.rate() == beast::zero)
273 return std::nullopt;
274
276 auto const f = feeMult(tfee);
277 auto const& a = f;
278 auto const b = pool.in * (1 + f);
279 auto const c =
280 pool.in * pool.in - pool.in * pool.out * targetQuality.rate();
281
282 auto nTakerPays = solveQuadraticEqSmallest(a, b, c);
283 if (!nTakerPays || nTakerPays <= 0)
284 return std::nullopt; // LCOV_EXCL_LINE
285
286 auto const nTakerPaysConstraint =
287 pool.out * targetQuality.rate() - pool.in / f;
288 if (nTakerPaysConstraint <= 0)
289 return std::nullopt;
290
291 // Select the smallest to maximize the quality
292 if (nTakerPaysConstraint < *nTakerPays)
293 nTakerPays = nTakerPaysConstraint;
294
295 auto getAmounts = [&pool, &tfee](Number const& nTakerPaysProposed) {
296 // Round downward to minimize the offer and to maximize the quality.
297 // This has the most impact when takerPays is XRP.
298 auto const takerPays = toAmount<TIn>(
299 getIssue(pool.in), nTakerPaysProposed, Number::downward);
300 return TAmounts<TIn, TOut>{
301 takerPays, swapAssetIn(pool, takerPays, tfee)};
302 };
303
304 // Try to reduce the offer size to improve the quality.
305 // The quality might still not match the targetQuality for a tiny offer.
306 if (auto const amounts = getAmounts(*nTakerPays);
307 Quality{amounts} < targetQuality)
308 return getAmounts(detail::reduceOffer(amounts.in));
309 else
310 return amounts;
311}
312
329template <typename TIn, typename TOut>
332 TAmounts<TIn, TOut> const& pool,
333 Quality const& quality,
334 std::uint16_t tfee,
335 Rules const& rules,
337{
338 if (!rules.enabled(fixAMMv1_1))
339 {
340 // Finds takerPays (i) and takerGets (o) such that given pool
341 // composition poolGets(I) and poolPays(O): (O - o) / (I + i) = quality.
342 // Where takerGets is calculated as the swapAssetIn (see below).
343 // The above equation produces the quadratic equation:
344 // i^2*(1-fee) + i*I*(2-fee) + I^2 - I*O/quality,
345 // which is solved for i, and o is found with swapAssetIn().
346 auto const f = feeMult(tfee); // 1 - fee
347 auto const& a = f;
348 auto const b = pool.in * (1 + f);
349 Number const c =
350 pool.in * pool.in - pool.in * pool.out * quality.rate();
351 if (auto const res = b * b - 4 * a * c; res < 0)
352 return std::nullopt; // LCOV_EXCL_LINE
353 else if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a);
354 nTakerPaysPropose > 0)
355 {
356 auto const nTakerPays = [&]() {
357 // The fee might make the AMM offer quality less than CLOB
358 // quality. Therefore, AMM offer has to satisfy this constraint:
359 // o / i >= q. Substituting o with swapAssetIn() gives: i <= O /
360 // q - I / (1 - fee).
361 auto const nTakerPaysConstraint =
362 pool.out * quality.rate() - pool.in / f;
363 if (nTakerPaysPropose > nTakerPaysConstraint)
364 return nTakerPaysConstraint;
365 return nTakerPaysPropose;
366 }();
367 if (nTakerPays <= 0)
368 {
369 JLOG(j.trace())
370 << "changeSpotPriceQuality calc failed: "
371 << to_string(pool.in) << " " << to_string(pool.out) << " "
372 << quality << " " << tfee;
373 return std::nullopt;
374 }
375 auto const takerPays =
376 toAmount<TIn>(getIssue(pool.in), nTakerPays, Number::upward);
377 // should not fail
378 if (auto const amounts =
379 TAmounts<TIn, TOut>{
380 takerPays, swapAssetIn(pool, takerPays, tfee)};
381 Quality{amounts} < quality &&
383 Quality{amounts}, quality, Number(1, -7)))
384 {
385 JLOG(j.error())
386 << "changeSpotPriceQuality failed: " << to_string(pool.in)
387 << " " << to_string(pool.out) << " "
388 << " " << quality << " " << tfee << " "
389 << to_string(amounts.in) << " " << to_string(amounts.out);
390 Throw<std::runtime_error>("changeSpotPriceQuality failed");
391 }
392 else
393 {
394 JLOG(j.trace())
395 << "changeSpotPriceQuality succeeded: "
396 << to_string(pool.in) << " " << to_string(pool.out) << " "
397 << " " << quality << " " << tfee << " "
398 << to_string(amounts.in) << " " << to_string(amounts.out);
399 return amounts;
400 }
401 }
402 JLOG(j.trace()) << "changeSpotPriceQuality calc failed: "
403 << to_string(pool.in) << " " << to_string(pool.out)
404 << " " << quality << " " << tfee;
405 return std::nullopt;
406 }
407
408 // Generate the offer starting with XRP side. Return seated offer amounts
409 // if the offer can be generated, otherwise nullopt.
410 auto const amounts = [&]() {
411 if (isXRP(getIssue(pool.out)))
412 return getAMMOfferStartWithTakerGets(pool, quality, tfee);
413 return getAMMOfferStartWithTakerPays(pool, quality, tfee);
414 }();
415 if (!amounts)
416 {
417 JLOG(j.trace()) << "changeSpotPrice calc failed: " << to_string(pool.in)
418 << " " << to_string(pool.out) << " " << quality << " "
419 << tfee << std::endl;
420 return std::nullopt;
421 }
422
423 if (Quality{*amounts} < quality)
424 {
425 JLOG(j.error()) << "changeSpotPriceQuality failed: "
426 << to_string(pool.in) << " " << to_string(pool.out)
427 << " " << quality << " " << tfee << " "
428 << to_string(amounts->in) << " "
429 << to_string(amounts->out);
430 return std::nullopt;
431 }
432
433 JLOG(j.trace()) << "changeSpotPriceQuality succeeded: "
434 << to_string(pool.in) << " " << to_string(pool.out) << " "
435 << " " << quality << " " << tfee << " "
436 << to_string(amounts->in) << " " << to_string(amounts->out);
437
438 return amounts;
439}
440
462template <typename TIn, typename TOut>
463TOut
465 TAmounts<TIn, TOut> const& pool,
466 TIn const& assetIn,
467 std::uint16_t tfee)
468{
469 if (auto const& rules = getCurrentTransactionRules();
470 rules && rules->enabled(fixAMMv1_1))
471 {
472 // set rounding to always favor the amm. Clip to zero.
473 // calculate:
474 // pool.out -
475 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
476 // and explicitly set the rounding modes
477 // Favoring the amm means we should:
478 // minimize:
479 // pool.out -
480 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
481 // maximize:
482 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
483 // (pool.in * pool.out)
484 // minimize:
485 // (pool.in + assetIn * feeMult(tfee)),
486 // minimize:
487 // assetIn * feeMult(tfee)
488 // feeMult is: (1-fee), fee is tfee/100000
489 // minimize:
490 // 1-fee
491 // maximize:
492 // fee
494
496 auto const numerator = pool.in * pool.out;
497 auto const fee = getFee(tfee);
498
500 auto const denom = pool.in + assetIn * (1 - fee);
501
502 if (denom.signum() <= 0)
503 return toAmount<TOut>(getIssue(pool.out), 0);
504
506 auto const ratio = numerator / denom;
507
509 auto const swapOut = pool.out - ratio;
510
511 if (swapOut.signum() < 0)
512 return toAmount<TOut>(getIssue(pool.out), 0);
513
514 return toAmount<TOut>(getIssue(pool.out), swapOut, Number::downward);
515 }
516 else
517 {
518 return toAmount<TOut>(
519 getIssue(pool.out),
520 pool.out -
521 (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
523 }
524}
525
535template <typename TIn, typename TOut>
536TIn
538 TAmounts<TIn, TOut> const& pool,
539 TOut const& assetOut,
540 std::uint16_t tfee)
541{
542 if (auto const& rules = getCurrentTransactionRules();
543 rules && rules->enabled(fixAMMv1_1))
544 {
545 // set rounding to always favor the amm. Clip to zero.
546 // calculate:
547 // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) /
548 // (1-tfee/100000)
549 // maximize:
550 // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in)
551 // maximize:
552 // (pool.in * pool.out) / (pool.out - assetOut)
553 // maximize:
554 // (pool.in * pool.out)
555 // minimize
556 // (pool.out - assetOut)
557 // minimize:
558 // (1-tfee/100000)
559 // maximize:
560 // tfee/100000
561
563
565 auto const numerator = pool.in * pool.out;
566
568 auto const denom = pool.out - assetOut;
569 if (denom.signum() <= 0)
570 {
571 return toMaxAmount<TIn>(getIssue(pool.in));
572 }
573
575 auto const ratio = numerator / denom;
576 auto const numerator2 = ratio - pool.in;
577 auto const fee = getFee(tfee);
578
580 auto const feeMult = 1 - fee;
581
583 auto const swapIn = numerator2 / feeMult;
584 if (swapIn.signum() < 0)
585 return toAmount<TIn>(getIssue(pool.in), 0);
586
587 return toAmount<TIn>(getIssue(pool.in), swapIn, Number::upward);
588 }
589 else
590 {
591 return toAmount<TIn>(
592 getIssue(pool.in),
593 ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) /
594 feeMult(tfee),
596 }
597}
598
601Number
602square(Number const& n);
603
615STAmount
617 STAmount const& lptAMMBalance,
618 STAmount const& lpTokens,
619 IsDeposit isDeposit);
620
634 STAmount const& amountBalance,
635 STAmount const& amount,
636 std::optional<STAmount> const& amount2,
637 STAmount const& lptAMMBalance,
638 STAmount const& lpTokens,
639 std::uint16_t tfee,
640 IsDeposit isDeposit);
641
645Number
646solveQuadraticEq(Number const& a, Number const& b, Number const& c);
647
648STAmount
649multiply(STAmount const& amount, Number const& frac, Number::rounding_mode rm);
650
651namespace detail {
652
655{
656 // Minimize on deposit, maximize on withdraw to ensure
657 // AMM invariant sqrt(poolAsset1 * poolAsset2) >= LPTokensBalance
658 return isDeposit == IsDeposit::Yes ? Number::downward : Number::upward;
659}
660
663{
664 // Maximize on deposit, minimize on withdraw to ensure
665 // AMM invariant sqrt(poolAsset1 * poolAsset2) >= LPTokensBalance
666 return isDeposit == IsDeposit::Yes ? Number::upward : Number::downward;
667}
668
669} // namespace detail
670
676template <typename A>
677STAmount
679 Rules const& rules,
680 STAmount const& balance,
681 A const& frac,
682 IsDeposit isDeposit)
683{
684 if (!rules.enabled(fixAMMv1_3))
685 {
686 if constexpr (std::is_same_v<A, STAmount>)
687 return multiply(balance, frac, balance.issue());
688 else
689 return toSTAmount(balance.issue(), balance * frac);
690 }
691 auto const rm = detail::getAssetRounding(isDeposit);
692 return multiply(balance, frac, rm);
693}
694
704STAmount
706 Rules const& rules,
707 std::function<Number()>&& noRoundCb,
708 STAmount const& balance,
709 std::function<Number()>&& productCb,
710 IsDeposit isDeposit);
711
719STAmount
721 Rules const& rules,
722 STAmount const& balance,
723 Number const& frac,
724 IsDeposit isDeposit);
725
737STAmount
739 Rules const& rules,
740 std::function<Number()>&& noRoundCb,
741 STAmount const& lptAMMBalance,
742 std::function<Number()>&& productCb,
743 IsDeposit isDeposit);
744
745/* Next two functions adjust asset in/out amount to factor in the adjusted
746 * lptokens. The lptokens are calculated from the asset in/out. The lptokens are
747 * then adjusted to factor in the loss in precision. The adjusted lptokens might
748 * be less than the initially calculated tokens. Therefore, the asset in/out
749 * must be adjusted. The rounding might result in the adjusted amount being
750 * greater than the original asset in/out amount. If this happens,
751 * then the original amount is reduced by the difference in the adjusted amount
752 * and the original amount. The actual tokens and the actual adjusted amount
753 * are then recalculated. The minimum of the original and the actual
754 * adjusted amount is returned.
755 */
758 Rules const& rules,
759 STAmount const& balance,
760 STAmount const& amount,
761 STAmount const& lptAMMBalance,
762 STAmount const& tokens,
763 std::uint16_t tfee);
766 Rules const& rules,
767 STAmount const& balance,
768 STAmount const& amount,
769 STAmount const& lptAMMBalance,
770 STAmount const& tokens,
771 std::uint16_t tfee);
772
776Number
778 Rules const& rules,
779 STAmount const& lptAMMBalance,
780 STAmount const& tokens,
781 Number const& frac);
782
783} // namespace ripple
784
785#endif // RIPPLE_APP_MISC_AMMHELPERS_H_INCLUDED
A generic endpoint for log messages.
Definition Journal.h:60
Stream error() const
Definition Journal.h:346
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
static rounding_mode getround()
Definition Number.cpp:47
static rounding_mode setround(rounding_mode mode)
Definition Number.cpp:53
Rules controlling protocol behavior.
Definition Rules.h:38
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:130
Issue const & issue() const
Definition STAmount.h:496
T endl(T... args)
T is_same_v
T minmax(T... args)
Number::rounding_mode getAssetRounding(IsDeposit isDeposit)
Definition AMMHelpers.h:662
Number::rounding_mode getLPTokenRounding(IsDeposit isDeposit)
Definition AMMHelpers.h:654
Number reduceOffer(auto const &amount)
Definition AMMHelpers.h:40
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
std::pair< STAmount, STAmount > adjustAssetInByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
bool isXRP(AccountID const &c)
Definition AccountID.h:90
std::optional< Number > solveQuadraticEqSmallest(Number const &a, Number const &b, Number const &c)
Solve quadratic equation to find takerGets or takerPays.
Issue getIssue(T const &amt)
Number solveQuadraticEq(Number const &a, Number const &b, Number const &c)
Positive solution for quadratic equation: x = (-b + sqrt(b**2 + 4*a*c))/(2*a)
std::pair< STAmount, STAmount > adjustAssetOutByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
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) ...
Definition AMMHelpers.h:464
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
STAmount ammAssetIn(STAmount const &asset1Balance, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee)
Calculate asset deposit given LP Tokens.
Number square(Number const &n)
Return square of n.
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:53
std::optional< TAmounts< TIn, TOut > > getAMMOfferStartWithTakerGets(TAmounts< TIn, TOut > const &pool, Quality const &targetQuality, std::uint16_t const &tfee)
Generate AMM offer starting with takerGets when AMM pool from the payment perspective is IOU(in)/XRP(...
Definition AMMHelpers.h:196
STAmount getRoundedLPTokens(Rules const &rules, STAmount const &balance, Number const &frac, IsDeposit isDeposit)
Round AMM deposit/withdrawal LPToken amount.
STAmount adjustLPTokens(STAmount const &lptAMMBalance, STAmount const &lpTokens, IsDeposit isDeposit)
Adjust LP tokens to deposit/withdraw.
Number feeMult(std::uint16_t tfee)
Get fee multiplier (1 - tfee) @tfee trading fee in basis points.
Definition AMMCore.h:110
std::tuple< STAmount, std::optional< STAmount >, STAmount > adjustAmountsByLPTokens(STAmount const &amountBalance, STAmount const &amount, std::optional< STAmount > const &amount2, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee, IsDeposit isDeposit)
Calls adjustLPTokens() and adjusts deposit or withdraw amounts if the adjusted LP tokens are less tha...
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...
Definition AMMHelpers.h:331
STAmount ammAssetOut(STAmount const &assetBalance, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee)
Calculate asset withdrawal by tokens.
Number getFee(std::uint16_t tfee)
Convert to the fee from the basis points.
Definition AMMCore.h:101
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Issue const &lptIssue)
Calculate LP Tokens given AMM pool reserves.
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:47
STAmount lpTokensIn(STAmount const &asset1Balance, STAmount const &asset1Withdraw, STAmount const &lptAMMBalance, std::uint16_t tfee)
Calculate LP Tokens given asset's withdraw amount.
STAmount lpTokensOut(STAmount const &asset1Balance, STAmount const &asset1Deposit, STAmount const &lptAMMBalance, std::uint16_t tfee)
Calculate LP Tokens given asset's deposit amount.
STAmount getRoundedAsset(Rules const &rules, STAmount const &balance, A const &frac, IsDeposit isDeposit)
Round AMM equal deposit/withdrawal amount.
Definition AMMHelpers.h:678
std::optional< TAmounts< TIn, TOut > > getAMMOfferStartWithTakerPays(TAmounts< TIn, TOut > const &pool, Quality const &targetQuality, std::uint16_t tfee)
Generate AMM offer starting with takerPays when AMM pool from the payment perspective is XRP(in)/IOU(...
Definition AMMHelpers.h:267
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
Definition AMMHelpers.h:129
Number root2(Number f)
Definition Number.cpp:701
Number adjustFracByTokens(Rules const &rules, STAmount const &lptAMMBalance, STAmount const &tokens, Number const &frac)
Find a fraction of tokens after the tokens are adjusted.
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.
Definition AMMHelpers.h:537