138 IOU
const usd{gw[
"USD"]};
140 Env env{*
this, features};
142 STAmount const startBalance{XRP(1000).value()};
143 env.fund(startBalance, gw, alice, bob);
149 auto writeTwoChecks = [&env, &usd,
this](
Account const& from,
Account const& to) {
156 env(check::create(from, to, XRP(2000)));
159 env(check::create(from, to, usd(50)));
165 env.require(Owners(from, fromOwnerCount + 2));
166 env.require(Owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
169 writeTwoChecks(alice, bob);
170 writeTwoChecks(gw, alice);
171 writeTwoChecks(alice, gw);
177 using namespace std::chrono_literals;
180 env(check::create(alice, bob, usd(50)), Expiration(env.now() + 1s));
183 env(check::create(alice, bob, usd(50)), SourceTag(2));
185 env(check::create(alice, bob, usd(50)), DestTag(3));
187 env(check::create(alice, bob, usd(50)), InvoiceId(
uint256{4}));
189 env(check::create(alice, bob, usd(50)),
190 Expiration(env.now() + 1s),
201 env(regkey(alice, alie));
206 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), Sig(alie));
210 env(check::create(alice, bob, usd(50)), Sig(alie));
216 XRPAmount const baseFeeDrops{env.current()->fees().base};
217 env(check::create(alice, bob, usd(50)), Msig(bogie, demon), Fee(3 * baseFeeDrops));
311 Account const gwF{
"gatewayFrozen"};
314 IOU
const usd{gw1[
"USD"]};
316 Env env{*
this, features};
318 STAmount const startBalance{XRP(1000).value()};
319 env.fund(startBalance, gw1, gwF, alice, bob);
323 env(check::create(alice, bob, usd(50)), Fee(drops(-10)), Ter(
temBAD_FEE));
327 env(check::create(alice, bob, usd(50)), Txflags(tfImmediateOrCancel), Ter(
temINVALID_FLAG));
331 env(check::create(alice, alice, XRP(10)), Ter(
temREDUNDANT));
335 env(check::create(alice, bob, drops(-1)), Ter(
temBAD_AMOUNT));
338 env(check::create(alice, bob, drops(0)), Ter(
temBAD_AMOUNT));
341 env(check::create(alice, bob, drops(1)));
350 env(check::create(alice, bob, usd(1)));
359 env(check::create(alice, bob, usd(50)),
366 env(check::create(alice, bogie, usd(50)), Ter(
tecNO_DST));
370 env(fset(bob, asfRequireDest));
376 env(check::create(alice, bob, usd(50)), DestTag(11));
379 env(fclear(bob, asfRequireDest));
383 IOU
const usf{gwF[
"USF"]};
384 env(fset(gwF, asfGlobalFreeze));
387 env(check::create(alice, bob, usf(50)), Ter(
tecFROZEN));
390 env(check::create(gwF, bob, usf(50)), Ter(
tecFROZEN));
393 env(fclear(gwF, asfGlobalFreeze));
396 env(check::create(alice, bob, usf(50)));
399 env(check::create(gwF, bob, usf(50)));
405 env.trust(usd(1000), alice);
406 env.trust(usd(1000), bob);
408 env(pay(gw1, alice, usd(25)));
409 env(pay(gw1, bob, usd(25)));
415 env(trust(gw1, alice[
"USD"](0), tfSetFreeze));
417 env(check::create(alice, bob, usd(50)), Ter(
tecFROZEN));
421 env(check::create(bob, alice, usd(50)));
423 env(pay(bob, alice, usd(1)));
425 env(check::create(gw1, alice, usd(50)));
427 env(pay(gw1, alice, usd(1)));
431 env(trust(gw1, alice[
"USD"](0), tfClearFreeze));
433 env(check::create(alice, bob, usd(50)));
435 env(check::create(bob, alice, usd(50)));
437 env(check::create(gw1, alice, usd(50)));
443 env(trust(alice, usd(0), tfSetFreeze));
445 env(check::create(alice, bob, usd(50)));
447 env(pay(alice, bob, usd(1)));
449 env(check::create(bob, alice, usd(50)), Ter(
tecFROZEN));
453 env(check::create(gw1, alice, usd(50)), Ter(
tecFROZEN));
459 env(trust(alice, usd(0), tfClearFreeze));
464 env(check::create(alice, bob, usd(50)), Expiration(env.now()), Ter(
tecEXPIRED));
467 using namespace std::chrono_literals;
468 env(check::create(alice, bob, usd(50)), Expiration(env.now() + 1s));
473 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
476 env(check::create(cheri, bob, usd(50)),
477 Fee(drops(env.current()->fees().base)),
481 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
484 env(check::create(cheri, bob, usd(50)));
499 Env env{*
this, features};
501 XRPAmount const baseFeeDrops{env.current()->fees().base};
502 STAmount const startBalance{XRP(300).value()};
503 env.fund(startBalance, alice, bob);
508 env(check::create(alice, bob, XRP(10)));
510 env.require(Balance(alice, startBalance - drops(baseFeeDrops)));
511 env.require(Balance(bob, startBalance));
514 BEAST_EXPECT(ownerCount(env, alice) == 1);
515 BEAST_EXPECT(ownerCount(env, bob) == 0);
517 env(check::cash(bob, chkId, XRP(10)));
519 env.require(Balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
520 env.require(Balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
523 BEAST_EXPECT(ownerCount(env, alice) == 0);
524 BEAST_EXPECT(ownerCount(env, bob) == 0);
527 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
528 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
530 env.require(Balance(alice, startBalance));
531 env.require(Balance(bob, startBalance));
535 STAmount const reserve{env.current()->fees().reserve};
536 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops)};
538 env(check::create(alice, bob, checkAmount));
542 env(check::cash(bob, chkId, checkAmount + drops(1)), Ter(
tecPATH_PARTIAL));
544 env(check::cash(bob, chkId, check::DeliverMin(checkAmount + drops(1))),
551 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
553 env.require(Balance(alice, reserve));
554 env.require(Balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
557 BEAST_EXPECT(ownerCount(env, alice) == 0);
558 BEAST_EXPECT(ownerCount(env, bob) == 0);
561 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
562 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
564 env.require(Balance(alice, startBalance));
565 env.require(Balance(bob, startBalance));
569 STAmount const reserve{env.current()->fees().reserve};
570 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops - 1)};
572 env(check::create(alice, bob, checkAmount));
581 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
583 env.require(Balance(alice, reserve));
584 env.require(Balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
587 BEAST_EXPECT(ownerCount(env, alice) == 0);
588 BEAST_EXPECT(ownerCount(env, bob) == 0);
591 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
592 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
594 env.require(Balance(alice, startBalance));
595 env.require(Balance(bob, startBalance));
610 IOU
const usd{gw[
"USD"]};
613 Env env{*
this, features};
615 env.fund(XRP(1000), gw, alice, bob);
620 env(check::create(alice, bob, usd(10)));
628 env(trust(alice, usd(20)));
630 env(pay(gw, alice, usd(9.5)));
637 env(pay(gw, alice, usd(0.5)));
641 env(trust(bob, usd(9.5)));
646 env(trust(bob, usd(10.5)));
652 env(check::cash(bob, chkId1, usd(10)));
654 env.require(Balance(alice, usd(0)));
655 env.require(Balance(bob, usd(10)));
659 BEAST_EXPECT(ownerCount(env, alice) == 1);
660 BEAST_EXPECT(ownerCount(env, bob) == 1);
663 env(check::cash(bob, chkId1, usd(10)), Ter(
tecNO_ENTRY));
667 env(pay(bob, alice, usd(7)));
671 env(check::create(alice, bob, usd(7)));
678 env(check::cash(bob, chkId2, usd(5)));
680 env.require(Balance(alice, usd(2)));
681 env.require(Balance(bob, usd(8)));
684 BEAST_EXPECT(ownerCount(env, alice) == 1);
685 BEAST_EXPECT(ownerCount(env, bob) == 1);
689 env(check::create(alice, bob, usd(2)));
692 env(check::create(alice, bob, usd(2)));
698 env(check::cash(bob, chkId4, usd(2)));
700 env.require(Balance(alice, usd(0)));
701 env.require(Balance(bob, usd(10)));
704 BEAST_EXPECT(ownerCount(env, alice) == 2);
705 BEAST_EXPECT(ownerCount(env, bob) == 1);
711 env.require(Balance(alice, usd(0)));
712 env.require(Balance(bob, usd(10)));
715 BEAST_EXPECT(ownerCount(env, alice) == 2);
716 BEAST_EXPECT(ownerCount(env, bob) == 1);
732 env(check::create(gw, bob, usd(20)));
736 env(check::cash(bob, chkId20, usd(20)));
738 env.require(Balance(bob, usd(30)));
742 env(pay(bob, gw, usd(20)));
745 env(check::cancel(bob, chkId3));
747 env.require(Balance(alice, usd(0)));
748 env.require(Balance(bob, usd(10)));
751 BEAST_EXPECT(ownerCount(env, alice) == 1);
752 BEAST_EXPECT(ownerCount(env, bob) == 1);
756 Env env{*
this, features};
758 env.fund(XRP(1000), gw, alice, bob);
761 env(trust(alice, usd(20)));
762 env(trust(bob, usd(20)));
764 env(pay(gw, alice, usd(8)));
769 env(check::create(alice, bob, usd(9)));
772 env(check::create(alice, bob, usd(8)));
775 env(check::create(alice, bob, usd(7)));
778 env(check::create(alice, bob, usd(6)));
783 env(check::cash(bob, chkId9, check::DeliverMin(usd(9))), Ter(
tecPATH_PARTIAL));
787 env(check::cash(bob, chkId9, check::DeliverMin(usd(7))));
789 env.require(Balance(alice, usd(0)));
790 env.require(Balance(bob, usd(8)));
793 BEAST_EXPECT(ownerCount(env, alice) == 4);
794 BEAST_EXPECT(ownerCount(env, bob) == 1);
797 env(pay(bob, alice, usd(7)));
802 env(check::cash(bob, chkId7, check::DeliverMin(usd(7))));
804 env.require(Balance(alice, usd(0)));
805 env.require(Balance(bob, usd(8)));
808 BEAST_EXPECT(ownerCount(env, alice) == 3);
809 BEAST_EXPECT(ownerCount(env, bob) == 1);
812 env(pay(bob, alice, usd(8)));
817 env(check::cash(bob, chkId6, check::DeliverMin(usd(4))));
819 env.require(Balance(alice, usd(2)));
820 env.require(Balance(bob, usd(6)));
823 BEAST_EXPECT(ownerCount(env, alice) == 2);
824 BEAST_EXPECT(ownerCount(env, bob) == 1);
828 env(check::cash(bob, chkId8, check::DeliverMin(usd(2))));
830 env.require(Balance(alice, usd(0)));
831 env.require(Balance(bob, usd(8)));
834 BEAST_EXPECT(ownerCount(env, alice) == 1);
835 BEAST_EXPECT(ownerCount(env, bob) == 1);
839 Env env(*
this, features);
841 env.fund(XRP(1000), gw, alice, bob);
842 env(fset(gw, asfRequireAuth));
844 env(trust(gw, alice[
"USD"](100)), Txflags(tfSetfAuth));
845 env(trust(alice, usd(20)));
847 env(pay(gw, alice, usd(8)));
853 env(check::create(alice, bob, usd(7)));
856 env(check::cash(bob, chkId, usd(7)), Ter(
tecNO_AUTH));
861 env(trust(bob, usd(5)));
864 env(check::cash(bob, chkId, usd(7)), Ter(
tecNO_AUTH));
868 env(trust(gw, bob[
"USD"](1)), Txflags(tfSetfAuth));
878 env(check::cash(bob, chkId, check::DeliverMin(usd(4))));
881 env.require(Balance(alice, usd(8) - bobGot));
882 env.require(Balance(bob, bobGot));
886 BEAST_EXPECT(ownerCount(env, alice) == 1);
887 BEAST_EXPECT(ownerCount(env, bob) == 1);
892 Env env{*
this, features};
893 env.fund(XRP(1000), gw, alice, bob);
898 env(check::create(alice, bob, usd(1)));
902 env(check::create(alice, bob, usd(2)));
905 env(trust(alice, usd(20)));
906 env(trust(bob, usd(20)));
908 env(pay(gw, alice, usd(8)));
913 env(regkey(bob, bobby));
918 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), Sig(bobby));
921 BEAST_EXPECT(ownerCount(env, bob) == 2);
924 env(check::cash(bob, chkId1, (usd(1))), Sig(bobby));
926 env.require(Balance(alice, usd(7)));
927 env.require(Balance(bob, usd(1)));
930 BEAST_EXPECT(ownerCount(env, alice) == 2);
931 BEAST_EXPECT(ownerCount(env, bob) == 2);
934 XRPAmount const baseFeeDrops{env.current()->fees().base};
935 env(check::cash(bob, chkId2, (usd(2))), Msig(bogie, demon), Fee(3 * baseFeeDrops));
937 env.require(Balance(alice, usd(5)));
938 env.require(Balance(bob, usd(3)));
941 BEAST_EXPECT(ownerCount(env, alice) == 1);
942 BEAST_EXPECT(ownerCount(env, bob) == 2);
1027 IOU
const usd{gw[
"USD"]};
1029 Env env{*
this, features};
1031 env.fund(XRP(1000), gw, alice, bob);
1034 env(trust(alice, usd(1000)));
1035 env(trust(bob, usd(1000)));
1037 env(pay(gw, alice, usd(1000)));
1045 auto qIn = [](
double percent) {
return QualityInPercent(percent); };
1046 auto qOut = [](
double percent) {
return QualityOutPercent(percent); };
1050 auto testNonIssuerQPay = [&env, &alice, &bob, &usd](
1053 auto const& inOrOut,
1057 STAmount const aliceStart{env.balance(alice, usd).value()};
1058 STAmount const bobStart{env.balance(bob, usd).value()};
1061 env(trust(truster, iou(1000)), inOrOut(pct));
1064 env(pay(alice, bob, usd(amount)), Sendmax(usd(10)));
1066 env.require(Balance(alice, aliceStart - usd(10)));
1067 env.require(Balance(bob, bobStart + usd(10)));
1071 env(trust(truster, iou(1000)), inOrOut(0));
1075 auto testNonIssuerQCheck = [&env, &alice, &bob, &usd](
1078 auto const& inOrOut,
1082 STAmount const aliceStart{env.balance(alice, usd).value()};
1083 STAmount const bobStart{env.balance(bob, usd).value()};
1086 env(trust(truster, iou(1000)), inOrOut(pct));
1090 env(check::create(alice, bob, usd(10)));
1093 env(check::cash(bob, chkId, usd(amount)));
1095 env.require(Balance(alice, aliceStart - usd(10)));
1096 env.require(Balance(bob, bobStart + usd(10)));
1100 env(trust(truster, iou(1000)), inOrOut(0));
1105 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1106 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1109 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1110 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1112 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1113 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1115 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1116 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1118 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1119 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1121 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1122 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1124 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1125 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1127 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1128 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1135 auto testIssuerQPay = [&env, &gw, &alice, &usd](
1138 auto const& inOrOut,
1146 STAmount const aliceStart{env.balance(alice, usd).value()};
1149 env(trust(truster, iou(1000)), inOrOut(pct));
1153 env(pay(alice, gw, usd(amt1)), Sendmax(usd(max1)));
1155 env.require(Balance(alice, aliceStart - usd(10)));
1158 env(pay(gw, alice, usd(amt2)), Sendmax(usd(max2)));
1160 env.require(Balance(alice, aliceStart));
1164 env(trust(truster, iou(1000)), inOrOut(0));
1168 auto testIssuerQCheck = [&env, &gw, &alice, &usd](
1171 auto const& inOrOut,
1179 STAmount const aliceStart{env.balance(alice, usd).value()};
1182 env(trust(truster, iou(1000)), inOrOut(pct));
1187 env(check::create(alice, gw, usd(max1)));
1190 env(check::cash(gw, chkAliceId, usd(amt1)));
1192 env.require(Balance(alice, aliceStart - usd(10)));
1196 env(check::create(gw, alice, usd(max2)));
1199 env(check::cash(alice, chkGwId, usd(amt2)));
1201 env.require(Balance(alice, aliceStart));
1205 env(trust(truster, iou(1000)), inOrOut(0));
1211 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1212 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1214 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1215 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1217 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1218 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1220 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1221 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1236 IOU
const usd{gw[
"USD"]};
1238 Env env(*
this, features);
1240 env.fund(XRP(1000), gw, alice, bob, zoe);
1244 env(trust(alice, usd(20)));
1246 env(pay(gw, alice, usd(20)));
1250 env(trust(bob, usd(20)));
1256 env(check::cash(bob, chkId, usd(20)), Ter(
tecNO_ENTRY));
1262 env(check::create(alice, bob, usd(20)));
1266 env(check::create(alice, bob, XRP(10)));
1269 using namespace std::chrono_literals;
1271 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 1s));
1275 env(check::create(alice, bob, usd(1)));
1279 env(check::create(alice, bob, usd(2)));
1283 env(check::create(alice, bob, usd(3)));
1287 env(check::create(alice, bob, usd(4)));
1291 env(check::create(alice, gw, usd(4)));
1295 env(check::create(gw, alice, usd(4)));
1299 env(check::create(alice, bob, usd(1)));
1303 env(check::create(alice, bob, usd(2)), DestTag(7));
1307 auto failingCases = [&env, &gw, &alice, &bob](
1310 env(check::cash(bob, chkId, amount), Fee(drops(-10)), Ter(
temBAD_FEE));
1314 env(check::cash(bob, chkId, amount),
1315 Txflags(tfImmediateOrCancel),
1340 env(check::cash(bob, chkId, amount.zeroed()), Ter(
temBAD_AMOUNT));
1345 if (!amount.native())
1362 IOU
const wrongCurrency{gw[
"EUR"]};
1365 env(check::cash(bob, chkId, badAmount), Ter(
temMALFORMED));
1371 IOU
const wrongIssuer{alice[
"USD"]};
1374 env(check::cash(bob, chkId, badAmount), Ter(
temMALFORMED));
1383 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)), Ter(
tecPATH_PARTIAL));
1387 failingCases(chkIdX, XRP(10));
1388 failingCases(chkIdU, usd(20));
1391 env(check::cash(bob, chkIdU, usd(20)));
1393 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1397 env(check::cash(bob, chkIdExp, XRP(10)), Ter(
tecEXPIRED));
1401 env(check::cancel(zoe, chkIdExp));
1406 env(pay(bob, alice, usd(20)));
1408 env.require(Balance(alice, usd(20)));
1409 env.require(Balance(bob, usd(0)));
1412 env(fset(gw, asfGlobalFreeze));
1417 env(check::cash(bob, chkIdFroz1, check::DeliverMin(usd(0.5))), Ter(
tecPATH_PARTIAL));
1420 env(check::cash(gw, chkIdFroz4ToIssuer, usd(1)), Ter(
tecPATH_PARTIAL));
1422 env(check::cash(gw, chkIdFroz4ToIssuer, check::DeliverMin(usd(0.5))),
1426 env(check::cash(alice, chkIdFroz4Issuer, usd(1)), Ter(
tecFROZEN));
1428 env(check::cash(alice, chkIdFroz4Issuer, check::DeliverMin(usd(0.5))), Ter(
tecFROZEN));
1431 env(fclear(gw, asfGlobalFreeze));
1435 env(check::cash(bob, chkIdFroz1, usd(1)));
1437 env.require(Balance(alice, usd(19)));
1438 env.require(Balance(bob, usd(1)));
1440 env(check::cash(gw, chkIdFroz4ToIssuer, usd(1)));
1444 env(trust(gw, alice[
"USD"](0), tfSetFreeze));
1448 env(check::cash(bob, chkIdFroz2, check::DeliverMin(usd(1))), Ter(
tecPATH_PARTIAL));
1452 env(trust(gw, alice[
"USD"](0), tfClearFreeze));
1454 env(check::cash(bob, chkIdFroz2, usd(2)));
1456 env.require(Balance(alice, usd(16)));
1457 env.require(Balance(bob, usd(3)));
1460 env(trust(gw, bob[
"USD"](0), tfSetFreeze));
1462 env(check::cash(bob, chkIdFroz3, usd(3)), Ter(
tecFROZEN));
1464 env(check::cash(bob, chkIdFroz3, check::DeliverMin(usd(1))), Ter(
tecFROZEN));
1468 env(trust(gw, bob[
"USD"](0), tfClearFreeze));
1470 env(check::cash(bob, chkIdFroz3, check::DeliverMin(usd(1))));
1472 env.require(Balance(alice, usd(13)));
1473 env.require(Balance(bob, usd(6)));
1477 env(trust(bob, usd(20), tfSetFreeze));
1479 env(check::cash(bob, chkIdFroz4, usd(4)), Ter(
terNO_LINE));
1481 env(check::cash(bob, chkIdFroz4, check::DeliverMin(usd(1))), Ter(
terNO_LINE));
1485 env(trust(bob, usd(20), tfClearFreeze));
1487 env(check::cash(bob, chkIdFroz4, usd(4)));
1489 env.require(Balance(alice, usd(9)));
1490 env.require(Balance(bob, usd(10)));
1495 env(fset(bob, asfRequireDest));
1499 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(usd(0.5))),
1504 env(check::cash(bob, chkIdHasDest2, usd(2)));
1506 env.require(Balance(alice, usd(7)));
1507 env.require(Balance(bob, usd(12)));
1511 env(fclear(bob, asfRequireDest));
1513 env(check::cash(bob, chkIdNoDest1, usd(1)));
1515 env.require(Balance(alice, usd(6)));
1516 env.require(Balance(bob, usd(13)));
1532 IOU
const usd{gw[
"USD"]};
1535 Env env{*
this, features};
1537 env.fund(XRP(1000), gw, alice, bob, zoe);
1543 env(check::create(alice, bob, usd(10)));
1547 env(check::create(alice, bob, XRP(10)));
1551 env(check::create(alice, bob, usd(10)));
1555 using namespace std::chrono_literals;
1557 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 600s));
1561 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 600s));
1565 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 600s));
1570 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 1s));
1574 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 1s));
1578 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 1s));
1583 env(check::create(alice, bob, usd(10)));
1587 env(check::create(alice, bob, XRP(10)));
1590 BEAST_EXPECT(ownerCount(env, alice) == 11);
1593 env(check::cancel(alice, chkId1));
1596 BEAST_EXPECT(ownerCount(env, alice) == 10);
1598 env(check::cancel(bob, chkId2));
1601 BEAST_EXPECT(ownerCount(env, alice) == 9);
1606 BEAST_EXPECT(ownerCount(env, alice) == 9);
1609 env(check::cancel(alice, chkIdNotExp1));
1612 BEAST_EXPECT(ownerCount(env, alice) == 8);
1614 env(check::cancel(bob, chkIdNotExp2));
1617 BEAST_EXPECT(ownerCount(env, alice) == 7);
1622 BEAST_EXPECT(ownerCount(env, alice) == 7);
1625 env(check::cancel(alice, chkIdExp1));
1628 BEAST_EXPECT(ownerCount(env, alice) == 6);
1630 env(check::cancel(bob, chkIdExp2));
1633 BEAST_EXPECT(ownerCount(env, alice) == 5);
1635 env(check::cancel(zoe, chkIdExp3));
1638 BEAST_EXPECT(ownerCount(env, alice) == 4);
1642 env(regkey(alice, alie));
1647 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), Sig(alie));
1651 env(check::cancel(alice, chkIdReg), Sig(alie));
1654 BEAST_EXPECT(ownerCount(env, alice) == 4);
1657 XRPAmount const baseFeeDrops{env.current()->fees().base};
1658 env(check::cancel(alice, chkIdMSig), Msig(bogie, demon), Fee(3 * baseFeeDrops));
1661 BEAST_EXPECT(ownerCount(env, alice) == 3);
1664 env(check::cancel(alice, chkId3), Sig(alice));
1667 BEAST_EXPECT(ownerCount(env, alice) == 2);
1669 env(check::cancel(bob, chkIdNotExp3));
1672 BEAST_EXPECT(ownerCount(env, alice) == 1);
1751 IOU
const usd{gw[
"USD"]};
1753 Env env{*
this, features};
1754 env.fund(XRP(1000), gw, alice, bob);
1761 env(ticket::create(alice, 10));
1765 env(ticket::create(bob, 10));
1769 env.require(Owners(alice, 10));
1770 env.require(Owners(bob, 10));
1773 env(trust(alice, usd(1000)), ticket::Use(aliceTicketSeq++));
1774 env(trust(bob, usd(1000)), ticket::Use(bobTicketSeq++));
1776 env.require(Owners(alice, 10));
1777 env.require(Owners(bob, 10));
1779 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1780 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1782 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1783 BEAST_EXPECT(env.seq(bob) == bobSeq);
1785 env(pay(gw, alice, usd(900)));
1791 env(check::create(alice, bob, XRP(200)), ticket::Use(aliceTicketSeq++));
1794 env(check::create(alice, bob, XRP(300)), ticket::Use(aliceTicketSeq++));
1797 env(check::create(alice, bob, usd(200)), ticket::Use(aliceTicketSeq++));
1800 env(check::create(alice, bob, usd(300)), ticket::Use(aliceTicketSeq++));
1804 env.require(Owners(alice, 10));
1805 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1807 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1809 env.require(Owners(bob, 10));
1810 BEAST_EXPECT(env.seq(bob) == bobSeq);
1813 env(check::cancel(bob, chkIdXrp1), ticket::Use(bobTicketSeq++));
1814 env(check::cancel(bob, chkIdUsd2), ticket::Use(bobTicketSeq++));
1817 env.require(Owners(alice, 8));
1818 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1820 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1822 env.require(Owners(bob, 8));
1823 BEAST_EXPECT(env.seq(bob) == bobSeq);
1826 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::Use(bobTicketSeq++));
1827 env(check::cash(bob, chkIdUsd1, usd(200)), ticket::Use(bobTicketSeq++));
1830 env.require(Owners(alice, 6));
1831 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1833 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1834 env.require(Balance(alice, usd(700)));
1836 env.require(Owners(bob, 6));
1837 BEAST_EXPECT(env.seq(bob) == bobSeq);
1838 env.require(Balance(bob, usd(200)));
1851 Env env{*
this, features};
1865 ownerCount(env, acct) == owners,
"Owner count mismatch", __FILE__, line);
1886 AccountOwns alice{.suite = *
this, .env = env, .acct =
"alice", .owners = 0};
1887 AccountOwns bob{.suite = *
this, .env = env, .acct =
"bob", .owners = 0};
1890 env.fund(XRP(5000), noripple(alice, bob));
1896 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
1901 env.fund(XRP(5000), noripple(gw1));
1904 IOU
const cK8 = gw1[
"CK8"];
1905 gw1.verifyOwners(__LINE__);
1912 env.fund(XRP(200), yui);
1916 env(check::create(gw1, yui, cK8(99)));
1921 alice.verifyOwners(__LINE__);
1925 env(pay(env.master, yui, XRP(51)));
1927 env(check::cash(yui, chkId, cK8(99)));
1930 BEAST_EXPECT(ownerCount(env, yui) == 1);
1934 gw1.verifyOwners(__LINE__);
1949 auto cmpTrustLines = [
this, &env](
1952 IOU
const& offerIou,
1953 IOU
const& checkIou) {
1954 auto const offerLine = env.le(
keylet::trustLine(acct1, acct2, offerIou.currency));
1955 auto const checkLine = env.le(
keylet::trustLine(acct1, acct2, checkIou.currency));
1956 if (offerLine ==
nullptr || checkLine ==
nullptr)
1958 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
1964 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
1968 auto cmpReqAmount = [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
1969 STAmount const offerAmount = offerLine->at(sfield);
1970 STAmount const checkAmount = checkLine->at(sfield);
1973 if (!BEAST_EXPECT(!offerAmount.
native() && !checkAmount.
native()))
1981 cmpReqAmount(sfBalance);
1982 cmpReqAmount(sfLowLimit);
1983 cmpReqAmount(sfHighLimit);
1987 auto cmpOptField = [
this, offerLine, checkLine](
auto const& sfield) {
1990 offerLine->isFieldPresent(sfield) == checkLine->isFieldPresent(sfield)))
1995 if (!offerLine->isFieldPresent(sfield))
2000 BEAST_EXPECT(offerLine->at(sfield) == checkLine->at(sfield));
2002 cmpOptField(sfLowNode);
2003 cmpOptField(sfLowQualityIn);
2004 cmpOptField(sfLowQualityOut);
2006 cmpOptField(sfHighNode);
2007 cmpOptField(sfHighQualityIn);
2008 cmpOptField(sfHighQualityOut);
2016 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2018 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2019 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2020 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2023 IOU
const oF1 = gw1[
"OF1"];
2024 env(offer(gw1, XRP(98), oF1(98)));
2027 env(offer(alice, oF1(98), XRP(98)));
2034 gw1.verifyOwners(__LINE__);
2037 alice.verifyOwners(__LINE__);
2040 IOU
const cK1 = gw1[
"CK1"];
2042 env(check::create(gw1, alice, cK1(98)));
2045 env(check::cash(alice, chkId, cK1(98)));
2053 gw1.verifyOwners(__LINE__);
2056 alice.verifyOwners(__LINE__);
2058 cmpTrustLines(gw1, alice, oF1, cK1);
2069 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2070 IOU
const oF1 = gw1[
"OF1"];
2071 env(offer(alice, XRP(97), oF1(97)));
2074 env(offer(bob, oF1(97), XRP(97)));
2079 env.require(Balance(alice, oF1(1)));
2080 env.require(Balance(bob, oF1(97)));
2083 gw1.verifyOwners(__LINE__);
2084 alice.verifyOwners(__LINE__);
2085 bob.verifyOwners(__LINE__);
2093 IOU
const cK1 = gw1[
"CK1"];
2095 env(check::create(alice, bob, cK1(97)));
2098 env(check::cash(bob, chkId, cK1(97)), Ter(
terNO_RIPPLE));
2105 env(check::cancel(alice, chkId));
2109 gw1.verifyOwners(__LINE__);
2110 alice.verifyOwners(__LINE__);
2111 bob.verifyOwners(__LINE__);
2118 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2119 env(fset(gw1, asfDefaultRipple));
2123 IOU
const oF2 = gw1[
"OF2"];
2124 env(offer(gw1, XRP(96), oF2(96)));
2127 env(offer(alice, oF2(96), XRP(96)));
2134 gw1.verifyOwners(__LINE__);
2137 alice.verifyOwners(__LINE__);
2140 IOU
const cK2 = gw1[
"CK2"];
2142 env(check::create(gw1, alice, cK2(96)));
2145 env(check::cash(alice, chkId, cK2(96)));
2153 gw1.verifyOwners(__LINE__);
2156 alice.verifyOwners(__LINE__);
2158 cmpTrustLines(gw1, alice, oF2, cK2);
2166 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2167 IOU
const oF2 = gw1[
"OF2"];
2168 env(offer(alice, XRP(95), oF2(95)));
2171 env(offer(bob, oF2(95), XRP(95)));
2176 gw1.verifyOwners(__LINE__);
2177 alice.verifyOwners(__LINE__);
2178 bob.verifyOwners(__LINE__);
2181 IOU
const cK2 = gw1[
"CK2"];
2183 env(check::create(alice, bob, cK2(95)));
2186 env(check::cash(bob, chkId, cK2(95)));
2192 gw1.verifyOwners(__LINE__);
2193 alice.verifyOwners(__LINE__);
2194 bob.verifyOwners(__LINE__);
2196 cmpTrustLines(alice, bob, oF2, cK2);
2207 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2208 env(fset(gw1, asfDepositAuth));
2209 env(fset(alice, asfDepositAuth));
2210 env(fset(bob, asfDepositAuth));
2214 IOU
const oF3 = gw1[
"OF3"];
2215 env(offer(gw1, XRP(94), oF3(94)));
2218 env(offer(alice, oF3(94), XRP(94)));
2225 gw1.verifyOwners(__LINE__);
2228 alice.verifyOwners(__LINE__);
2231 IOU
const cK3 = gw1[
"CK3"];
2233 env(check::create(gw1, alice, cK3(94)));
2236 env(check::cash(alice, chkId, cK3(94)));
2244 gw1.verifyOwners(__LINE__);
2247 alice.verifyOwners(__LINE__);
2249 cmpTrustLines(gw1, alice, oF3, cK3);
2257 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2258 IOU
const oF3 = gw1[
"OF3"];
2259 env(offer(alice, XRP(93), oF3(93)));
2262 env(offer(bob, oF3(93), XRP(93)));
2267 gw1.verifyOwners(__LINE__);
2268 alice.verifyOwners(__LINE__);
2269 bob.verifyOwners(__LINE__);
2272 IOU
const cK3 = gw1[
"CK3"];
2274 env(check::create(alice, bob, cK3(93)));
2277 env(check::cash(bob, chkId, cK3(93)));
2283 gw1.verifyOwners(__LINE__);
2284 alice.verifyOwners(__LINE__);
2285 bob.verifyOwners(__LINE__);
2287 cmpTrustLines(alice, bob, oF3, cK3);
2294 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2295 env(fset(gw1, asfGlobalFreeze));
2299 IOU
const oF4 = gw1[
"OF4"];
2300 env(offer(gw1, XRP(92), oF4(92)), Ter(
tecFROZEN));
2303 env(offer(alice, oF4(92), XRP(92)), Ter(
tecFROZEN));
2307 gw1.verifyOwners(__LINE__);
2308 alice.verifyOwners(__LINE__);
2309 bob.verifyOwners(__LINE__);
2312 IOU
const cK4 = gw1[
"CK4"];
2314 env(check::create(gw1, alice, cK4(92)), Ter(
tecFROZEN));
2317 env(check::cash(alice, chkId, cK4(92)), Ter(
tecNO_ENTRY));
2321 gw1.verifyOwners(__LINE__);
2322 alice.verifyOwners(__LINE__);
2323 bob.verifyOwners(__LINE__);
2336 AccountOwns
const gw1{.suite = *
this, .env = env, .acct =
"gw1", .owners = 0};
2337 IOU
const oF4 = gw1[
"OF4"];
2338 env(offer(alice, XRP(91), oF4(91)), Ter(
tecFROZEN));
2341 env(offer(bob, oF4(91), XRP(91)), Ter(
tecFROZEN));
2345 gw1.verifyOwners(__LINE__);
2346 alice.verifyOwners(__LINE__);
2347 bob.verifyOwners(__LINE__);
2350 IOU
const cK4 = gw1[
"CK4"];
2352 env(check::create(alice, bob, cK4(91)), Ter(
tecFROZEN));
2355 env(check::cash(bob, chkId, cK4(91)), Ter(
tecNO_ENTRY));
2359 gw1.verifyOwners(__LINE__);
2360 alice.verifyOwners(__LINE__);
2361 bob.verifyOwners(__LINE__);
2375 AccountOwns gw2{.suite = *
this, .env = env, .acct =
"gw2", .owners = 0};
2376 env.fund(XRP(5000), gw2);
2381 env(fset(gw2, asfRequireAuth));
2385 IOU
const oF5 = gw2[
"OF5"];
2387 env(offer(gw2, XRP(92), oF5(92)));
2391 env(offer(alice, oF5(92), XRP(92)), Ter(
tecNO_LINE));
2396 gw2.verifyOwners(__LINE__);
2397 alice.verifyOwners(__LINE__);
2398 bob.verifyOwners(__LINE__);
2401 env(offerCancel(gw2, gw2OfferSeq));
2404 gw2.verifyOwners(__LINE__);
2407 IOU
const cK5 = gw2[
"CK5"];
2409 env(check::create(gw2, alice, cK5(92)));
2413 env(check::cash(alice, chkId, cK5(92)), Ter(
tecNO_AUTH));
2418 gw2.verifyOwners(__LINE__);
2419 alice.verifyOwners(__LINE__);
2420 bob.verifyOwners(__LINE__);
2428 env(check::cancel(gw2, chkId));
2431 gw2.verifyOwners(__LINE__);
2439 AccountOwns
const gw2{.suite = *
this, .env = env, .acct =
"gw2", .owners = 0};
2440 IOU
const oF5 = gw2[
"OF5"];
2443 env(offer(bob, oF5(91), XRP(91)), Ter(
tecNO_LINE));
2447 gw2.verifyOwners(__LINE__);
2448 alice.verifyOwners(__LINE__);
2449 bob.verifyOwners(__LINE__);
2452 IOU
const cK5 = gw2[
"CK5"];
2454 env(check::create(alice, bob, cK5(91)));
2461 env(check::cancel(alice, chkId));
2465 gw2.verifyOwners(__LINE__);
2466 alice.verifyOwners(__LINE__);
2467 bob.verifyOwners(__LINE__);