20#include <xrpld/app/misc/AMMHelpers.h>
21#include <xrpld/app/misc/AMMUtils.h>
22#include <xrpld/app/tx/detail/AMMClawback.h>
23#include <xrpld/app/tx/detail/AMMWithdraw.h>
25#include <xrpl/ledger/Sandbox.h>
26#include <xrpl/ledger/View.h>
27#include <xrpl/protocol/Feature.h>
28#include <xrpl/protocol/Indexes.h>
29#include <xrpl/protocol/TxFlags.h>
30#include <xrpl/protocol/st.h>
55 <<
"AMMClawback: holder cannot be the same as issuer.";
60 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
61 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
69 <<
"AMMClawback: tfClawTwoAssets can only be enabled when two "
70 "assets in the AMM pool are both issued by the issuer";
74 if (asset.account != issuer)
76 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Asset's account does not "
77 "match Account field.";
81 if (clawAmount && clawAmount->get<
Issue>() != asset)
83 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Amount's issuer/currency subfield "
84 "does not match Asset field";
88 if (clawAmount && *clawAmount <= beast::zero)
97 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
98 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
109 JLOG(ctx.
j.
debug()) <<
"AMM Clawback: Invalid asset pair.";
113 std::uint32_t const issuerFlagsIn = sleIssuer->getFieldU32(sfFlags);
149 auto const ammAccount = (*ammSle)[sfAccount];
158 auto const lpTokenBalance =
ammLPHolds(sb, *ammSle, holder,
j_);
159 if (lpTokenBalance == beast::zero)
163 sb, lpTokenBalance, ammSle, holder);
177 return expected.error();
178 auto const [amountBalance, amount2Balance, lptAMMBalance] = *expected;
185 auto const holdLPtokens =
ammLPHolds(sb, *ammSle, holder,
j_);
186 if (holdLPtokens == beast::zero)
192 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
209 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
225 sb, ammSle, newLPTokenBalance, asset, asset2,
j_);
230 <<
"AMM Withdraw during AMMClawback: lptoken new balance: "
232 <<
" old balance: " <<
to_string(lptAMMBalance.iou());
234 auto const ter =
rippleCredit(sb, holder, issuer, amountWithdraw,
true,
j_);
242 if (!amount2Withdraw)
247 return rippleCredit(sb, holder, issuer, *amount2Withdraw,
true,
j_);
264 auto frac =
Number{amount} / amountBalance;
265 auto amount2Withdraw = amount2Balance * frac;
267 auto const lpTokensWithdraw =
270 if (lpTokensWithdraw > holdLPtokens)
290 auto const& rules = sb.
rules();
291 if (rules.enabled(fixAMMClawbackRounding))
297 if (tokensAdj == beast::zero)
303 auto amount2Rounded =
Stream trace() const
Severity stream access functions.
TER applyGuts(Sandbox &view)
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
std::tuple< TER, STAmount, STAmount, std::optional< STAmount > > equalWithdrawMatchingOneAmount(Sandbox &view, SLE const &ammSle, AccountID const &holder, AccountID const &ammAccount, STAmount const &amountBalance, STAmount const &amount2Balance, STAmount const &lptAMMBalance, STAmount const &holdLPtokens, STAmount const &amount)
Withdraw both assets by providing maximum amount of asset1, asset2's amount will be calculated accord...
static std::tuple< TER, STAmount, STAmount, std::optional< STAmount > > equalWithdrawTokens(Sandbox &view, SLE const &ammSle, AccountID const account, AccountID const &ammAccount, STAmount const &amountBalance, STAmount const &amount2Balance, STAmount const &lptAMMBalance, STAmount const &lpTokens, STAmount const &lpTokensWithdraw, std::uint16_t tfee, FreezeHandling freezeHanding, WithdrawAll withdrawAll, XRPAmount const &priorBalance, beast::Journal const &journal)
Equal-asset withdrawal (LPTokens) of some AMM instance pools shares represented by the number of LPTo...
static std::pair< TER, bool > deleteAMMAccountIfEmpty(Sandbox &sb, std::shared_ptr< SLE > const ammSle, STAmount const &lpTokenBalance, Issue const &issue1, Issue const &issue2, beast::Journal const &journal)
static std::tuple< TER, STAmount, STAmount, std::optional< STAmount > > withdraw(Sandbox &view, SLE const &ammSle, AccountID const &ammAccount, AccountID const &account, STAmount const &amountBalance, STAmount const &amountWithdraw, std::optional< STAmount > const &amount2Withdraw, STAmount const &lpTokensAMMBalance, STAmount const &lpTokensWithdraw, std::uint16_t tfee, FreezeHandling freezeHandling, WithdrawAll withdrawAll, XRPAmount const &priorBalance, beast::Journal const &journal)
Withdraw requested assets and token from AMM into LP account.
beast::Journal const journal
A currency issued by an account.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Issue const & issue() const
std::uint32_t getFlags() const
Discardable, editable view to a ledger.
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Rules const & rules() const override
Returns the tx processing rules.
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool isXRP(AccountID const &c)
@ lsfAllowTrustLineClawback
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
constexpr std::uint32_t tfClawTwoAssets
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
STAmount getRoundedLPTokens(Rules const &rules, STAmount const &balance, Number const &frac, IsDeposit isDeposit)
Round AMM deposit/withdrawal LPToken amount.
Expected< bool, TER > verifyAndAdjustLPTokenBalance(Sandbox &sb, STAmount const &lpTokens, std::shared_ptr< SLE > &ammSle, AccountID const &account)
Due to rounding, the LPTokenBalance of the last LP might not match the LP's trustline balance.
constexpr std::uint32_t tfAMMClawbackMask
STAmount ammLPHolds(ReadView const &view, Currency const &cur1, Currency const &cur2, AccountID const &ammAccount, AccountID const &lpAccount, beast::Journal const j)
Get the balance of LP tokens.
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
TER rippleCredit(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
Calls static rippleCreditIOU if saAmount represents Issue.
bool isTesSuccess(TER x) noexcept
Expected< std::tuple< STAmount, STAmount, STAmount >, TER > ammHolds(ReadView const &view, SLE const &ammSle, std::optional< Issue > const &optIssue1, std::optional< Issue > const &optIssue2, FreezeHandling freezeHandling, beast::Journal const j)
Get AMM pool and LP token balances.
std::string to_string(base_uint< Bits, Tag > const &a)
STAmount getRoundedAsset(Rules const &rules, STAmount const &balance, A const &frac, IsDeposit isDeposit)
Round AMM equal deposit/withdrawal amount.
Number adjustFracByTokens(Rules const &rules, STAmount const &lptAMMBalance, STAmount const &tokens, Number const &frac)
Find a fraction of tokens after the tokens are adjusted.
TERSubset< CanCvtToNotTEC > NotTEC
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.