3#include <xrpl/ledger/Dir.h>
4#include <xrpl/ledger/Sandbox.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/Indexes.h>
7#include <xrpl/protocol/STAmount.h>
8#include <xrpl/protocol/TxFlags.h>
9#include <xrpl/protocol/jss.h>
10#include <xrpl/tx/applySteps.h>
24 if (sle && sle->isFieldPresent(sfLockedAmount))
25 return (*sle)[sfLockedAmount];
33 if (sle && sle->isFieldPresent(sfLockedAmount))
34 return (*sle)[sfLockedAmount];
42 params[jss::account] = account.human();
43 auto jrr = env.
rpc(
"json",
"gateway_balances",
to_string(params));
44 auto const result = jrr[jss::result];
46 if (obligations.isNull())
47 return {
STAmount(issue, 0), account.name()};
49 return {
amount, account.name()};
56 params[jss::account] = account.human();
57 auto jrr = env.
rpc(
"json",
"gateway_balances",
to_string(params));
58 auto const result = jrr[jss::result];
61 return {
STAmount(issue, 0), account.name()};
63 return {
amount, account.name()};
74 for (
bool const withTokenEscrow : {
false,
true})
76 auto const amend = withTokenEscrow ? features : features - featureTokenEscrow;
77 Env env{*
this, amend};
78 auto const baseFee = env.
current()->fees().base;
79 auto const alice =
Account(
"alice");
80 auto const bob =
Account(
"bob");
81 auto const gw =
Account{
"gateway"};
82 auto const USD = gw[
"USD"];
83 env.fund(
XRP(5000), alice, bob, gw);
84 env(
fset(gw, asfAllowTrustLineLocking));
86 env.trust(USD(10'000), alice, bob);
88 env(
pay(gw, alice, USD(5000)));
89 env(
pay(gw, bob, USD(5000)));
95 auto const seq1 = env.seq(alice);
109 auto const seq2 = env.seq(alice);
121 for (
bool const withTokenEscrow : {
false,
true})
123 auto const amend = withTokenEscrow ? features : features - featureTokenEscrow;
124 Env env{*
this, amend};
125 auto const baseFee = env.
current()->fees().base;
126 auto const alice =
Account(
"alice");
127 auto const bob =
Account(
"bob");
128 auto const gw =
Account{
"gateway"};
129 auto const USD = gw[
"USD"];
130 env.fund(
XRP(5000), alice, bob, gw);
131 env(
fset(gw, asfAllowTrustLineLocking));
133 env.trust(USD(10'000), alice, bob);
135 env(
pay(gw, alice, USD(5000)));
136 env(
pay(gw, bob, USD(5000)));
139 auto const seq1 = env.seq(alice);
160 Env env{*
this, features};
161 auto const baseFee = env.current()->fees().base;
162 auto const alice =
Account(
"alice");
163 auto const bob =
Account(
"bob");
164 auto const gw =
Account{
"gateway"};
165 auto const USD = gw[
"USD"];
166 env.fund(
XRP(5000), alice, bob, gw);
167 env(
fset(gw, asfAllowTrustLineLocking));
169 env.trust(USD(10'000), alice, bob);
171 env(
pay(gw, alice, USD(5000)));
172 env(
pay(gw, bob, USD(5000)));
176 auto const seq1 = env.seq(alice);
184 auto const seq2 = env.seq(alice);
193 env(
fclear(gw, asfAllowTrustLineLocking));
195 env.require(
nflags(gw, asfAllowTrustLineLocking));
222 using namespace test::jtx;
227 Env env{*
this, features};
228 auto const alice =
Account(
"alice");
229 auto const bob =
Account(
"bob");
230 auto const gw =
Account{
"gateway"};
231 auto const USD = gw[
"USD"];
232 env.fund(
XRP(5000), alice, bob, gw);
243 Env env{*
this, features};
244 auto const baseFee = env.current()->fees().base;
245 auto const alice =
Account(
"alice");
246 auto const bob =
Account(
"bob");
247 auto const gw =
Account{
"gateway"};
248 auto const USD = gw[
"USD"];
249 env.fund(
XRP(5000), alice, bob, gw);
261 Env env{*
this, features};
262 auto const baseFee = env.current()->fees().base;
263 auto const alice =
Account(
"alice");
264 auto const bob =
Account(
"bob");
265 auto const gw =
Account{
"gateway"};
267 env.fund(
XRP(5000), alice, bob, gw);
282 using namespace test::jtx;
287 Env env{*
this, features};
288 auto const baseFee = env.current()->fees().base;
289 auto const alice =
Account(
"alice");
290 auto const bob =
Account(
"bob");
291 auto const gw =
Account{
"gateway"};
292 auto const USD = gw[
"USD"];
293 env.fund(
XRP(5000), alice, bob, gw);
305 Env env{*
this, features};
306 auto const baseFee = env.current()->fees().base;
307 auto const alice =
Account(
"alice");
308 auto const bob =
Account(
"bob");
309 auto const gw =
Account{
"gateway"};
310 auto const USD = gw[
"USD"];
311 env.fund(
XRP(5000), alice, bob);
325 Env env{*
this, features};
326 auto const baseFee = env.current()->fees().base;
327 auto const alice =
Account(
"alice");
328 auto const bob =
Account(
"bob");
329 auto const gw =
Account{
"gateway"};
330 auto const USD = gw[
"USD"];
331 env.fund(
XRP(5000), alice, bob, gw);
333 env.trust(USD(10'000), alice, bob);
335 env(
pay(gw, alice, USD(5000)));
336 env(
pay(gw, bob, USD(5000)));
349 Env env{*
this, features};
350 auto const baseFee = env.current()->fees().base;
351 auto const alice =
Account(
"alice");
352 auto const bob =
Account(
"bob");
353 auto const gw =
Account{
"gateway"};
354 auto const USD = gw[
"USD"];
355 env.fund(
XRP(5000), alice, bob, gw);
356 env(
fset(gw, asfAllowTrustLineLocking));
370 Env env{*
this, features};
371 auto const baseFee = env.current()->fees().base;
372 auto const alice =
Account(
"alice");
373 auto const bob =
Account(
"bob");
374 auto const gw =
Account{
"gateway"};
375 auto const USD = gw[
"USD"];
376 env.fund(
XRP(5000), alice, bob, gw);
377 env(
fset(gw, asfAllowTrustLineLocking));
378 env(
fset(gw, asfRequireAuth));
380 env.trust(USD(10'000), alice, bob);
393 Env env{*
this, features};
394 auto const baseFee = env.current()->fees().base;
395 auto const alice =
Account(
"alice");
396 auto const bob =
Account(
"bob");
397 auto const gw =
Account{
"gateway"};
398 auto const USD = gw[
"USD"];
399 auto const aliceUSD = alice[
"USD"];
400 env.fund(
XRP(5000), alice, bob, gw);
401 env(
fset(gw, asfAllowTrustLineLocking));
402 env(
fset(gw, asfRequireAuth));
405 env.trust(USD(10'000), alice, bob);
419 Env env{*
this, features};
420 auto const alice =
Account(
"alice");
421 auto const bob =
Account(
"bob");
422 auto const gw =
Account{
"gateway"};
423 auto const USD = gw[
"USD"];
424 auto const baseFee = env.current()->fees().base;
425 env.fund(
XRP(10'000), alice, bob, gw);
426 env(
fset(gw, asfAllowTrustLineLocking));
428 env(
trust(alice, USD(100'000)));
429 env(
trust(bob, USD(100'000)));
431 env(
pay(gw, alice, USD(10'000)));
432 env(
pay(gw, bob, USD(10'000)));
436 env(
trust(gw, USD(10'000), alice, tfSetFreeze));
450 Env env{*
this, features};
451 auto const alice =
Account(
"alice");
452 auto const bob =
Account(
"bob");
453 auto const gw =
Account{
"gateway"};
454 auto const USD = gw[
"USD"];
455 auto const baseFee = env.current()->fees().base;
456 env.fund(
XRP(10'000), alice, bob, gw);
457 env(
fset(gw, asfAllowTrustLineLocking));
459 env(
trust(alice, USD(100'000)));
460 env(
trust(bob, USD(100'000)));
462 env(
pay(gw, alice, USD(10'000)));
463 env(
pay(gw, bob, USD(10'000)));
467 env(
trust(gw, USD(10'000), bob, tfSetFreeze));
481 Env env{*
this, features};
482 auto const alice =
Account(
"alice");
483 auto const bob =
Account(
"bob");
484 auto const gw =
Account{
"gateway"};
485 auto const USD = gw[
"USD"];
486 auto const baseFee = env.current()->fees().base;
487 env.fund(
XRP(10'000), alice, bob, gw);
488 env(
fset(gw, asfAllowTrustLineLocking));
490 env(
trust(alice, USD(100'000)));
491 env(
trust(bob, USD(100'000)));
505 Env env{*
this, features};
506 auto const alice =
Account(
"alice");
507 auto const bob =
Account(
"bob");
508 auto const gw =
Account{
"gateway"};
509 auto const USD = gw[
"USD"];
510 auto const baseFee = env.current()->fees().base;
511 env.fund(
XRP(10'000), alice, bob, gw);
512 env(
fset(gw, asfAllowTrustLineLocking));
514 env(
trust(alice, USD(100'000)));
515 env(
trust(bob, USD(100'000)));
517 env(
pay(gw, alice, USD(10'000)));
518 env(
pay(gw, bob, USD(10'000)));
531 Env env{*
this, features};
532 auto const alice =
Account(
"alice");
533 auto const bob =
Account(
"bob");
534 auto const gw =
Account{
"gateway"};
535 auto const USD = gw[
"USD"];
536 auto const baseFee = env.current()->fees().base;
537 env.fund(
XRP(10'000), alice, bob, gw);
538 env(
fset(gw, asfAllowTrustLineLocking));
540 env.trust(USD(100000000000000000), alice);
541 env.trust(USD(100000000000000000), bob);
543 env(
pay(gw, alice, USD(10000000000000000)));
544 env(
pay(gw, bob, USD(1)));
547 bool const largeMantissa =
548 features[featureSingleAssetVault] || features[featureLendingProtocol];
564 using namespace test::jtx;
569 Env env{*
this, features};
570 auto const baseFee = env.current()->fees().base;
571 auto const alice =
Account(
"alice");
572 auto const bob =
Account(
"bob");
573 auto const gw =
Account{
"gateway"};
574 auto const USD = gw[
"USD"];
575 auto const aliceUSD = alice[
"USD"];
576 auto const bobUSD = bob[
"USD"];
577 env.fund(
XRP(5000), alice, bob, gw);
578 env(
fset(gw, asfAllowTrustLineLocking));
579 env(
fset(gw, asfRequireAuth));
583 env.trust(USD(10'000), alice, bob);
585 env(
pay(gw, alice, USD(10'000)));
586 env(
pay(gw, bob, USD(10'000)));
589 auto const seq1 = env.seq(alice);
597 env(
pay(bob, gw, USD(10'000)));
599 env(
trust(bob, USD(0)));
602 env.trust(USD(10'000), bob);
616 Env env{*
this, features};
617 auto const baseFee = env.current()->fees().base;
618 auto const alice =
Account(
"alice");
619 auto const bob =
Account(
"bob");
620 auto const gw =
Account{
"gateway"};
621 auto const USD = gw[
"USD"];
622 env.fund(
XRP(5000), alice, bob, gw);
623 env(
fset(gw, asfAllowTrustLineLocking));
625 env.trust(USD(10'000), alice, bob);
627 env(
pay(gw, alice, USD(10'000)));
628 env(
pay(gw, bob, USD(10'000)));
631 auto const seq1 = env.seq(alice);
640 env(
trust(gw, USD(10'000), bob, tfSetFreeze | tfSetDeepFreeze));
656 using namespace test::jtx;
661 Env env{*
this, features};
662 auto const baseFee = env.current()->fees().base;
663 auto const acctReserve = env.current()->fees().reserve;
664 auto const incReserve = env.current()->fees().increment;
665 auto const alice =
Account(
"alice");
666 auto const bob =
Account(
"bob");
667 auto const gw =
Account{
"gateway"};
668 auto const USD = gw[
"USD"];
669 env.fund(
XRP(5000), alice, gw);
670 env.fund(acctReserve + (incReserve - 1), bob);
672 env(
fset(gw, asfAllowTrustLineLocking));
674 env.trust(USD(10'000), alice);
676 env(
pay(gw, alice, USD(10'000)));
679 auto const seq1 = env.seq(alice);
698 Env env{*
this, features};
699 auto const baseFee = env.current()->fees().base;
700 auto const alice =
Account(
"alice");
701 auto const bob =
Account(
"bob");
702 auto const gw =
Account{
"gateway"};
703 auto const USD = gw[
"USD"];
704 env.fund(
XRP(5000), alice, bob, gw);
706 env(
fset(gw, asfAllowTrustLineLocking));
708 env.trust(USD(10'000), alice);
710 env(
pay(gw, alice, USD(10'000)));
713 auto const seq1 = env.seq(alice);
732 Env env{*
this, features};
733 auto const baseFee = env.current()->fees().base;
734 auto const alice =
Account(
"alice");
735 auto const bob =
Account(
"bob");
736 auto const gw =
Account{
"gateway"};
737 auto const USD = gw[
"USD"];
738 env.fund(
XRP(5000), alice, bob, gw);
740 env(
fset(gw, asfAllowTrustLineLocking));
742 env.trust(USD(1000), alice, bob);
744 env(
pay(gw, alice, USD(1000)));
747 auto const seq1 = env.seq(alice);
755 env.trust(USD(1), bob);
769 Env env{*
this, features};
770 auto const baseFee = env.current()->fees().base;
771 auto const alice =
Account(
"alice");
772 auto const bob =
Account(
"bob");
773 auto const gw =
Account{
"gateway"};
774 auto const USD = gw[
"USD"];
775 env.fund(
XRP(5000), alice, bob, gw);
777 env(
fset(gw, asfAllowTrustLineLocking));
779 env.trust(USD(1000), alice, bob);
781 env(
pay(gw, alice, USD(1000)));
784 auto const seq1 = env.seq(alice);
792 env.trust(USD(1), bob);
796 auto const bobPreLimit = env.limit(bob, USD);
806 BEAST_EXPECT(env.limit(bob, USD) == bobPreLimit);
814 using namespace test::jtx;
819 Env env{*
this, features};
820 auto const baseFee = env.current()->fees().base;
821 auto const alice =
Account(
"alice");
822 auto const bob =
Account(
"bob");
823 auto const gw =
Account{
"gateway"};
824 auto const USD = gw[
"USD"];
825 auto const aliceUSD = alice[
"USD"];
826 auto const bobUSD = bob[
"USD"];
827 env.fund(
XRP(5000), alice, bob, gw);
828 env(
fset(gw, asfAllowTrustLineLocking));
829 env(
fset(gw, asfRequireAuth));
833 env.trust(USD(10'000), alice, bob);
835 env(
pay(gw, alice, USD(10'000)));
836 env(
pay(gw, bob, USD(10'000)));
839 auto const seq1 = env.seq(alice);
847 env(
pay(alice, gw, USD(9'999)));
849 env(
trust(alice, USD(0)));
852 env.trust(USD(10'000), alice);
869 Env env{*
this, features};
870 auto const baseFee = env.current()->fees().base;
871 auto const alice =
Account(
"alice");
872 auto const bob =
Account(
"bob");
873 auto const gw =
Account{
"gateway"};
874 auto const USD = gw[
"USD"];
875 env.fund(
XRP(5000), alice, bob, gw);
876 env(
fset(gw, asfAllowTrustLineLocking));
878 env.trust(USD(10'000), alice, bob);
880 env(
pay(gw, alice, USD(5'000)));
881 env(
pay(gw, bob, USD(5'000)));
884 auto const outstandingUSD = USD(10'000);
887 auto const seq1 = env.seq(alice);
889 auto const preAliceUSD = env.balance(alice, USD);
890 auto const preBobUSD = env.balance(bob, USD);
898 BEAST_EXPECT(env.balance(alice, USD) == preAliceUSD - USD(1'000));
899 BEAST_EXPECT(env.balance(bob, USD) == preBobUSD);
900 BEAST_EXPECT(
issuerBalance(env, gw, USD) == outstandingUSD - USD(1'000));
904 auto const preAliceUSD = env.balance(alice, USD);
905 auto const preBobUSD = env.balance(bob, USD);
913 BEAST_EXPECT(env.balance(alice, USD) == preAliceUSD);
914 BEAST_EXPECT(env.balance(bob, USD) == preBobUSD + USD(1'000));
920 auto const seq2 = env.seq(alice);
922 auto const preAliceUSD = env.balance(alice, USD);
923 auto const preBobUSD = env.balance(bob, USD);
932 BEAST_EXPECT(env.balance(alice, USD) == preAliceUSD - USD(1'000));
933 BEAST_EXPECT(env.balance(bob, USD) == preBobUSD);
934 BEAST_EXPECT(
issuerBalance(env, gw, USD) == outstandingUSD - USD(1'000));
938 auto const preAliceUSD = env.balance(alice, USD);
939 auto const preBobUSD = env.balance(bob, USD);
943 BEAST_EXPECT(env.balance(alice, USD) == preAliceUSD + USD(1'000));
944 BEAST_EXPECT(env.balance(bob, USD) == preBobUSD);
956 auto const alice =
Account(
"alice");
957 auto const bob =
Account(
"bob");
958 auto const carol =
Account(
"carol");
959 auto const gw =
Account{
"gateway"};
960 auto const USD = gw[
"USD"];
964 Env env{*
this, features};
965 env.fund(
XRP(5000), alice, bob, carol, gw);
966 env(
fset(gw, asfAllowTrustLineLocking));
968 env.trust(USD(10'000), alice, bob, carol);
970 env(
pay(gw, alice, USD(5000)));
971 env(
pay(gw, bob, USD(5000)));
972 env(
pay(gw, carol, USD(5000)));
974 auto const aseq = env.seq(alice);
975 auto const bseq = env.seq(bob);
1057 Env env{*
this, features};
1058 env.fund(
XRP(5000), alice, bob, carol, gw);
1059 env(
fset(gw, asfAllowTrustLineLocking));
1061 env.trust(USD(10'000), alice, bob, carol);
1063 env(
pay(gw, alice, USD(5000)));
1064 env(
pay(gw, bob, USD(5000)));
1065 env(
pay(gw, carol, USD(5000)));
1067 auto const aseq = env.seq(alice);
1068 auto const bseq = env.seq(bob);
1157 testcase(
"IOU Metadata to issuer");
1159 Env env{*
this, features};
1160 env.fund(
XRP(5000), alice, carol, gw);
1161 env(
fset(gw, asfAllowTrustLineLocking));
1163 env.trust(USD(10'000), alice, carol);
1165 env(
pay(gw, alice, USD(5000)));
1166 env(
pay(gw, carol, USD(5000)));
1168 auto const aseq = env.seq(alice);
1220 using namespace test::jtx;
1223 struct TestAccountData
1251 for (
auto const& t : tests)
1253 Env env{*
this, features};
1254 auto const baseFee = env.current()->fees().base;
1255 auto const USD = t.gw[
"USD"];
1256 env.fund(
XRP(5000), t.src, t.dst, t.gw);
1257 env(
fset(t.gw, asfAllowTrustLineLocking));
1262 env.trust(USD(100'000), t.src, t.dst);
1266 env.trust(USD(100'000), t.src);
1270 env(
pay(t.gw, t.src, USD(10'000)));
1272 env(
pay(t.gw, t.dst, USD(10'000)));
1276 auto const seq1 = env.seq(t.src);
1277 auto const delta = USD(1'000);
1281 fee(baseFee * 150));
1285 auto const preSrc = env.balance(t.src, USD);
1286 auto const preDst = env.balance(t.dst, USD);
1291 fee(baseFee * 150));
1294 BEAST_EXPECT(env.balance(t.src, USD) == preSrc);
1295 BEAST_EXPECT(env.balance(t.dst, USD) == preDst + delta);
1303 using namespace test::jtx;
1306 struct TestAccountData
1315 auto const gw =
Account{
"gateway"};
1316 auto const alice =
Account{
"alice"};
1317 Env env{*
this, features};
1318 auto const baseFee = env.current()->fees().base;
1319 auto const USD = gw[
"USD"];
1320 env.fund(
XRP(5000), alice, gw);
1321 env(
fset(gw, asfAllowTrustLineLocking));
1323 env.trust(USD(100'000), alice);
1326 env(
pay(gw, alice, USD(10'000)));
1350 for (
auto const& t : gwDstTests)
1352 Env env{*
this, features};
1353 auto const baseFee = env.current()->fees().base;
1354 auto const USD = t.dst[
"USD"];
1355 env.fund(
XRP(5000), t.dst, t.src);
1356 env(
fset(t.dst, asfAllowTrustLineLocking));
1359 env.trust(USD(100'000), t.src);
1362 env(
pay(t.dst, t.src, USD(10'000)));
1366 auto const seq1 = env.seq(t.src);
1367 auto const preSrc = env.balance(t.src, USD);
1371 fee(baseFee * 150));
1378 fee(baseFee * 150));
1380 auto const preAmount = 10'000;
1381 BEAST_EXPECT(preSrc == USD(preAmount));
1382 auto const postAmount = 9000;
1383 BEAST_EXPECT(env.balance(t.src, USD) == USD(postAmount));
1384 BEAST_EXPECT(env.balance(t.dst, USD) == USD(0));
1389 auto const gw =
Account{
"gateway"};
1390 auto const USD = gw[
"USD"];
1391 Env env{*
this, features};
1392 auto const baseFee = env.current()->fees().base;
1393 env.fund(
XRP(5000), gw);
1394 env(
fset(gw, asfAllowTrustLineLocking));
1411 using namespace test::jtx;
1414 auto const alice =
Account(
"alice");
1415 auto const bob =
Account(
"bob");
1416 auto const carol =
Account(
"carol");
1417 auto const gw =
Account{
"gateway"};
1418 auto const USD = gw[
"USD"];
1422 Env env{*
this, features};
1423 auto const baseFee = env.current()->fees().base;
1424 env.fund(
XRP(10'000), alice, bob, gw);
1425 env(
fset(gw, asfAllowTrustLineLocking));
1426 env(
rate(gw, 1.25));
1428 env.trust(USD(100'000), alice);
1429 env.trust(USD(100'000), bob);
1431 env(
pay(gw, alice, USD(10'000)));
1432 env(
pay(gw, bob, USD(10'000)));
1436 auto const preAlice = env.balance(alice, USD);
1437 auto const seq1 = env.seq(alice);
1438 auto const delta = USD(125);
1442 fee(baseFee * 150));
1451 fee(baseFee * 150));
1454 BEAST_EXPECT(env.balance(alice, USD) == preAlice - delta);
1455 BEAST_EXPECT(env.balance(bob, USD) == USD(10'100));
1459 Env env{*
this, features};
1460 auto const baseFee = env.current()->fees().base;
1461 env.fund(
XRP(10'000), alice, bob, gw);
1462 env(
fset(gw, asfAllowTrustLineLocking));
1463 env(
rate(gw, 1.25));
1465 env.trust(USD(100'000), alice);
1466 env.trust(USD(100'000), bob);
1468 env(
pay(gw, alice, USD(10'000)));
1469 env(
pay(gw, bob, USD(10'000)));
1473 auto const preAlice = env.balance(alice, USD);
1474 auto const seq1 = env.seq(alice);
1475 auto const delta = USD(125);
1479 fee(baseFee * 150));
1485 env(
rate(gw, 1.26));
1492 fee(baseFee * 150));
1495 BEAST_EXPECT(env.balance(alice, USD) == preAlice - delta);
1496 BEAST_EXPECT(env.balance(bob, USD) == USD(10'100));
1501 Env env{*
this, features};
1502 auto const baseFee = env.current()->fees().base;
1503 env.fund(
XRP(10'000), alice, bob, gw);
1504 env(
fset(gw, asfAllowTrustLineLocking));
1505 env(
rate(gw, 1.25));
1507 env.trust(USD(100'000), alice);
1508 env.trust(USD(100'000), bob);
1510 env(
pay(gw, alice, USD(10'000)));
1511 env(
pay(gw, bob, USD(10'000)));
1515 auto const preAlice = env.balance(alice, USD);
1516 auto const seq1 = env.seq(alice);
1517 auto const delta = USD(125);
1521 fee(baseFee * 150));
1527 env(
rate(gw, 1.00));
1534 fee(baseFee * 150));
1537 BEAST_EXPECT(env.balance(alice, USD) == preAlice - delta);
1538 BEAST_EXPECT(env.balance(bob, USD) == USD(10125));
1543 Env env{*
this, features};
1544 auto const baseFee = env.current()->fees().base;
1545 env.fund(
XRP(10'000), alice, bob, gw);
1546 env(
fset(gw, asfAllowTrustLineLocking));
1547 env(
rate(gw, 1.25));
1549 env.trust(USD(100'000), alice);
1550 env.trust(USD(100'000), bob);
1552 env(
pay(gw, alice, USD(10'000)));
1553 env(
pay(gw, bob, USD(10'000)));
1557 auto const preAlice = env.balance(alice, USD);
1558 auto const seq1 = env.seq(alice);
1559 auto const delta = USD(125);
1569 env(
rate(gw, 1.00));
1576 BEAST_EXPECT(env.balance(alice, USD) == preAlice);
1577 BEAST_EXPECT(env.balance(bob, USD) == USD(10000));
1585 using namespace test::jtx;
1588 auto const alice =
Account(
"alice");
1589 auto const bob =
Account(
"bob");
1590 auto const gw =
Account{
"gateway"};
1591 auto const USD = gw[
"USD"];
1595 Env env{*
this, features};
1596 auto const baseFee = env.current()->fees().base;
1597 env.fund(
XRP(1'000), alice, bob, gw);
1598 env(
fset(gw, asfAllowTrustLineLocking));
1600 env.trust(USD(10'000), alice, bob);
1602 env(
pay(gw, alice, USD(1'000)));
1603 env(
pay(gw, bob, USD(1'000)));
1607 auto seq1 = env.seq(alice);
1608 auto const delta = USD(125);
1612 fee(baseFee * 150));
1616 auto const preBobLimit = env.limit(bob, USD);
1620 fee(baseFee * 150));
1622 auto const postBobLimit = env.limit(bob, USD);
1624 BEAST_EXPECT(postBobLimit == preBobLimit);
1632 using namespace test::jtx;
1635 auto const alice =
Account(
"alice");
1636 auto const bob =
Account(
"bob");
1637 auto const carol =
Account(
"carol");
1638 auto const gw =
Account{
"gateway"};
1639 auto const USD = gw[
"USD"];
1641 auto const aliceUSD = alice[
"USD"];
1642 auto const bobUSD = bob[
"USD"];
1644 Env env{*
this, features};
1645 auto const baseFee = env.current()->fees().base;
1646 env.fund(
XRP(1'000), alice, bob, gw);
1647 env(
fset(gw, asfAllowTrustLineLocking));
1648 env(
fset(gw, asfRequireAuth));
1651 env(
trust(alice, USD(10'000)));
1652 env(
trust(bob, USD(10'000)));
1654 env(
pay(gw, alice, USD(1'000)));
1658 auto seq1 = env.seq(alice);
1659 auto const delta = USD(125);
1669 env(
trust(bob, USD(10'000)));
1671 env(
pay(gw, bob, USD(1'000)));
1675 seq1 = env.seq(alice);
1679 fee(baseFee * 150));
1686 fee(baseFee * 150));
1694 using namespace test::jtx;
1697 auto const alice =
Account(
"alice");
1698 auto const bob =
Account(
"bob");
1699 auto const carol =
Account(
"carol");
1700 auto const gw =
Account{
"gateway"};
1701 auto const USD = gw[
"USD"];
1705 Env env{*
this, features};
1706 auto const baseFee = env.current()->fees().base;
1707 env.fund(
XRP(10'000), alice, bob, gw);
1708 env(
fset(gw, asfAllowTrustLineLocking));
1710 env.trust(USD(100'000), alice);
1711 env.trust(USD(100'000), bob);
1713 env(
pay(gw, alice, USD(10'000)));
1714 env(
pay(gw, bob, USD(10'000)));
1716 env(
fset(gw, asfGlobalFreeze));
1720 auto seq1 = env.seq(alice);
1721 auto const delta = USD(125);
1732 env(
fclear(gw, asfGlobalFreeze));
1736 seq1 = env.seq(alice);
1740 fee(baseFee * 150));
1744 env(
fset(gw, asfGlobalFreeze));
1751 fee(baseFee * 150));
1755 env(
fclear(gw, asfGlobalFreeze));
1759 seq1 = env.seq(alice);
1763 fee(baseFee * 150));
1767 env(
fset(gw, asfGlobalFreeze));
1778 Env env{*
this, features};
1779 auto const baseFee = env.current()->fees().base;
1780 env.fund(
XRP(10'000), alice, bob, gw);
1781 env(
fset(gw, asfAllowTrustLineLocking));
1783 env(
trust(alice, USD(100'000)));
1784 env(
trust(bob, USD(100'000)));
1786 env(
pay(gw, alice, USD(10'000)));
1787 env(
pay(gw, bob, USD(10'000)));
1791 env(
trust(gw, USD(10'000), alice, tfSetFreeze));
1795 auto seq1 = env.seq(alice);
1796 auto const delta = USD(125);
1807 env(
trust(gw, USD(10'000), alice, tfClearFreeze));
1811 seq1 = env.seq(alice);
1815 fee(baseFee * 150));
1819 env(
trust(gw, USD(10'000), bob, tfSetFreeze));
1826 fee(baseFee * 150));
1830 env(
trust(gw, USD(10'000), alice, tfClearFreeze));
1831 env(
trust(gw, USD(10'000), bob, tfClearFreeze));
1835 seq1 = env.seq(alice);
1839 fee(baseFee * 150));
1843 env(
trust(gw, USD(10'000), bob, tfSetFreeze));
1854 Env env{*
this, features};
1855 auto const baseFee = env.current()->fees().base;
1856 env.fund(
XRP(10'000), alice, bob, gw);
1857 env(
fset(gw, asfAllowTrustLineLocking));
1859 env(
trust(alice, USD(100'000)));
1860 env(
trust(bob, USD(100'000)));
1862 env(
pay(gw, alice, USD(10'000)));
1863 env(
pay(gw, bob, USD(10'000)));
1867 env(
trust(gw, USD(10'000), alice, tfSetFreeze | tfSetDeepFreeze));
1871 auto seq1 = env.seq(alice);
1872 auto const delta = USD(125);
1883 env(
trust(gw, USD(10'000), alice, tfClearFreeze | tfClearDeepFreeze));
1887 seq1 = env.seq(alice);
1891 fee(baseFee * 150));
1895 env(
trust(gw, USD(10'000), bob, tfSetFreeze | tfSetDeepFreeze));
1907 env(
trust(gw, USD(10'000), alice, tfClearFreeze | tfClearDeepFreeze));
1908 env(
trust(gw, USD(10'000), bob, tfClearFreeze | tfClearDeepFreeze));
1912 seq1 = env.seq(alice);
1916 fee(baseFee * 150));
1920 env(
trust(gw, USD(10'000), bob, tfSetFreeze | tfSetDeepFreeze));
1931 testcase(
"IOU Insufficient Funds");
1932 using namespace test::jtx;
1935 auto const alice =
Account(
"alice");
1936 auto const bob =
Account(
"bob");
1937 auto const carol =
Account(
"carol");
1938 auto const gw =
Account{
"gateway"};
1939 auto const USD = gw[
"USD"];
1943 Env env{*
this, features};
1944 auto const baseFee = env.current()->fees().base;
1945 env.fund(
XRP(10'000), alice, bob, gw);
1946 env(
fset(gw, asfAllowTrustLineLocking));
1948 env.trust(USD(100'000), alice);
1949 env.trust(USD(100'000), bob);
1951 env(
pay(gw, alice, USD(10'000)));
1952 env(
pay(gw, bob, USD(10'000)));
1956 auto const delta = USD(1'000);
1960 fee(baseFee * 150));
1967 Env env{*
this, features};
1968 auto const baseFee = env.current()->fees().base;
1969 env.fund(
XRP(10'000), alice, bob, gw);
1970 env(
fset(gw, asfAllowTrustLineLocking));
1972 env.trust(USD(100'000), alice);
1973 env.trust(USD(100'000), bob);
1975 env(
pay(gw, alice, USD(10'000)));
1976 env(
pay(gw, bob, USD(10'000)));
1979 auto const delta = USD(1'000);
1983 fee(baseFee * 150));
1999 using namespace test::jtx;
2002 auto const alice =
Account(
"alice");
2003 auto const bob =
Account(
"bob");
2004 auto const gw =
Account{
"gateway"};
2005 auto const USD = gw[
"USD"];
2009 Env env(*
this, features);
2010 auto const baseFee = env.
current()->fees().base;
2011 env.
fund(
XRP(10'000), alice, bob, gw);
2012 env(
fset(gw, asfAllowTrustLineLocking));
2014 env.
trust(USD(100000000000000000), alice);
2015 env.
trust(USD(100000000000000000), bob);
2017 env(
pay(gw, alice, USD(10000000000000000)));
2018 env(
pay(gw, bob, USD(1)));
2021 bool const largeMantissa =
2022 features[featureSingleAssetVault] || features[featureLendingProtocol];
2032 auto const seq1 = env.
seq(alice);
2037 fee(baseFee * 150));
2044 fee(baseFee * 150));
2054 using namespace jtx;
2057 for (
bool const withTokenEscrow : {
false,
true})
2059 auto const amend = withTokenEscrow ? features : features - featureTokenEscrow;
2060 Env env{*
this, amend};
2061 auto const baseFee = env.
current()->fees().base;
2062 auto const alice =
Account(
"alice");
2063 auto const bob =
Account(
"bob");
2064 auto const gw =
Account(
"gw");
2065 env.fund(
XRP(5000), bob);
2067 MPTTester mptGw(env, gw, {.holders = {alice}});
2069 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2070 mptGw.authorize({.account = alice});
2071 auto const MPT = mptGw[
"MPT"];
2072 env(
pay(gw, alice,
MPT(10'000)));
2078 auto const seq1 = env.seq(alice);
2091 auto const seq2 = env.seq(alice);
2108 using namespace test::jtx;
2111 for (
bool const withMPT : {
true,
false})
2113 auto const amend = withMPT ? features : features - featureMPTokensV1;
2114 Env env{*
this, amend};
2115 auto const baseFee = env.
current()->fees().base;
2116 auto const alice =
Account(
"alice");
2117 auto const bob =
Account(
"bob");
2118 auto const gw =
Account(
"gw");
2119 env.fund(
XRP(1'000), alice, bob, gw);
2123 jv[jss::Amount][jss::mpt_issuance_id] =
2124 "00000004A407AF5856CCF3C42619DAA925813FC955C72983";
2125 jv[jss::Amount][jss::value] =
"-1";
2138 Env env{*
this, features};
2139 auto const baseFee = env.current()->fees().base;
2140 auto const alice =
Account(
"alice");
2141 auto const bob =
Account(
"bob");
2142 auto const gw =
Account(
"gw");
2144 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2146 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2147 mptGw.authorize({.account = alice});
2148 mptGw.authorize({.account = bob});
2149 auto const MPT = mptGw[
"MPT"];
2150 env(
pay(gw, alice,
MPT(10'000)));
2151 env(
pay(gw, bob,
MPT(10'000)));
2167 using namespace test::jtx;
2172 Env env{*
this, features};
2173 auto const baseFee = env.current()->fees().base;
2174 auto const alice =
Account(
"alice");
2175 auto const gw =
Account(
"gw");
2177 MPTTester mptGw(env, gw, {.holders = {alice}});
2179 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2180 mptGw.authorize({.account = alice});
2181 auto const MPT = mptGw[
"MPT"];
2182 env(
pay(gw, alice,
MPT(10'000)));
2195 Env env{*
this, features};
2196 auto const baseFee = env.current()->fees().base;
2197 auto const alice =
Account(
"alice");
2198 auto const bob =
Account(
"bob");
2199 auto const gw =
Account(
"gw");
2200 env.fund(
XRP(10'000), alice, bob, gw);
2205 jv[jss::Amount][jss::mpt_issuance_id] =
2206 "00000004A407AF5856CCF3C42619DAA925813FC955C72983";
2217 Env env{*
this, features};
2218 auto const baseFee = env.current()->fees().base;
2219 auto const alice =
Account(
"alice");
2220 auto const bob =
Account(
"bob");
2221 auto const gw =
Account(
"gw");
2223 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2224 mptGw.
create({.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});
2225 mptGw.authorize({.account = alice});
2226 mptGw.authorize({.account = bob});
2227 auto const MPT = mptGw[
"MPT"];
2228 env(
pay(gw, alice,
MPT(10'000)));
2229 env(
pay(gw, bob,
MPT(10'000)));
2242 Env env{*
this, features};
2243 auto const baseFee = env.current()->fees().base;
2244 auto const alice =
Account(
"alice");
2245 auto const bob =
Account(
"bob");
2246 auto const gw =
Account(
"gw");
2248 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2250 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2251 auto const MPT = mptGw[
"MPT"];
2263 Env env{*
this, features};
2264 auto const baseFee = env.current()->fees().base;
2265 auto const alice =
Account(
"alice");
2266 auto const bob =
Account(
"bob");
2267 auto const gw =
Account(
"gw");
2269 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2273 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTRequireAuth});
2274 mptGw.authorize({.account = alice});
2275 mptGw.authorize({.account = gw, .holder = alice});
2276 auto const MPT = mptGw[
"MPT"];
2277 env(
pay(gw, alice,
MPT(10'000)));
2281 mptGw.authorize({.account = gw, .holder = alice, .flags = tfMPTUnauthorize});
2293 Env env{*
this, features};
2294 auto const baseFee = env.current()->fees().base;
2295 auto const alice =
Account(
"alice");
2296 auto const bob =
Account(
"bob");
2297 auto const gw =
Account(
"gw");
2299 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2303 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTRequireAuth});
2304 mptGw.authorize({.account = alice});
2305 mptGw.authorize({.account = gw, .holder = alice});
2306 mptGw.authorize({.account = bob});
2307 mptGw.authorize({.account = gw, .holder = bob});
2308 auto const MPT = mptGw[
"MPT"];
2309 env(
pay(gw, alice,
MPT(10'000)));
2310 env(
pay(gw, bob,
MPT(10'000)));
2314 mptGw.authorize({.account = gw, .holder = bob, .flags = tfMPTUnauthorize});
2326 Env env{*
this, features};
2327 auto const baseFee = env.current()->fees().base;
2328 auto const alice =
Account(
"alice");
2329 auto const bob =
Account(
"bob");
2330 auto const gw =
Account(
"gw");
2332 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2336 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTCanLock});
2337 mptGw.authorize({.account = alice});
2338 mptGw.authorize({.account = bob});
2339 auto const MPT = mptGw[
"MPT"];
2340 env(
pay(gw, alice,
MPT(10'000)));
2341 env(
pay(gw, bob,
MPT(10'000)));
2345 mptGw.set({.account = gw, .holder = alice, .flags = tfMPTLock});
2357 Env env{*
this, features};
2358 auto const baseFee = env.current()->fees().base;
2359 auto const alice =
Account(
"alice");
2360 auto const bob =
Account(
"bob");
2361 auto const gw =
Account(
"gw");
2363 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2367 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTCanLock});
2368 mptGw.authorize({.account = alice});
2369 mptGw.authorize({.account = bob});
2370 auto const MPT = mptGw[
"MPT"];
2371 env(
pay(gw, alice,
MPT(10'000)));
2372 env(
pay(gw, bob,
MPT(10'000)));
2376 mptGw.set({.account = gw, .holder = bob, .flags = tfMPTLock});
2388 Env env{*
this, features};
2389 auto const baseFee = env.current()->fees().base;
2390 auto const alice =
Account(
"alice");
2391 auto const bob =
Account(
"bob");
2392 auto const gw =
Account(
"gw");
2394 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2395 mptGw.
create({.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow});
2396 mptGw.authorize({.account = alice});
2397 mptGw.authorize({.account = bob});
2398 auto const MPT = mptGw[
"MPT"];
2399 env(
pay(gw, alice,
MPT(10'000)));
2400 env(
pay(gw, bob,
MPT(10'000)));
2413 Env env{*
this, features};
2414 auto const baseFee = env.current()->fees().base;
2415 auto const alice =
Account(
"alice");
2416 auto const bob =
Account(
"bob");
2417 auto const gw =
Account(
"gw");
2419 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2421 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2422 mptGw.authorize({.account = alice});
2423 mptGw.authorize({.account = bob});
2424 auto const MPT = mptGw[
"MPT"];
2425 env(
pay(gw, bob,
MPT(10)));
2438 Env env{*
this, features};
2439 auto const baseFee = env.current()->fees().base;
2440 auto const alice =
Account(
"alice");
2441 auto const bob =
Account(
"bob");
2442 auto const gw =
Account(
"gw");
2444 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2446 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2447 mptGw.authorize({.account = alice});
2448 mptGw.authorize({.account = bob});
2449 auto const MPT = mptGw[
"MPT"];
2450 env(
pay(gw, alice,
MPT(10)));
2451 env(
pay(gw, bob,
MPT(10)));
2467 using namespace test::jtx;
2472 Env env{*
this, features};
2473 auto const baseFee = env.current()->fees().base;
2474 auto const alice =
Account(
"alice");
2475 auto const bob =
Account(
"bob");
2476 auto const gw =
Account(
"gw");
2478 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2482 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTRequireAuth});
2483 mptGw.authorize({.account = alice});
2484 mptGw.authorize({.account = gw, .holder = alice});
2485 mptGw.authorize({.account = bob});
2486 mptGw.authorize({.account = gw, .holder = bob});
2487 auto const MPT = mptGw[
"MPT"];
2488 env(
pay(gw, alice,
MPT(10'000)));
2489 env(
pay(gw, bob,
MPT(10'000)));
2492 auto const seq1 = env.seq(alice);
2501 mptGw.authorize({.account = gw, .holder = bob, .flags = tfMPTUnauthorize});
2513 Env env{*
this, features};
2514 auto const baseFee = env.current()->fees().base;
2515 auto const alice =
Account(
"alice");
2516 auto const bob =
Account(
"bob");
2517 env.fund(
XRP(10'000), alice, bob);
2520 auto const seq1 = env.seq(alice);
2526 sleNew->setAccountID(sfDestination, bob);
2527 sleNew->setFieldAmount(sfAmount, amt);
2543 Env env{*
this, features};
2544 auto const baseFee = env.current()->fees().base;
2545 auto const alice =
Account(
"alice");
2546 auto const bob =
Account(
"bob");
2547 auto const gw =
Account(
"gw");
2549 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2553 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTCanLock});
2554 mptGw.authorize({.account = alice});
2555 mptGw.authorize({.account = bob});
2556 auto const MPT = mptGw[
"MPT"];
2557 env(
pay(gw, alice,
MPT(10'000)));
2558 env(
pay(gw, bob,
MPT(10'000)));
2561 auto const seq1 = env.seq(alice);
2570 mptGw.set({.account = gw, .holder = bob, .flags = tfMPTLock});
2585 using namespace test::jtx;
2590 Env env{*
this, features};
2591 auto const baseFee = env.current()->fees().base;
2592 auto const acctReserve = env.current()->fees().reserve;
2593 auto const incReserve = env.current()->fees().increment;
2595 auto const alice =
Account(
"alice");
2596 auto const bob =
Account(
"bob");
2597 auto const gw =
Account(
"gw");
2598 env.fund(acctReserve + (incReserve - 1), bob);
2601 MPTTester mptGw(env, gw, {.holders = {alice}});
2603 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2604 mptGw.authorize({.account = alice});
2605 auto const MPT = mptGw[
"MPT"];
2606 env(
pay(gw, alice,
MPT(10'000)));
2609 auto const seq1 = env.seq(alice);
2627 Env env{*
this, features};
2628 auto const baseFee = env.current()->fees().base;
2629 auto const alice =
Account(
"alice");
2630 auto const bob =
Account(
"bob");
2631 auto const gw =
Account(
"gw");
2632 env.fund(
XRP(10'000), bob);
2635 MPTTester mptGw(env, gw, {.holders = {alice}});
2637 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2638 mptGw.authorize({.account = alice});
2639 auto const MPT = mptGw[
"MPT"];
2640 env(
pay(gw, alice,
MPT(10'000)));
2643 auto const seq1 = env.seq(alice);
2661 Env env{*
this, features};
2662 auto const baseFee = env.current()->fees().base;
2663 auto const alice =
Account(
"alice");
2664 auto const bob =
Account(
"bob");
2665 auto const carol =
Account(
"carol");
2666 auto const gw =
Account(
"gw");
2667 env.fund(
XRP(10'000), bob, carol);
2670 MPTTester mptGw(env, gw, {.holders = {alice}});
2672 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2673 mptGw.authorize({.account = alice});
2674 auto const MPT = mptGw[
"MPT"];
2675 env(
pay(gw, alice,
MPT(10'000)));
2678 auto const seq1 = env.seq(alice);
2699 using namespace test::jtx;
2704 Env env{*
this, features};
2705 auto const baseFee = env.current()->fees().base;
2706 auto const alice =
Account(
"alice");
2707 auto const bob =
Account(
"bob");
2708 auto const gw =
Account(
"gw");
2710 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2714 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTRequireAuth});
2715 mptGw.authorize({.account = alice});
2716 mptGw.authorize({.account = gw, .holder = alice});
2717 mptGw.authorize({.account = bob});
2718 mptGw.authorize({.account = gw, .holder = bob});
2719 auto const MPT = mptGw[
"MPT"];
2720 env(
pay(gw, alice,
MPT(10'000)));
2721 env(
pay(gw, bob,
MPT(10'000)));
2724 auto const seq1 = env.seq(alice);
2733 mptGw.authorize({.account = gw, .holder = alice, .flags = tfMPTUnauthorize});
2741 Env env{*
this, features};
2742 auto const baseFee = env.current()->fees().base;
2743 auto const alice =
Account(
"alice");
2744 auto const bob =
Account(
"bob");
2745 env.fund(
XRP(10'000), alice, bob);
2747 auto const seq1 = env.seq(alice);
2753 sleNew->setAccountID(sfDestination, bob);
2754 sleNew->setFieldAmount(sfAmount, amt);
2770 using namespace jtx;
2773 Env env{*
this, features};
2774 auto const baseFee = env.current()->fees().base;
2775 auto const alice =
Account(
"alice");
2776 auto const bob =
Account(
"bob");
2777 auto const carol =
Account(
"carol");
2778 auto const gw =
Account(
"gw");
2779 env.fund(
XRP(5000), bob);
2781 MPTTester mptGw(env, gw, {.holders = {alice, carol}});
2783 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2784 mptGw.authorize({.account = alice});
2785 mptGw.authorize({.account = carol});
2786 auto const MPT = mptGw[
"MPT"];
2787 env(
pay(gw, alice,
MPT(10'000)));
2788 env(
pay(gw, carol,
MPT(10'000)));
2791 auto outstandingMPT = env.balance(gw,
MPT);
2794 auto const seq1 = env.seq(alice);
2796 auto const preAliceMPT = env.balance(alice,
MPT);
2797 auto const preBobMPT = env.balance(bob,
MPT);
2805 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
2807 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
2809 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2813 auto const preAliceMPT = env.balance(alice,
MPT);
2814 auto const preBobMPT = env.balance(bob,
MPT);
2822 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT);
2824 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT +
MPT(1'000));
2826 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2831 auto const seq2 = env.seq(alice);
2833 auto const preAliceMPT = env.balance(alice,
MPT);
2834 auto const preBobMPT = env.balance(bob,
MPT);
2843 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
2845 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
2847 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2851 auto const preAliceMPT = env.balance(alice,
MPT);
2852 auto const preBobMPT = env.balance(bob,
MPT);
2856 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT +
MPT(1'000));
2858 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
2860 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2866 auto const seq = env.
seq(alice);
2867 auto const preAliceMPT = env.balance(alice,
MPT);
2875 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
2877 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2887 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT);
2889 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2895 auto const seq = env.
seq(alice);
2896 auto const preAliceMPT = env.balance(alice,
MPT);
2905 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
2907 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2913 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT);
2915 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2921 auto const preAliceMPT = env.balance(alice,
MPT);
2922 auto const preBobMPT = env.balance(bob,
MPT);
2923 auto const preCarolMPT = env.balance(carol,
MPT);
2938 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
2940 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
2942 BEAST_EXPECT(env.balance(carol,
MPT) == preCarolMPT -
MPT(1'000));
2944 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2950 Env env{*
this, features};
2951 auto const baseFee = env.current()->fees().base;
2952 auto const alice =
Account(
"alice");
2953 auto const bob =
Account(
"bob");
2954 auto const gw =
Account(
"gw");
2956 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
2958 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
2959 mptGw.authorize({.account = alice});
2960 mptGw.authorize({.account = bob});
2961 auto const MPT = mptGw[
"MPT"];
2965 auto const preAliceMPT = env.balance(alice,
MPT);
2966 auto const preBobMPT = env.balance(bob,
MPT);
2967 auto const outstandingMPT = env.balance(gw,
MPT);
2969 auto const seq1 = env.seq(alice);
2973 fee(baseFee * 150));
2976 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1));
2978 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
2980 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
2990 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1));
2994 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT +
MPT(1));
2996 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
3003 Env env{*
this, features};
3004 auto const baseFee = env.current()->fees().base;
3005 auto const alice =
Account(
"alice");
3006 auto const bob =
Account(
"bob");
3007 auto const gw =
Account(
"gw");
3009 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3011 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3012 mptGw.authorize({.account = alice});
3013 mptGw.authorize({.account = bob});
3014 auto const MPT = mptGw[
"MPT"];
3018 auto const preAliceMPT = env.balance(alice,
MPT);
3019 auto const preBobMPT = env.balance(bob,
MPT);
3020 auto const outstandingMPT = env.balance(gw,
MPT);
3023 auto const seq1 = env.seq(alice);
3027 fee(baseFee * 150));
3031 auto const seq2 = env.seq(alice);
3035 fee(baseFee * 150));
3040 BEAST_EXPECT(env.balance(bob,
MPT) == preBobMPT);
3042 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
3063 BEAST_EXPECT(env.balance(gw,
MPT) == outstandingMPT);
3071 using namespace jtx;
3074 auto const alice =
Account(
"alice");
3075 auto const bob =
Account(
"bob");
3076 auto const carol =
Account(
"carol");
3077 auto const gw =
Account{
"gateway"};
3081 Env env{*
this, features};
3082 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3084 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3085 mptGw.authorize({.account = alice});
3086 mptGw.authorize({.account = bob});
3087 auto const MPT = mptGw[
"MPT"];
3088 env(
pay(gw, alice,
MPT(10'000)));
3089 env(
pay(gw, bob,
MPT(10'000)));
3091 auto const aseq = env.seq(alice);
3092 auto const bseq = env.seq(bob);
3161 Env env{*
this, features};
3162 MPTTester mptGw(env, gw, {.holders = {alice, bob, carol}});
3164 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3165 mptGw.authorize({.account = alice});
3166 mptGw.authorize({.account = bob});
3167 mptGw.authorize({.account = carol});
3168 auto const MPT = mptGw[
"MPT"];
3169 env(
pay(gw, alice,
MPT(10'000)));
3170 env(
pay(gw, bob,
MPT(10'000)));
3171 env(
pay(gw, carol,
MPT(10'000)));
3173 auto const aseq = env.seq(alice);
3174 auto const bseq = env.seq(bob);
3252 using namespace test::jtx;
3257 Env env{*
this, features};
3258 auto const baseFee = env.current()->fees().base;
3259 auto const alice =
Account(
"alice");
3260 auto const gw =
Account(
"gw");
3262 MPTTester mptGw(env, gw, {.holders = {alice}});
3264 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3265 mptGw.authorize({.account = alice});
3266 auto const MPT = mptGw[
"MPT"];
3267 env(
pay(gw, alice,
MPT(10'000)));
3271 auto const seq1 = env.seq(alice);
3272 auto const preAliceMPT = env.balance(alice,
MPT);
3273 auto const preOutstanding = env.balance(gw,
MPT);
3275 BEAST_EXPECT(preOutstanding ==
MPT(-10'000));
3276 BEAST_EXPECT(preEscrowed == 0);
3281 fee(baseFee * 150));
3284 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
3286 BEAST_EXPECT(env.balance(gw,
MPT) == preOutstanding);
3293 fee(baseFee * 150));
3296 BEAST_EXPECT(env.balance(alice,
MPT) == preAliceMPT -
MPT(1'000));
3298 BEAST_EXPECT(env.balance(gw,
MPT) == preOutstanding +
MPT(1'000));
3307 using namespace test::jtx;
3310 auto const alice =
Account(
"alice");
3311 auto const bob =
Account(
"bob");
3312 auto const carol =
Account(
"carol");
3313 auto const gw =
Account{
"gateway"};
3314 auto const USD = gw[
"USD"];
3318 Env env{*
this, features};
3319 auto const baseFee = env.current()->fees().base;
3320 auto const alice =
Account(
"alice");
3321 auto const bob =
Account(
"bob");
3322 auto const gw =
Account(
"gw");
3324 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3326 {.transferFee = 25000,
3329 .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3330 mptGw.authorize({.account = alice});
3331 mptGw.authorize({.account = bob});
3332 auto const MPT = mptGw[
"MPT"];
3333 env(
pay(gw, alice,
MPT(10'000)));
3334 env(
pay(gw, bob,
MPT(10'000)));
3338 auto const preAlice = env.balance(alice,
MPT);
3339 auto const seq1 = env.seq(alice);
3340 auto const delta =
MPT(125);
3344 fee(baseFee * 150));
3351 BEAST_EXPECT(env.balance(gw,
MPT) ==
MPT(-20'000));
3357 fee(baseFee * 150));
3360 BEAST_EXPECT(env.balance(alice,
MPT) == preAlice - delta);
3361 BEAST_EXPECT(env.balance(bob,
MPT) ==
MPT(10'100));
3363 auto const escrowedWithFix = env.current()->rules().enabled(fixTokenEscrowV1) ? 0 : 25;
3364 auto const outstandingWithFix =
3365 env.current()->rules().enabled(fixTokenEscrowV1) ?
MPT(19'975) :
MPT(20'000);
3368 BEAST_EXPECT(env.balance(gw,
MPT) == -outstandingWithFix);
3373 Env env{*
this, features};
3374 auto const baseFee = env.current()->fees().base;
3375 auto const alice =
Account(
"alice");
3376 auto const bob =
Account(
"bob");
3377 auto const gw =
Account(
"gw");
3379 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3381 {.transferFee = 25000,
3384 .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3385 mptGw.authorize({.account = alice});
3386 mptGw.authorize({.account = bob});
3387 auto const MPT = mptGw[
"MPT"];
3388 env(
pay(gw, alice,
MPT(10'000)));
3389 env(
pay(gw, bob,
MPT(10'000)));
3393 auto const preAlice = env.balance(alice,
MPT);
3394 auto const preBob = env.balance(bob,
MPT);
3395 auto const seq1 = env.seq(alice);
3396 auto const delta =
MPT(125);
3401 fee(baseFee * 150));
3410 BEAST_EXPECT(env.balance(alice,
MPT) == preAlice);
3411 BEAST_EXPECT(env.balance(bob,
MPT) == preBob);
3412 BEAST_EXPECT(env.balance(gw,
MPT) ==
MPT(-20'000));
3419 Env env{*
this, features};
3420 auto const baseFee = env.current()->fees().base;
3421 auto const alice =
Account(
"alice");
3422 auto const bob =
Account(
"bob");
3423 auto const gw =
Account(
"gw");
3425 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3427 {.transferFee = 25000,
3430 .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3431 mptGw.authorize({.account = alice});
3432 mptGw.authorize({.account = bob});
3433 auto const MPT = mptGw[
"MPT"];
3434 env(
pay(gw, alice,
MPT(10'000)));
3435 env(
pay(gw, bob,
MPT(10'000)));
3439 auto const preAlice = env.balance(alice,
MPT);
3440 auto const seq1 = env.seq(alice);
3441 auto const delta =
MPT(125);
3445 fee(baseFee * 150));
3452 BEAST_EXPECT(env.balance(gw,
MPT) ==
MPT(-20'000));
3458 fee(baseFee * 150));
3461 BEAST_EXPECT(env.balance(alice,
MPT) == preAlice - delta);
3464 BEAST_EXPECT(env.balance(gw,
MPT) ==
MPT(-19'875));
3472 using namespace test::jtx;
3475 Env env{*
this, features};
3476 auto const baseFee = env.current()->fees().base;
3477 auto const alice =
Account(
"alice");
3478 auto const bob =
Account(
"bob");
3479 auto const gw =
Account(
"gw");
3481 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3485 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTRequireAuth});
3486 mptGw.authorize({.account = alice});
3487 mptGw.authorize({.account = gw, .holder = alice});
3488 mptGw.authorize({.account = bob});
3489 mptGw.authorize({.account = gw, .holder = bob});
3490 auto const MPT = mptGw[
"MPT"];
3491 env(
pay(gw, alice,
MPT(10'000)));
3494 auto seq = env.
seq(alice);
3495 auto const delta =
MPT(125);
3500 fee(baseFee * 150));
3507 fee(baseFee * 150));
3515 using namespace test::jtx;
3518 Env env{*
this, features};
3519 auto const baseFee = env.current()->fees().base;
3520 auto const alice =
Account(
"alice");
3521 auto const bob =
Account(
"bob");
3522 auto const gw =
Account(
"gw");
3524 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3528 .flags = tfMPTCanEscrow | tfMPTCanTransfer | tfMPTCanLock});
3529 mptGw.authorize({.account = alice});
3530 mptGw.authorize({.account = bob});
3531 auto const MPT = mptGw[
"MPT"];
3532 env(
pay(gw, alice,
MPT(10'000)));
3533 env(
pay(gw, bob,
MPT(10'000)));
3537 auto seq1 = env.seq(alice);
3542 fee(baseFee * 150));
3546 mptGw.set({.account = gw, .holder = alice, .flags = tfMPTLock});
3547 mptGw.set({.account = gw, .holder = bob, .flags = tfMPTLock});
3566 using namespace test::jtx;
3569 Env env{*
this, features};
3570 auto const baseFee = env.current()->fees().base;
3571 auto const alice =
Account(
"alice");
3572 auto const bob =
Account(
"bob");
3573 auto const gw =
Account(
"gw");
3575 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3576 mptGw.
create({.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow});
3577 mptGw.authorize({.account = alice});
3578 mptGw.authorize({.account = bob});
3579 auto const MPT = mptGw[
"MPT"];
3580 env(
pay(gw, alice,
MPT(10'000)));
3581 env(
pay(gw, bob,
MPT(10'000)));
3596 auto seq = env.
seq(alice);
3600 fee(baseFee * 150));
3607 fee(baseFee * 150));
3614 auto seq = env.
seq(alice);
3619 fee(baseFee * 150));
3632 using namespace test::jtx;
3637 Env env{*
this, features};
3638 auto const baseFee = env.current()->fees().base;
3639 auto const alice =
Account(
"alice");
3640 auto const bob =
Account(
"bob");
3641 auto const gw =
Account(
"gw");
3643 MPTTester mptGw(env, gw, {.holders = {alice, bob}});
3645 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3646 mptGw.authorize({.account = alice});
3647 mptGw.authorize({.account = bob});
3648 auto const MPT = mptGw[
"MPT"];
3649 env(
pay(gw, alice,
MPT(10'000)));
3650 env(
pay(gw, bob,
MPT(10'000)));
3653 auto const seq1 = env.seq(alice);
3657 fee(baseFee * 150));
3661 env(
pay(alice, gw,
MPT(9'990)));
3662 env(
pay(bob, gw,
MPT(10'000)));
3663 BEAST_EXPECT(env.balance(alice,
MPT) ==
MPT(0));
3665 BEAST_EXPECT(env.balance(bob,
MPT) ==
MPT(0));
3667 BEAST_EXPECT(env.balance(gw,
MPT) ==
MPT(-10));
3668 mptGw.authorize({.account = bob, .flags = tfMPTUnauthorize});
3678 env(
pay(bob, gw,
MPT(10)));
3679 mptGw.destroy({.id = mptGw.issuanceID(), .
ownerCount = 0});
3684 Env env{*
this, features};
3685 auto const baseFee = env.current()->fees().base;
3686 auto const alice =
Account(
"alice");
3687 auto const bob =
Account(
"bob");
3688 auto const gw =
Account(
"gw");
3689 env.fund(
XRP(10'000), bob);
3692 MPTTester mptGw(env, gw, {.holders = {alice}});
3694 {.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanEscrow | tfMPTCanTransfer});
3695 mptGw.authorize({.account = alice});
3696 auto const MPT = mptGw[
"MPT"];
3697 env(
pay(gw, alice,
MPT(10'000)));
3700 auto const seq1 = env.seq(alice);
3708 env(
pay(alice, gw,
MPT(9'990)));
3711 BEAST_EXPECT(env.balance(alice,
MPT) ==
MPT(0));
3723 BEAST_EXPECT(env.balance(alice,
MPT) ==
MPT(0));
3725 mptGw.authorize({.account = alice, .flags = tfMPTUnauthorize});
3775 using namespace test::jtx;
3778 {all - featureSingleAssetVault - featureLendingProtocol, all})
3787BEAST_DEFINE_TESTSUITE(EscrowToken, app,
xrpl);
Value removeMember(char const *key)
Remove and return the named member.
A generic endpoint for log messages.
testcase_t testcase
Memberspace for declaring test cases.
A class that simplifies iterating ledger directory pages.
const_iterator begin() const
const_iterator end() const
A currency issued by an account.
Writable ledger view that accumulates state and tx changes.
Discardable, editable view to a ledger.
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
Immutable cryptographic account descriptor.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
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.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
NetClock::time_point now()
Returns the current network time.
Converts to IOU Issue or STAmount.
void create(MPTCreate const &arg=MPTCreate{})
Converts to MPT Issue or STAmount.
xrpl::MPTID const & mpt() const
Match clear account flags.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
auto const finish_time
Set the "FinishAfter" time tag on a JTx.
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount)
Rate rate(Env &env, Account const &account, std::uint32_t const &seq)
Json::Value cancel(AccountID const &account, Account const &from, std::uint32_t seq)
std::array< std::uint8_t, 39 > const cb2
std::array< std::uint8_t, 39 > const cb1
auto const cancel_time
Set the "CancelAfter" time tag on a JTx.
Json::Value finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
std::array< std::uint8_t, 4 > const fb1
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
std::uint32_t ownerCount(Env const &env, Account const &account)
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
FeatureBitset testable_amendments()
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_string(base_uint< Bits, Tag > const &a)
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
STAmount amountFromString(Asset const &asset, std::string const &amount)
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
TERSubset< CanCvtToTER > TER
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
@ tecNO_LINE_INSUF_RESERVE
@ tecINSUFFICIENT_RESERVE
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
void testMPTCreatePreclaim(FeatureBitset features)
void testMPTFinishDoApply(FeatureBitset features)
void testMPTMetaAndOwnership(FeatureBitset features)
void testIOUBalances(FeatureBitset features)
void testIOUCreatePreclaim(FeatureBitset features)
void testMPTGateway(FeatureBitset features)
void testMPTCanTransfer(FeatureBitset features)
void testIOUFinishPreclaim(FeatureBitset features)
static jtx::PrettyAmount issuerEscrowed(jtx::Env &env, jtx::Account const &account, Issue const &issue)
void run() override
Runs the suite.
void testIOUMetaAndOwnership(FeatureBitset features)
void testIOUPrecisionLoss(FeatureBitset features)
void testMPTLock(FeatureBitset features)
void testMPTCancelPreclaim(FeatureBitset features)
void testIOUEnablement(FeatureBitset features)
void testMPTBalances(FeatureBitset features)
static jtx::PrettyAmount issuerBalance(jtx::Env &env, jtx::Account const &account, Issue const &issue)
void testMPTRequireAuth(FeatureBitset features)
void testIOUFinishDoApply(FeatureBitset features)
void testIOUFreeze(FeatureBitset features)
void testMPTEnablement(FeatureBitset features)
static uint64_t mptEscrowed(jtx::Env const &env, jtx::Account const &account, jtx::MPT const &mpt)
void testIOUCancelPreclaim(FeatureBitset features)
void testIOUGateway(FeatureBitset features)
static uint64_t issuerMPTEscrowed(jtx::Env const &env, jtx::MPT const &mpt)
void testIOULimitAmount(FeatureBitset features)
void testIOUAllowLockingFlag(FeatureBitset features)
void testMPTCreatePreflight(FeatureBitset features)
void testIOULockedRate(FeatureBitset features)
void testMPTFinishPreclaim(FeatureBitset features)
void testIOUInsufficientFunds(FeatureBitset features)
void testIOUWithFeats(FeatureBitset features)
void testMPTLockedRate(FeatureBitset features)
void testMPTWithFeats(FeatureBitset features)
void testIOUCreatePreflight(FeatureBitset features)
void testIOURequireAuth(FeatureBitset features)
void testMPTDestroy(FeatureBitset features)
void testIOURippleState(FeatureBitset features)
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Set the sequence number on a JTx.