xrpld
Loading...
Searching...
No Matches
AMMHelpers.h
1#pragma once
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/beast/utility/Zero.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/ReadView.h>
10#include <xrpl/ledger/Sandbox.h>
11#include <xrpl/ledger/helpers/TokenHelpers.h>
12#include <xrpl/protocol/AMMCore.h>
13#include <xrpl/protocol/AccountID.h>
14#include <xrpl/protocol/AmountConversions.h>
15#include <xrpl/protocol/Asset.h>
16#include <xrpl/protocol/Feature.h>
17#include <xrpl/protocol/IOUAmount.h>
18#include <xrpl/protocol/Issue.h>
19#include <xrpl/protocol/MPTAmount.h>
20#include <xrpl/protocol/Quality.h>
21#include <xrpl/protocol/Rules.h>
22#include <xrpl/protocol/STAmount.h>
23#include <xrpl/protocol/STLedgerEntry.h>
24#include <xrpl/protocol/TER.h>
25#include <xrpl/protocol/XRPAmount.h>
26
27#include <algorithm>
28#include <cstdint>
29#include <expected>
30#include <functional>
31#include <optional>
32#include <stdexcept>
33#include <tuple>
34#include <utility>
35
36namespace xrpl {
37
38namespace detail {
39
40Number
41reduceOffer(auto const& amount)
42{
43 static Number const kReducedOfferPct(9999, -4);
44
45 // Make sure the result is always less than amount or zero.
47 return amount * kReducedOfferPct;
48}
49
50} // namespace detail
51
52enum class IsDeposit : bool { No = false, Yes = true };
53
55
62STAmount
63ammLPTokens(STAmount const& asset1, STAmount const& asset2, Asset const& lptIssue);
64
73STAmount
75 STAmount const& asset1Balance,
76 STAmount const& asset1Deposit,
77 STAmount const& lptAMMBalance,
78 std::uint16_t tfee);
79
88STAmount
90 STAmount const& asset1Balance,
91 STAmount const& lptAMMBalance,
92 STAmount const& lpTokens,
93 std::uint16_t tfee);
94
104STAmount
106 STAmount const& asset1Balance,
107 STAmount const& asset1Withdraw,
108 STAmount const& lptAMMBalance,
109 std::uint16_t tfee);
110
119STAmount
121 STAmount const& assetBalance,
122 STAmount const& lptAMMBalance,
123 STAmount const& lpTokens,
124 std::uint16_t tfee);
125
134inline bool
135withinRelativeDistance(Quality const& calcQuality, Quality const& reqQuality, Number const& dist)
136{
137 if (calcQuality == reqQuality)
138 return true;
139 auto const [min, max] = std::minmax(calcQuality, reqQuality);
140 // Relative distance is (max - min)/max. Can't use basic operations
141 // on Quality. Have to use Quality::rate() instead, which
142 // is inverse of quality: (1/max.rate - 1/min.rate)/(1/max.rate)
143 return ((min.rate() - max.rate()) / min.rate()) < dist;
144}
145
154template <typename Amt>
155 requires(
159bool
160withinRelativeDistance(Amt const& calc, Amt const& req, Number const& dist)
161{
162 if (calc == req)
163 return true;
164 auto const [min, max] = std::minmax(calc, req);
165 return ((max - min) / max) < dist;
166}
167
173solveQuadraticEqSmallest(Number const& a, Number const& b, Number const& c);
174
199template <typename TIn, typename TOut>
202 TAmounts<TIn, TOut> const& pool,
203 Quality const& targetQuality,
204 std::uint16_t const& tfee)
205{
206 if (targetQuality.rate() == beast::kZero)
207 return std::nullopt;
208
210 auto const f = feeMult(tfee);
211 auto const a = 1;
212 auto const b = pool.in * (1 - 1 / f) / targetQuality.rate() - 2 * pool.out;
213 auto const c = pool.out * pool.out - (pool.in * pool.out) / targetQuality.rate();
214
215 auto nTakerGets = solveQuadraticEqSmallest(a, b, c);
216 if (!nTakerGets || *nTakerGets <= 0)
217 return std::nullopt; // LCOV_EXCL_LINE
218
219 auto const nTakerGetsConstraint = pool.out - pool.in / (targetQuality.rate() * f);
220 if (nTakerGetsConstraint <= 0)
221 return std::nullopt;
222
223 // Select the smallest to maximize the quality
224 if (nTakerGetsConstraint < *nTakerGets)
225 nTakerGets = nTakerGetsConstraint;
226
227 auto getAmounts = [&pool, &tfee](Number const& nTakerGetsProposed) {
228 // Round downward to minimize the offer and to maximize the quality.
229 // This has the most impact when takerGets is integral.
230 auto const takerGets =
231 toAmount<TOut>(getAsset(pool.out), nTakerGetsProposed, Number::RoundingMode::Downward);
232 return TAmounts<TIn, TOut>{swapAssetOut(pool, takerGets, tfee), takerGets};
233 };
234
235 // Try to reduce the offer size to improve the quality.
236 // The quality might still not match the targetQuality for a tiny offer.
237 auto amounts = getAmounts(*nTakerGets);
238 if (Quality{amounts} < targetQuality)
239 return getAmounts(detail::reduceOffer(amounts.out));
240 return amounts;
241}
242
267template <typename TIn, typename TOut>
270 TAmounts<TIn, TOut> const& pool,
271 Quality const& targetQuality,
272 std::uint16_t tfee)
273{
274 if (targetQuality.rate() == beast::kZero)
275 return std::nullopt;
276
278 auto const f = feeMult(tfee);
279 auto const& a = f;
280 auto const b = pool.in * (1 + f);
281 auto const c = pool.in * pool.in - pool.in * pool.out * targetQuality.rate();
282
283 auto nTakerPays = solveQuadraticEqSmallest(a, b, c);
284 if (!nTakerPays || nTakerPays <= 0)
285 return std::nullopt; // LCOV_EXCL_LINE
286
287 auto const nTakerPaysConstraint = 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 integral.
298 auto const takerPays =
299 toAmount<TIn>(getAsset(pool.in), nTakerPaysProposed, Number::RoundingMode::Downward);
300 return TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
301 };
302
303 // Try to reduce the offer size to improve the quality.
304 // The quality might still not match the targetQuality for a tiny offer.
305 auto amounts = getAmounts(*nTakerPays);
306 if (Quality{amounts} < targetQuality)
307 return getAmounts(detail::reduceOffer(amounts.in));
308 return amounts;
309}
310
328template <typename TIn, typename TOut>
331 TAmounts<TIn, TOut> const& pool,
332 Quality const& quality,
333 std::uint16_t tfee,
334 Rules const& rules,
336{
337 if (!rules.enabled(fixAMMv1_1))
338 {
339 // Finds takerPays (i) and takerGets (o) such that given pool
340 // composition poolGets(I) and poolPays(O): (O - o) / (I + i) = quality.
341 // Where takerGets is calculated as the swapAssetIn (see below).
342 // The above equation produces the quadratic equation:
343 // i^2*(1-fee) + i*I*(2-fee) + I^2 - I*O/quality,
344 // which is solved for i, and o is found with swapAssetIn().
345 auto const f = feeMult(tfee); // 1 - fee
346 auto const& a = f;
347 auto const b = pool.in * (1 + f);
348 Number const c = pool.in * pool.in - pool.in * pool.out * quality.rate();
349 auto const res = b * b - 4 * a * c;
350 if (res < 0)
351 {
352 return std::nullopt; // LCOV_EXCL_LINE
353 }
354 if (auto const nTakerPaysPropose = (-b + root2(res)) / (2 * a); 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 = pool.out * quality.rate() - pool.in / f;
362 if (nTakerPaysPropose > nTakerPaysConstraint)
363 return nTakerPaysConstraint;
364 return nTakerPaysPropose;
365 }();
366 if (nTakerPays <= 0)
367 {
368 JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " << to_string(pool.in)
369 << " " << to_string(pool.out) << " " << quality << " " << tfee;
370 return std::nullopt;
371 }
372 auto const takerPays =
374 // should not fail
375 if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
376 Quality{amounts} < quality &&
377 !withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
378 {
379 JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
380 << to_string(pool.out) << " "
381 << " " << quality << " " << tfee << " " << to_string(amounts.in)
382 << " " << to_string(amounts.out);
383 Throw<std::runtime_error>("changeSpotPriceQuality failed");
384 }
385 else
386 {
387 JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
388 << to_string(pool.out) << " "
389 << " " << quality << " " << tfee << " " << to_string(amounts.in)
390 << " " << to_string(amounts.out);
391 return amounts;
392 }
393 }
394 JLOG(j.trace()) << "changeSpotPriceQuality calc failed: " << to_string(pool.in) << " "
395 << to_string(pool.out) << " " << quality << " " << tfee;
396 return std::nullopt;
397 }
398
399 auto amounts = [&]() {
400 bool const inIntegral = getAsset(pool.in).integral();
401 bool const outIntegral = getAsset(pool.out).integral();
402
403 // Preserve historical behavior for fractional pairs and XRP/IOU-style
404 // one-integral-side pairs. For two integral assets, pick the side whose
405 // minimum unit is economically coarser at this quality.
406 //
407 // Quality::rate() is input units per output unit, so one output unit is
408 // coarser when it costs at least one input unit. Ties use takerGets,
409 // matching the historical XRP-output behavior.
410 if (outIntegral && (!inIntegral || Number(quality.rate()) >= 1))
411 return getAMMOfferStartWithTakerGets(pool, quality, tfee);
412 return getAMMOfferStartWithTakerPays(pool, quality, tfee);
413 }();
414 if (!amounts)
415 {
416 JLOG(j.trace()) << "changeSpotPrice calc failed: " << to_string(pool.in) << " "
417 << to_string(pool.out) << " " << quality << " " << tfee;
418 return std::nullopt;
419 }
420
421 if (Quality{*amounts} < quality)
422 {
423 JLOG(j.error()) << "changeSpotPriceQuality failed: " << to_string(pool.in) << " "
424 << to_string(pool.out) << " " << quality << " " << tfee << " "
425 << to_string(amounts->in) << " " << to_string(amounts->out);
426 return std::nullopt;
427 }
428
429 JLOG(j.trace()) << "changeSpotPriceQuality succeeded: " << to_string(pool.in) << " "
430 << to_string(pool.out) << " "
431 << " " << quality << " " << tfee << " " << to_string(amounts->in) << " "
432 << to_string(amounts->out);
433
434 return amounts;
435}
436
449
460template <typename TIn, typename TOut>
461TOut
462swapAssetIn(TAmounts<TIn, TOut> const& pool, TIn const& assetIn, std::uint16_t tfee)
463{
464 if (auto const& rules = getCurrentTransactionRules(); rules && rules->enabled(fixAMMv1_1))
465 {
466 // set rounding to always favor the amm. Clip to zero.
467 // calculate:
468 // pool.out -
469 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
470 // and explicitly set the rounding modes
471 // Favoring the amm means we should:
472 // minimize:
473 // pool.out -
474 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
475 // maximize:
476 // (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
477 // (pool.in * pool.out)
478 // minimize:
479 // (pool.in + assetIn * feeMult(tfee)),
480 // minimize:
481 // assetIn * feeMult(tfee)
482 // feeMult is: (1-fee), fee is tfee/100000
483 // minimize:
484 // 1-fee
485 // maximize:
486 // fee
488
490 auto const numerator = pool.in * pool.out;
491 auto const fee = getFee(tfee);
492
494 auto const denom = pool.in + assetIn * (1 - fee);
495
496 if (denom.signum() <= 0)
497 return toAmount<TOut>(getAsset(pool.out), 0);
498
500 auto const ratio = numerator / denom;
501
503 auto const swapOut = pool.out - ratio;
504
505 if (swapOut.signum() < 0)
506 return toAmount<TOut>(getAsset(pool.out), 0);
507
509 }
510
511 return toAmount<TOut>(
512 getAsset(pool.out),
513 pool.out - (pool.in * pool.out) / (pool.in + assetIn * feeMult(tfee)),
515}
516
527template <typename TIn, typename TOut>
528TIn
529swapAssetOut(TAmounts<TIn, TOut> const& pool, TOut const& assetOut, std::uint16_t tfee)
530{
531 if (auto const& rules = getCurrentTransactionRules(); rules && rules->enabled(fixAMMv1_1))
532 {
533 // set rounding to always favor the amm. Clip to zero.
534 // calculate:
535 // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) /
536 // (1-tfee/100000)
537 // maximize:
538 // ((pool.in * pool.out) / (pool.out - assetOut) - pool.in)
539 // maximize:
540 // (pool.in * pool.out) / (pool.out - assetOut)
541 // maximize:
542 // (pool.in * pool.out)
543 // minimize
544 // (pool.out - assetOut)
545 // minimize:
546 // (1-tfee/100000)
547 // maximize:
548 // tfee/100000
549
551
553 auto const numerator = pool.in * pool.out;
554
556 auto const denom = pool.out - assetOut;
557 if (denom.signum() <= 0)
558 {
559 return toMaxAmount<TIn>(getAsset(pool.in));
560 }
561
563 auto const ratio = numerator / denom;
564 auto const numerator2 = ratio - pool.in;
565 auto const fee = getFee(tfee);
566
568 auto const feeMult = 1 - fee;
569
571 auto const swapIn = numerator2 / feeMult;
572 if (swapIn.signum() < 0)
573 return toAmount<TIn>(getAsset(pool.in), 0);
574
576 }
577
578 return toAmount<TIn>(
579 getAsset(pool.in),
580 ((pool.in * pool.out) / (pool.out - assetOut) - pool.in) / feeMult(tfee),
582}
583
587Number
588square(Number const& n);
589
602STAmount
603adjustLPTokens(STAmount const& lptAMMBalance, STAmount const& lpTokens, IsDeposit isDeposit);
604
619 STAmount const& amountBalance,
620 STAmount const& amount,
621 std::optional<STAmount> const& amount2,
622 STAmount const& lptAMMBalance,
623 STAmount const& lpTokens,
624 std::uint16_t tfee,
625 IsDeposit isDeposit);
626
631Number
632solveQuadraticEq(Number const& a, Number const& b, Number const& c);
633
634STAmount
635multiply(STAmount const& amount, Number const& frac, Number::RoundingMode rm);
636
637namespace detail {
638
641{
642 // Minimize on deposit, maximize on withdraw to ensure
643 // AMM invariant sqrt(poolAsset1 * poolAsset2) >= LPTokensBalance
646}
647
650{
651 // Maximize on deposit, minimize on withdraw to ensure
652 // AMM invariant sqrt(poolAsset1 * poolAsset2) >= LPTokensBalance
653 return isDeposit == IsDeposit::Yes ? Number::RoundingMode::Upward
655}
656
657} // namespace detail
658
665template <typename A>
666STAmount
667getRoundedAsset(Rules const& rules, STAmount const& balance, A const& frac, IsDeposit isDeposit)
668{
669 if (!rules.enabled(fixAMMv1_3))
670 {
671 if constexpr (std::is_same_v<A, STAmount>)
672 {
673 return multiply(balance, frac, balance.asset());
674 }
675 else
676 {
677 return toSTAmount(balance.asset(), balance * frac);
678 }
679 }
680 auto const rm = detail::getAssetRounding(isDeposit);
681 return multiply(balance, frac, rm);
682}
683
694STAmount
696 Rules const& rules,
697 std::function<Number()> const& noRoundCb,
698 STAmount const& balance,
699 std::function<Number()> const& productCb,
700 IsDeposit isDeposit);
701
710STAmount
712 Rules const& rules,
713 STAmount const& balance,
714 Number const& frac,
715 IsDeposit isDeposit);
716
729STAmount
731 Rules const& rules,
732 std::function<Number()> const& noRoundCb,
733 STAmount const& lptAMMBalance,
734 std::function<Number()> const& productCb,
735 IsDeposit isDeposit);
736
737/* Next two functions adjust asset in/out amount to factor in the adjusted
738 * lptokens. The lptokens are calculated from the asset in/out. The lptokens are
739 * then adjusted to factor in the loss in precision. The adjusted lptokens might
740 * be less than the initially calculated tokens. Therefore, the asset in/out
741 * must be adjusted. The rounding might result in the adjusted amount being
742 * greater than the original asset in/out amount. If this happens,
743 * then the original amount is reduced by the difference in the adjusted amount
744 * and the original amount. The actual tokens and the actual adjusted amount
745 * are then recalculated. The minimum of the original and the actual
746 * adjusted amount is returned.
747 */
750 Rules const& rules,
751 STAmount const& balance,
752 STAmount const& amount,
753 STAmount const& lptAMMBalance,
754 STAmount const& tokens,
755 std::uint16_t tfee);
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);
764
769Number
771 Rules const& rules,
772 STAmount const& lptAMMBalance,
773 STAmount const& tokens,
774 Number const& frac);
775
781 ReadView const& view,
782 AccountID const& ammAccountID,
783 Asset const& asset1,
784 Asset const& asset2,
785 FreezeHandling freezeHandling,
786 AuthHandling authHandling,
787 beast::Journal const j);
788
796TER
797checkAMMPrecisionLoss(Number const& poolProductMean, STAmount const& newLPTokenBalance);
798
806TER
808 ReadView const& view,
809 AccountID const& ammAccountID,
810 Asset const& asset1,
811 Asset const& asset2,
812 STAmount const& newLPTokenBalance,
813 beast::Journal const j);
814
820std::expected<std::tuple<STAmount, STAmount, STAmount>, TER>
822 ReadView const& view,
823 SLE const& ammSle,
824 std::optional<Asset> const& optAsset1,
825 std::optional<Asset> const& optAsset2,
826 FreezeHandling freezeHandling,
827 AuthHandling authHandling,
828 beast::Journal const j);
829
833STAmount
835 ReadView const& view,
836 Asset const& asset1,
837 Asset const& asset2,
838 AccountID const& ammAccount,
839 AccountID const& lpAccount,
840 beast::Journal const j);
841
842STAmount
844 ReadView const& view,
845 SLE const& ammSle,
846 AccountID const& lpAccount,
847 beast::Journal const j);
848
855getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account);
856
860STAmount
861ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const& asset);
862
867TER
868deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::Journal j);
869
873void
875 ApplyView& view,
876 SLE::pointer& ammSle,
877 AccountID const& account,
878 Asset const& lptAsset,
879 std::uint16_t tfee);
880
886std::expected<bool, TER>
887isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID const& lpAccount);
888
894std::expected<bool, TER>
896 Sandbox& sb,
897 STAmount const& lpTokens,
898 SLE::pointer& ammSle,
899 AccountID const& account);
900
901} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
Stream error() const
Definition Journal.h:362
Stream trace() const
Severity stream access functions.
Definition Journal.h:338
bool integral() const
Definition Asset.h:133
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
static RoundingMode setround(RoundingMode inMode)
static RoundingMode getround()
Represents the logical ratio of output currency to input currency.
Definition Quality.h:90
STAmount rate() const
Returns the quality as STAmount.
Definition Quality.h:162
Rules controlling protocol behavior.
Definition Rules.h:40
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
Asset const & asset() const
Definition STAmount.h:496
std::shared_ptr< STLedgerEntry > pointer
T is_same_v
T minmax(T... args)
constexpr Zero kZero
Definition Zero.h:30
Number reduceOffer(auto const &amount)
Definition AMMHelpers.h:41
Number::RoundingMode getLPTokenRounding(IsDeposit isDeposit)
Definition AMMHelpers.h:640
Number::RoundingMode getAssetRounding(IsDeposit isDeposit)
Definition AMMHelpers.h:649
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
STAmount ammLPHolds(ReadView const &view, Asset const &asset1, Asset const &asset2, AccountID const &ammAccount, AccountID const &lpAccount, beast::Journal const j)
Get the balance of LP tokens.
FreezeHandling
Controls the treatment of frozen account balances.
Number adjustFracByTokens(Rules const &rules, STAmount const &lptAMMBalance, STAmount const &tokens, Number const &frac)
Find a fraction of tokens after the tokens are adjusted.
T toMaxAmount(Asset const &asset)
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Asset const &lptIssue)
Calculate LP Tokens given AMM pool reserves.
std::expected< bool, TER > isOnlyLiquidityProvider(ReadView const &view, Issue const &ammIssue, AccountID const &lpAccount)
Return true if the Liquidity Provider is the only AMM provider, false otherwise.
std::expected< bool, TER > verifyAndAdjustLPTokenBalance(Sandbox &sb, STAmount const &lpTokens, SLE::pointer &ammSle, AccountID const &account)
Due to rounding, the LPTokenBalance of the last LP might not match the LP's trustline balance.
IsDeposit
Definition AMMHelpers.h:52
void initializeFeeAuctionVote(ApplyView &view, SLE::pointer &ammSle, AccountID const &account, Asset const &lptAsset, std::uint16_t tfee)
Initialize Auction and Voting slots and set the trading/discounted fee.
STAmount adjustLPTokens(STAmount const &lptAMMBalance, STAmount const &lpTokens, IsDeposit isDeposit)
Adjust LP tokens to deposit/withdraw.
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:30
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).
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:462
STAmount ammAssetOut(STAmount const &assetBalance, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee)
Calculate asset withdrawal by tokens.
STAmount getRoundedLPTokens(Rules const &rules, STAmount const &balance, Number const &frac, IsDeposit isDeposit)
Round AMM deposit/withdrawal LPToken amount.
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
std::pair< STAmount, STAmount > ammPoolHolds(ReadView const &view, AccountID const &ammAccountID, Asset const &asset1, Asset const &asset2, FreezeHandling freezeHandling, AuthHandling authHandling, beast::Journal const j)
Get AMM pool balances.
T toAmount(STAmount const &amt)=delete
STLedgerEntry SLE
@ Yes
We have consensus along with the network.
@ No
We do not have consensus.
std::pair< STAmount, STAmount > adjustAssetInByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
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:201
STAmount ammAccountHolds(ReadView const &view, AccountID const &ammAccountID, Asset const &asset)
Returns total amount held by AMM for the given token.
Asset getAsset(T const &amt)
std::pair< STAmount, STAmount > adjustAssetOutByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
TER deleteAMMAccount(Sandbox &view, Asset const &asset, Asset const &asset2, beast::Journal j)
Delete trustlines to AMM.
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:269
STAmount getRoundedAsset(Rules const &rules, STAmount const &balance, A const &frac, IsDeposit isDeposit)
Round AMM equal deposit/withdrawal amount.
Definition AMMHelpers.h:667
AuthHandling
Controls the treatment of unauthorized MPT balances.
Number feeMult(std::uint16_t tfee)
Get fee multiplier (1 - tfee) @tfee trading fee in basis points.
Definition AMMCore.h:99
TER checkAMMPrecisionLoss(Number const &poolProductMean, STAmount const &newLPTokenBalance)
Check AMM pool product invariant after an AMM operation that changes LP tokens (deposit/withdraw/claw...
std::optional< Number > solveQuadraticEqSmallest(Number const &a, Number const &b, Number const &c)
Solve quadratic equation to find takerGets or takerPays.
Number root2(Number f)
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:330
STAmount ammAssetIn(STAmount const &asset1Balance, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee)
Calculate asset deposit given LP Tokens.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
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...
STAmount lpTokensIn(STAmount const &asset1Balance, STAmount const &asset1Withdraw, STAmount const &lptAMMBalance, std::uint16_t tfee)
Calculate LP Tokens given asset's withdraw amount.
Number getFee(std::uint16_t tfee)
Convert to the fee from the basis points.
Definition AMMCore.h:89
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:529
TERSubset< CanCvtToTER > TER
Definition TER.h:647
Number const kAMMInvariantRelativeTolerance
Definition AMMHelpers.h:54
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:135
STAmount multiply(STAmount const &amount, Number const &frac, Number::RoundingMode rm)
std::expected< std::tuple< STAmount, STAmount, STAmount >, TER > ammHolds(ReadView const &view, SLE const &ammSle, std::optional< Asset > const &optAsset1, std::optional< Asset > const &optAsset2, FreezeHandling freezeHandling, AuthHandling authHandling, beast::Journal const j)
Get AMM pool and LP token balances.
std::uint16_t getTradingFee(ReadView const &view, SLE const &ammSle, AccountID const &account)
Get AMM trading fee for the given account.
Number square(Number const &n)
Return square of n.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
STAmount toSTAmount(IOUAmount const &iou, Asset const &asset)
STAmount lpTokensOut(STAmount const &asset1Balance, STAmount const &asset1Deposit, STAmount const &lptAMMBalance, std::uint16_t tfee)
Calculate LP Tokens given asset's deposit amount.
Represents a pair of input and output currencies.
Definition Quality.h:29