512 "test AMMClawback specific amount which exceeds the current "
521 Env env(*
this, features);
525 env.
fund(
XRP(1000000), gw, gw2, alice);
529 env(
fset(gw, asfAllowTrustLineClawback));
534 auto const usd = gw[
"USD"];
535 env.
trust(usd(100000), alice);
536 env(
pay(gw, alice, usd(6000)));
541 auto const eur = gw2[
"EUR"];
542 env.
trust(eur(100000), alice);
543 env(
pay(gw2, alice, eur(6000)));
551 if (!features[fixAMMv1_3])
554 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999580, -12}));
559 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999579, -12}));
578 if (!features[fixAMMv1_3])
581 amm.expectBalances(usd(3000), eur(3750),
IOUAmount{3354101966249685, -12}));
586 amm.expectBalances(usd(3000), eur(3750),
IOUAmount{3354101966249684, -12}));
590 if (!features[fixAMMv1_3])
592 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{3354101966249685, -12}));
596 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{3354101966249684, -12}));
607 if (!features[fixAMMv1_3])
609 BEAST_EXPECT(
amm.expectBalances(
610 STAmount{usd, UINT64_C(2500000000000001), -12},
611 STAmount{eur, UINT64_C(3125000000000001), -12},
617 amm.expectBalances(usd(2500), eur(3125),
IOUAmount{2795084971874737, -12}));
620 if (!features[fixAMMv1_3])
623 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2874999999999999), -12));
627 BEAST_EXPECT(env.
balance(alice, eur) == eur(2875));
637 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
639 BEAST_EXPECT(
amm.expectBalances(
640 STAmount{usd, UINT64_C(2499000000000002), -12},
641 STAmount{eur, UINT64_C(3123750000000002), -12},
644 else if (!features[fixAMMClawbackRounding])
647 amm.expectBalances(usd(2499), eur(3123.75),
IOUAmount{2793966937885987, -12}));
649 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
651 BEAST_EXPECT(
amm.expectBalances(
652 STAmount{usd, UINT64_C(2499000000000001), -12},
653 STAmount{eur, UINT64_C(3123750000000001), -12},
657 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
660 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2876'249999999998), -12));
662 else if (!features[fixAMMClawbackRounding])
664 BEAST_EXPECT(env.
balance(alice, eur) == eur(2876.25));
666 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
669 env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(2876'249999999999), -12));
680 BEAST_EXPECT(env.
balance(alice, eur) ==
STAmount(eur, UINT64_C(6000000000000000), -12));
683 BEAST_EXPECT(!
amm.ammExists());
692 Env env(*
this, features);
697 env.
fund(
XRP(1000000), gw, gw2, alice, bob);
701 env(
fset(gw, asfAllowTrustLineClawback));
706 env(
fset(gw2, asfAllowTrustLineClawback));
711 auto const usd = gw[
"USD"];
712 env.
trust(usd(100000), alice);
713 env(
pay(gw, alice, usd(6000)));
714 env.
trust(usd(100000), bob);
715 env(
pay(gw, bob, usd(5000)));
719 auto const eur = gw2[
"EUR"];
720 env.
trust(eur(100000), alice);
721 env(
pay(gw2, alice, eur(5000)));
722 env.
trust(eur(100000), bob);
723 env(
pay(gw2, bob, eur(4000)));
728 BEAST_EXPECT(
amm.expectBalances(usd(1000),
XRP(2000),
IOUAmount{1414213562373095, -9}));
729 amm.deposit(alice, usd(1000),
XRP(2000));
730 BEAST_EXPECT(
amm.expectBalances(usd(2000),
XRP(4000),
IOUAmount{2828427124746190, -9}));
731 amm.deposit(bob, usd(1000),
XRP(2000));
732 BEAST_EXPECT(
amm.expectBalances(usd(3000),
XRP(6000),
IOUAmount{4242640687119285, -9}));
737 if (!features[fixAMMv1_3])
749 if (!features[fixAMMv1_3])
761 if (!features[fixAMMv1_3])
773 auto aliceXrpBalance = env.
balance(alice,
XRP);
789 if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
800 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
803 amm.expectBalances(usd(2500),
XRP(5000),
IOUAmount{3535533905932738, -9}));
805 else if (!features[fixAMMClawbackRounding])
808 amm.expectBalances(usd(2500),
XRP(5000),
IOUAmount{3535533905932737, -9}));
810 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
812 BEAST_EXPECT(
amm.expectBalances(
816 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
818 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865480, -10}));
820 else if (!features[fixAMMClawbackRounding])
822 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865474, -10}));
824 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
826 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{707106781186548, -9}));
829 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1414213562373095, -9}));
842 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
844 BEAST_EXPECT(
amm.expectBalances(
845 STAmount{usd, UINT64_C(2490000000000001), -12},
849 else if (!features[fixAMMClawbackRounding])
852 amm.expectBalances(usd(2'490),
XRP(4980),
IOUAmount{3521391770309006, -9}));
854 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
856 BEAST_EXPECT(
amm.expectBalances(
857 STAmount{usd, UINT64_C(2490000000000001), -12},
862 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
864 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865480, -10}));
866 else if (!features[fixAMMClawbackRounding])
868 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865474, -10}));
870 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
872 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{707106781186548, -9}));
875 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
877 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
879 else if (!features[fixAMMClawbackRounding])
881 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749364, -9}));
883 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
885 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
895 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
899 else if (!features[fixAMMClawbackRounding])
903 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
910 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
915 else if (!features[fixAMMClawbackRounding])
920 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
926 if (!features[fixAMMv1_3])
934 if (!features[fixAMMv1_3])
953 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
957 else if (!features[fixAMMClawbackRounding])
962 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
969 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
971 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
973 else if (!features[fixAMMClawbackRounding])
975 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749364, -9}));
977 else if (features[fixAMMClawbackRounding] && features[fixAMMv1_3])
979 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1400071426749365, -9}));
982 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
984 BEAST_EXPECT(
amm.expectBalances(
985 STAmount{usd, UINT64_C(1990000000000001), -12},
989 else if (!features[fixAMMClawbackRounding])
991 BEAST_EXPECT(
amm.expectBalances(
994 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
996 BEAST_EXPECT(
amm.expectBalances(
997 STAmount{usd, UINT64_C(1990000000000001), -12},
1039 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1044 else if (!features[fixAMMClawbackRounding])
1049 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1075 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1080 else if (!features[fixAMMClawbackRounding])
1085 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1096 testcase(
"test AMMClawback all the tokens in the AMM pool");
1097 using namespace jtx;
1102 Env env(*
this, features);
1104 Account const gw2{
"gateway2"};
1108 env.
fund(
XRP(1000000), gw, gw2, alice, bob, carol);
1112 env(
fset(gw, asfAllowTrustLineClawback));
1117 env(
fset(gw2, asfAllowTrustLineClawback));
1123 auto const usd = gw[
"USD"];
1124 env.
trust(usd(100000), alice);
1125 env(
pay(gw, alice, usd(6000)));
1126 env.
trust(usd(100000), bob);
1127 env(
pay(gw, bob, usd(5000)));
1128 env.
trust(usd(100000), carol);
1129 env(
pay(gw, carol, usd(4000)));
1134 auto const eur = gw2[
"EUR"];
1135 env.
trust(eur(100000), alice);
1136 env(
pay(gw2, alice, eur(6000)));
1137 env.
trust(eur(100000), bob);
1138 env(
pay(gw2, bob, eur(5000)));
1139 env.
trust(eur(100000), carol);
1140 env(
pay(gw2, carol, eur(4000)));
1147 if (!features[fixAMMv1_3])
1150 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999580, -12}));
1155 amm.expectBalances(usd(4000), eur(5000),
IOUAmount{4472135954999579, -12}));
1157 amm.deposit(bob, usd(2000), eur(2500));
1158 if (!features[fixAMMv1_3])
1161 amm.expectBalances(usd(6000), eur(7500),
IOUAmount{6708203932499370, -12}));
1166 amm.expectBalances(usd(6000), eur(7500),
IOUAmount{6708203932499368, -12}));
1168 amm.deposit(carol, usd(1000), eur(1250));
1169 if (!features[fixAMMv1_3])
1172 amm.expectBalances(usd(7000), eur(8750),
IOUAmount{7826237921249265, -12}));
1177 amm.expectBalances(usd(7000), eur(8750),
IOUAmount{7826237921249262, -12}));
1180 if (!features[fixAMMv1_3])
1182 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1186 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1188 if (!features[fixAMMv1_3])
1190 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2236067977499790, -12}));
1194 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2236067977499789, -12}));
1196 if (!features[fixAMMv1_3])
1198 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749895, -12}));
1202 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749894, -12}));
1216 if (!features[fixAMMv1_3])
1218 BEAST_EXPECT(
amm.expectBalances(
1219 STAmount{usd, UINT64_C(4999999999999999), -12},
1220 STAmount{eur, UINT64_C(6249999999999999), -12},
1225 BEAST_EXPECT(
amm.expectBalances(
1226 STAmount{usd, UINT64_C(5000000000000001), -12},
1227 STAmount{eur, UINT64_C(6250000000000001), -12},
1231 if (!features[fixAMMv1_3])
1233 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1237 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1240 if (!features[fixAMMv1_3])
1242 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749895, -12}));
1246 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount{1118033988749894, -12}));
1252 BEAST_EXPECT(env.
balance(bob, usd) ==
STAmount(usd, UINT64_C(3000000000000000), -12));
1254 if (!features[fixAMMv1_3])
1257 env.
balance(bob, eur) ==
STAmount(eur, UINT64_C(5000000000000001), -12));
1262 env.
balance(bob, eur) ==
STAmount(eur, UINT64_C(4999999999999999), -12));
1270 if (!features[fixAMMv1_3])
1272 BEAST_EXPECT(
amm.expectBalances(
1273 STAmount{usd, UINT64_C(3999999999999999), -12},
1274 STAmount{eur, UINT64_C(4999999999999999), -12},
1279 BEAST_EXPECT(
amm.expectBalances(
1280 STAmount{usd, UINT64_C(4000000000000001), -12},
1281 STAmount{eur, UINT64_C(5000000000000002), -12},
1285 if (!features[fixAMMv1_3])
1287 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999580, -12}));
1291 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4472135954999579, -12}));
1302 BEAST_EXPECT(!
amm.ammExists());
1308 Env env(*
this, features);
1312 env.
fund(
XRP(1000000), gw, alice, bob);
1316 env(
fset(gw, asfAllowTrustLineClawback));
1321 auto const usd = gw[
"USD"];
1322 env.
trust(usd(1000000), alice);
1323 env(
pay(gw, alice, usd(600000)));
1324 env.
trust(usd(1000000), bob);
1325 env(
pay(gw, bob, usd(500000)));
1330 if (!features[fixAMMv1_3])
1333 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999580, -9}));
1338 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999579, -9}));
1340 amm.deposit(alice, usd(1000),
XRP(200));
1341 if (!features[fixAMMv1_3])
1344 amm.expectBalances(usd(11000),
XRP(2200),
IOUAmount{4919349550499538, -9}));
1349 amm.expectBalances(usd(11000),
XRP(2200),
IOUAmount{4919349550499536, -9}));
1351 amm.deposit(bob, usd(2000),
XRP(400));
1352 if (!features[fixAMMv1_3])
1355 amm.expectBalances(usd(13000),
XRP(2600),
IOUAmount{5813776741499453, -9}));
1360 amm.expectBalances(usd(13000),
XRP(2600),
IOUAmount{5813776741499451, -9}));
1364 auto aliceXrpBalance = env.
balance(alice,
XRP);
1370 if (!features[fixAMMv1_3])
1373 amm.expectBalances(usd(12000),
XRP(2400),
IOUAmount{5366563145999495, -9}));
1377 BEAST_EXPECT(
amm.expectBalances(
1380 if (!features[fixAMMv1_3])
1394 if (!features[fixAMMv1_3])
1397 amm.expectBalances(usd(10000),
XRP(2000),
IOUAmount{4472135954999580, -9}));
1401 BEAST_EXPECT(
amm.expectBalances(
1414 "test AMMClawback from AMM pool with assets having the same "
1416 using namespace jtx;
1420 Env env(*
this, features);
1425 env.
fund(
XRP(1000000), gw, alice, bob, carol);
1429 env(
fset(gw, asfAllowTrustLineClawback));
1433 auto const usd = gw[
"USD"];
1434 env.
trust(usd(100000), alice);
1435 env(
pay(gw, alice, usd(10000)));
1436 env.
trust(usd(100000), bob);
1437 env(
pay(gw, bob, usd(9000)));
1438 env.
trust(usd(100000), carol);
1439 env(
pay(gw, carol, usd(8000)));
1442 auto const eur = gw[
"EUR"];
1443 env.
trust(eur(100000), alice);
1444 env(
pay(gw, alice, eur(10000)));
1445 env.
trust(eur(100000), bob);
1446 env(
pay(gw, bob, eur(9000)));
1447 env.
trust(eur(100000), carol);
1448 env(
pay(gw, carol, eur(8000)));
1454 BEAST_EXPECT(
amm.expectBalances(usd(8000), eur(2000),
IOUAmount(4000)));
1455 amm.deposit(bob, usd(4000), eur(1000));
1456 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
1457 if (!features[fixAMMv1_3])
1459 amm.deposit(carol, usd(2000), eur(500));
1463 amm.deposit(carol, usd(2000.25), eur(500));
1465 BEAST_EXPECT(
amm.expectBalances(usd(14000), eur(3500),
IOUAmount(7000)));
1469 BEAST_EXPECT(
amm.expectBalances(usd(13000), eur(3250),
IOUAmount(6500)));
1471 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
1472 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(2000)));
1473 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1474 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1475 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1476 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1477 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1478 if (!features[fixAMMv1_3])
1480 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1485 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1488 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1497 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
1499 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
1500 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
1501 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1502 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1503 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1504 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1506 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1507 if (!features[fixAMMv1_3])
1509 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1514 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1516 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1523 BEAST_EXPECT(
amm.expectBalances(usd(4000), eur(1000),
IOUAmount(2000)));
1526 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
1527 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
1528 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1529 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
1530 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
1531 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
1532 if (!features[fixAMMv1_3])
1534 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
1539 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
1541 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
1644 testcase(
"test AMMClawback when issuing token for each other");
1645 using namespace jtx;
1649 Env env(*
this, features);
1651 Account const gw2{
"gateway2"};
1653 env.
fund(
XRP(1000000), gw, gw2, alice);
1657 env(
fset(gw, asfAllowTrustLineClawback));
1662 env(
fset(gw2, asfAllowTrustLineClawback));
1666 auto const usd = gw[
"USD"];
1667 env.
trust(usd(100000), gw2);
1668 env(
pay(gw, gw2, usd(5000)));
1669 env.
trust(usd(100000), alice);
1670 env(
pay(gw, alice, usd(5000)));
1672 auto const eur = gw2[
"EUR"];
1673 env.
trust(eur(100000), gw);
1674 env(
pay(gw2, gw, eur(6000)));
1675 env.
trust(eur(100000), alice);
1676 env(
pay(gw2, alice, eur(6000)));
1681 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(2000),
IOUAmount{1414213562373095, -12}));
1683 amm.deposit(gw2, usd(2000), eur(4000));
1684 BEAST_EXPECT(
amm.expectBalances(usd(3000), eur(6000),
IOUAmount{4242640687119285, -12}));
1686 amm.deposit(alice, usd(3000), eur(6000));
1687 BEAST_EXPECT(
amm.expectBalances(usd(6000), eur(12000),
IOUAmount{8485281374238570, -12}));
1689 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414213562373095, -12}));
1690 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{2828427124746190, -12}));
1691 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1696 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1699 amm.expectBalances(usd(5000), eur(10000),
IOUAmount{7071067811865475, -12}));
1704 amm.expectBalances(usd(5000), eur(10000),
IOUAmount{7071067811865474, -12}));
1707 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414213562373095, -12}));
1708 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1710 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1714 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1716 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1718 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1719 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1720 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1721 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1726 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1728 BEAST_EXPECT(
amm.expectBalances(
1730 STAmount(eur, UINT64_C(9000000000000001), -12),
1733 else if (!features[fixAMMClawbackRounding])
1736 amm.expectBalances(usd(4500), eur(9000),
IOUAmount{6363961030678928, -12}));
1738 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1740 BEAST_EXPECT(
amm.expectBalances(
1742 STAmount(eur, UINT64_C(9000000000000001), -12),
1746 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1748 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1750 else if (!features[fixAMMClawbackRounding])
1752 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865475, -13}));
1754 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1756 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1759 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1761 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1765 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1768 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242640687119285, -12}));
1770 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
1771 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1772 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1773 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1778 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1780 BEAST_EXPECT(
amm.expectBalances(
1782 STAmount(eur, UINT64_C(5000000000000001), -12),
1785 else if (!features[fixAMMClawbackRounding])
1788 amm.expectBalances(usd(2500), eur(5000),
IOUAmount{3535533905932738, -12}));
1790 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1792 BEAST_EXPECT(
amm.expectBalances(
1794 STAmount(eur, UINT64_C(5000000000000001), -12),
1798 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
1800 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1802 else if (!features[fixAMMClawbackRounding])
1804 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865475, -13}));
1806 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1808 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{7071067811865480, -13}));
1811 if (!features[fixAMMv1_3] || !features[fixAMMClawbackRounding])
1813 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373095, -12}));
1817 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414213562373094, -12}));
1819 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1414213562373095, -12}));
1821 BEAST_EXPECT(env.
balance(alice, usd) == usd(4000));
1822 BEAST_EXPECT(env.
balance(alice, eur) == eur(0));
1823 BEAST_EXPECT(env.
balance(gw, eur) == eur(4000));
1824 BEAST_EXPECT(env.
balance(gw2, usd) == usd(3000));
1862 using namespace jtx;
1866 Env env(*
this, features);
1868 Account const gw2{
"gateway2"};
1870 env.
fund(
XRP(1000000), gw, gw2, alice);
1874 env(
fset(gw, asfAllowTrustLineClawback));
1879 auto const usd = gw[
"USD"];
1880 env.
trust(usd(100000), alice);
1881 env(
pay(gw, alice, usd(3000)));
1886 auto const eur = gw2[
"EUR"];
1887 env.
trust(eur(100000), alice);
1888 env(
pay(gw2, alice, eur(3000)));
1897 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
1900 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1909 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
1912 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
1925 BEAST_EXPECT(!
amm.ammExists());
1930 Env env(*
this, features);
1932 Account const gw2{
"gateway2"};
1934 env.
fund(
XRP(1000000), gw, gw2, alice);
1938 env(
fset(gw, asfAllowTrustLineClawback));
1943 auto const usd = gw[
"USD"];
1944 env.
trust(usd(100000), alice);
1945 env(
pay(gw, alice, usd(3000)));
1950 auto const eur = gw2[
"EUR"];
1951 env.
trust(eur(100000), alice);
1952 env(
pay(gw2, alice, eur(3000)));
1961 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
1964 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1965 env(
trust(gw2, alice[
"EUR"](0), tfSetFreeze));
1974 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
1975 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
1980 Env env(*
this, features);
1982 Account const gw2{
"gateway2"};
1984 env.
fund(
XRP(1000000), gw, gw2, alice);
1988 env(
fset(gw, asfAllowTrustLineClawback));
1993 auto const usd = gw[
"USD"];
1994 env.
trust(usd(100000), alice);
1995 env(
pay(gw, alice, usd(3000)));
2000 auto const eur = gw2[
"EUR"];
2001 env.
trust(eur(100000), alice);
2002 env(
pay(gw2, alice, eur(3000)));
2011 amm.expectBalances(usd(2000), eur(1000),
IOUAmount{1414213562373095, -12}));
2014 env(
fset(gw, asfGlobalFreeze));
2023 BEAST_EXPECT(
amm.expectBalances(usd(1000), eur(500),
IOUAmount{7071067811865475, -13}));
2024 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{7071067811865475, -13}));
2030 Env env(*
this, features);
2035 env.
fund(
XRP(1000000), gw, alice, bob, carol);
2039 env(
fset(gw, asfAllowTrustLineClawback));
2043 auto const usd = gw[
"USD"];
2044 env.
trust(usd(100000), alice);
2045 env(
pay(gw, alice, usd(10000)));
2046 env.
trust(usd(100000), bob);
2047 env(
pay(gw, bob, usd(9000)));
2048 env.
trust(usd(100000), carol);
2049 env(
pay(gw, carol, usd(8000)));
2052 auto const eur = gw[
"EUR"];
2053 env.
trust(eur(100000), alice);
2054 env(
pay(gw, alice, eur(10000)));
2055 env.
trust(eur(100000), bob);
2056 env(
pay(gw, bob, eur(9000)));
2057 env.
trust(eur(100000), carol);
2058 env(
pay(gw, carol, eur(8000)));
2064 BEAST_EXPECT(
amm.expectBalances(usd(8000), eur(2000),
IOUAmount(4000)));
2065 amm.deposit(bob, usd(4000), eur(1000));
2066 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
2067 if (!features[fixAMMv1_3])
2069 amm.deposit(carol, usd(2000), eur(500));
2073 amm.deposit(carol, usd(2000.25), eur(500));
2075 BEAST_EXPECT(
amm.expectBalances(usd(14000), eur(3500),
IOUAmount(7000)));
2078 env(
fset(gw, asfGlobalFreeze));
2084 BEAST_EXPECT(
amm.expectBalances(usd(13000), eur(3250),
IOUAmount(6500)));
2086 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
2087 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(2000)));
2088 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2089 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2090 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2091 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2092 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2093 if (!features[fixAMMv1_3])
2095 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2100 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2103 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2112 BEAST_EXPECT(
amm.expectBalances(usd(12000), eur(3000),
IOUAmount(6000)));
2114 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount(4000)));
2115 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
2116 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2117 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2118 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2119 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2121 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2122 if (!features[fixAMMv1_3])
2124 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2129 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2131 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2138 BEAST_EXPECT(
amm.expectBalances(usd(4000), eur(1000),
IOUAmount(2000)));
2141 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(1500)));
2142 BEAST_EXPECT(
amm.expectLPTokens(carol,
IOUAmount(500)));
2143 BEAST_EXPECT(env.
balance(alice, usd) == usd(2000));
2144 BEAST_EXPECT(env.
balance(alice, eur) == eur(8000));
2145 BEAST_EXPECT(env.
balance(bob, usd) == usd(5000));
2146 BEAST_EXPECT(env.
balance(bob, eur) == eur(8000));
2147 if (!features[fixAMMv1_3])
2149 BEAST_EXPECT(env.
balance(carol, usd) == usd(6000));
2154 env.
balance(carol, usd) ==
STAmount(usd, UINT64_C(5999'999999999999), -12));
2156 BEAST_EXPECT(env.
balance(carol, eur) == eur(7750));
2228 "test last holder's lptoken balance not equal to AMM's lptoken "
2229 "balance before clawback");
2230 using namespace jtx;
2233 auto setupAccounts =
2235 env.
fund(
XRP(100000), gw, alice, bob);
2237 env(
fset(gw, asfAllowTrustLineClawback));
2240 auto const usd = gw[
"USD"];
2241 env.
trust(usd(100000), alice);
2242 env(
pay(gw, alice, usd(50000)));
2243 env.
trust(usd(100000), bob);
2244 env(
pay(gw, bob, usd(40000)));
2250 auto getLPTokenBalances = [&](
auto& env,
2253 auto const lpToken =
2256 auto const lpTokenBalance =
2257 amm.ammRpcInfo()[jss::amm][jss::lp_token][jss::value].asString();
2258 return {lpToken, lpTokenBalance};
2264 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2265 auto const usd = setupAccounts(env, gw, alice, bob);
2270 amm.withdraw(alice,
IOUAmount{1'876123487565916, -15});
2271 amm.withdrawAll(bob);
2273 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2274 BEAST_EXPECT(lpToken ==
"1414.21356237366" && lpTokenBalance ==
"1414.213562374");
2277 BEAST_EXPECT(res && res.value());
2279 if (!features[fixAMMClawbackRounding] || !features[fixAMMv1_3])
2282 BEAST_EXPECT(
amm.ammExists());
2286 auto const lpBalance =
IOUAmount{989, -12};
2288 BEAST_EXPECT(
amm.expectBalances(
2290 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));
2297 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2298 auto const usd = setupAccounts(env, gw, alice, bob);
2303 amm.withdrawAll(bob);
2305 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2306 BEAST_EXPECT(lpToken ==
"1416.08968586066" && lpTokenBalance ==
"1416.089685861");
2309 BEAST_EXPECT(res && res.value());
2313 if (!features[fixAMMv1_3] && !features[fixAMMClawbackRounding])
2315 BEAST_EXPECT(
amm.expectBalances(
2316 STAmount(usd, UINT64_C(5013266196406), -13),
2320 else if (!features[fixAMMClawbackRounding])
2322 BEAST_EXPECT(
amm.expectBalances(
2323 STAmount(usd, UINT64_C(5013266196407), -13),
2327 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2329 auto const lpBalance =
IOUAmount{708'9829046743238, -13};
2330 BEAST_EXPECT(
amm.expectBalances(
2331 STAmount(usd, UINT64_C(5013266196406999), -16),
XRPAmount(1002655), lpBalance));
2332 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));
2339 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2340 auto const usd = setupAccounts(env, gw, alice, bob);
2345 amm.withdraw(alice,
IOUAmount{1'876123487565916, -15});
2346 amm.withdrawAll(bob);
2348 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2349 BEAST_EXPECT(lpToken ==
"1414.21356237366" && lpTokenBalance ==
"1414.213562374");
2352 BEAST_EXPECT(res && res.value());
2354 if (!features[fixAMMClawbackRounding] && !features[fixAMMv1_3])
2358 else if (!features[fixAMMClawbackRounding])
2361 BEAST_EXPECT(
amm.expectBalances(
2362 STAmount(usd, UINT64_C(2410000000000000), -28),
2366 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2369 BEAST_EXPECT(!
amm.ammExists());
2376 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2377 auto const usd = setupAccounts(env, gw, alice, bob);
2379 Account const gw2{
"gateway2"};
2382 auto const eur = gw2[
"EUR"];
2383 env.
trust(eur(100000), alice);
2384 env(
pay(gw2, alice, eur(50000)));
2385 env.
trust(eur(100000), bob);
2386 env(
pay(gw2, bob, eur(50000)));
2389 AMM amm(env, alice, usd(2), eur(1));
2392 amm.withdraw(alice,
IOUAmount{1'576123487565916, -15});
2393 amm.withdrawAll(bob);
2395 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2396 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
2399 BEAST_EXPECT(res && res.value());
2401 if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2404 BEAST_EXPECT(!
amm.ammExists());
2409 BEAST_EXPECT(
amm.ammExists());
2416 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2417 auto const usd = setupAccounts(env, gw, alice, bob);
2419 auto const eur = gw[
"EUR"];
2420 env.
trust(eur(100000), alice);
2421 env(
pay(gw, alice, eur(50000)));
2422 env.
trust(eur(100000), bob);
2423 env(
pay(gw, bob, eur(50000)));
2426 AMM amm(env, alice, usd(1), eur(2));
2429 amm.withdraw(alice,
IOUAmount{1'076123487565916, -15});
2430 amm.withdrawAll(bob);
2432 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2433 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
2436 BEAST_EXPECT(res && res.value());
2438 if (features[fixAMMClawbackRounding])
2441 BEAST_EXPECT(!
amm.ammExists());
2448 BEAST_EXPECT(
amm.ammExists());
2455 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
2456 auto const usd = setupAccounts(env, gw, alice, bob);
2458 auto const eur = gw[
"EUR"];
2459 env.
trust(eur(1000000000), alice);
2460 env(
pay(gw, alice, eur(500000000)));
2461 env.
trust(eur(1000000000), bob);
2462 env(
pay(gw, bob, eur(500000000)));
2465 AMM amm(env, alice, usd(1), eur(2000000));
2468 amm.withdraw(alice,
IOUAmount{1'076123487565916, -12});
2469 amm.withdrawAll(bob);
2471 auto [lpToken, lpTokenBalance] = getLPTokenBalances(env,
amm, alice);
2473 BEAST_EXPECT(lpToken ==
"1414.213562373101" && lpTokenBalance ==
"1414.2135623731");
2476 BEAST_EXPECT(res && res.value());
2478 if (!features[fixAMMClawbackRounding] && !features[fixAMMv1_3])
2481 BEAST_EXPECT(
amm.expectBalances(
2486 else if (!features[fixAMMClawbackRounding])
2492 if (features[fixCleanup3_3_0])
2500 BEAST_EXPECT(
amm.ammExists());
2502 else if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
2505 auto const lpBalance =
IOUAmount{5, -12};
2506 BEAST_EXPECT(
amm.expectBalances(
2507 STAmount(usd, UINT64_C(4), -15),
STAmount(eur, UINT64_C(8), -9), lpBalance));
2508 BEAST_EXPECT(
amm.expectLPTokens(alice, lpBalance));