1#include <xrpld/app/misc/AMMHelpers.h>
11 auto const tokens =
root2(asset1 * asset2);
30 Number const r = asset1Deposit / asset1Balance;
31 auto const c =
root2(f2 * f2 + r / f1) - f2;
34 auto const t = lptAMMBalance * (r - c) / (1 + c);
40 auto const frac = (r - c) / (1 + c);
61 auto const t1 = lpTokens / lptAMMBalance;
62 auto const t2 = 1 + t1;
63 auto const d = f2 - t1 / t2;
64 auto const a = 1 / (t2 * t2);
65 auto const b = 2 * d / t2 - 1 / f1;
66 auto const c = d * d - f2 * f2;
90 Number const fr = asset1Withdraw / asset1Balance;
91 auto const f1 =
getFee(tfee);
92 auto const c = fr * f1 + 2 - f1;
95 auto const t = lptAMMBalance * (c -
root2(c * c - 4 * fr)) / 2;
101 auto const frac = (c -
root2(c * c - 4 * fr)) / 2;
119 auto const f =
getFee(tfee);
120 Number const t1 = lpTokens / lptAMMBalance;
123 auto const b = assetBalance * (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
129 auto const frac = (t1 * t1 - t1 * (2 - f)) / (t1 * f - 1);
147 return (lptAMMBalance + lpTokens) - lptAMMBalance;
148 return (lpTokens - lptAMMBalance) + lptAMMBalance;
165 auto const lpTokensActual =
adjustLPTokens(lptAMMBalance, lpTokens, isDeposit);
167 if (lpTokensActual == beast::zero)
173 if (lpTokensActual < lpTokens)
175 bool const ammRoundingEnabled = [&]() {
184 Number const fr = lpTokensActual / lpTokens;
185 auto const amountActual =
toSTAmount(amount.issue(), fr * amount);
186 auto const amount2Actual =
toSTAmount(amount2->issue(), fr * *amount2);
187 if (!ammRoundingEnabled)
189 amountActual < amount ? amountActual : amount,
190 amount2Actual < amount2 ? amount2Actual : amount2,
197 auto const amountActual = [&]() {
199 return ammAssetIn(amountBalance, lptAMMBalance, lpTokensActual, tfee);
200 else if (!ammRoundingEnabled)
201 return ammAssetOut(amountBalance, lptAMMBalance, lpTokens, tfee);
203 return ammAssetOut(amountBalance, lptAMMBalance, lpTokensActual, tfee);
205 if (!ammRoundingEnabled)
212 XRPL_ASSERT(lpTokensActual == lpTokens,
"xrpl::adjustAmountsByLPTokens : LP tokens match actual");
214 return {amount, amount2, lpTokensActual};
220 return (-b +
root2(b * b - 4 * a * c)) / (2 * a);
227 auto const d = b * b - 4 * a * c;
233 return (2 * c) / (-b -
root2(d));
235 return (2 * c) / (-b +
root2(d));
242 auto const t = amount * frac;
254 if (!rules.
enabled(fixAMMv1_3))
259 return multiply(balance, productCb(), rm);
267 if (!rules.
enabled(fixAMMv1_3))
271 auto const tokens =
multiply(balance, frac, rm);
283 if (!rules.
enabled(fixAMMv1_3))
286 auto const tokens = [&] {
293 return multiply(lptAMMBalance, productCb(), rm);
307 if (!rules.
enabled(fixAMMv1_3))
308 return {tokens, amount};
309 auto assetAdj =
ammAssetIn(balance, lptAMMBalance, tokens, tfee);
310 auto tokensAdj = tokens;
314 if (assetAdj > amount)
316 auto const adjAmount = amount - (assetAdj - amount);
317 auto const t =
lpTokensOut(balance, adjAmount, lptAMMBalance, tfee);
319 assetAdj =
ammAssetIn(balance, lptAMMBalance, tokensAdj, tfee);
321 return {tokensAdj,
std::min(amount, assetAdj)};
333 if (!rules.
enabled(fixAMMv1_3))
334 return {tokens, amount};
335 auto assetAdj =
ammAssetOut(balance, lptAMMBalance, tokens, tfee);
336 auto tokensAdj = tokens;
340 if (assetAdj > amount)
342 auto const adjAmount = amount - (assetAdj - amount);
343 auto const t =
lpTokensIn(balance, adjAmount, lptAMMBalance, tfee);
345 assetAdj =
ammAssetOut(balance, lptAMMBalance, tokensAdj, tfee);
347 return {tokensAdj,
std::min(amount, assetAdj)};
353 if (!rules.
enabled(fixAMMv1_3))
355 return tokens / lptAMMBalance;
A currency issued by an account.
Number is a floating point type that can represent a wide range of values.
static rounding_mode getround()
static rounding_mode setround(rounding_mode mode)
Rules controlling protocol behavior.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Issue const & issue() const
T make_optional(T... args)
Number::rounding_mode getLPTokenRounding(IsDeposit isDeposit)
Number::rounding_mode getAssetRounding(IsDeposit isDeposit)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Number feeMultHalf(std::uint16_t tfee)
Get fee multiplier (1 - tfee / 2) @tfee trading fee in basis points.
Number adjustFracByTokens(Rules const &rules, STAmount const &lptAMMBalance, STAmount const &tokens, Number const &frac)
Find a fraction of tokens after the tokens are adjusted.
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
STAmount adjustLPTokens(STAmount const &lptAMMBalance, STAmount const &lpTokens, IsDeposit isDeposit)
Adjust LP tokens to deposit/withdraw.
std::optional< Rules > const & getCurrentTransactionRules()
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)
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Issue const &lptIssue)
Calculate LP Tokens given AMM pool reserves.
STAmount multiply(STAmount const &amount, Rate const &rate)
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::pair< STAmount, STAmount > adjustAssetInByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
std::pair< STAmount, STAmount > adjustAssetOutByTokens(Rules const &rules, STAmount const &balance, STAmount const &amount, STAmount const &lptAMMBalance, STAmount const &tokens, std::uint16_t tfee)
STAmount getRoundedAsset(Rules const &rules, STAmount const &balance, A const &frac, IsDeposit isDeposit)
Round AMM equal deposit/withdrawal amount.
Number feeMult(std::uint16_t tfee)
Get fee multiplier (1 - tfee) @tfee trading fee in basis points.
std::optional< Number > solveQuadraticEqSmallest(Number const &a, Number const &b, Number const &c)
Solve quadratic equation to find takerGets or takerPays.
STAmount ammAssetIn(STAmount const &asset1Balance, STAmount const &lptAMMBalance, STAmount const &lpTokens, std::uint16_t tfee)
Calculate asset deposit given LP Tokens.
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.
Number square(Number const &n)
Return square of n.
STAmount lpTokensOut(STAmount const &asset1Balance, STAmount const &asset1Deposit, STAmount const &lptAMMBalance, std::uint16_t tfee)
Calculate LP Tokens given asset's deposit amount.
bool isFeatureEnabled(uint256 const &feature)