276 Account const gwF{
"gatewayFrozen"};
280 Env env{*
this, features};
282 STAmount const startBalance{XRP(1'000).value()};
283 env.fund(startBalance, gw1, gwF, alice, bob);
285 auto usdm = MPTTester({.env = env, .issuer = gw1, .flags = kMptDexFlags | tfMPTCanLock});
286 MPT
const usd = usdm;
289 env(check::create(alice, bob, usd(50)), Fee(drops(-10)), Ter(
temBAD_FEE));
293 env(check::create(alice, bob, usd(50)), Txflags(tfImmediateOrCancel), Ter(
temINVALID_FLAG));
297 env(check::create(alice, alice, XRP(10)), Ter(
temREDUNDANT));
301 env(check::create(alice, bob, drops(-1)), Ter(
temBAD_AMOUNT));
304 env(check::create(alice, bob, drops(0)), Ter(
temBAD_AMOUNT));
307 env(check::create(alice, bob, drops(1)));
316 env(check::create(alice, bob, usd(1)));
325 env(check::create(alice, bob, usd(50)),
332 env(check::create(alice, bogie, usd(50)), Ter(
tecNO_DST));
336 env(fset(bob, asfRequireDest));
342 env(check::create(alice, bob, usd(50)), DestTag(11));
345 env(fclear(bob, asfRequireDest));
351 MPTTester({.env = env, .issuer = gwF, .flags = kMptDexFlags | tfMPTCanLock});
352 MPT
const usf = usfm;
353 usfm.set({.flags = tfMPTLock});
355 env(check::create(alice, bob, usf(50)), Ter(
tecLOCKED));
358 usfm.set({.flags = tfMPTUnlock});
360 env(check::create(alice, bob, usf(50)));
366 usdm.authorizeHolders({alice, bob});
367 env(pay(gw1, alice, usd(25)));
368 env(pay(gw1, bob, usd(25)));
371 usdm.set({.holder = alice, .flags = tfMPTLock});
376 env(check::create(alice, bob, usd(50)), Ter(
tecLOCKED));
383 env(check::create(bob, alice, usd(50)), Ter(
tecLOCKED));
387 env(check::create(gw1, alice, usd(50)), Ter(
tecLOCKED));
389 env(pay(gw1, alice, usd(1)));
393 usdm.set({.holder = alice, .flags = tfMPTUnlock});
394 env(check::create(alice, bob, usd(50)));
396 env(check::create(bob, alice, usd(50)));
398 env(check::create(gw1, alice, usd(50)));
403 env(check::create(alice, bob, usd(50)), Expiration(env.now()), Ter(
tecEXPIRED));
406 using namespace std::chrono_literals;
407 env(check::create(alice, bob, usd(50)), Expiration(env.now() + 1s));
412 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
414 env(check::create(cheri, bob, usd(50)),
415 Fee(drops(env.current()->fees().base)),
419 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
422 env(check::create(cheri, bob, usd(50)));
439 Env env{*
this, features};
441 env.fund(XRP(1'000), gw, alice, bob);
444 MPTTester({.env = env, .issuer = gw, .holders = {alice}, .maxAmt = 105});
447 uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
448 env(check::create(alice, bob, usd(100)));
456 env(pay(gw, alice, usd(95)));
462 env(pay(gw, alice, usd(5)));
472 env(check::cash(bob, chkId1, usd(100)));
474 env.require(Balance(alice, usd(0)));
475 env.require(Balance(bob, usd(100)));
478 BEAST_EXPECT(ownerCount(env, alice) == 1);
479 BEAST_EXPECT(ownerCount(env, bob) == 1);
482 env(check::cash(bob, chkId1, usd(100)), Ter(
tecNO_ENTRY));
486 env(pay(bob, alice, usd(70)));
489 uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
490 env(check::create(alice, bob, usd(70)));
497 env(check::cash(bob, chkId2, usd(50)));
499 env.require(Balance(alice, usd(20)));
500 env.require(Balance(bob, usd(80)));
503 BEAST_EXPECT(ownerCount(env, alice) == 1);
504 BEAST_EXPECT(ownerCount(env, bob) == 1);
508 uint256 const chkId3{getCheckIndex(alice, env.seq(alice))};
509 env(check::create(alice, bob, usd(20)));
511 uint256 const chkId4{getCheckIndex(alice, env.seq(alice))};
512 env(check::create(alice, bob, usd(20)));
518 env(check::cash(bob, chkId4, usd(20)));
520 env.require(Balance(alice, usd(0)));
521 env.require(Balance(bob, usd(100)));
524 BEAST_EXPECT(ownerCount(env, alice) == 2);
525 BEAST_EXPECT(ownerCount(env, bob) == 1);
531 env.require(Balance(alice, usd(0)));
532 env.require(Balance(bob, usd(100)));
535 BEAST_EXPECT(ownerCount(env, alice) == 2);
536 BEAST_EXPECT(ownerCount(env, bob) == 1);
549 uint256 const chkId20{getCheckIndex(gw, env.seq(gw))};
550 env(check::create(gw, bob, usd(200)));
556 env.require(Balance(bob, usd(100)));
560 env(pay(bob, gw, usd(100)));
561 env(check::cancel(bob, chkId20));
565 env(check::cancel(bob, chkId3));
567 env.require(Balance(alice, usd(0)));
568 env.require(Balance(bob, usd(0)));
571 BEAST_EXPECT(ownerCount(env, alice) == 1);
572 BEAST_EXPECT(ownerCount(env, bob) == 1);
576 Env env{*
this, features};
578 env.fund(XRP(1'000), gw, alice, bob);
581 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 20});
583 env(pay(gw, alice, usd(8)));
587 uint256 const chkId9{getCheckIndex(alice, env.seq(alice))};
588 env(check::create(alice, bob, usd(9)));
590 uint256 const chkId8{getCheckIndex(alice, env.seq(alice))};
591 env(check::create(alice, bob, usd(8)));
593 uint256 const chkId7{getCheckIndex(alice, env.seq(alice))};
594 env(check::create(alice, bob, usd(7)));
596 uint256 const chkId6{getCheckIndex(alice, env.seq(alice))};
597 env(check::create(alice, bob, usd(6)));
602 env(check::cash(bob, chkId9, check::DeliverMin(usd(9))), Ter(
tecPATH_PARTIAL));
606 env(check::cash(bob, chkId9, check::DeliverMin(usd(7))));
608 env.require(Balance(alice, usd(0)));
609 env.require(Balance(bob, usd(8)));
612 BEAST_EXPECT(ownerCount(env, alice) == 4);
613 BEAST_EXPECT(ownerCount(env, bob) == 1);
616 env(pay(bob, alice, usd(7)));
621 env(check::cash(bob, chkId7, check::DeliverMin(usd(7))));
623 env.require(Balance(alice, usd(0)));
624 env.require(Balance(bob, usd(8)));
627 BEAST_EXPECT(ownerCount(env, alice) == 3);
628 BEAST_EXPECT(ownerCount(env, bob) == 1);
631 env(pay(bob, alice, usd(8)));
636 env(check::cash(bob, chkId6, check::DeliverMin(usd(4))));
638 env.require(Balance(alice, usd(2)));
639 env.require(Balance(bob, usd(6)));
642 BEAST_EXPECT(ownerCount(env, alice) == 2);
643 BEAST_EXPECT(ownerCount(env, bob) == 1);
647 env(check::cash(bob, chkId8, check::DeliverMin(usd(2))));
649 env.require(Balance(alice, usd(0)));
650 env.require(Balance(bob, usd(8)));
653 BEAST_EXPECT(ownerCount(env, alice) == 1);
654 BEAST_EXPECT(ownerCount(env, bob) == 1);
658 Env env(*
this, features);
660 env.fund(XRP(1000), gw, alice, bob);
661 auto usdm = MPTTester(
665 .flags = kMptDexFlags | tfMPTRequireAuth,
667 MPT
const usd = usdm;
668 usdm.authorize({.holder = alice});
670 env(pay(gw, alice, usd(8)));
675 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
676 env(check::create(alice, bob, usd(7)));
679 env(check::cash(bob, chkId, usd(7)), Ter(
tecNO_AUTH));
684 usdm.authorize({.account = bob});
687 env(check::cash(bob, chkId, usd(7)), Ter(
tecNO_AUTH));
691 usdm.authorize({.holder = bob});
694 env(check::cash(bob, chkId, check::DeliverMin(usd(4))));
697 env.require(Balance(alice, usd(8) - bobGot));
698 env.require(Balance(bob, bobGot));
702 BEAST_EXPECT(ownerCount(env, alice) == 1);
703 BEAST_EXPECT(ownerCount(env, bob) == 1);
707 Env env{*
this, features};
709 env.fund(XRP(1'000), gw, alice, bob);
712 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 20});
715 uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
716 env(check::create(alice, bob, usd(1)));
719 uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
720 env(check::create(alice, bob, usd(2)));
723 env(pay(gw, alice, usd(8)));
728 env(regkey(bob, bobby));
733 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), Sig(bobby));
736 int const signersCount = 1;
737 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
740 env(check::cash(bob, chkId1, (usd(1))), Sig(bobby));
742 env.require(Balance(alice, usd(7)));
743 env.require(Balance(bob, usd(1)));
746 BEAST_EXPECT(ownerCount(env, alice) == 2);
747 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
750 XRPAmount const baseFeeDrops{env.current()->fees().base};
751 env(check::cash(bob, chkId2, (usd(2))), Msig(bogie, demon), Fee(3 * baseFeeDrops));
753 env.require(Balance(alice, usd(5)));
754 env.require(Balance(bob, usd(3)));
757 BEAST_EXPECT(ownerCount(env, alice) == 1);
758 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
850 Env env(*
this, features);
852 env.fund(XRP(1000), gw, alice, bob, zoe);
854 auto usdm = MPTTester(
858 .flags = kMptDexFlags | tfMPTCanLock,
860 MPT
const usd = usdm;
862 env(pay(gw, alice, usd(20)));
865 usdm.authorize({.account = bob});
869 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
870 env(check::cash(bob, chkId, usd(20)), Ter(
tecNO_ENTRY));
875 uint256 const chkIdU{getCheckIndex(alice, env.seq(alice))};
876 env(check::create(alice, bob, usd(20)));
879 uint256 const chkIdX{getCheckIndex(alice, env.seq(alice))};
880 env(check::create(alice, bob, XRP(10)));
883 using namespace std::chrono_literals;
884 uint256 const chkIdExp{getCheckIndex(alice, env.seq(alice))};
885 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 1s));
888 uint256 const chkIdFroz1{getCheckIndex(alice, env.seq(alice))};
889 env(check::create(alice, bob, usd(1)));
892 uint256 const chkIdFroz2{getCheckIndex(alice, env.seq(alice))};
893 env(check::create(alice, bob, usd(2)));
896 uint256 const chkIdFroz3{getCheckIndex(alice, env.seq(alice))};
897 env(check::create(alice, bob, usd(3)));
900 uint256 const chkIdNoDest1{getCheckIndex(alice, env.seq(alice))};
901 env(check::create(alice, bob, usd(1)));
904 uint256 const chkIdHasDest2{getCheckIndex(alice, env.seq(alice))};
905 env(check::create(alice, bob, usd(2)), DestTag(7));
909 auto failingCases = [&env, &gw, &alice, &bob](
912 env(check::cash(bob, chkId, amount), Fee(drops(-10)), Ter(
temBAD_FEE));
916 env(check::cash(bob, chkId, amount),
917 Txflags(tfImmediateOrCancel),
942 env(check::cash(bob, chkId, amount.zeroed()), Ter(
temBAD_AMOUNT));
947 if (!amount.native())
964 MPT
const eur = MPTTester({.env = env, .issuer = gw});
965 STAmount const badAmount{eur, amount};
966 env(check::cash(bob, chkId, badAmount), Ter(
temMALFORMED));
978 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)), Ter(
tecPATH_PARTIAL));
982 failingCases(chkIdX, XRP(10));
983 failingCases(chkIdU, usd(20));
986 env(check::cash(bob, chkIdU, usd(20)));
988 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
992 env(check::cash(bob, chkIdExp, XRP(10)), Ter(
tecEXPIRED));
996 env(check::cancel(zoe, chkIdExp));
1001 env(pay(bob, alice, usd(20)));
1003 env.require(Balance(alice, usd(20)));
1004 env.require(Balance(bob, usd(0)));
1007 usdm.set({.flags = tfMPTLock});
1012 env(check::cash(bob, chkIdFroz1, check::DeliverMin(usd(1))), Ter(
tecPATH_PARTIAL));
1015 usdm.set({.flags = tfMPTUnlock});
1018 env(check::cash(bob, chkIdFroz1, usd(1)));
1020 env.require(Balance(alice, usd(19)));
1021 env.require(Balance(bob, usd(1)));
1024 usdm.set({.holder = alice, .flags = tfMPTLock});
1027 env(check::cash(bob, chkIdFroz2, check::DeliverMin(usd(1))), Ter(
tecPATH_PARTIAL));
1031 usdm.set({.holder = alice, .flags = tfMPTUnlock});
1032 env(check::cash(bob, chkIdFroz2, usd(2)));
1034 env.require(Balance(alice, usd(17)));
1035 env.require(Balance(bob, usd(3)));
1038 usdm.set({.holder = bob, .flags = tfMPTLock});
1039 env(check::cash(bob, chkIdFroz3, usd(3)), Ter(
tecLOCKED));
1041 env(check::cash(bob, chkIdFroz3, check::DeliverMin(usd(1))), Ter(
tecLOCKED));
1045 usdm.set({.holder = bob, .flags = tfMPTUnlock});
1047 env(check::cash(bob, chkIdFroz3, check::DeliverMin(usd(1))));
1049 env.require(Balance(alice, usd(14)));
1050 env.require(Balance(bob, usd(6)));
1055 env(fset(bob, asfRequireDest));
1059 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(usd(1))), Ter(
tecDST_TAG_NEEDED));
1063 env(check::cash(bob, chkIdHasDest2, usd(2)));
1066 env.require(Balance(alice, usd(12)));
1067 env.require(Balance(bob, usd(8)));
1071 env(fclear(bob, asfRequireDest));
1073 env(check::cash(bob, chkIdNoDest1, usd(1)));
1075 env.require(Balance(alice, usd(11)));
1076 env.require(Balance(bob, usd(9)));
1082 BEAST_EXPECT(env.balance(gw, usdm) == usdm(-maxAmt));
1084 uint256 const chkId{getCheckIndex(gw, env.seq(gw))};
1085 env(check::create(gw, bob, usdm(10)));
1093 env(pay(alice, gw, usdm(9)));
1116 Env env{*
this, features};
1118 env.fund(XRP(1'000), gw, alice, bob, zoe);
1120 MPT
const usd = MPTTester({.env = env, .issuer = gw});
1124 uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
1125 env(check::create(alice, bob, usd(10)));
1128 uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
1129 env(check::create(alice, bob, XRP(10)));
1132 uint256 const chkId3{getCheckIndex(alice, env.seq(alice))};
1133 env(check::create(alice, bob, usd(10)));
1137 using namespace std::chrono_literals;
1138 uint256 const chkIdNotExp1{getCheckIndex(alice, env.seq(alice))};
1139 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 600s));
1142 uint256 const chkIdNotExp2{getCheckIndex(alice, env.seq(alice))};
1143 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 600s));
1146 uint256 const chkIdNotExp3{getCheckIndex(alice, env.seq(alice))};
1147 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 600s));
1151 uint256 const chkIdExp1{getCheckIndex(alice, env.seq(alice))};
1152 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 1s));
1155 uint256 const chkIdExp2{getCheckIndex(alice, env.seq(alice))};
1156 env(check::create(alice, bob, XRP(10)), Expiration(env.now() + 1s));
1159 uint256 const chkIdExp3{getCheckIndex(alice, env.seq(alice))};
1160 env(check::create(alice, bob, usd(10)), Expiration(env.now() + 1s));
1164 uint256 const chkIdReg{getCheckIndex(alice, env.seq(alice))};
1165 env(check::create(alice, bob, usd(10)));
1168 uint256 const chkIdMSig{getCheckIndex(alice, env.seq(alice))};
1169 env(check::create(alice, bob, XRP(10)));
1172 BEAST_EXPECT(ownerCount(env, alice) == 11);
1175 env(check::cancel(alice, chkId1));
1178 BEAST_EXPECT(ownerCount(env, alice) == 10);
1180 env(check::cancel(bob, chkId2));
1183 BEAST_EXPECT(ownerCount(env, alice) == 9);
1188 BEAST_EXPECT(ownerCount(env, alice) == 9);
1191 env(check::cancel(alice, chkIdNotExp1));
1194 BEAST_EXPECT(ownerCount(env, alice) == 8);
1196 env(check::cancel(bob, chkIdNotExp2));
1199 BEAST_EXPECT(ownerCount(env, alice) == 7);
1204 BEAST_EXPECT(ownerCount(env, alice) == 7);
1207 env(check::cancel(alice, chkIdExp1));
1210 BEAST_EXPECT(ownerCount(env, alice) == 6);
1212 env(check::cancel(bob, chkIdExp2));
1215 BEAST_EXPECT(ownerCount(env, alice) == 5);
1217 env(check::cancel(zoe, chkIdExp3));
1220 BEAST_EXPECT(ownerCount(env, alice) == 4);
1224 env(regkey(alice, alie));
1229 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), Sig(alie));
1232 int const signersCount{1};
1235 env(check::cancel(alice, chkIdReg), Sig(alie));
1238 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1241 XRPAmount const baseFeeDrops{env.current()->fees().base};
1242 env(check::cancel(alice, chkIdMSig), Msig(bogie, demon), Fee(3 * baseFeeDrops));
1245 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1248 env(check::cancel(alice, chkId3), Sig(alice));
1251 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1253 env(check::cancel(bob, chkIdNotExp3));
1256 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1271 Env env{*
this, features};
1272 env.fund(XRP(1'000), gw, alice, bob);
1276 MPTTester({.env = env, .issuer = gw, .holders = {alice, bob}, .maxAmt = 1'000});
1282 env(ticket::create(alice, 10));
1286 env(ticket::create(bob, 10));
1291 env.require(Owners(alice, 11));
1292 env.require(Owners(bob, 11));
1294 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1295 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1297 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1298 BEAST_EXPECT(env.seq(bob) == bobSeq);
1300 env(pay(gw, alice, usd(900)));
1305 uint256 const chkIdXrp1{getCheckIndex(alice, aliceTicketSeq)};
1306 env(check::create(alice, bob, XRP(200)), ticket::Use(aliceTicketSeq++));
1308 uint256 const chkIdXrp2{getCheckIndex(alice, aliceTicketSeq)};
1309 env(check::create(alice, bob, XRP(300)), ticket::Use(aliceTicketSeq++));
1311 uint256 const chkIdUsd1{getCheckIndex(alice, aliceTicketSeq)};
1312 env(check::create(alice, bob, usd(200)), ticket::Use(aliceTicketSeq++));
1314 uint256 const chkIdUsd2{getCheckIndex(alice, aliceTicketSeq)};
1315 env(check::create(alice, bob, usd(300)), ticket::Use(aliceTicketSeq++));
1319 env.require(Owners(alice, 11));
1320 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1322 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1324 env.require(Owners(bob, 11));
1325 BEAST_EXPECT(env.seq(bob) == bobSeq);
1328 env(check::cancel(bob, chkIdXrp1), ticket::Use(bobTicketSeq++));
1329 env(check::cancel(bob, chkIdUsd2), ticket::Use(bobTicketSeq++));
1332 env.require(Owners(alice, 9));
1333 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1335 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1337 env.require(Owners(bob, 9));
1338 BEAST_EXPECT(env.seq(bob) == bobSeq);
1341 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::Use(bobTicketSeq++));
1342 env(check::cash(bob, chkIdUsd1, usd(200)), ticket::Use(bobTicketSeq++));
1345 auto const baseFee = env.current()->fees().base;
1346 env.require(Owners(alice, 7));
1347 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1349 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1350 env.require(Balance(alice, usd(700)));
1351 env.require(Balance(alice, XRP(700) - 6 * baseFee));
1352 env.require(Owners(bob, 7));
1353 BEAST_EXPECT(env.seq(bob) == bobSeq);
1354 env.require(Balance(bob, usd(200)));
1355 env.require(Balance(bob, XRP(1'300) - 6 * baseFee));
1367 Env env{*
this, features};
1372 using iterator = hash_map<std::string, MPTTester>::iterator;
1378 bool const isIssuer;
1396 std::cout << acct.name() <<
" " << ownerCount(env, acct) <<
" " << owners
1400 ownerCount(env, acct) == owners,
"Owner count mismatch", __FILE__, line);
1422 if (
auto const& it = mpts.
find(s); it != mpts.
end())
1423 return it->second[s];
1424 auto flags = kMptDexFlags | tfMPTCanLock;
1426 flags |= tfMPTRequireAuth;
1428 mpts.
emplace(s, MPTTester({.env = env, .issuer = acct, .flags = flags}));
1432 return it->second[s];
1436 getIt(MPT
const& mpt)
1440 auto it = mpts.
find(mpt.name);
1441 if (it == mpts.
end())
1449 auto it = getIt(mpt);
1450 it->second.set({.flags = flag});
1454 authorize(MPT
const& mpt, AccountOwns&
id)
1456 auto it = getIt(mpt);
1457 it->second.authorize({.account =
id});
1462 cleanup(MPT
const& mpt, AccountOwns&
id)
1464 auto it = getIt(mpt);
1466 if (
auto const redeem = it->second.getBalance(
id))
1467 pay(it,
id, acct, redeem);
1469 it->second.authorize({.account = id, .flags = tfMPTUnauthorize});
1478 env(fclear(dst, asfDepositAuth));
1479 it->second.pay(src, dst, amount);
1480 env(fset(dst, asfDepositAuth));
1484 it->second.pay(src, dst, amount);
1491 auto it = getIt(amount.name());
1492 pay(it, src, dst, amount.value().mpt().value());
1496 AccountOwns alice{*
this, env,
"alice",
false};
1497 AccountOwns bob{*
this, env,
"bob",
false};
1498 AccountOwns gw1{*
this, env,
"gw1",
true};
1501 env.fund(XRP(5000), noripple(alice, bob));
1510 env.fund(XRP(5'000), noripple(gw1));
1513 MPT
const cK8 = gw1[
"CK8"];
1514 gw1.verifyOwners(__LINE__);
1521 env.fund(XRP(200), yui);
1524 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1525 env(check::create(gw1, yui, cK8(99)));
1530 alice.verifyOwners(__LINE__);
1534 env(pay(env.master, yui, XRP(51)));
1536 env(check::cash(yui, chkId, cK8(99)));
1539 BEAST_EXPECT(ownerCount(env, yui) == 1);
1543 gw1.verifyOwners(__LINE__);
1558 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
1559 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
1560 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
1563 MPT
const oF1 = gw1[
"OF1"];
1564 env(offer(gw1, XRP(98), oF1(98)));
1566 BEAST_EXPECT(env.le(
keylet::mptoken(oF1.issuanceID, alice)) ==
nullptr);
1567 env(offer(alice, oF1(98), XRP(98)));
1574 gw1.verifyOwners(__LINE__);
1577 alice.verifyOwners(__LINE__);
1580 MPT
const cK1 = gw1[
"CK1"];
1581 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1582 env(check::create(gw1, alice, cK1(98)));
1584 BEAST_EXPECT(env.le(
keylet::mptoken(cK1.issuanceID, alice)) ==
nullptr);
1585 env(check::cash(alice, chkId, cK1(98)));
1593 gw1.verifyOwners(__LINE__);
1596 alice.verifyOwners(__LINE__);
1607 MPT
const oF1 = gw1[
"OF1"];
1608 env(offer(alice, XRP(97), oF1(97)));
1611 env(offer(bob, oF1(97), XRP(97)));
1616 env.require(Balance(alice, oF1(1)));
1617 env.require(Balance(bob, oF1(97)));
1620 gw1.verifyOwners(__LINE__);
1621 alice.verifyOwners(__LINE__);
1622 bob.verifyOwners(__LINE__);
1630 MPT
const cK1 = gw1[
"CK1"];
1631 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1632 env(check::create(alice, bob, cK1(97)));
1635 env(check::cash(bob, chkId, cK1(97)));
1641 gw1.verifyOwners(__LINE__);
1642 alice.verifyOwners(__LINE__);
1643 bob.verifyOwners(__LINE__);
1650 env(fset(gw1, asfDefaultRipple));
1654 MPT
const oF2 = gw1[
"OF2"];
1655 env(offer(gw1, XRP(96), oF2(96)));
1658 env(offer(alice, oF2(96), XRP(96)));
1664 gw1.verifyOwners(__LINE__);
1667 alice.verifyOwners(__LINE__);
1670 MPT
const cK2 = gw1[
"CK2"];
1671 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1672 env(check::create(gw1, alice, cK2(96)));
1675 env(check::cash(alice, chkId, cK2(96)));
1683 gw1.verifyOwners(__LINE__);
1686 alice.verifyOwners(__LINE__);
1695 MPT
const oF2 = gw1[
"OF2"];
1696 env(offer(alice, XRP(95), oF2(95)));
1700 env(offer(bob, oF2(95), XRP(95)));
1705 gw1.verifyOwners(__LINE__);
1706 alice.verifyOwners(__LINE__);
1707 bob.verifyOwners(__LINE__);
1710 MPT
const cK2 = gw1[
"CK2"];
1711 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1712 env(check::create(alice, bob, cK2(95)));
1715 env(check::cash(bob, chkId, cK2(95)));
1721 gw1.verifyOwners(__LINE__);
1722 alice.verifyOwners(__LINE__);
1723 bob.verifyOwners(__LINE__);
1734 env(fset(gw1, asfDepositAuth));
1735 env(fset(alice, asfDepositAuth));
1736 env(fset(bob, asfDepositAuth));
1740 MPT
const oF3 = gw1[
"OF3"];
1741 env(offer(gw1, XRP(94), oF3(94)));
1744 env(offer(alice, oF3(94), XRP(94)));
1751 gw1.verifyOwners(__LINE__);
1754 alice.verifyOwners(__LINE__);
1757 MPT
const cK3 = gw1[
"CK3"];
1758 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1759 env(check::create(gw1, alice, cK3(94)));
1762 env(check::cash(alice, chkId, cK3(94)));
1770 gw1.verifyOwners(__LINE__);
1773 alice.verifyOwners(__LINE__);
1782 MPT
const oF3 = gw1[
"OF3"];
1783 env(offer(alice, XRP(93), oF3(93)));
1786 env(offer(bob, oF3(93), XRP(93)));
1791 gw1.verifyOwners(__LINE__);
1792 alice.verifyOwners(__LINE__);
1793 bob.verifyOwners(__LINE__);
1796 MPT
const cK3 = gw1[
"CK3"];
1797 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1798 env(check::create(alice, bob, cK3(93)));
1801 env(check::cash(bob, chkId, cK3(93)));
1807 gw1.verifyOwners(__LINE__);
1808 alice.verifyOwners(__LINE__);
1809 bob.verifyOwners(__LINE__);
1816 env(fset(gw1, asfGlobalFreeze));
1820 MPT
const oF4 = gw1[
"OF4"];
1821 env(offer(gw1, XRP(92), oF4(92)));
1824 env(offer(alice, oF4(92), XRP(92)));
1829 gw1.verifyOwners(__LINE__);
1830 alice.verifyOwners(__LINE__);
1831 bob.verifyOwners(__LINE__);
1834 MPT
const cK4 = gw1[
"CK4"];
1835 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1836 env(check::create(gw1, bob, cK4(92)));
1839 env(check::cash(bob, chkId, cK4(92)));
1845 gw1.verifyOwners(__LINE__);
1846 alice.verifyOwners(__LINE__);
1847 bob.verifyOwners(__LINE__);
1850 gw1.cleanup(oF4, alice);
1851 gw1.cleanup(cK4, bob);
1860 MPT
const oF4 = gw1[
"OF4"];
1861 gw1.set(oF4, tfMPTLock);
1862 env(offer(gw1, XRP(92), oF4(92)), Ter(
tecLOCKED));
1865 env(offer(alice, oF4(92), XRP(92)), Ter(
tecLOCKED));
1869 gw1.verifyOwners(__LINE__);
1870 alice.verifyOwners(__LINE__);
1871 bob.verifyOwners(__LINE__);
1874 MPT
const cK4 = gw1[
"CK4"];
1875 gw1.set(cK4, tfMPTLock);
1876 uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
1877 env(check::create(gw1, alice, cK4(92)), Ter(
tecLOCKED));
1880 env(check::cash(alice, chkId, cK4(92)), Ter(
tecNO_ENTRY));
1884 gw1.verifyOwners(__LINE__);
1885 alice.verifyOwners(__LINE__);
1886 bob.verifyOwners(__LINE__);
1894 gw1.set(oF4, tfMPTUnlock);
1895 gw1.set(cK4, tfMPTUnlock);
1904 MPT
const oF4 = gw1[
"OF4"];
1905 gw1.authorize(oF4, alice);
1906 gw1.pay(gw1, alice, oF4(91));
1907 env(offer(alice, XRP(91), oF4(91)));
1910 env(offer(bob, oF4(91), XRP(91)));
1916 gw1.verifyOwners(__LINE__);
1917 alice.verifyOwners(__LINE__);
1918 bob.verifyOwners(__LINE__);
1921 MPT
const cK4 = gw1[
"CK4"];
1922 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1923 env(check::create(alice, bob, cK4(91)));
1926 gw1.authorize(cK4, alice);
1927 gw1.pay(gw1, alice, cK4(91));
1928 env(check::cash(bob, chkId, cK4(91)));
1934 gw1.verifyOwners(__LINE__);
1935 alice.verifyOwners(__LINE__);
1936 bob.verifyOwners(__LINE__);
1939 gw1.cleanup(oF4, alice);
1940 gw1.cleanup(cK4, alice);
1941 gw1.cleanup(oF4, bob);
1942 gw1.cleanup(cK4, bob);
1951 MPT
const oF4 = gw1[
"OF4"];
1952 gw1.set(oF4, tfMPTLock);
1953 env(offer(alice, XRP(91), oF4(91)), Ter(
tecLOCKED));
1956 env(offer(bob, oF4(91), XRP(91)), Ter(
tecLOCKED));
1960 gw1.verifyOwners(__LINE__);
1961 alice.verifyOwners(__LINE__);
1962 bob.verifyOwners(__LINE__);
1965 MPT
const cK4 = gw1[
"CK4"];
1966 gw1.set(cK4, tfMPTLock);
1967 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1968 env(check::create(alice, bob, cK4(91)), Ter(
tecLOCKED));
1971 env(check::cash(bob, chkId, cK4(91)), Ter(
tecNO_ENTRY));
1975 gw1.verifyOwners(__LINE__);
1976 alice.verifyOwners(__LINE__);
1977 bob.verifyOwners(__LINE__);
1984 gw1.set(oF4, tfMPTUnlock);
1985 gw1.set(cK4, tfMPTUnlock);
1993 AccountOwns gw2{*
this, env,
"gw2",
true};
1995 env.fund(XRP(5'000), gw2);
2000 env(fset(gw2, asfRequireAuth));
2004 MPT
const oF5 = gw2[
"OF5"];
2005 env(offer(gw2, XRP(92), oF5(92)));
2008 env(offer(alice, oF5(92), XRP(92)));
2013 gw2.verifyOwners(__LINE__);
2014 alice.verifyOwners(__LINE__);
2015 bob.verifyOwners(__LINE__);
2018 MPT
const cK5 = gw2[
"CK5"];
2019 uint256 const chkId{getCheckIndex(gw2, env.seq(gw2))};
2020 env(check::create(gw2, alice, cK5(92)));
2023 env(check::cash(alice, chkId, cK5(92)));
2029 gw2.verifyOwners(__LINE__);
2030 alice.verifyOwners(__LINE__);
2031 bob.verifyOwners(__LINE__);
2034 gw2.cleanup(oF5, alice);
2035 gw2.cleanup(cK5, alice);
2040 AccountOwns gw3{*
this, env,
"gw3",
true,
true};
2042 env.fund(XRP(5'000), gw3);
2045 MPT
const oF5 = gw3[
"OF5"];
2047 env(offer(gw3, XRP(92), oF5(92)));
2051 env(offer(alice, oF5(92), XRP(92)), Ter(
tecNO_AUTH));
2056 gw3.verifyOwners(__LINE__);
2057 alice.verifyOwners(__LINE__);
2058 bob.verifyOwners(__LINE__);
2061 env(offerCancel(gw3, gw3OfferSeq));
2064 gw3.verifyOwners(__LINE__);
2067 MPT
const cK5 = gw3[
"CK5"];
2068 uint256 const chkId{getCheckIndex(gw3, env.seq(gw3))};
2069 env(check::create(gw3, alice, cK5(92)));
2073 env(check::cash(alice, chkId, cK5(92)), Ter(
tecNO_AUTH));
2078 gw3.verifyOwners(__LINE__);
2079 alice.verifyOwners(__LINE__);
2080 bob.verifyOwners(__LINE__);
2088 env(check::cancel(gw3, chkId));
2091 gw3.verifyOwners(__LINE__);
2100 MPT
const oF5 = gw2[
"OF5"];
2101 gw2.authorize(oF5, alice);
2102 gw2.pay(gw2, alice, oF5(91));
2103 env(offer(alice, XRP(91), oF5(91)));
2105 env(offer(bob, oF5(91), XRP(91)));
2110 gw2.verifyOwners(__LINE__);
2111 alice.verifyOwners(__LINE__);
2112 bob.verifyOwners(__LINE__);
2115 MPT
const cK5 = gw2[
"CK5"];
2116 gw2.authorize(cK5, alice);
2117 gw2.pay(gw2, alice, cK5(91));
2118 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2119 env(check::create(alice, bob, cK5(91)));
2122 env(check::cash(bob, chkId, cK5(91)));
2127 gw2.verifyOwners(__LINE__);
2128 alice.verifyOwners(__LINE__);
2129 bob.verifyOwners(__LINE__);
2139 MPT
const oF5 = gw3[
"OF5"];
2142 env(offer(bob, oF5(91), XRP(91)), Ter(
tecNO_AUTH));
2146 gw3.verifyOwners(__LINE__);
2147 alice.verifyOwners(__LINE__);
2148 bob.verifyOwners(__LINE__);
2151 MPT
const cK5 = gw3[
"CK5"];
2152 uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2153 env(check::create(alice, bob, cK5(91)));
2160 env(check::cancel(alice, chkId));
2164 gw3.verifyOwners(__LINE__);
2165 alice.verifyOwners(__LINE__);
2166 bob.verifyOwners(__LINE__);