1#include <xrpl/tx/invariants/AMMInvariant.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Number.h>
5#include <xrpl/beast/utility/Journal.h>
6#include <xrpl/beast/utility/Zero.h>
7#include <xrpl/ledger/ReadView.h>
8#include <xrpl/ledger/helpers/AMMHelpers.h>
9#include <xrpl/ledger/helpers/TokenHelpers.h>
10#include <xrpl/protocol/Feature.h>
11#include <xrpl/protocol/HashPrefix.h>
12#include <xrpl/protocol/Issue.h>
13#include <xrpl/protocol/LedgerFormats.h>
14#include <xrpl/protocol/SField.h>
15#include <xrpl/protocol/STAmount.h>
16#include <xrpl/protocol/STLedgerEntry.h>
17#include <xrpl/protocol/STTx.h>
18#include <xrpl/protocol/TER.h>
19#include <xrpl/protocol/TxFormats.h>
20#include <xrpl/protocol/XRPAmount.h>
31 if (before && before->getType() == ltAMM)
41 auto const type =
after->getType();
50 (type == ltRIPPLE_STATE &&
after->isFlag(lsfAMMNode)) ||
51 (type == ltACCOUNT_ROOT &&
after->isFieldPresent(sfAMMID)) ||
52 (type == ltMPTOKEN &&
after->isFlag(lsfMPTAMM)))
61 if (before->getType() == ltAMM)
76 amount > beast::kZero && amount2 > beast::kZero && lptAMMBalance > beast::kZero;
80 (amount == beast::kZero && amount2 == beast::kZero && lptAMMBalance == beast::kZero);
92 JLOG(j.
error()) <<
"Invariant failed: AMMVote failed, "
110 JLOG(j.
error()) <<
"Invariant failed: AMMBid failed, pool changed";
141 JLOG(j.
error()) <<
"Invariant failed: AMMCreate failed, AMM object is not created";
151 tx[sfAmount].asset(),
152 tx[sfAmount2].asset(),
164 JLOG(j.
error()) <<
"Invariant failed: AMMCreate failed, " << amount <<
" " << amount2
183 :
"AMM object changed on tecINCOMPLETE";
184 JLOG(j.
error()) <<
"Invariant failed: AMMDelete failed, " << msg;
189 if (enforceAMMDelete)
197 <<
"Invariant failed: AMMDelete failed, AMM object remained on tesSUCCESS";
205 <<
"Invariant failed: AMMDelete failed, AMM object deleted without LP balance";
213 <<
"Invariant failed: AMMDelete failed, AMM object deleted with non-zero LP "
224 JLOG(j.
error()) <<
"Invariant failed: AMMDelete failed, AMM object deleted when result "
240 JLOG(j.
error()) <<
"Invariant failed: AMM swap failed, AMM object changed";
270 auto const poolProductMean =
root2(amount * amount2);
271 bool const nonNegativeBalances =
274 if (!nonNegativeBalances || !
isTesSuccess(precisionLoss))
278 << amount <<
" " << amount2 <<
" " << poolProductMean <<
" "
300 JLOG(j.
error()) <<
"Invariant failed: AMMDeposit failed, AMM object is deleted";
318 bool enforceAMMDelete,
351 bool const enforceAMMDelete = view.
rules().
enabled(fixCleanup3_3_0);
364 JLOG(j.
error()) <<
"Invariant failed: AMM failed, unexpected AMM deletion by "
A generic endpoint for log messages.
A currency issued by an account.
Number is a floating point type that can represent a wide range of values.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
std::shared_ptr< STLedgerEntry const > const & const_ref
uint256 getHash(HashPrefix prefix) const
TxType getTxnType() const
std::optional< AccountID > ammAccount_
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
bool finalizeBid(bool enforce, beast::Journal const &) const
bool finalizeDelete(bool enforce, bool enforceAMMDelete, TER res, beast::Journal const &) const
bool finalizeCreate(STTx const &, ReadView const &, bool enforce, beast::Journal const &) const
bool finalizeWithdraw(STTx const &, ReadView const &, bool enforce, bool enforceAMMDelete, beast::Journal const &) const
bool finalizeDEX(bool enforce, beast::Journal const &) const
void visitEntry(bool, SLE::const_ref, SLE::const_ref)
bool finalizeDeposit(STTx const &, ReadView const &, bool enforce, beast::Journal const &) const
bool generalInvariant(STTx const &, ReadView const &, ZeroAllowed zeroAllowed, beast::Journal const &) const
std::optional< STAmount > lptAMMBalanceBeforeDeletion_
std::optional< STAmount > lptAMMBalanceAfter_
bool finalizeVote(bool enforce, beast::Journal const &) const
std::optional< STAmount > lptAMMBalanceBefore_
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Asset const &lptIssue)
Calculate LP Tokens given AMM pool reserves.
std::pair< STAmount, STAmount > ammPoolHolds(ReadView const &view, AccountID const &ammAccountID, Asset const &asset1, Asset const &asset2, FreezeHandling freezeHandling, AuthHandling authHandling, beast::Journal const j)
Get AMM pool balances.
static bool validBalances(STAmount const &amount, STAmount const &amount2, STAmount const &lptAMMBalance, ValidAMM::ZeroAllowed zeroAllowed)
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
TER checkAMMPrecisionLoss(Number const &poolProductMean, STAmount const &newLPTokenBalance)
Check AMM pool product invariant after an AMM operation that changes LP tokens (deposit/withdraw/claw...
@ TransactionId
transaction plus signature to give transaction ID
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER