19 using namespace test::jtx;
20 Env env(*
this, features);
23 Account alice{
"alice"};
26 env.fund(XRP(1000), G1, alice, bob);
29 env.trust(G1[
"USD"](100), bob);
30 env.trust(G1[
"USD"](100), alice);
33 env(pay(G1, bob, G1[
"USD"](10)));
34 env(pay(G1, alice, G1[
"USD"](100)));
37 env(offer(alice, XRP(500), G1[
"USD"](100)));
41 auto lines = getAccountLines(env, bob);
42 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
44 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == G1.human());
45 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] ==
"100");
46 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] ==
"10");
50 auto lines = getAccountLines(env, alice);
51 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
53 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == G1.human());
54 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] ==
"100");
55 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] ==
"100");
61 env(pay(alice, bob, G1[
"USD"](1)));
64 env(pay(bob, alice, G1[
"USD"](1)));
72 auto affected = env.meta()->getJson(
JsonOptions::none)[sfAffectedNodes.fieldName];
73 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
75 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
76 BEAST_EXPECT(ff[sfLowLimit.fieldName] == G1[
"USD"](0).value().getJson(
JsonOptions::none));
85 env(offer(bob, G1[
"USD"](5), XRP(25)));
86 auto affected = env.meta()->getJson(
JsonOptions::none)[sfAffectedNodes.fieldName];
87 if (!BEAST_EXPECT(checkArraySize(affected, 5u)))
89 auto ff = affected[3u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
90 BEAST_EXPECT(ff[sfHighLimit.fieldName] == bob[
"USD"](100).value().getJson(
JsonOptions::none));
92 BEAST_EXPECT(ff[sfBalance.fieldName] == amt);
101 env(pay(alice, bob, G1[
"USD"](1)));
104 env(pay(bob, alice, G1[
"USD"](1)), ter(
tecPATH_DRY));
110 auto lines = getAccountLines(env, G1);
112 for (
auto const& it : lines[jss::lines])
114 if (it[jss::account] == bob.human())
120 if (!BEAST_EXPECT(bobLine))
122 BEAST_EXPECT(bobLine[jss::freeze] ==
true);
123 BEAST_EXPECT(bobLine[jss::balance] ==
"-16");
128 auto lines = getAccountLines(env, bob);
130 for (
auto const& it : lines[jss::lines])
132 if (it[jss::account] == G1.human())
138 if (!BEAST_EXPECT(g1Line))
140 BEAST_EXPECT(g1Line[jss::freeze_peer] ==
true);
141 BEAST_EXPECT(g1Line[jss::balance] ==
"16");
148 auto affected = env.meta()->getJson(
JsonOptions::none)[sfAffectedNodes.fieldName];
149 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
151 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
152 BEAST_EXPECT(ff[sfLowLimit.fieldName] == G1[
"USD"](0).value().getJson(
JsonOptions::none));
153 BEAST_EXPECT(!(ff[jss::Flags].asUInt() &
lsfLowFreeze));
342 using namespace test::jtx;
343 Env env(*
this, features);
351 env.fund(XRP(12000), G1);
352 env.fund(XRP(1000), A1);
353 env.fund(XRP(20000), A2, A3, A4);
356 env.trust(G1[
"USD"](1200), A1);
357 env.trust(G1[
"USD"](200), A2);
358 env.trust(G1[
"BTC"](100), A3);
359 env.trust(G1[
"BTC"](100), A4);
362 env(pay(G1, A1, G1[
"USD"](1000)));
363 env(pay(G1, A2, G1[
"USD"](100)));
364 env(pay(G1, A3, G1[
"BTC"](100)));
365 env(pay(G1, A4, G1[
"BTC"](100)));
368 env(offer(G1, XRP(10000), G1[
"USD"](100)), txflags(
tfPassive));
369 env(offer(G1, G1[
"USD"](100), XRP(10000)), txflags(
tfPassive));
370 env(offer(A1, XRP(10000), G1[
"USD"](100)), txflags(
tfPassive));
371 env(offer(A2, G1[
"USD"](100), XRP(10000)), txflags(
tfPassive));
391 auto offers = env.rpc(
"book_offers",
std::string(
"USD/") + G1.human(),
"XRP")[jss::result][jss::offers];
392 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
395 for (
auto const& offer : offers)
397 accounts.
insert(offer[jss::Account].asString());
399 BEAST_EXPECT(accounts.
find(A2.human()) !=
std::end(accounts));
400 BEAST_EXPECT(accounts.
find(G1.human()) !=
std::end(accounts));
403 offers = env.rpc(
"book_offers",
"XRP",
std::string(
"USD/") + G1.human())[jss::result][jss::offers];
404 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
407 for (
auto const& offer : offers)
409 accounts.
insert(offer[jss::Account].asString());
411 BEAST_EXPECT(accounts.
find(A1.human()) !=
std::end(accounts));
412 BEAST_EXPECT(accounts.
find(G1.human()) !=
std::end(accounts));
418 env(offer(A3, G1[
"BTC"](1), XRP(1)));
421 env(offer(A4, XRP(1), G1[
"BTC"](1)));
424 env(pay(G1, A2, G1[
"USD"](1)));
427 env(pay(A2, G1, G1[
"USD"](1)));
430 env(pay(A2, A1, G1[
"USD"](1)));
433 env(pay(A1, A2, G1[
"USD"](1)));
446 env(offer(A3, G1[
"BTC"](1), XRP(1)), ter(
tecFROZEN));
449 env(offer(A4, XRP(1), G1[
"BTC"](1)), ter(
tecFROZEN));
455 auto offers = getAccountOffers(env, G1)[jss::offers];
456 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
461 offers = env.rpc(
"book_offers",
"XRP",
std::string(
"USD/") + G1.human())[jss::result][jss::offers];
462 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
465 offers = env.rpc(
"book_offers",
std::string(
"USD/") + G1.human(),
"XRP")[jss::result][jss::offers];
466 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
473 env(pay(G1, A2, G1[
"USD"](1)));
476 env(pay(A2, G1, G1[
"USD"](1)));
597 testcase(
"Offers for Frozen Trust Lines");
599 using namespace test::jtx;
600 Env env(*
this, features);
607 env.fund(XRP(1000), G1, A3, A4);
608 env.fund(XRP(2000), A2);
611 env.trust(G1[
"USD"](1000), A2);
612 env.trust(G1[
"USD"](2000), A3);
613 env.trust(G1[
"USD"](2000), A4);
616 env(pay(G1, A3, G1[
"USD"](2000)));
617 env(pay(G1, A4, G1[
"USD"](2000)));
620 env(offer(A3, XRP(1000), G1[
"USD"](1000)), txflags(
tfPassive));
625 env(pay(A2, G1, G1[
"USD"](1)), paths(G1[
"USD"]), sendmax(XRP(1)));
629 auto offers = getAccountOffers(env, A3)[jss::offers];
630 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
635 env(offer(A4, XRP(999), G1[
"USD"](999)));
640 auto affected = env.meta()->getJson(
JsonOptions::none)[sfAffectedNodes.fieldName];
641 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
643 auto ff = affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
644 BEAST_EXPECT(ff[sfHighLimit.fieldName] == G1[
"USD"](0).value().getJson(
JsonOptions::none));
645 BEAST_EXPECT(!(ff[jss::Flags].asUInt() &
lsfLowFreeze));
650 offers = getAccountOffers(env, A3)[jss::offers];
651 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
655 env(pay(A2, G1, G1[
"USD"](1)), paths(G1[
"USD"]), sendmax(XRP(1)));
659 offers = getAccountOffers(env, A3)[jss::offers];
660 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
667 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
669 ff = affected[0u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
670 BEAST_EXPECT(ff[sfLowLimit.fieldName] == G1[
"USD"](0).value().getJson(
JsonOptions::none));
676 env(offer(A2, G1[
"USD"](999), XRP(999)));
678 if (!BEAST_EXPECT(checkArraySize(affected, 8u)))
680 auto created = affected[0u][sfCreatedNode.fieldName];
681 BEAST_EXPECT(created[sfNewFields.fieldName][jss::Account] == A2.human());
685 offers = getAccountOffers(env, A4)[jss::offers];
686 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
693 testcase(
"Offers on frozen trust lines");
695 using namespace test::jtx;
696 Env env(*
this, features);
702 auto const USD{G1[
"USD"]};
704 env.fund(XRP(10000), G1, A1, A2, A3);
707 auto const limit = USD(10000);
708 env.trust(limit, A1, A2, A3);
711 env(pay(G1, A1, USD(1000)));
712 env(pay(G1, A2, USD(1000)));
717 env(offer(A2, XRP(100), USD(50)), txflags(
tfPassive));
721 env(offer(A3, USD(100), XRP(100)), txflags(
tfPassive));
723 env.require(offers(A2, 1), offers(A3, 1));
728 env.require(balance(A1, USD(1001)), balance(A2, USD(999)));
733 env.require(balance(A1, USD(1000)), balance(A3, USD(1)));
742 env(offer(A1, USD(1), XRP(0.5)), txflags(
tfPassive));
744 env.require(balance(A1, USD(1000)), offers(A1, 1));
746 env(offer_cancel(A1, env.seq(A1) - 1));
747 env.require(offers(A1, 0));
753 env.require(balance(A1, USD(1001)), balance(A2, USD(998)), offers(A1, 0));
758 env.require(balance(A1, USD(1001)), offers(A1, 0));
763 env.require(balance(A1, USD(1001)), offers(A1, 0));
771 if (features[featureDeepFreeze])
794 env.require(balance(A1, USD(1001)), offers(A1, 0));
800 env.require(balance(A1, USD(1001)));
801 env(offer(A1, XRP(1.9), USD(1)));
802 env(offer(A1, USD(1), XRP(1.1)));
804 env.require(balance(A1, USD(1001)), offers(A1, 2));
810 env.require(balance(A1, USD(1001)), balance(A2, USD(998)));
811 env(offer(A2, XRP(1.1), USD(1)), txflags(
tfFillOrKill));
813 env.require(balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 1));
816 env.require(balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 1));
819 env.require(balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 0));
827 if (features[featureDeepFreeze])
829 env.require(balance(A1, USD(1002)));
830 env(offer(A1, XRP(1.9), USD(1)));
831 env(offer(A1, USD(1), XRP(1.1)));
833 env.require(balance(A1, USD(1002)), offers(A1, 2));
839 env.require(balance(A1, USD(1002)), balance(A2, USD(997)));
842 env.require(balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 1));
845 env.require(balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 1));
848 env.require(balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 0));
861 env(offer(A1, USD(1), XRP(0.5)), txflags(
tfPassive));
863 env.require(balance(A1, USD(1002)), offers(A1, 1));
865 env(offer_cancel(A1, env.seq(A1) - 1));
866 env.require(offers(A1, 0));
872 env.require(balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 0));
875 env(offer(A1, XRP(2), USD(1)), txflags(
tfPassive));
877 env.require(balance(A1, USD(1002)), offers(A1, 1));
879 env(offer_cancel(A1, env.seq(A1) - 1));
880 env.require(offers(A1, 0));
886 env.require(balance(A1, USD(1001)), offers(A1, 0));
894 if (features[featureDeepFreeze])
923 testcase(
"Longer paths payment on frozen trust lines");
924 using namespace test::jtx;
927 Env env(*
this, features);
931 auto const USD{G1[
"USD"]};
933 env.fund(XRP(10000), G1, A1, A2);
936 auto const limit = USD(10000);
937 env.trust(limit, A1, A2);
940 env(pay(G1, A1, USD(1000)));
941 env(pay(G1, A2, USD(1000)));
944 env(offer(A2, XRP(100), USD(100)), txflags(
tfPassive));
965 if (features[featureDeepFreeze])
989 env(pay(A1, G1, USD(10)), path(~USD), sendmax(XRP(11)), txflags(
tfNoRippleDirect));
993 env(pay(G1, A1, USD(10)), path(~USD), sendmax(XRP(11)), txflags(
tfNoRippleDirect));
1002 if (features[featureDeepFreeze])
1020 env(offer_cancel(A1, env.seq(A1) - 1));
1021 env.require(offers(A1, 0));
1024 env(offer(A2, USD(100), XRP(100)), txflags(
tfPassive));
1033 env(pay(A1, G1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1037 env(pay(G1, A1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1046 if (features[featureDeepFreeze])
1070 env(pay(A1, G1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1074 env(pay(G1, A1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1083 if (features[featureDeepFreeze])
1101 env(offer_cancel(A1, env.seq(A1) - 1));
1102 env.require(offers(A1, 0));
1109 testcase(
"Direct payments on frozen trust lines");
1111 using namespace test::jtx;
1112 Env env(*
this, features);
1117 auto const USD{G1[
"USD"]};
1119 env.fund(XRP(10000), G1, A1, A2);
1122 auto const limit = USD(10000);
1123 env.trust(limit, A1, A2);
1126 env(pay(G1, A1, USD(1000)));
1127 env(pay(G1, A2, USD(1000)));
1132 env(pay(A1, G1, USD(1)));
1133 env(pay(A2, G1, USD(1)));
1137 env(pay(A1, A2, USD(1)));
1138 env(pay(A2, A1, USD(1)));
1146 env(pay(A1, G1, USD(1)));
1147 env(pay(G1, A1, USD(1)));
1154 env(pay(A2, A1, USD(1)));
1157 if (features[featureDeepFreeze])
1164 env(pay(A1, G1, USD(1)));
1165 env(pay(G1, A1, USD(1)));
1188 env(pay(A2, G1, USD(1)));
1189 env(pay(G1, A2, USD(1)));
1193 env(pay(A1, G1, USD(1)));
1196 env(pay(A1, A2, USD(1)));
1200 env(pay(G1, A1, USD(1)));
1204 if (features[featureDeepFreeze])
1211 env(pay(A2, G1, USD(1)));
1212 env(pay(G1, A2, USD(1)));
1216 env(pay(A1, G1, USD(1)));
1220 env(pay(G1, A1, USD(1)));
1231 testcase(
"Checks on frozen trust lines");
1233 using namespace test::jtx;
1234 Env env(*
this, features);
1239 auto const USD{G1[
"USD"]};
1241 env.fund(XRP(10000), G1, A1, A2);
1244 auto const limit = USD(10000);
1245 env.trust(limit, A1, A2);
1248 env(pay(G1, A1, USD(1000)));
1249 env(pay(G1, A2, USD(1000)));
1255 env(check::create(G1, A1, USD(10)));
1257 env(check::cash(A1, checkId, USD(10)));
1263 env(check::create(G1, A2, USD(10)));
1265 env(check::cash(A2, checkId, USD(10)));
1271 env(check::create(A1, G1, USD(10)));
1273 env(check::cash(G1, checkId, USD(10)));
1279 env(check::create(A1, A2, USD(10)));
1281 env(check::cash(A2, checkId, USD(10)));
1287 env(check::create(A2, G1, USD(10)));
1289 env(check::cash(G1, checkId, USD(10)));
1295 env(check::create(A2, A1, USD(10)));
1297 env(check::cash(A1, checkId, USD(10)));
1310 env(check::create(G1, A1, USD(10)));
1312 env(check::cash(A1, checkId, USD(10)), ter(
tecFROZEN));
1319 env(check::create(A2, A1, USD(10)));
1322 env(check::cash(A1, checkId, USD(10)), ter(
tecFROZEN));
1328 env(check::create(A1, G1, USD(10)), ter(
tecFROZEN));
1335 env(check::create(A1, A2, USD(10)), ter(
tecFROZEN));
1345 env(check::create(A1, G1, USD(10)));
1348 env(check::create(A1, A2, USD(10)));
1372 if (features[featureDeepFreeze])
1380 env(check::create(G1, A1, USD(10)));
1383 env(check::cash(A1, checkId, USD(10)), ter(
tecFROZEN));
1390 env(check::create(A2, A1, USD(10)));
1393 env(check::cash(A1, checkId, USD(10)), ter(
tecFROZEN));
1399 env(check::create(A1, G1, USD(10)), ter(
tecFROZEN));
1406 env(check::create(A1, A2, USD(10)), ter(
tecFROZEN));
1416 env(check::create(A1, G1, USD(10)));
1419 env(check::create(A1, A2, USD(10)));
1449 env(check::create(G1, A1, USD(10)), ter(
tecFROZEN));
1455 env(check::create(A2, A1, USD(10)), ter(
tecFROZEN));
1462 env(check::create(A1, G1, USD(10)));
1464 env(check::cash(G1, checkId, USD(10)));
1471 env(check::create(A1, A2, USD(10)));
1473 env(check::cash(A2, checkId, USD(10)));
1483 if (features[featureDeepFreeze])
1490 env(check::create(G1, A1, USD(10)), ter(
tecFROZEN));
1496 env(check::create(A2, A1, USD(10)), ter(
tecFROZEN));
1503 env(check::create(A1, G1, USD(10)));
1512 env(check::create(A1, A2, USD(10)));
1526 testcase(
"AMM payments on frozen trust lines");
1527 using namespace test::jtx;
1530 Env env(*
this, features);
1534 auto const USD{G1[
"USD"]};
1536 env.fund(XRP(10000), G1, A1, A2);
1539 env.trust(G1[
"USD"](10000), A1, A2);
1542 env(pay(G1, A1, USD(1000)));
1543 env(pay(G1, A2, USD(1000)));
1546 AMM ammG1(env, G1, XRP(1'000), USD(1'000));
1555 env(pay(A1, A2, USD(10)), path(~USD), sendmax(XRP(11)), txflags(
tfNoRippleDirect));
1563 env(pay(A2, A1, USD(10)), path(~USD), sendmax(XRP(11)), txflags(
tfNoRippleDirect));
1567 env(pay(A2, A1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1576 if (features[featureDeepFreeze])
1582 env(pay(A1, A2, USD(10)), path(~USD), sendmax(XRP(11)), txflags(
tfNoRippleDirect));
1594 env(pay(A2, A1, XRP(10)), path(~XRP), sendmax(USD(11)), txflags(
tfNoRippleDirect));
1605 testcase(
"NFT offers on frozen trust lines");
1606 using namespace test::jtx;
1608 Env env(*
this, features);
1612 auto const USD{G1[
"USD"]};
1614 env.fund(XRP(10000), G1, A1, A2);
1617 auto const limit = USD(10000);
1618 env.trust(limit, A1, A2);
1621 env(pay(G1, A1, USD(1000)));
1622 env(pay(G1, A2, USD(1000)));
1632 env(token::acceptSellOffer(A1, sellOfferIndex));
1640 if (features[featureDeepFreeze])
1648 env(token::acceptSellOffer(A1, sellOfferIndex), ter(
tecFROZEN));
1670 if (features[featureDeepFreeze])
1685 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1695 env(token::createOffer(A1, nftID, USD(10)), token::owner(A2));
1698 env(token::acceptBuyOffer(A2, buyIdx), ter(
tecFROZEN));
1704 env(token::acceptBuyOffer(A2, buyIdx));
1715 env(token::acceptSellOffer(A1, sellOfferIndex));
1723 if (features[featureDeepFreeze])
1731 env(token::acceptSellOffer(A1, sellOfferIndex), ter(
tecFROZEN));
1745 env(token::acceptSellOffer(A2, sellOfferIndex));
1753 if (features[featureDeepFreeze])
1768 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1770 Account broker{
"broker"};
1771 env.fund(XRP(10000), broker);
1781 env(token::createOffer(A2, nftID, USD(10)), txflags(
tfSellNFToken));
1784 env(token::createOffer(A1, nftID, USD(11)), token::owner(A2));
1787 env(token::brokerOffers(broker, buyIdx, sellIdx), token::brokerFee(USD(1)), ter(
tecFROZEN));
1792 if (features[featureDeepFreeze] && features[fixEnforceNFTokenTrustlineV2])
1794 Account minter{
"minter"};
1795 env.fund(XRP(10000), minter);
1797 env(trust(G1, minter[
"USD"](1000)));
1801 env(token::mint(minter, 0), token::xferFee(1u), txflags(
tfTransferable));
1805 env(token::createOffer(minter, nftID, drops(1)), txflags(
tfSellNFToken));
1807 env(token::acceptSellOffer(A2, minterSellIdx));
1811 env(token::createOffer(A2, nftID, USD(100)), txflags(
tfSellNFToken));
1815 env(token::acceptSellOffer(A1, sellIdx), ter(
tecFROZEN));