515 "test AMMClawback specific amount which exceeds the current "
524 Env env(*
this, features);
528 env.
fund(
XRP(1000000), gw, gw2, alice);
532 env(
fset(gw, asfAllowTrustLineClawback));
537 auto const usd = gw[
"USD"];
538 env.
trust(usd(100000), alice);
539 env(
pay(gw, alice, usd(6000)));
544 auto const eur = gw2[
"EUR"];
545 env.
trust(eur(100000), alice);
546 env(
pay(gw2, alice, eur(6000)));
554 if (!features[fixAMMv1_3])
557 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999580, -12}));
562 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999579, -12}));
581 if (!features[fixAMMv1_3])
584 amm.expectBalances(usd(3000), eur(3750),
IOUAmount{3354101966249685, -12}));
589 amm.expectBalances(usd(3000), eur(3750),
IOUAmount{3354101966249684, -12}));
593 if (!features[fixAMMv1_3])
595 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{3354101966249685, -12}));
599 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{3354101966249684, -12}));
610 if (!features[fixAMMv1_3])
612 BEAST_EXPECT(
amm.expectBalances(
613 STAmount{usd, UINT64_C(2500000000000001), -12},
614 STAmount{eur, UINT64_C(3125000000000001), -12},
620 amm.expectBalances(usd(2500), eur(3125),
IOUAmount{2795084971874737, -12}));
623 if (!features[fixAMMv1_3])
626 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2874999999999999), -12));
630 BEAST_EXPECT(env.
balance(alice, eur) == eur(2875));
640 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
642 BEAST_EXPECT(
amm.expectBalances(
643 STAmount{usd, UINT64_C(2499000000000002), -12},
644 STAmount{eur, UINT64_C(3123750000000002), -12},
647 else if (!features[fixAMMClawbackRounding])
650 amm.expectBalances(usd(2499), eur(3123.75),
IOUAmount{2793966937885987, -12}));
652 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
654 BEAST_EXPECT(
amm.expectBalances(
655 STAmount{usd, UINT64_C(2499000000000001), -12},
656 STAmount{eur, UINT64_C(3123750000000001), -12},
660 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
663 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2876'249999999998), -12));
665 else if (!features[fixAMMClawbackRounding])
667 BEAST_EXPECT(env.
balance(alice, eur) == eur(2876.25));
669 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
672 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2876'249999999999), -12));
683 BEAST_EXPECT(env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(6000000000000000), -12));
686 BEAST_EXPECT(!
amm.ammExists());
695 Env env(*
this, features);
700 env.
fund(
XRP(1000000), gw, gw2, alice, bob);
704 env(
fset(gw, asfAllowTrustLineClawback));
709 env(
fset(gw2, asfAllowTrustLineClawback));
714 auto const usd = gw[
"USD"];
715 env.
trust(usd(100000), alice);
716 env(
pay(gw, alice, usd(6000)));
717 env.
trust(usd(100000), bob);
718 env(
pay(gw, bob, usd(5000)));
722 auto const eur = gw2[
"EUR"];
723 env.
trust(eur(100000), alice);
724 env(
pay(gw2, alice, eur(5000)));
725 env.
trust(eur(100000), bob);
726 env(
pay(gw2, bob, eur(4000)));
731 BEAST_EXPECT(
amm.expectBalances(usd(1000),
XRP(2000),
IOUAmount{1414213562373095, -9}));
732 amm.deposit(alice, usd(1000),
XRP(2000));
733 BEAST_EXPECT(
amm.expectBalances(usd(2000),
XRP(4000),
IOUAmount{2828427124746190, -9}));
734 amm.deposit(bob, usd(1000),
XRP(2000));
735 BEAST_EXPECT(
amm.expectBalances(usd(3000),
XRP(6000),
IOUAmount{4242640687119285, -9}));
740 if (!features[fixAMMv1_3])
752 if (!features[fixAMMv1_3])
764 if (!features[fixAMMv1_3])
776 auto aliceXrpBalance = env.
balance(alice,
XRP);
792 if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
803 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
806 amm.expectBalances(usd(2500),
XRP(5000),
IOUAmount{3535533905932738, -9}));
808 else if (!features[fixAMMClawbackRounding])
811 amm.expectBalances(usd(2500),
XRP(5000),
IOUAmount{3535533905932737, -9}));
813 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
815 BEAST_EXPECT(
amm.expectBalances(
819 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
821 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865480, -10}));
823 else if (!features[fixAMMClawbackRounding])
825 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865474, -10}));
827 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
829 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{707106781186548, -9}));
832 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1414213562373095, -9}));
845 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
847 BEAST_EXPECT(
amm.expectBalances(
848 STAmount{usd, UINT64_C(2490000000000001), -12},
852 else if (!features[fixAMMClawbackRounding])
855 amm.expectBalances(usd(2'490),
XRP(4980),
IOUAmount{3521391770309006, -9}));
857 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
859 BEAST_EXPECT(
amm.expectBalances(
860 STAmount{usd, UINT64_C(2490000000000001), -12},
865 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
867 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865480, -10}));
869 else if (!features[fixAMMClawbackRounding])
871 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865474, -10}));
873 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
875 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{707106781186548, -9}));
878 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
880 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
882 else if (!features[fixAMMClawbackRounding])
884 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749364, -9}));
886 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
888 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
898 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
902 else if (!features[fixAMMClawbackRounding])
906 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
913 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
918 else if (!features[fixAMMClawbackRounding])
923 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
929 if (!features[fixAMMv1_3])
937 if (!features[fixAMMv1_3])
956 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
960 else if (!features[fixAMMClawbackRounding])
965 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
972 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
974 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
976 else if (!features[fixAMMClawbackRounding])
978 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749364, -9}));
980 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
982 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
985 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
987 BEAST_EXPECT(
amm.expectBalances(
988 STAmount{usd, UINT64_C(1990000000000001), -12},
992 else if (!features[fixAMMClawbackRounding])
994 BEAST_EXPECT(
amm.expectBalances(
997 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
999 BEAST_EXPECT(
amm.expectBalances(
1000 STAmount{usd, UINT64_C(1990000000000001), -12},
1042 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1047 else if (!features[fixAMMClawbackRounding])
1052 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1078 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1083 else if (!features[fixAMMClawbackRounding])
1088 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1099 testcase(
"test AMMClawback all the tokens in the AMM pool");
1100 using namespace jtx;
1105 Env env(*
this, features);
1107 Account const gw2{
"gateway2"};
1111 env.
fund(
XRP(1000000), gw, gw2, alice, bob, carol);
1115 env(
fset(gw, asfAllowTrustLineClawback));
1120 env(
fset(gw2, asfAllowTrustLineClawback));
1126 auto const usd = gw[
"USD"];
1127 env.
trust(usd(100000), alice);
1128 env(
pay(gw, alice, usd(6000)));
1129 env.
trust(usd(100000), bob);
1130 env(
pay(gw, bob, usd(5000)));
1131 env.
trust(usd(100000), carol);
1132 env(
pay(gw, carol, usd(4000)));
1137 auto const eur = gw2[
"EUR"];
1138 env.
trust(eur(100000), alice);
1139 env(
pay(gw2, alice, eur(6000)));
1140 env.
trust(eur(100000), bob);
1141 env(
pay(gw2, bob, eur(5000)));
1142 env.
trust(eur(100000), carol);
1143 env(
pay(gw2, carol, eur(4000)));
1150 if (!features[fixAMMv1_3])
1153 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999580, -12}));
1158 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999579, -12}));
1160 amm.deposit(bob, usd(2000), eur(2500));
1161 if (!features[fixAMMv1_3])
1164 amm.expectBalances(usd(6000), eur(7500),
IOUAmount{6708203932499370, -12}));
1169 amm.expectBalances(usd(6000), eur(7500),
IOUAmount{6708203932499368, -12}));
1171 amm.deposit(carol, usd(1000), eur(1250));
1172 if (!features[fixAMMv1_3])
1175 amm.expectBalances(usd(7000), eur(8750),
IOUAmount{7826237921249265, -12}));
1180 amm.expectBalances(usd(7000), eur(8750),
IOUAmount{7826237921249262, -12}));
1183 if (!features[fixAMMv1_3])
1185 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1189 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1191 if (!features[fixAMMv1_3])
1193 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2236067977499790, -12}));
1197 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2236067977499789, -12}));
1199 if (!features[fixAMMv1_3])
1201 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749895, -12}));
1205 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749894, -12}));
1219 if (!features[fixAMMv1_3])
1221 BEAST_EXPECT(
amm.expectBalances(
1222 STAmount{usd, UINT64_C(4999999999999999), -12},
1223 STAmount{eur, UINT64_C(6249999999999999), -12},
1228 BEAST_EXPECT(
amm.expectBalances(
1229 STAmount{usd, UINT64_C(5000000000000001), -12},
1230 STAmount{eur, UINT64_C(6250000000000001), -12},
1234 if (!features[fixAMMv1_3])
1236 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1240 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1243 if (!features[fixAMMv1_3])
1245 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749895, -12}));
1249 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749894, -12}));
1255 BEAST_EXPECT(env.
balance(bob, usd) ==
STAmount(usd, UINT64_C(3000000000000000), -12));
1257 if (!features[fixAMMv1_3])
1260 env.
balance(bob, eur) ==
STAmount(eur, UINT64_C(5000000000000001), -12));
1265 env.
balance(bob, eur) ==
STAmount(eur, UINT64_C(4999999999999999), -12));
1273 if (!features[fixAMMv1_3])
1275 BEAST_EXPECT(
amm.expectBalances(
1276 STAmount{usd, UINT64_C(3999999999999999), -12},
1277 STAmount{eur, UINT64_C(4999999999999999), -12},
1282 BEAST_EXPECT(
amm.expectBalances(
1283 STAmount{usd, UINT64_C(4000000000000001), -12},
1284 STAmount{eur, UINT64_C(5000000000000002), -12},
1288 if (!features[fixAMMv1_3])
1290 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1294 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1305 BEAST_EXPECT(!
amm.ammExists());
1311 Env env(*
this, features);
1315 env.
fund(
XRP(1000000), gw, alice, bob);
1319 env(
fset(gw, asfAllowTrustLineClawback));
1324 auto const usd = gw[
"USD"];
1325 env.
trust(usd(1000000), alice);
1326 env(
pay(gw, alice, usd(600000)));
1327 env.
trust(usd(1000000), bob);
1328 env(
pay(gw, bob, usd(500000)));
1333 if (!features[fixAMMv1_3])
1336 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999580, -9}));
1341 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999579, -9}));
1343 amm.deposit(alice, usd(1000),
XRP(200));
1344 if (!features[fixAMMv1_3])
1347 amm.expectBalances(usd(11000),
XRP(2200),
IOUAmount{4919349550499538, -9}));
1352 amm.expectBalances(usd(11000),
XRP(2200),
IOUAmount{4919349550499536, -9}));
1354 amm.deposit(bob, usd(2000),
XRP(400));
1355 if (!features[fixAMMv1_3])
1358 amm.expectBalances(usd(13000),
XRP(2600),
IOUAmount{5813776741499453, -9}));
1363 amm.expectBalances(usd(13000),
XRP(2600),
IOUAmount{5813776741499451, -9}));
1367 auto aliceXrpBalance = env.
balance(alice,
XRP);
1373 if (!features[fixAMMv1_3])
1376 amm.expectBalances(usd(12000),
XRP(2400),
IOUAmount{5366563145999495, -9}));
1380 BEAST_EXPECT(
amm.expectBalances(
1383 if (!features[fixAMMv1_3])
1397 if (!features[fixAMMv1_3])
1400 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999580, -9}));
1404 BEAST_EXPECT(
amm.expectBalances(
1417 "test AMMClawback from AMM pool with assets having the same "
1419 using namespace jtx;
1423 Env env(*
this, features);
1428 env.
fund(
XRP(1000000), gw, alice, bob, carol);
1432 env(
fset(gw, asfAllowTrustLineClawback));
1436 auto const usd = gw[
"USD"];
1437 env.
trust(usd(100000), alice);
1438 env(
pay(gw, alice, usd(10000)));
1439 env.
trust(usd(100000), bob);
1440 env(
pay(gw, bob, usd(9000)));
1441 env.
trust(usd(100000), carol);
1442 env(
pay(gw, carol, usd(8000)));
1445 auto const eur = gw[
"EUR"];
1446 env.
trust(eur(100000), alice);
1447 env(
pay(gw, alice, eur(10000)));
1448 env.
trust(eur(100000), bob);
1449 env(
pay(gw, bob, eur(9000)));
1450 env.
trust(eur(100000), carol);
1451 env(
pay(gw, carol, eur(8000)));
1457 BEAST_EXPECT(
amm.expectBalances(usd(8000), eur(2000),
IOUAmount(4000)));
1458 amm.deposit(bob, usd(4000), eur(1000));
1459 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
1460 if (!features[fixAMMv1_3])
1462 amm.deposit(carol, usd(2000), eur(500));
1466 amm.deposit(carol, usd(2000.25), eur(500));
1468 BEAST_EXPECT(
amm.expectBalances(usd(14000), eur(3500),
IOUAmount(7000)));
1472 BEAST_EXPECT(
amm.expectBalances(usd(13000), eur(3250),
IOUAmount(6500)));
1474 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
1475 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(2000)));
1476 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1477 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1478 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1479 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1480 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1481 if (!features[fixAMMv1_3])
1483 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1488 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1491 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1500 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
1502 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
1503 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
1504 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1505 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1506 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1507 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1509 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1510 if (!features[fixAMMv1_3])
1512 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1517 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1519 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1526 BEAST_EXPECT(
amm.expectBalances(usd(4000), eur(1000),
IOUAmount(2000)));
1529 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
1530 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1531 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1532 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1533 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1534 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1535 if (!features[fixAMMv1_3])
1537 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1542 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1544 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1647 testcase(
"test AMMClawback when issuing token for each other");
1648 using namespace jtx;
1652 Env env(*
this, features);
1654 Account const gw2{
"gateway2"};
1656 env.
fund(
XRP(1000000), gw, gw2, alice);
1660 env(
fset(gw, asfAllowTrustLineClawback));
1665 env(
fset(gw2, asfAllowTrustLineClawback));
1669 auto const usd = gw[
"USD"];
1670 env.
trust(usd(100000), gw2);
1671 env(
pay(gw, gw2, usd(5000)));
1672 env.
trust(usd(100000), alice);
1673 env(
pay(gw, alice, usd(5000)));
1675 auto const eur = gw2[
"EUR"];
1676 env.
trust(eur(100000), gw);
1677 env(
pay(gw2, gw, eur(6000)));
1678 env.
trust(eur(100000), alice);
1679 env(
pay(gw2, alice, eur(6000)));
1684 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(2000),
IOUAmount{1414213562373095, -12}));
1686 amm.deposit(gw2, usd(2000), eur(4000));
1687 BEAST_EXPECT(
amm.expectBalances(usd(3000), eur(6000),
IOUAmount{4242640687119285, -12}));
1689 amm.deposit(alice, usd(3000), eur(6000));
1690 BEAST_EXPECT(
amm.expectBalances(usd(6000), eur(12000),
IOUAmount{8485281374238570, -12}));
1692 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414213562373095, -12}));
1693 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{2828427124746190, -12}));
1694 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1699 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1702 amm.expectBalances(usd(5000), eur(10000),
IOUAmount{7071067811865475, -12}));
1707 amm.expectBalances(usd(5000), eur(10000),
IOUAmount{7071067811865474, -12}));
1710 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414213562373095, -12}));
1711 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1713 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1717 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1719 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1721 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1722 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1723 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1724 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1729 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1731 BEAST_EXPECT(
amm.expectBalances(
1733 STAmount(eur, UINT64_C(9000000000000001), -12),
1736 else if (!features[fixAMMClawbackRounding])
1739 amm.expectBalances(usd(4500), eur(9000),
IOUAmount{6363961030678928, -12}));
1741 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1743 BEAST_EXPECT(
amm.expectBalances(
1745 STAmount(eur, UINT64_C(9000000000000001), -12),
1749 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1751 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1753 else if (!features[fixAMMClawbackRounding])
1755 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865475, -13}));
1757 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1759 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1762 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1764 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1768 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1771 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1773 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1774 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1775 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1776 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1781 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1783 BEAST_EXPECT(
amm.expectBalances(
1785 STAmount(eur, UINT64_C(5000000000000001), -12),
1788 else if (!features[fixAMMClawbackRounding])
1791 amm.expectBalances(usd(2500), eur(5000),
IOUAmount{3535533905932738, -12}));
1793 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1795 BEAST_EXPECT(
amm.expectBalances(
1797 STAmount(eur, UINT64_C(5000000000000001), -12),
1801 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1803 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1805 else if (!features[fixAMMClawbackRounding])
1807 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865475, -13}));
1809 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1811 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1814 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1816 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1820 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1822 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1414213562373095, -12}));
1824 BEAST_EXPECT(env.
balance(alice, usd) == usd(4000));
1825 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1826 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1827 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1865 using namespace jtx;
1869 Env env(*
this, features);
1871 Account const gw2{
"gateway2"};
1873 env.
fund(
XRP(1000000), gw, gw2, alice);
1877 env(
fset(gw, asfAllowTrustLineClawback));
1882 auto const usd = gw[
"USD"];
1883 env.
trust(usd(100000), alice);
1884 env(
pay(gw, alice, usd(3000)));
1889 auto const eur = gw2[
"EUR"];
1890 env.
trust(eur(100000), alice);
1891 env(
pay(gw2, alice, eur(3000)));
1900 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
1903 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1912 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
1915 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
1928 BEAST_EXPECT(!
amm.ammExists());
1933 Env env(*
this, features);
1935 Account const gw2{
"gateway2"};
1937 env.
fund(
XRP(1000000), gw, gw2, alice);
1941 env(
fset(gw, asfAllowTrustLineClawback));
1946 auto const usd = gw[
"USD"];
1947 env.
trust(usd(100000), alice);
1948 env(
pay(gw, alice, usd(3000)));
1953 auto const eur = gw2[
"EUR"];
1954 env.
trust(eur(100000), alice);
1955 env(
pay(gw2, alice, eur(3000)));
1964 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
1967 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1968 env(
trust(gw2, alice[
"EUR"](0), tfSetFreeze));
1977 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
1978 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
1983 Env env(*
this, features);
1985 Account const gw2{
"gateway2"};
1987 env.
fund(
XRP(1000000), gw, gw2, alice);
1991 env(
fset(gw, asfAllowTrustLineClawback));
1996 auto const usd = gw[
"USD"];
1997 env.
trust(usd(100000), alice);
1998 env(
pay(gw, alice, usd(3000)));
2003 auto const eur = gw2[
"EUR"];
2004 env.
trust(eur(100000), alice);
2005 env(
pay(gw2, alice, eur(3000)));
2014 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2017 env(
fset(gw, asfGlobalFreeze));
2026 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2027 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2033 Env env(*
this, features);
2038 env.
fund(
XRP(1000000), gw, alice, bob, carol);
2042 env(
fset(gw, asfAllowTrustLineClawback));
2046 auto const usd = gw[
"USD"];
2047 env.
trust(usd(100000), alice);
2048 env(
pay(gw, alice, usd(10000)));
2049 env.
trust(usd(100000), bob);
2050 env(
pay(gw, bob, usd(9000)));
2051 env.
trust(usd(100000), carol);
2052 env(
pay(gw, carol, usd(8000)));
2055 auto const eur = gw[
"EUR"];
2056 env.
trust(eur(100000), alice);
2057 env(
pay(gw, alice, eur(10000)));
2058 env.
trust(eur(100000), bob);
2059 env(
pay(gw, bob, eur(9000)));
2060 env.
trust(eur(100000), carol);
2061 env(
pay(gw, carol, eur(8000)));
2067 BEAST_EXPECT(
amm.expectBalances(usd(8000), eur(2000),
IOUAmount(4000)));
2068 amm.deposit(bob, usd(4000), eur(1000));
2069 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
2070 if (!features[fixAMMv1_3])
2072 amm.deposit(carol, usd(2000), eur(500));
2076 amm.deposit(carol, usd(2000.25), eur(500));
2078 BEAST_EXPECT(
amm.expectBalances(usd(14000), eur(3500),
IOUAmount(7000)));
2081 env(
fset(gw, asfGlobalFreeze));
2087 BEAST_EXPECT(
amm.expectBalances(usd(13000), eur(3250),
IOUAmount(6500)));
2089 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
2090 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(2000)));
2091 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2092 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2093 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2094 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2095 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2096 if (!features[fixAMMv1_3])
2098 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2103 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2106 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2115 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
2117 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
2118 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
2119 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2120 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2121 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2122 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2124 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2125 if (!features[fixAMMv1_3])
2127 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2132 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2134 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2141 BEAST_EXPECT(
amm.expectBalances(usd(4000), eur(1000),
IOUAmount(2000)));
2144 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
2145 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2146 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2147 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2148 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2149 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2150 if (!features[fixAMMv1_3])
2152 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2157 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2159 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2168 Env env(*
this, features);
2170 Account const gw2{
"gateway2"};
2172 env.
fund(
XRP(1000000), gw, gw2, alice);
2175 env(
fset(gw, asfAllowTrustLineClawback));
2179 auto const usd = gw[
"USD"];
2180 env.
trust(usd(100000), alice);
2181 env(
pay(gw, alice, usd(3000)));
2184 auto const eur = gw2[
"EUR"];
2185 env.
trust(eur(100000), alice);
2186 env(
pay(gw2, alice, eur(3000)));
2193 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2205 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2206 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2214 Env env(*
this, features);
2216 Account const gw2{
"gateway2"};
2218 env.
fund(
XRP(1000000), gw, gw2, alice);
2221 env(
fset(gw, asfAllowTrustLineClawback));
2225 auto const usd = gw[
"USD"];
2226 env.
trust(usd(100000), alice);
2227 env(
pay(gw, alice, usd(3000)));
2230 auto const eur = gw2[
"EUR"];
2231 env.
trust(eur(100000), alice);
2232 env(
pay(gw2, alice, eur(3000)));
2239 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2245 if (features[fixCleanup3_4_0])
2255 amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2256 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2270 Env env(*
this, features);
2272 Account const gw2{
"gateway2"};
2274 env.
fund(
XRP(1000000), gw, gw2, alice);
2277 env(
fset(gw, asfAllowTrustLineClawback));
2281 auto const usd = gw[
"USD"];
2282 env.
trust(usd(100000), alice);
2283 env(
pay(gw, alice, usd(3000)));
2286 auto const eur = gw2[
"EUR"];
2287 env.
trust(eur(100000), alice);
2288 env(
pay(gw2, alice, eur(3000)));
2295 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2297 env(
fset(gw2, asfGlobalFreeze));
2305 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2306 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2310 if (features[featureDeepFreeze])
2312 Env env(*
this, features);
2314 Account const gw2{
"gateway2"};
2316 env.
fund(
XRP(1000000), gw, gw2, alice);
2319 env(
fset(gw, asfAllowTrustLineClawback));
2323 auto const usd = gw[
"USD"];
2324 env.
trust(usd(100000), alice);
2325 env(
pay(gw, alice, usd(3000)));
2328 auto const eur = gw2[
"EUR"];
2329 env.
trust(eur(100000), alice);
2330 env(
pay(gw2, alice, eur(3000)));
2337 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2343 tfSetFreeze | tfSetDeepFreeze));
2346 if (features[fixCleanup3_4_0])
2354 amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2355 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2434 "test last holder's lptoken balance not equal to AMM's lptoken "
2435 "balance before clawback");
2436 using namespace jtx;
2439 auto setupAccounts =
2441 env.
fund(
XRP(100000), gw, alice, bob);
2443 env(
fset(gw, asfAllowTrustLineClawback));
2446 auto const usd = gw[
"USD"];
2447 env.
trust(usd(100000), alice);
2448 env(
pay(gw, alice, usd(50000)));
2449 env.
trust(usd(100000), bob);
2450 env(
pay(gw, bob, usd(40000)));
2456 auto getLPTokenBalances = [&](
auto& env,
2459 auto const lpToken =
2462 auto const lpTokenBalance =
2463 amm.ammRpcInfo()[jss::amm][jss::lp_token][jss::value].asString();
2464 return {lpToken, lpTokenBalance};
2470 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2471 auto const usd = setupAccounts(env, gw, alice, bob);
2476 amm.withdraw(alice,
IOUAmount{1'876123487565916, -15});
2477 amm.withdrawAll(bob);
2479 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2480 BEAST_EXPECT(lpToken ==
"1414.21356237366" && lpTokenBalance ==
"1414.213562374");
2483 BEAST_EXPECT(res && res.value());
2485 if (!features[fixAMMClawbackRounding] || !features[fixAMMv1_3])
2488 BEAST_EXPECT(
amm.ammExists());
2492 auto const lpBalance =
IOUAmount{989, -12};
2494 BEAST_EXPECT(
amm.expectBalances(
2496 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));
2503 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2504 auto const usd = setupAccounts(env, gw, alice, bob);
2509 amm.withdrawAll(bob);
2511 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2512 BEAST_EXPECT(lpToken ==
"1416.08968586066" && lpTokenBalance ==
"1416.089685861");
2515 BEAST_EXPECT(res && res.value());
2519 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
2521 BEAST_EXPECT(
amm.expectBalances(
2522 STAmount(usd, UINT64_C(5013266196406), -13),
2526 else if (!features[fixAMMClawbackRounding])
2528 BEAST_EXPECT(
amm.expectBalances(
2529 STAmount(usd, UINT64_C(5013266196407), -13),
2533 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2535 auto const lpBalance =
IOUAmount{708'9829046743238, -13};
2536 BEAST_EXPECT(
amm.expectBalances(
2537 STAmount(usd, UINT64_C(5013266196406999), -16),
XRPAmount(1002655), lpBalance));
2538 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));
2545 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2546 auto const usd = setupAccounts(env, gw, alice, bob);
2551 amm.withdraw(alice,
IOUAmount{1'876123487565916, -15});
2552 amm.withdrawAll(bob);
2554 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2555 BEAST_EXPECT(lpToken ==
"1414.21356237366" && lpTokenBalance ==
"1414.213562374");
2558 BEAST_EXPECT(res && res.value());
2560 if (!features[fixAMMClawbackRounding] && !features[fixAMMv1_3])
2564 else if (!features[fixAMMClawbackRounding])
2567 BEAST_EXPECT(
amm.expectBalances(
2568 STAmount(usd, UINT64_C(2410000000000000), -28),
2572 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2575 BEAST_EXPECT(!
amm.ammExists());
2582 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2583 auto const usd = setupAccounts(env, gw, alice, bob);
2585 Account const gw2{
"gateway2"};
2588 auto const eur = gw2[
"EUR"];
2589 env.
trust(eur(100000), alice);
2590 env(
pay(gw2, alice, eur(50000)));
2591 env.
trust(eur(100000), bob);
2592 env(
pay(gw2, bob, eur(50000)));
2595 AMM amm(env, alice, usd(2), eur(1));
2598 amm.withdraw(alice,
IOUAmount{1'576123487565916, -15});
2599 amm.withdrawAll(bob);
2601 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2602 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
2605 BEAST_EXPECT(res && res.value());
2607 if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2610 BEAST_EXPECT(!
amm.ammExists());
2615 BEAST_EXPECT(
amm.ammExists());
2622 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2623 auto const usd = setupAccounts(env, gw, alice, bob);
2625 auto const eur = gw[
"EUR"];
2626 env.
trust(eur(100000), alice);
2627 env(
pay(gw, alice, eur(50000)));
2628 env.
trust(eur(100000), bob);
2629 env(
pay(gw, bob, eur(50000)));
2632 AMM amm(env, alice, usd(1), eur(2));
2635 amm.withdraw(alice,
IOUAmount{1'076123487565916, -15});
2636 amm.withdrawAll(bob);
2638 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2639 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
2642 BEAST_EXPECT(res && res.value());
2644 if (features[fixAMMClawbackRounding])
2647 BEAST_EXPECT(!
amm.ammExists());
2654 BEAST_EXPECT(
amm.ammExists());
2661 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2662 auto const usd = setupAccounts(env, gw, alice, bob);
2664 auto const eur = gw[
"EUR"];
2665 env.
trust(eur(1000000000), alice);
2666 env(
pay(gw, alice, eur(500000000)));
2667 env.
trust(eur(1000000000), bob);
2668 env(
pay(gw, bob, eur(500000000)));
2671 AMM amm(env, alice, usd(1), eur(2000000));
2674 amm.withdraw(alice,
IOUAmount{1'076123487565916, -12});
2675 amm.withdrawAll(bob);
2677 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2679 BEAST_EXPECT(lpToken ==
"1414.213562373101" && lpTokenBalance ==
"1414.2135623731");
2682 BEAST_EXPECT(res && res.value());
2684 if (!features[fixAMMClawbackRounding] && !features[fixAMMv1_3])
2687 BEAST_EXPECT(
amm.expectBalances(
2692 else if (!features[fixAMMClawbackRounding])
2698 if (features[fixCleanup3_3_0])
2706 BEAST_EXPECT(
amm.ammExists());
2708 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2711 auto const lpBalance =
IOUAmount{5, -12};
2712 BEAST_EXPECT(
amm.expectBalances(
2713 STAmount(usd, UINT64_C(4), -15),
STAmount(eur, UINT64_C(8), -9), lpBalance));
2714 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));