1#include <test/jtx/AMM.h>
2#include <test/jtx/AMMTest.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/check.h>
7#include <test/jtx/mpt.h>
8#include <test/jtx/offer.h>
9#include <test/jtx/owners.h>
10#include <test/jtx/pay.h>
11#include <test/jtx/sendmax.h>
12#include <test/jtx/ter.h>
13#include <test/jtx/token.h>
14#include <test/jtx/trust.h>
15#include <test/jtx/txflags.h>
17#include <xrpl/basics/base_uint.h>
18#include <xrpl/beast/unit_test/suite.h>
19#include <xrpl/protocol/Feature.h>
20#include <xrpl/protocol/Indexes.h>
21#include <xrpl/protocol/SeqProxy.h>
22#include <xrpl/protocol/TER.h>
23#include <xrpl/protocol/TxFlags.h>
37 Env env{*
this, features};
52 auto const lpIssue = ammAlice.
lptIssue();
73 if (features[fixFrozenLPTokenTransfer])
91 Env env{*
this, features};
95 ammAlice.deposit(
carol_, 1'000);
96 ammAlice.deposit(
bob_, 1'000);
98 auto const lpIssue = ammAlice.lptIssue();
117 if (features[fixFrozenLPTokenTransfer])
181 Env env{*
this, features};
185 ammAlice.deposit(
carol_, 1'000);
186 ammAlice.deposit(
bob_, 1'000);
188 auto const lpIssue = ammAlice.lptIssue();
196 if (features[fixFrozenLPTokenTransfer])
241 Env env{*
this, features};
246 ammAlice1.deposit(
carol_, 10'000'000);
250 ammAlice2.deposit(
carol_, 10'000'000);
251 auto const token1 = ammAlice1.lptIssue();
252 auto const token2 = ammAlice2.lptIssue();
270 if (features[fixFrozenLPTokenTransfer])
302 Env env{*
this, features};
306 ammAlice.deposit(
carol_, 1'000);
307 ammAlice.deposit(
bob_, 1'000);
309 auto const lpIssue = ammAlice.lptIssue();
322 if (features[fixFrozenLPTokenTransfer])
350 Env env{*
this, features};
355 ammAlice.deposit(
carol_, 1'000);
356 ammAlice.deposit(
bob_, 1'000);
358 auto const lpIssue = ammAlice.lptIssue();
377 if (features[fixFrozenLPTokenTransfer])
442 testcase(
"MPT CanTransfer DirectStep");
449 if (!features[featureMPTokensV2])
458 auto testLPTokenTransfer = [&](
std::uint32_t mptFlags,
bool poolXrpToBtc) {
459 Env env{*
this, features};
466 {.env = env, .issuer =
gw_, .holders = {
alice_}, .pay = 1'000, .flags = mptFlags});
468 auto const asset1 = poolXrpToBtc ?
XRP(10'000) : btc(10'000);
469 auto const asset2 = poolXrpToBtc ? btc(10'000) :
XRP(10'000);
471 auto const lpIssue =
amm.lptIssue();
485 if ((mptFlags & tfMPTCanTransfer) != 0u)
497 testLPTokenTransfer(tfMPTCanTrade,
true);
498 testLPTokenTransfer(tfMPTCanTrade,
false);
501 testLPTokenTransfer(tfMPTCanTrade | tfMPTCanTransfer,
true);
502 testLPTokenTransfer(tfMPTCanTrade | tfMPTCanTransfer,
false);
512 if (!features[featureMPTokensV2])
520 auto testLPTokenTransfer = [&](
std::uint32_t mptFlags,
bool poolXrpToBtc) {
521 Env env{*
this, features};
526 {.env = env, .issuer =
gw_, .holders = {
carol_}, .pay = 1'000, .flags = mptFlags});
528 auto const asset1 = poolXrpToBtc ?
XRP(10'000) : btc(10'000);
529 auto const asset2 = poolXrpToBtc ? btc(10'000) :
XRP(10'000);
531 auto const lpIssue =
amm.lptIssue();
542 if ((mptFlags & tfMPTCanTransfer) != 0u)
561 testLPTokenTransfer(tfMPTCanTrade,
true);
562 testLPTokenTransfer(tfMPTCanTrade,
false);
565 testLPTokenTransfer(tfMPTCanTrade | tfMPTCanTransfer,
true);
566 testLPTokenTransfer(tfMPTCanTrade | tfMPTCanTransfer,
false);
575 for (
auto const features : {all, all - fixFrozenLPTokenTransfer})
TestcaseT testcase
Memberspace for declaring test cases.
Floating point representation of amounts with high dynamic range.
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
void testMPTCanTransferDirectStep(FeatureBitset features)
void run() override
Runs the suite.
void testOfferCrossing(FeatureBitset features)
void testOfferCreation(FeatureBitset features)
void testMPTCanTransferOffer(FeatureBitset features)
void testDirectStep(FeatureBitset features)
void testBookStep(FeatureBitset features)
void testCheck(FeatureBitset features)
void testNFTOffers(FeatureBitset features)
jtx::Account const alice_
jtx::Account const carol_
Convenience class to test AMM functionality.
IOUAmount deposit(std::optional< Account > const &account, LPToken tokens, std::optional< STAmount > const &asset1InDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< Ter > const &ter=std::nullopt)
bool expectBalances(STAmount const &asset1, STAmount const &asset2, IOUAmount const &lpt, std::optional< AccountID > const &account=std::nullopt) const
Verify the AMM balances.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
Converts to MPT Issue or STAmount.
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Sets the optional Owner on an NFTokenOffer.
Keylet nftokenOffer(AccountID const &owner, SeqProxy const &seq)
An offer from an account to buy or sell an NFT.
Keylet check(AccountID const &id, SeqProxy const &seq) noexcept
A Check.
json::Value cash(jtx::Account const &dest, UInt256 const &checkId, STAmount const &amount)
Cash a check requiring that a specific amount be delivered.
json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
json::Value acceptSellOffer(jtx::Account const &account, UInt256 const &offerIndex)
Accept an NFToken sell offer.
json::Value mint(jtx::Account const &account, std::uint32_t nfTokenTaxon)
Mint an NFToken.
json::Value createOffer(jtx::Account const &account, UInt256 const &nftokenID, STAmount const &amount)
Create an NFTokenOffer.
UInt256 getNextID(jtx::Env const &env, jtx::Account const &issuer, std::uint32_t nfTokenTaxon, std::uint16_t flags, std::uint16_t xferFee)
Get the next NFTokenID that will be issued.
json::Value acceptBuyOffer(jtx::Account const &account, UInt256 const &offerIndex)
Accept an NFToken buy offer.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
std::vector< STAmount > fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.