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>
51 <<
"AMMClawback: holder cannot be the same as issuer.";
56 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
57 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
67 <<
"AMMClawback: tfClawTwoAssets can only be enabled when two "
68 "assets in the AMM pool are both issued by the issuer";
72 if (asset.account != issuer)
74 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Asset's account does not "
75 "match Account field.";
79 if (clawAmount && clawAmount->get<
Issue>() != asset)
81 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Amount's issuer/currency subfield "
82 "does not match Asset field";
86 if (clawAmount && *clawAmount <= beast::zero)
95 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
96 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
107 JLOG(ctx.
j.
debug()) <<
"AMM Clawback: Invalid asset pair.";
111 std::uint32_t const issuerFlagsIn = sleIssuer->getFieldU32(sfFlags);
147 auto const ammAccount = (*ammSle)[sfAccount];
156 auto const lpTokenBalance =
ammLPHolds(sb, *ammSle, holder,
j_);
157 if (lpTokenBalance == beast::zero)
161 sb, lpTokenBalance, ammSle, holder);
175 return expected.error();
176 auto const [amountBalance, amount2Balance, lptAMMBalance] = *expected;
183 auto const holdLPtokens =
ammLPHolds(sb, *ammSle, holder,
j_);
184 if (holdLPtokens == beast::zero)
190 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
207 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
223 sb, ammSle, newLPTokenBalance, asset, asset2,
j_);
228 <<
"AMM Withdraw during AMMClawback: lptoken new balance: "
230 <<
" old balance: " <<
to_string(lptAMMBalance.iou());
232 auto const ter =
rippleCredit(sb, holder, issuer, amountWithdraw,
true,
j_);
240 if (!amount2Withdraw)
245 return rippleCredit(sb, holder, issuer, *amount2Withdraw,
true,
j_);
262 auto frac =
Number{amount} / amountBalance;
263 auto amount2Withdraw = amount2Balance * frac;
265 auto const lpTokensWithdraw =
268 if (lpTokensWithdraw > holdLPtokens)
288 auto const& rules = sb.
rules();
289 if (rules.enabled(fixAMMClawbackRounding))
295 if (tokensAdj == beast::zero)
301 auto amount2Rounded =
Stream trace() const
Severity stream access functions.
TER applyGuts(Sandbox &view)
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
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
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.
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.
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.
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.