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.