2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/balance.h>
7#include <test/jtx/mpt.h>
8#include <test/jtx/offer.h>
9#include <test/jtx/paths.h>
10#include <test/jtx/pay.h>
11#include <test/jtx/sendmax.h>
12#include <test/jtx/ter.h>
13#include <test/jtx/txflags.h>
15#include <xrpl/beast/unit_test/suite.h>
16#include <xrpl/ledger/ApplyView.h>
17#include <xrpl/ledger/PaymentSandbox.h>
18#include <xrpl/protocol/AccountID.h>
19#include <xrpl/protocol/Asset.h>
20#include <xrpl/protocol/Book.h>
21#include <xrpl/protocol/Feature.h>
22#include <xrpl/protocol/Issue.h>
23#include <xrpl/protocol/STAmount.h>
24#include <xrpl/protocol/STPathSet.h>
25#include <xrpl/protocol/TER.h>
26#include <xrpl/protocol/TxFlags.h>
27#include <xrpl/protocol/UintTypes.h>
28#include <xrpl/tx/paths/RippleCalc.h>
29#include <xrpl/tx/paths/detail/Steps.h>
30#include <xrpl/tx/transactors/dex/AMMContext.h>
57 auto const alice =
Account(
"alice");
58 auto const bob =
Account(
"bob");
59 auto const carol =
Account(
"carol");
68 auto test = [&,
this](
88 BEAST_EXPECT(ter == expTer);
89 if (
sizeof...(expSteps) != 0)
94 auto testMultiToken = [&](
auto&& issue1,
auto&& issue2) {
95 Env env(*
this, features);
96 env.
fund(
XRP(10'000), alice, bob, gw);
98 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 1'000});
99 auto const bobUSD = issue1(
106 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 1'000});
107 auto const bobEUR = issue2(
113 env(
pay(gw, alice, eur(100)));
165 auto testMultiToken = [&](
auto&& issue1,
auto&& issue2) {
166 Env env(*
this, features);
167 env.
fund(
XRP(10'000), alice, bob, carol, gw);
168 auto usd = issue1({.env = env, .token =
"USD", .issuer = gw, .
limit = 1'000});
170 auto eur = issue2({.env = env, .token =
"EUR", .issuer = gw, .
limit = 1'000});
173 auto const err = [&]() {
191 env.
trust(usd(1'000), alice, bob, carol);
196 env(
pay(gw, alice, usd(100)));
197 env(
pay(gw, carol, usd(100)));
214 env.
trust(eur(1'000), alice, bob);
225 B{usd, eur, std::nullopt},
236 B{usd, eur, std::nullopt},
247 B{
XRP, usd, std::nullopt},
259 B{usd,
XRP, std::nullopt},
270 B{usd,
XRP, std::nullopt},
271 B{
XRP, eur, std::nullopt},
288 auto testMultiToken = [&](
auto&& issue1,
auto&& issue2) {
289 Env env(*
this, features);
291 env.
fund(
XRP(10'000), alice, bob, carol, gw);
293 auto const usd = issue1(
297 .holders = {alice, bob, carol},
299 auto const eur = issue2(
303 .holders = {alice, bob, carol},
306 env(
pay(gw, bob, usd(100)));
307 env(
pay(gw, bob, eur(100)));
309 env(
offer(bob,
XRP(100), usd(100)));
310 env(
offer(bob, usd(100), eur(100)),
Txflags(tfPassive));
311 env(
offer(bob, eur(100), usd(100)),
Txflags(tfPassive));
314 env(
pay(alice, carol, usd(100)),
315 Path(~usd, ~eur, ~usd),
325 Env env(*
this, features);
326 env.
fund(
XRP(10000), alice, bob, gw);
330 .holders = {alice, bob},
333 MPT const usd = usdm;
334 env(
pay(gw, alice, usd(100)));
337 usdm.set({.holder = alice, .flags = tfMPTLock});
339 usdm.set({.holder = alice, .flags = tfMPTUnlock});
343 usdm.set({.flags = tfMPTLock});
345 usdm.set({.flags = tfMPTUnlock});
349 usdm.set({.holder = bob, .flags = tfMPTLock});
351 usdm.set({.holder = bob, .flags = tfMPTUnlock});
359 Env env(*
this, features);
360 env.
fund(
XRP(10'000), alice, bob, gw);
366 MPT const usd = usdm;
369 usdm.authorize({.account = alice});
370 usdm.authorize({.holder = alice});
371 env(
pay(gw, alice, usd(100)));
390 BEAST_EXPECT(
equal(strand, M{alice, gw, usd}));
395 Env env(*
this, features);
396 env.
fund(
XRP(10'000), alice, bob, gw);
398 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 1'000});
399 env(
pay(gw, alice, usd(100)));
420 equal(strand, M{alice, gw, usd}, B{usd,
xrpIssue(), std::nullopt}, XRPS{bob}));
430 auto const alice =
Account(
"alice");
431 auto const bob =
Account(
"bob");
432 auto const carol =
Account(
"carol");
436 Env env(*
this, features);
438 env.
fund(
XRP(10000), alice, bob, carol, gw);
440 {.env = env, .issuer = gw, .holders = {alice, bob, carol}, .maxAmt = 10'000});
442 env(
pay(gw, bob, usd(100)));
448 env(
pay(alice, carol,
XRP(100)),
455 Env env(*
this, features);
457 env.
fund(
XRP(10000), alice, bob, carol, gw);
459 {.env = env, .issuer = gw, .holders = {alice, bob, carol}, .maxAmt = 10'000});
461 env(
pay(gw, bob, usd(100)));
467 env(
pay(alice, carol,
XRP(100)),
481 auto const alice =
Account(
"alice");
482 auto const bob =
Account(
"bob");
483 auto const carol =
Account(
"carol");
485 auto const eur = gw[
"EUR"];
486 auto const cny = gw[
"CNY"];
489 Env env(*
this, features);
491 env.
fund(
XRP(10'000), alice, bob, carol, gw);
493 {.env = env, .issuer = gw, .holders = {alice, bob, carol}, .maxAmt = 10'000});
495 env(
pay(gw, bob, usd(100)));
496 env(
pay(gw, alice, usd(100)));
502 env(
pay(alice, carol, usd(100)),
509 auto testMultiToken = [&](
auto&& issue1,
auto&& issue2,
auto&& issue3) {
510 Env env(*
this, features);
512 env.
fund(
XRP(10'000), alice, bob, carol, gw);
513 auto const usd = issue1(
517 .holders = {alice, bob, carol},
519 auto const eur = issue2(
523 .holders = {alice, bob, carol},
525 auto const cny = issue3(
529 .holders = {alice, bob, carol},
532 env(
pay(gw, bob, usd(100)));
533 env(
pay(gw, bob, eur(100)));
534 env(
pay(gw, bob, cny(100)));
537 env(
offer(bob, usd(100), eur(100)),
Txflags(tfPassive));
538 env(
offer(bob, eur(100), cny(100)),
Txflags(tfPassive));
541 env(
pay(alice, carol, cny(100)),
543 Path(~usd, ~eur, ~usd, ~cny),
557 auto const alice =
Account(
"alice");
558 auto const bob =
Account(
"bob");
561 Env env(*
this, features);
562 env.
fund(
XRP(10'000), alice, bob, gw);
563 MPT const usd =
MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}});
565 STAmount const sendMax{usd, 100, 1};
void fail(String const &reason, char const *file, int line)
Record a failure.
TestcaseT testcase
Memberspace for declaring test cases.
Maintains AMM info per overall payment engine execution and individual iteration.
beast::Journal journal(std::string const &name)
A wrapper which makes credits unavailable to balances.
virtual Logs & getLogs()=0
static Output rippleCalculate(PaymentSandbox &view, STAmount const &saMaxAmountReq, STAmount const &saDstAmountReq, AccountID const &uDstAccountID, AccountID const &uSrcAccountID, STPathSet const &spsPaths, std::optional< uint256 > const &domainID, ServiceRegistry ®istry, Input const *const pInputs=nullptr)
Immutable cryptographic account descriptor.
A transaction testing environment.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
PrettyAmount limit(Account const &account, Issue const &issue) const
Returns the IOU limit on an account.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
void require(Args const &... args)
Check a set of requirements.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Converts to IOU Issue or STAmount.
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
void authorizeHolders(Holders const &holders)
Converts to MPT Issue or STAmount.
xrpl::MPTID const & mpt() const
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
void testHelper2TokensMix(TTester &&tester)
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
void testHelper3TokensMix(TTester &&tester)
STPathElement cpe(PathAsset const &pa)
STPathElement ipe(Asset const &asset)
bool equal(STAmount const &sa1, STAmount const &sa2)
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
std::pair< TER, Strand > toStrand(ReadView const &sb, AccountID const &src, AccountID const &dst, Asset const &deliver, std::optional< Quality > const &limitQuality, std::optional< Asset > const &sendMaxAsset, STPath const &path, bool ownerPaysTransferFee, OfferCrossing offerCrossing, AMMContext &ammContext, std::optional< uint256 > const &domainID, beast::Journal j)
Create a Strand for the specified path.
Currency const & xrpCurrency()
XRP currency.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
AccountID const & noAccount()
A placeholder for empty accounts.
TERSubset< CanCvtToTER > TER
AccountID const & xrpAccount()
Compute AccountID from public key.
void testToStrand(FeatureBitset features)
void testNoAccount(FeatureBitset features)
static jtx::DirectStepInfo makeEndpointStep(jtx::Account const &src, jtx::Account const &dst, jtx::IOU const &iou)
static jtx::MPTEndpointStepInfo makeEndpointStep(jtx::Account const &src, jtx::Account const &dst, jtx::MPT const &mpt)
void testLoop(FeatureBitset features)
void testRIPD1373(FeatureBitset features)
void run() override
Runs the suite.