1#include <xrpld/app/misc/AMMHelpers.h>
2#include <xrpld/app/misc/AMMUtils.h>
3#include <xrpld/app/tx/detail/AMMClawback.h>
4#include <xrpld/app/tx/detail/AMMWithdraw.h>
6#include <xrpl/ledger/Sandbox.h>
7#include <xrpl/ledger/View.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/protocol/TxFlags.h>
11#include <xrpl/protocol/st.h>
32 <<
"AMMClawback: holder cannot be the same as issuer.";
37 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
38 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
48 <<
"AMMClawback: tfClawTwoAssets can only be enabled when two "
49 "assets in the AMM pool are both issued by the issuer";
53 if (asset.account != issuer)
55 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Asset's account does not "
56 "match Account field.";
60 if (clawAmount && clawAmount->get<
Issue>() != asset)
62 JLOG(ctx.
j.
trace()) <<
"AMMClawback: Amount's issuer/currency subfield "
63 "does not match Asset field";
67 if (clawAmount && *clawAmount <= beast::zero)
76 auto const asset = ctx.
tx[sfAsset].get<
Issue>();
77 auto const asset2 = ctx.
tx[sfAsset2].get<
Issue>();
88 JLOG(ctx.
j.
debug()) <<
"AMM Clawback: Invalid asset pair.";
92 std::uint32_t const issuerFlagsIn = sleIssuer->getFieldU32(sfFlags);
128 auto const ammAccount = (*ammSle)[sfAccount];
137 auto const lpTokenBalance =
ammLPHolds(sb, *ammSle, holder,
j_);
138 if (lpTokenBalance == beast::zero)
142 sb, lpTokenBalance, ammSle, holder);
156 return expected.error();
157 auto const [amountBalance, amount2Balance, lptAMMBalance] = *expected;
164 auto const holdLPtokens =
ammLPHolds(sb, *ammSle, holder,
j_);
165 if (holdLPtokens == beast::zero)
171 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
188 std::tie(result, newLPTokenBalance, amountWithdraw, amount2Withdraw) =
204 sb, ammSle, newLPTokenBalance, asset, asset2,
j_);
209 <<
"AMM Withdraw during AMMClawback: lptoken new balance: "
211 <<
" old balance: " <<
to_string(lptAMMBalance.iou());
213 auto const ter =
rippleCredit(sb, holder, issuer, amountWithdraw,
true,
j_);
221 if (!amount2Withdraw)
226 return rippleCredit(sb, holder, issuer, *amount2Withdraw,
true,
j_);
243 auto frac =
Number{amount} / amountBalance;
244 auto amount2Withdraw = amount2Balance * frac;
246 auto const lpTokensWithdraw =
249 if (lpTokensWithdraw > holdLPtokens)
269 auto const& rules = sb.
rules();
270 if (rules.enabled(fixAMMClawbackRounding))
276 if (tokensAdj == beast::zero)
282 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.