38 for (
auto const& feature : {features, features - featureSingleAssetVault})
40 Env env(*
this, feature);
44 env.
fund(
XRP(100000), gw, alice, bob);
47 env(
fset(gw, asfAllowTrustLineClawback));
57 auto const usd = gw[
"USD"];
58 env.
trust(usd(10000), alice);
59 env(
pay(gw, alice, usd(100)));
62 AMM amm(env, gw, btc(100), usd(100));
74 gw, alice,
Issue{gw[
"USD"].currency, alice.
id()}, btc, std::nullopt),
83 gw, alice, usd, btc,
STAmount{
Issue{gw[
"USD"].currency, alice.
id()}, 1}),
101 Issue const ammUsd(usd.currency,
amm.ammAccount());
105 env(
claw(gw, amount),
Ter(err));
112 BEAST_EXPECT(!
amm.ammExists());
120 Env env(*
this, features);
123 env.
fund(
XRP(100000), gw, alice);
126 env(
fset(gw, asfAllowTrustLineClawback));
130 MPTTester({.env = env, .issuer = gw, .holders = {alice}, .pay = 40'000});
132 auto const usd = gw[
"USD"];
133 env.
trust(usd(10000), alice);
134 env(
pay(gw, alice, usd(10000)));
137 AMM amm(env, gw, btc(100), usd(100));
139 amm.deposit(alice, 1'000);
149 Env env(*
this, features);
153 env.
fund(
XRP(100000), gw, gw2, alice);
156 env(
fset(gw, asfAllowTrustLineClawback));
159 auto const usd = gw[
"USD"];
160 env.
trust(usd(10000), alice);
161 env(
pay(gw, alice, usd(10000)));
172 AMM const amm(env, alice, btc(100), usd(100));
189 Env env(*
this, features);
192 env.
fund(
XRP(10000), gw, alice);
202 AMM const amm(env, alice, btc(100),
XRP(100));
249 testcase(
"test AMMClawback specific amount");
254 Env env(*
this, features);
258 env.
fund(
XRP(100000), gw, gw2, alice);
261 env(
fset(gw, asfAllowTrustLineClawback));
262 env(
fset(gw2, asfAllowTrustLineClawback));
265 auto const usd = gw[
"USD"];
266 env.
trust(usd(100000), alice);
267 env(
pay(gw, alice, usd(50000)));
274 .pay = 40'000'000000,
277 AMM const amm(env, alice, btc(1000000000), usd(2000));
279 BEAST_EXPECT(
amm.expectBalances(
280 btc(1'000'000000), usd(2000),
IOUAmount{1414'213'562373095, -9}));
288 auto aliceUSD = env.
balance(alice, usd);
289 auto aliceBTC = env.
balance(alice, btc);
295 amm.expectBalances(btc(500'000000), usd(1000),
IOUAmount{707'106'7811865475, -10}));
300 aliceBTC = env.
balance(alice, btc);
306 amm.expectBalances(btc(250'000000), usd(500),
IOUAmount{353'553'3905932737, -10}));
309 aliceUSD = env.
balance(alice, usd);
315 BEAST_EXPECT(!
amm.ammExists());
322 Env env(*
this, features);
326 env.
fund(
XRP(100000), gw, alice, bob);
329 env(
fset(gw, asfAllowTrustLineClawback));
335 .holders = {alice, bob},
336 .pay = 40'000'000000,
339 AMM amm(env, alice, btc(1000000000),
XRP(2000));
341 BEAST_EXPECT(
amm.expectBalances(
342 btc(1'000'000000),
XRP(2000),
IOUAmount{1'414'213'562'373095, -6}));
344 amm.deposit(bob, btc(2'000'000000),
XRP(4000));
345 BEAST_EXPECT(
amm.expectBalances(
346 btc(3'000'000000),
XRP(6000),
IOUAmount{4'242'640'687'119285, -6}));
349 auto aliceBTC = env.
balance(alice, btc);
351 auto bobBTC = env.
balance(bob, btc);
363 BEAST_EXPECT(
amm.expectBalances(
371 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'414'212'855'266314, -6}));
372 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2'828'427'124'74619, -5}));
378 BEAST_EXPECT(
amm.expectBalances(
386 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'414'212'855'266314, -6}));
387 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1'414'213'562'844499, -6}));
394 BEAST_EXPECT(
amm.expectBalances(
401 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{1'414'213'562'844499, -6}));
408 BEAST_EXPECT(!
amm.ammExists());
417 Env env(*
this, features);
422 env.
fund(
XRP(100000), gw, gw2, alice, bob);
425 env(
fset(gw, asfAllowTrustLineClawback));
426 env(
fset(gw2, asfAllowTrustLineClawback));
432 .holders = {alice, bob},
433 .pay = 40'000'000000,
439 .holders = {alice, bob},
440 .pay = 30'000'000000,
443 AMM amm(env, alice, btc(2'000'000000), eth(3'000'000000));
445 BEAST_EXPECT(
amm.expectBalances(
446 btc(2'000'000000), eth(3'000'000000),
IOUAmount{2'449'489'742'783178, -6}));
448 amm.deposit(bob, btc(4'000'000000), eth(6'000'000000));
449 BEAST_EXPECT(
amm.expectBalances(
450 btc(6'000'000000), eth(9'000'000000),
IOUAmount{7'348'469'228'349534, -6}));
452 auto aliceBTC = env.
balance(alice, btc);
453 auto aliceETH = env.
balance(alice, eth);
454 auto bobBTC = env.
balance(bob, btc);
455 auto bobETH = env.
balance(bob, eth);
460 BEAST_EXPECT(
amm.expectBalances(
461 btc(5'000'000000), eth(7'500'000000),
IOUAmount{6'123'724'356'957944, -6}));
466 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'224'744'871'391588, -6}));
467 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{4'898'979'485'566356, -6}));
468 aliceETH = env.
balance(alice, eth);
473 BEAST_EXPECT(
amm.expectBalances(
474 btc(3'000'000000), eth(4'500'000000),
IOUAmount{3'674'234'614'174766, -6}));
479 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'224'744'871'391588, -6}));
480 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2'449'489'742'783178, -6}));
481 bobBTC = env.
balance(bob, btc);
486 BEAST_EXPECT(
amm.expectBalances(
487 btc(2'000'000001), eth(3'000'000001),
IOUAmount{2'449'489'742'783178, -6}));
492 aliceBTC = env.
balance(alice, btc);
498 BEAST_EXPECT(!
amm.ammExists());
514 Env env(*
this, features);
519 env.
fund(
XRP(100000), gw, gw2, alice, bob);
522 env(
fset(gw, asfAllowTrustLineClawback));
523 env(
fset(gw2, asfAllowTrustLineClawback));
526 auto const usd = gw[
"USD"];
527 env.
trust(usd(100000), alice);
528 env(
pay(gw, alice, usd(50000)));
529 env.
trust(usd(200000), bob);
530 env(
pay(gw, bob, usd(60000)));
536 .holders = {alice, bob},
537 .pay = 40'000'000000,
540 AMM amm(env, alice, btc(2000000000), usd(2000));
542 BEAST_EXPECT(
amm.expectBalances(btc(2'000'000000), usd(2000),
IOUAmount(2000000)));
545 amm.deposit(bob, btc(1'000'000000), usd(2000));
547 BEAST_EXPECT(
amm.expectBalances(btc(3'000'000000), usd(3000),
IOUAmount(3000000)));
549 auto aliceBTC = env.
balance(alice, btc);
550 auto aliceUSD = env.
balance(alice, usd);
551 auto bobBTC = env.
balance(bob, btc);
552 auto bobUSD = env.
balance(bob, usd);
557 BEAST_EXPECT(
amm.expectBalances(btc(1'000'000000), usd(1000),
IOUAmount(1000000)));
562 aliceUSD = env.
balance(alice, usd);
568 BEAST_EXPECT(!
amm.ammExists());
577 Env env(*
this, features);
581 env.
fund(
XRP(100000), gw, alice, bob);
584 env(
fset(gw, asfAllowTrustLineClawback));
590 .holders = {alice, bob},
591 .pay = 40'000'000000,
594 AMM amm(env, alice, btc(5000),
XRP(10'000));
597 amm.expectBalances(btc(5'000),
XRP(10'000),
IOUAmount{7'071'067'811865475, -9}));
599 amm.deposit(bob, btc(10'000),
XRP(20'000));
601 amm.expectBalances(btc(15'000),
XRP(30'000),
IOUAmount{21'213'203'43559642, -8}));
604 auto aliceBTC = env.
balance(alice, btc);
606 auto bobBTC = env.
balance(bob, btc);
612 amm.expectBalances(btc(10'000),
XRP(20'000),
IOUAmount{14'142'135'62373094, -8}));
623 BEAST_EXPECT(!
amm.ammExists());
632 Env env(*
this, features);
637 env.
fund(
XRP(100000), gw, gw2, alice, bob);
640 env(
fset(gw, asfAllowTrustLineClawback));
641 env(
fset(gw2, asfAllowTrustLineClawback));
647 .holders = {alice, bob},
648 .pay = 40'000'000000,
654 .holders = {alice, bob},
655 .pay = 30'000'000000,
658 AMM amm(env, alice, btc(20'000), eth(50'000));
661 amm.expectBalances(btc(20'000), eth(50'000),
IOUAmount{31'622'77660168379, -11}));
663 amm.deposit(bob, btc(40'000), eth(100'000));
665 amm.expectBalances(btc(60'000), eth(150'000),
IOUAmount{94'868'32980505137, -11}));
667 auto aliceBTC = env.
balance(alice, btc);
668 auto aliceETH = env.
balance(alice, eth);
669 auto bobBTC = env.
balance(bob, btc);
670 auto bobETH = env.
balance(bob, eth);
676 amm.expectBalances(btc(20'000), eth(50'000),
IOUAmount{31'622'77660168379, -11}));
681 bobETH = env.
balance(bob, eth);
687 BEAST_EXPECT(!
amm.ammExists());
698 testcase(
"test AMMClawback specific amount, assets have the same issuer");
703 Env env(*
this, features);
707 env.
fund(
XRP(100000), gw, alice, bob);
710 env(
fset(gw, asfAllowTrustLineClawback));
713 auto const usd = gw[
"USD"];
714 env.
trust(usd(100000), alice);
715 env(
pay(gw, alice, usd(50000)));
716 env.
trust(usd(100000), bob);
717 env(
pay(gw, bob, usd(40000)));
723 .holders = {alice, bob},
724 .pay = 40'000'000000,
727 AMM amm(env, alice, btc(1'000'000000), usd(2000));
729 BEAST_EXPECT(
amm.expectBalances(
730 btc(1'000'000000), usd(2000),
IOUAmount{1414'213'562373095, -9}));
732 amm.deposit(bob, btc(500'000000), usd(1000));
733 BEAST_EXPECT(
amm.expectBalances(
735 STAmount{usd, UINT64_C(2'999'999999999999), -12},
738 auto aliceUSD = env.
balance(alice, usd);
739 auto aliceBTC = env.
balance(alice, btc);
740 auto bobUSD = env.
balance(bob, usd);
741 auto bobBTC = env.
balance(bob, btc);
746 BEAST_EXPECT(
amm.expectBalances(
747 btc(1250'000001), usd(2500),
IOUAmount{1'767'766'952966369, -9}));
752 aliceBTC = env.
balance(alice, btc);
757 BEAST_EXPECT(
amm.expectBalances(
759 STAmount{usd, UINT64_C(2000'0000004), -7},
765 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'060'660'171779822, -9}));
766 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{353'553'390876116, -9}));
771 BEAST_EXPECT(
amm.expectBalances(
773 STAmount{usd, UINT64_C(500'0000004), -7},
780 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{353'553'390876116, -9}));
781 aliceBTC = env.
balance(alice, btc);
788 BEAST_EXPECT(!
amm.ammExists());
799 Env env(*
this, features);
803 env.
fund(
XRP(100000), gw, alice, bob);
806 env(
fset(gw, asfAllowTrustLineClawback));
812 .holders = {alice, bob},
813 .pay = 40'000'000000,
819 .holders = {alice, bob},
820 .pay = 30'000'000000,
823 AMM amm(env, alice, btc(2'000'000000), eth(3'000'000000));
825 BEAST_EXPECT(
amm.expectBalances(
826 btc(2'000'000000), eth(3'000'000000),
IOUAmount{2'449'489'742'783178, -6}));
828 amm.deposit(bob, btc(4'000'000000), eth(6'000'000000));
829 BEAST_EXPECT(
amm.expectBalances(
830 btc(6'000'000000), eth(9'000'000000),
IOUAmount{7'348'469'228'349534, -6}));
832 auto aliceBTC = env.
balance(alice, btc);
833 auto aliceETH = env.
balance(alice, eth);
834 auto bobBTC = env.
balance(bob, btc);
835 auto bobETH = env.
balance(bob, eth);
840 BEAST_EXPECT(
amm.expectBalances(
841 btc(5'000'000000), eth(7'500'000000),
IOUAmount{6'123'724'356'957944, -6}));
846 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'224'744'871'391588, -6}));
847 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{4'898'979'485'566356, -6}));
848 aliceETH = env.
balance(alice, eth);
853 BEAST_EXPECT(
amm.expectBalances(
854 btc(3'000'000000), eth(4'500'000000),
IOUAmount{3'674'234'614'174766, -6}));
859 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1'224'744'871'391588, -6}));
860 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2'449'489'742'783178, -6}));
866 BEAST_EXPECT(
amm.expectBalances(
867 btc(2'000'000001), eth(3'000'000001),
IOUAmount{2'449'489'742'783178, -6}));
873 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount{2'449'489'742'783178, -6}));
879 BEAST_EXPECT(!
amm.ammExists());
890 testcase(
"test AMMClawback all, assets have the same issuer");
895 Env env(*
this, features);
899 env.
fund(
XRP(100000), gw, alice, bob);
902 env(
fset(gw, asfAllowTrustLineClawback));
905 auto const usd = gw[
"USD"];
906 env.
trust(usd(100000), alice);
907 env(
pay(gw, alice, usd(50000)));
908 env.
trust(usd(200000), bob);
909 env(
pay(gw, bob, usd(60000)));
915 .holders = {alice, bob},
916 .pay = 40'000'000000,
919 AMM amm(env, alice, btc(2'000'000000), usd(8'000));
921 BEAST_EXPECT(
amm.expectBalances(btc(2'000'000000), usd(8'000),
IOUAmount(4'000'000)));
923 amm.deposit(bob, btc(1'000'000000), usd(4'000));
925 BEAST_EXPECT(
amm.expectBalances(btc(3'000'000000), usd(12'000),
IOUAmount(6'000'000)));
927 auto aliceBTC = env.
balance(alice, btc);
928 auto aliceUSD = env.
balance(alice, usd);
929 auto bobBTC = env.
balance(bob, btc);
930 auto bobUSD = env.
balance(bob, usd);
936 BEAST_EXPECT(
amm.expectBalances(btc(1'000'000000), usd(4'000),
IOUAmount(2'000'000)));
937 BEAST_EXPECT(
amm.expectLPTokens(bob,
IOUAmount(2'000'000)));
948 BEAST_EXPECT(!
amm.ammExists());
957 Env env(*
this, features);
961 env.
fund(
XRP(100000), gw, alice, bob);
964 env(
fset(gw, asfAllowTrustLineClawback));
970 .holders = {alice, bob},
971 .pay = 40'000'000000,
977 .holders = {alice, bob},
978 .pay = 30'000'000000,
981 AMM amm(env, alice, btc(20'000), eth(10'000));
984 amm.expectBalances(btc(20'000), eth(10'000),
IOUAmount{14'142'13562373095, -11}));
986 amm.deposit(bob, btc(40'000), eth(20'000));
988 amm.expectBalances(btc(60'000), eth(30'000),
IOUAmount{42'426'40687119285, -11}));
990 auto aliceBTC = env.
balance(alice, btc);
991 auto aliceETH = env.
balance(alice, eth);
992 auto bobBTC = env.
balance(bob, btc);
993 auto bobETH = env.
balance(bob, eth);
999 amm.expectBalances(btc(20'000), eth(10'000),
IOUAmount{14'142'13562373095, -11}));
1004 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{14'142'13562373095, -11}));
1006 bobBTC = env.
balance(bob, btc);
1013 BEAST_EXPECT(!
amm.ammExists());
1024 testcase(
"test AMMClawback when issuing token for each other");
1025 using namespace jtx;
1029 Env env(*
this, features);
1031 Account const gw2{
"gateway2"};
1033 env.
fund(
XRP(1000000), gw, gw2, alice);
1036 env(
fset(gw, asfAllowTrustLineClawback));
1037 env(
fset(gw2, asfAllowTrustLineClawback));
1040 auto const usd = gw[
"USD"];
1041 env.
trust(usd(100000), gw2);
1042 env(
pay(gw, gw2, usd(5000)));
1043 env.
trust(usd(100000), alice);
1044 env(
pay(gw, alice, usd(5000)));
1049 .holders = {alice, gw},
1050 .pay = 40'000'000000,
1053 AMM amm(env, gw, usd(1000), btc(2000));
1056 amm.expectBalances(usd(1000), btc(2000),
IOUAmount{1414'213562373095, -12}));
1058 amm.deposit(gw2, usd(2000), btc(4000));
1060 amm.expectBalances(usd(3000), btc(6000),
IOUAmount{4242'640687119285, -12}));
1062 amm.deposit(alice, usd(3000), btc(6000));
1064 amm.expectBalances(usd(6000), btc(12000),
IOUAmount{8485'281374238570, -12}));
1066 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414'213562373095, -12}));
1067 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{2828'427124746190, -12}));
1068 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242'640687119285, -12}));
1070 auto aliceBTC = env.
balance(alice, btc);
1071 auto aliceUSD = env.
balance(alice, usd);
1072 auto gwBTC = env.
balance(gw, btc);
1073 auto gw2USD = env.
balance(gw2, usd);
1079 amm.expectBalances(usd(5000), btc(10000),
IOUAmount{7071'067811865474, -12}));
1080 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{1414'213562373095, -12}));
1081 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414'213562373094, -12}));
1082 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242'640687119285, -12}));
1092 amm.expectBalances(usd(4500), btc(9001),
IOUAmount{6363'961030678927, -12}));
1094 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{707'1067811865480, -13}));
1095 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414'213562373094, -12}));
1096 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{4242'640687119285, -12}));
1105 BEAST_EXPECT(
amm.expectBalances(
1106 STAmount{usd, UINT64_C(2500'222197533607), -12},
1110 BEAST_EXPECT(
amm.expectLPTokens(gw,
IOUAmount{707'1067811865480, -13}));
1111 BEAST_EXPECT(
amm.expectLPTokens(gw2,
IOUAmount{1414'213562373094, -12}));
1112 BEAST_EXPECT(
amm.expectLPTokens(alice,
IOUAmount{1414'527797138648, -12}));
1121 Env env(*
this, features);
1123 Account const gw2{
"gateway2"};
1125 env.
fund(
XRP(100000), gw, gw2, alice);
1128 env(
fset(gw, asfAllowTrustLineClawback));
1129 env(
fset(gw2, asfAllowTrustLineClawback));
1135 .holders = {gw2, alice},
1136 .pay = 40'000'000000,
1142 .holders = {gw, alice},
1143 .pay = 30'000'000000,
1146 AMM amm(env, gw, btc(10'000), eth(50'000));
1149 amm.expectBalances(btc(10'000), eth(50'000),
IOUAmount{22'360'67977499789, -11}));
1151 amm.deposit(gw2, btc(20'000), eth(100'000));
1153 amm.expectBalances(btc(30'000), eth(150'000),
IOUAmount{67'082'03932499367, -11}));
1155 amm.deposit(alice, btc(40'000), eth(200'000));
1157 amm.expectBalances(btc(70'000), eth(350'000),
IOUAmount{156'524'7584249852, -10}));
1159 auto aliceBTC = env.
balance(alice, btc);
1160 auto aliceETH = env.
balance(alice, eth);
1161 auto gw2BTC = env.
balance(gw2, btc);
1162 auto gwETH = env.
balance(gw, eth);
1168 amm.expectBalances(btc(69'001), eth(345'001),
IOUAmount{154'288'6904474855, -10}));
1178 amm.expectBalances(btc(59'001), eth(295'001),
IOUAmount{131'928'0106724876, -10}));
1188 amm.expectBalances(btc(19'001), eth(95'001),
IOUAmount{42'485'29157249607, -11}));
1199 testcase(
"test AMMClawback when asset is frozen or locked");
1200 using namespace jtx;
1204 Env env{*
this, features};
1207 env.
fund(
XRP(1'000'000), gw, alice);
1209 env(
fset(gw, asfAllowTrustLineClawback));
1211 auto const usd = gw[
"USD"];
1212 env.
trust(usd(1'000'000), alice);
1213 env(
pay(gw, alice, usd(500'000)));
1220 .flags = tfMPTCanClawback | tfMPTCanLock |
kMptDexFlags});
1221 AMM const ammAlice(env, alice, usd(10'000), btc(10'000));
1222 BEAST_EXPECT(ammAlice.expectBalances(usd(10'000), btc(10'000),
IOUAmount(10'000)));
1225 auto aliceBTC = env.
balance(alice,
MPT(btc));
1226 auto aliceUSD = env.
balance(alice, usd);
1230 btc.set({.flags = tfMPTLock});
1232 BEAST_EXPECT(ammAlice.expectBalances(usd(9'000), btc(9'000),
IOUAmount(9'000)));
1235 aliceUSD = env.
balance(alice, usd);
1238 btc.set({.flags = tfMPTUnlock});
1240 BEAST_EXPECT(ammAlice.expectBalances(
1241 STAmount(usd, UINT64_C(7'000'000000000001), -12), btc(7'001),
IOUAmount(7'000)));
1244 aliceUSD = env.
balance(alice, usd);
1248 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1251 BEAST_EXPECT(ammAlice.expectBalances(
1252 STAmount(usd, UINT64_C(6000'000000000002), -12),
1261 env(
fset(gw, asfGlobalFreeze));
1264 BEAST_EXPECT(ammAlice.expectBalances(
1265 STAmount(usd, UINT64_C(4'000'000000000002), -12),
1275 Env env{*
this, features};
1278 env.
fund(
XRP(1'000'000), gw, alice);
1280 env(
fset(gw, asfAllowTrustLineClawback));
1282 auto const usd = gw[
"USD"];
1283 env.
trust(usd(1'000'000), alice);
1284 env(
pay(gw, alice, usd(500'000)));
1291 .flags = tfMPTCanClawback | tfMPTCanLock |
kMptDexFlags});
1292 AMM const ammAlice(env, alice, usd(10'000), btc(10'000));
1293 BEAST_EXPECT(ammAlice.expectBalances(usd(10'000), btc(10'000),
IOUAmount(10'000)));
1296 auto aliceBTC = env.
balance(alice,
MPT(btc));
1297 auto aliceUSD = env.
balance(alice, usd);
1300 btc.set({.holder = alice, .flags = tfMPTLock});
1302 BEAST_EXPECT(ammAlice.expectBalances(usd(8'000), btc(8'000),
IOUAmount(8'000)));
1305 aliceUSD = env.
balance(alice, usd);
1308 env(
trust(gw, alice[
"USD"](0), tfSetFreeze));
1311 BEAST_EXPECT(ammAlice.expectBalances(usd(7'000), btc(7'000),
IOUAmount(7'000)));
1317 btc.set({.holder = alice, .flags = tfMPTUnlock});
1319 BEAST_EXPECT(ammAlice.expectBalances(
1320 STAmount{usd, UINT64_C(4000'000000000001), -12}, btc(4'001),
IOUAmount(4'000)));
1323 aliceUSD = env.
balance(alice, usd);
1326 env(
trust(gw, alice[
"USD"](0), tfClearFreeze));
1329 BEAST_EXPECT(ammAlice.expectBalances(
1330 STAmount(usd, UINT64_C(3'000'000000000002), -12),
1341 testcase(
"test single depoit and clawback");
1342 using namespace jtx;
1346 Env env(*
this, features);
1349 env.
fund(
XRP(1000000000), gw, alice);
1356 .pay = 40'000'000000,
1362 BEAST_EXPECT(
amm.expectBalances(
XRP(100), btc(400),
IOUAmount(200000)));
1363 amm.deposit(alice, btc(400));
1365 BEAST_EXPECT(
amm.expectBalances(
XRP(100), btc(800),
IOUAmount{282842'712474619, -9}));
1367 auto aliceBTC = env.
balance(alice,
MPT(btc));
1372 BEAST_EXPECT(
amm.expectBalances(
1381 Env env(*
this, features);
1384 env.
fund(
XRP(1000000000), gw, alice);
1388 env(
fset(gw, asfAllowTrustLineClawback));
1393 auto const usd = gw[
"USD"];
1394 env.
trust(usd(100000), alice);
1395 env(
pay(gw, alice, usd(1000)));
1402 .pay = 40'000'000000,
1408 BEAST_EXPECT(
amm.expectBalances(usd(100), btc(400),
IOUAmount(200)));
1409 amm.deposit(alice, btc(400));
1411 BEAST_EXPECT(
amm.expectBalances(usd(100), btc(800),
IOUAmount{282'842712474619, -12}));
1413 auto aliceBTC = env.
balance(alice,
MPT(btc));
1414 auto aliceUSD = env.
balance(alice, usd);
1418 BEAST_EXPECT(
amm.expectBalances(
1419 STAmount{usd, UINT64_C(87'50000000000003), -14},
1425 aliceUSD = env.
balance(alice, usd);
1430 BEAST_EXPECT(
amm.expectBalances(
1440 Env env(*
this, features);
1443 env.
fund(
XRP(1000000000), gw, alice);
1450 .pay = 40'000'000000,
1457 .pay = 40'000'000000,
1463 BEAST_EXPECT(
amm.expectBalances(usd(100), btc(400),
IOUAmount(200)));
1464 amm.deposit(alice, btc(400));
1466 BEAST_EXPECT(
amm.expectBalances(usd(100), btc(800),
IOUAmount{282'842712474619, -12}));
1468 auto aliceBTC = env.
balance(alice,
MPT(btc));
1469 auto aliceUSD = env.
balance(alice, usd);
1473 BEAST_EXPECT(
amm.expectBalances(usd(88), btc(701),
IOUAmount{247'4873734152917, -13}));
1477 aliceUSD = env.
balance(alice, usd);
1482 BEAST_EXPECT(
amm.expectBalances(usd(72), btc(567),
IOUAmount(200)));
1494 "test last holder's lptoken balance not equal to AMM's lptoken "
1495 "balance before clawback");
1496 using namespace jtx;
1502 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
1503 env.
fund(
XRP(100000), gw, alice, bob);
1505 env(
fset(gw, asfAllowTrustLineClawback));
1508 auto const usd = gw[
"USD"];
1509 env.
trust(usd(100000), alice);
1510 env(
pay(gw, alice, usd(50000)));
1511 env.
trust(usd(100000), bob);
1512 env(
pay(gw, bob, usd(40000)));
1518 .holders = {alice, bob},
1519 .pay = 40'000'000000,
1522 AMM amm(env, alice, usd(2), eur(1));
1525 amm.withdraw(alice,
IOUAmount{1'576123487565916, -15});
1526 amm.withdrawAll(bob);
1528 auto const lpToken =
1531 auto const lpTokenBalance =
1532 amm.ammRpcInfo()[jss::amm][jss::lp_token][jss::value].asString();
1533 if (features[featureSingleAssetVault] || features[featureLendingProtocol])
1535 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.4142135623741");
1539 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
1543 BEAST_EXPECT(res && res.value());
1545 if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1548 BEAST_EXPECT(!
amm.ammExists());
1551 features[fixAMMv1_3] &&
1552 (features[featureSingleAssetVault] || features[featureLendingProtocol]))
1557 BEAST_EXPECT(
amm.ammExists());
1559 else if (!features[featureSingleAssetVault] && !features[featureLendingProtocol])
1562 BEAST_EXPECT(
amm.ammExists());
1567 BEAST_EXPECT(
amm.ammExists());
1574 Account const gw{
"gateway"}, alice{
"alice"}, bob{
"bob"};
1575 env.
fund(
XRP(100000), gw, alice, bob);
1581 .holders = {alice, bob},
1582 .pay = 40'000'000000,
1588 .holders = {alice, bob},
1589 .pay = 40'000'000000,
1592 AMM amm(env, alice, usd(2), eur(1));
1595 amm.withdraw(alice,
IOUAmount{1'576123487565916, -15});
1596 amm.withdrawAll(bob);
1598 auto const lpToken =
1601 auto const lpTokenBalance =
1602 amm.ammRpcInfo()[jss::amm][jss::lp_token][jss::value].asString();
1603 if (!features[featureSingleAssetVault] && !features[featureLendingProtocol])
1605 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.414213562374");
1609 BEAST_EXPECT(lpToken ==
"1.414213562374011" && lpTokenBalance ==
"1.4142135623741");
1613 BEAST_EXPECT(res && res.value());
1615 if (features[fixAMMv1_3] && features[fixAMMClawbackRounding])
1618 BEAST_EXPECT(!
amm.ammExists());
1621 features[fixAMMv1_3] &&
1622 (features[featureSingleAssetVault] || features[featureLendingProtocol]))
1627 BEAST_EXPECT(
amm.ammExists());
1629 else if (!features[featureSingleAssetVault] && !features[featureLendingProtocol])
1632 BEAST_EXPECT(
amm.ammExists());
1634 else if (features[featureMPTokensV2])
1637 BEAST_EXPECT(
amm.ammExists());
1645 testcase(
"claw asset check for MPT and IOU");
1646 using namespace jtx;
1650 Env env(*
this, features);
1653 env.
fund(
XRP(100000), gw, alice);
1656 env(
fset(gw, asfAllowTrustLineClawback));
1659 auto const usd = gw[
"USD"];
1660 env.
trust(usd(100000), alice);
1661 env(
pay(gw, alice, usd(1000)));
1665 MPTTester({.env = env, .issuer = gw, .holders = {alice}, .pay = 40'000});
1667 AMM const amm(env, alice, usd(200), btc(100));
1684 Env env(*
this, features);
1687 env.
fund(
XRP(100000), gw, alice);
1690 auto const usd = gw[
"USD"];
1691 env.
trust(usd(100000), alice);
1692 env(
pay(gw, alice, usd(1000)));
1703 AMM const amm(env, alice, usd(200), btc(100));
1720 Env env(*
this, features);
1722 Account const gw2{
"gateway2"};
1724 env.
fund(
XRP(100000), gw, gw2, alice);
1727 env(
fset(gw, asfAllowTrustLineClawback));
1730 auto const usd = gw[
"USD"];
1731 env.
trust(usd(100000), alice);
1732 env(
pay(gw, alice, usd(1000)));
1742 AMM const amm(env, alice, usd(200), btc(100));
1751 auto test = [&](
auto&& issue1,
auto&& issue2) {
1753 Account const gw(
"gateway"), alice(
"alice"), bob(
"bob");
1754 env.
fund(
XRP(30'000), alice, bob, gw);
1756 auto const usd = issue1(
1761 .
limit = 1'000'000});
1762 auto const btc = issue2(
1767 .limit = 1'000'000});
1768 env(
pay(gw, alice, usd(50000)));
1769 env(
pay(bob, alice, btc(50000)));
1772 auto ammAlice =
AMM(env, alice, usd(10000), btc(10100));
1781 auto test = [&](
auto&& issue1,
auto&& issue2) {
1783 Account const gw(
"gateway"), alice(
"alice"), bob(
"bob");
1784 env.
fund(
XRP(30'000), alice, bob, gw);
1786 auto const usd = issue1(
1791 .
limit = 1'000'000});
1792 auto const btc = issue2(
1797 .limit = 1'000'000});
1798 env(
pay(gw, alice, usd(50000)));
1799 env(
pay(bob, alice, btc(50000)));
1802 auto ammAlice =
AMM(env, alice, usd(10000), btc(10100));