413 [&](
AMM& ammAlice,
Env& env) {
424 jv[jss::Account] =
alice_.human();
425 jv[jss::TransactionType] = jss::AMMDeposit;
429 jv[jss::LPTokenOut] =
431 jv[jss::Flags] = tfLPToken;
439 jv[jss::Account] =
alice_.human();
440 jv[jss::TransactionType] = jss::AMMDeposit;
445 jv[jss::Flags] = tfLPToken;
454 MPT(ammAlice[1])(200),
499 MPT(ammAlice[1])(200),
509 .authHolder =
true});
527 MPT(ammAlice[1])(100),
528 MPT(ammAlice[1])(200),
543 MPT(ammAlice[1])(-1'000),
556 MPT(ammAlice[1])(1'000),
574 {{
MPT(btc),
MPT(ammAlice[1])}},
584 MPT(ammAlice[1])(200),
636 MPT(ammAlice[1])(100),
645 [&](
AMM& ammAlice,
Env& env) {
646 auto const enabledV13 = env.
current()->rules().enabled(fixAMMv1_3);
655 {features, features - fixAMMv1_3});
659 [&](
AMM& ammAlice,
Env& env) {
668 [&](
AMM& ammAlice,
Env& env) {
671 MPT(ammAlice[1])(100),
682 MPT(ammAlice[1])(100),
702 btc.set({.flags = tfMPTLock});
718 Env env{*
this, features};
730 btc.set({.holder =
carol_, .flags = tfMPTLock});
740 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
742 ammAlice.deposit(
carol_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
751 ammAlice.deposit(
alice_, btc(100), std::nullopt, std::nullopt, std::nullopt);
752 ammAlice.deposit(
alice_, 1'000, std::nullopt, std::nullopt);
753 ammAlice.deposit(
alice_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
756 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
758 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
759 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
788 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
791 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
809 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
811 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
812 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
835 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
838 btc.set({.holder =
carol_, .flags = tfMPTLock});
846 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
849 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
850 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
853 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
866 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
868 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
869 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
872 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
885 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
887 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
888 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
893 Env env{*
this, features};
894 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
895 env.
fund(
XRP(30'000), alice, carol, gw);
898 MPTTester btc(env, gw, {.holders = {alice, carol}, .fund =
false});
900 {.maxAmt = 1'000'000,
901 .authorize = {{alice}},
902 .pay = {{{alice}, 10'000}},
904 .authHolder =
true});
906 AMM amm(env, alice,
XRP(10'000), btc(10'000));
911 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
913 amm.deposit(carol,
XRP(10), std::nullopt, std::nullopt, std::nullopt);
924 Env env{*
this, features};
925 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
926 env.
fund(
XRP(30'000), alice, carol, gw);
934 .flags = tfMPTCanTrade});
936 AMM amm(env, gw,
XRP(10'000), btc(10'000));
938 amm.deposit({.account = alice, .asset1In = btc(10), .err =
Ter(
tecNO_AUTH)});
943 [&](
AMM& ammAlice,
Env& env) {
959 [&](
AMM& ammAlice,
Env& env) {
962 MPT(ammAlice[1])(450'000),
972 [&](
AMM& ammAlice,
Env& env) {
993 .transferFee = 1'500,
1011 Env env(*
this, features);
1012 auto const startingXrp =
reserve(env, 4) + env.
current()->fees().base * 4;
1021 .transferFee = 1'500,
1046 [&](
AMM& ammAlice,
Env& env) {
1054 MPT(ammAlice[1])(100),
1067 MPT(ammAlice[1])(100),
1078 MPT(ammAlice[1])(-1),
1101 [&](
AMM& ammAlice,
Env& env) {
1107 MPT(ammAlice[1])(1'001),
1118 MPT(ammAlice[1])(1'000),
1130 MPT(ammAlice[1])(100),
1157 MPTTester const btc({.env = env, .issuer =
gw_, .holders = {
alice_}, .maxAmt = 100});
1180 using namespace jtx;
1184 [&](
AMM& ammAlice,
Env& env) {
1202 [&](
AMM& ammAlice,
Env& env) {
1205 MPT(ammAlice[1])(100),
1215 MPT(ammAlice[1])(100),
1224 auto test = [&](
auto&& issue1,
auto&& issue2) {
1228 auto const usd = issue1(
1233 .limit = 1'000'000});
1234 auto const btc = issue2(
1239 .limit = 1'000'000});
1246 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1261 [&](
AMM& ammAlice,
Env& env) {
1277 auto test = [&](
auto&& issue1,
auto&& issue2) {
1281 auto const usd = issue1(
1286 .limit = 1'000'000});
1287 auto const btc = issue2(
1292 .limit = 1'000'000});
1299 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1315 [&](
AMM& ammAlice,
Env& env) {
1331 auto test = [&](
auto&& issue1,
auto&& issue2) {
1335 auto const usd = issue1(
1340 .limit = 1'000'000});
1341 auto const btc = issue2(
1346 .limit = 1'000'000});
1353 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1367 [&](
AMM& ammAlice,
Env& env) {
1374 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1383 [&](
AMM& ammAlice,
Env& env) {
1390 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1399 [&](
AMM& ammAlice,
Env& env) {
1405 MPT(ammAlice[0])(11'000),
1406 MPT(ammAlice[1])(10'000),
1416 [&](
AMM& ammAlice,
Env& env) {
1422 MPT(ammAlice[0])(11'000),
USD(10'000),
IOUAmount{10'488'08848170151, -11}));
1431 [&](
AMM& ammAlice,
Env& env) {
1437 MPT(ammAlice[0])(10'000),
1449 [&](
AMM& ammAlice,
Env& env) {
1467 [&](
AMM& ammAlice,
Env& env) {
1486 auto test = [&](
auto&& issue1,
auto&& issue2) {
1490 auto const usd = issue1(
1495 .limit = 1'000'000});
1496 auto const btc = issue2(
1501 .limit = 1'000'000});
1508 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1513 auto deltaUSD = [&]() {
1519 btc(10'000), usd(10'000) + deltaUSD,
IOUAmount{10'100, 0}));
1531 [&](
AMM& ammAlice,
Env& env) {
1534 MPT(ammAlice[1])(100),
1539 XRP(10'000),
MPT(ammAlice[1])(10100),
IOUAmount{10'049'875'62112089, -8}));
1546 [&](
AMM& ammAlice,
Env& env) {
1553 MPT(ammAlice[1])(100),
1558 XRP(10'000),
MPT(ammAlice[1])(10'080),
IOUAmount{10'039'920'3184089, -7}));
1568 [&](
AMM& ammAlice,
Env& env) {
1575 MPT(ammAlice[1])(0),
1580 XRP(10'000),
MPT(ammAlice[1])(10'080),
IOUAmount{10'039'920'3184089, -7}));
1591 [&](
AMM& ammAlice,
Env& env) {
1594 MPT(ammAlice[1])(100),
1599 USD(10'000'000'000),
1600 MPT(ammAlice[1])(10100),
1609 [&](
AMM& ammAlice,
Env& env) {
1613 MPT(ammAlice[1])(10'000'000'000),
1623 [&](
AMM& ammAlice,
Env& env) {
1626 MPT(ammAlice[0])(100),
1631 MPT(ammAlice[1])(10'000'000'000),
1632 MPT(ammAlice[0])(10100),
1647 .transferFee = 25'000,
1654 .transferFee = 25'000,
1657 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1658 BEAST_EXPECT(ammAlice.expectBalances(usd(200'000), btc(5),
IOUAmount{1000, 0}));
1660 ammAlice.deposit(
carol_, 100, std::nullopt, std::nullopt);
1661 BEAST_EXPECT(ammAlice.expectBalances(usd(220'000), btc(6),
IOUAmount{1100, 0}));
1677 .transferFee = 25'000,
1680 auto const usd =
gw_[
"USD"];
1690 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1699 .transferFee = 25'000,
1703 AMM ammBob(env,
bob_, eth(20'000), usd(0.5));
1704 BEAST_EXPECT(ammBob.expectBalances(eth(20'000), usd(0.5),
IOUAmount{100, 0}));
1705 ammBob.deposit(
carol_, 10);
1706 BEAST_EXPECT(ammBob.expectBalances(eth(22'000), usd(0.55),
IOUAmount{110, 0}));
1711 [&](
AMM& ammAlice,
Env& env) {
1715 STAmount{USD, UINT64_C(10'000'001), -3},
1716 MPT(ammAlice[1])(10'001),
1721 STAmount{USD, UINT64_C(10'001'001), -3},
1722 MPT(ammAlice[1])(10'003),
1727 [&](
AMM& ammAlice,
Env& env) {
1730 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1731 MPT(ammAlice[1])(10'000),
1736 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1737 MPT(ammAlice[1])(10'001),
1744 [&](
AMM& ammAlice,
Env& env) {
1748 MPT(ammAlice[1])(10'000),
1753 [&](
AMM& ammAlice,
Env& env) {
1756 XRP(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000'499'98750062, -8}));
1762 [&](
AMM& ammAlice,
Env& env) {
1766 MPT(ammAlice[0])(10'000),
1767 MPT(ammAlice[1])(10'001),
1778 MPT const btc =
MPTTester({.env = env, .issuer =
gw_, .holders = {}});
1780 AMM ammGw(env,
gw_,
XRP(10'000), btc(10'000'000'000));
1782 ammGw.expectBalances(
XRP(10'000), btc(10'000'000'000),
IOUAmount{10'000'000'000}));
1784 ammGw.deposit(
gw_, 1'000'000);
1786 ammGw.expectBalances(
XRP(10'001), btc(10'001000000),
IOUAmount{10'001000000}));
1788 ammGw.deposit(
gw_, btc(1'000000000));
1789 BEAST_EXPECT(ammGw.expectBalances(
1790 XRP(10'001), btc(11'001000000),
IOUAmount{1048'908'961731188, -5}));
1795 [&](
AMM& ammAlice,
Env& env) {
1798 MPT(ammAlice[0])(1'010'000),
1799 MPT(ammAlice[1])(1'010'000),
1804 MPT(ammAlice[0])(1'011'000),
1805 MPT(ammAlice[1])(1'010'000),
1812 [&](
AMM& ammAlice,
Env& env) {
1818 XRP(11'000),
MPT(ammAlice[1])(12'000),
IOUAmount{11'489'125'29307605, -8}));
1824 [&](
AMM& ammAlice,
Env& env) {
1829 MPT(ammAlice[1])(1'000),
1841 auto test = [&](
auto&& issue1,
auto&& issue2) {
1845 auto const usd = issue1(
1850 .limit = 1'000'000});
1851 auto const btc = issue2(
1856 .limit = 1'000'000});
1863 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1886 [&](
AMM& ammAlice,
Env& env) {
1891 MPT(ammAlice[1])(1'000),
1903 auto test = [&](
auto&& issue1,
auto&& issue2) {
1907 auto const usd = issue1(
1912 .limit = 1'000'000});
1913 auto const btc = issue2(
1918 .limit = 1'000'000});
1924 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1948 [&](
AMM& ammAlice,
Env& env) {
1959 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1965 [&](
AMM& ammAlice,
Env& env) {
1969 MPT(ammAlice[1])(1'000),
1976 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1982 [&](
AMM& ammAlice,
Env& env) {
1993 STAmount{USD, UINT64_C(10'999'99999999999), -11},
1994 MPT(ammAlice[1])(10'000),
2001 [&](
AMM& ammAlice,
Env& env) {
2005 MPT(ammAlice[1])(1'000),
2012 USD(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -11}));
2018 [&](
AMM& ammAlice,
Env& env) {
2022 MPT(ammAlice[1])(1'000),
2029 MPT(ammAlice[0])(10'000),
2030 MPT(ammAlice[1])(11'000),
2041 using namespace jtx;
2045 [&](
AMM& ammAlice,
Env& env) {
2047 .asset1Out =
XRP(100),
2055 [&](
AMM& ammAlice,
Env& env) {
2057 .asset1Out =
MPT(ammAlice[1])(100),
2075 .authHolder =
true});
2079 .asset1Out = btc(100),
2082 ammAlice.withdraw(args);
2086 [&](
AMM& ammAlice,
Env& env) {
2111 MPT(ammAlice[1])(100),
2112 MPT(ammAlice[1])(100),
2128 MPT(ammAlice[1])(10'000),
2137 MPT(ammAlice[1])(0),
2140 tfOneAssetWithdrawAll,
2175 {{
MPT(ammAlice[1]),
GBP}},
2185 [&](
AMM& ammAlice,
Env& env) {
2195 alice_,
IOUAmount{9'999'999'9999, -4}, std::nullopt, std::nullopt, err);
2205 {all, all - fixAMMv1_3});
2208 [&](
AMM& ammAlice,
Env& env) {
2215 alice_,
IOUAmount{9'999'999'999999999, -9}, std::nullopt, std::nullopt, err);
2225 {all, all - fixAMMv1_3});
2229 [&](
AMM& ammAlice,
Env& env) {
2248 .asset1Out =
MPT(
gw_, 1'000)(10),
2264 .authHolder =
true});
2265 MPT const btc = btcm;
2269 btcm.authorize({.account =
gw_, .holder =
alice_, .flags = tfMPTUnauthorize});
2274 .asset1Out = btc(100),
2275 .assets = {{
XRP, btc}},
2291 .flags = tfMPTCanTrade,
2292 .authHolder =
true});
2296 auto const lpIssue =
amm.lptIssue();
2318 .authHolder =
true});
2321 btc.set({.flags = tfMPTLock});
2328 ammAlice.withdraw({.account =
alice_, .asset1Out =
XRP(100)});
2349 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
2352 btc.set({.holder =
alice_, .flags = tfMPTLock});
2357 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2360 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2361 ammAlice.withdraw(
alice_, 1000, std::nullopt, std::nullopt);
2362 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2363 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2380 btc.set({.holder =
alice_, .flags = tfMPTLock});
2385 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2388 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2391 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2392 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2393 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2396 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
2399 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2406 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
2408 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2409 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2417 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2431 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2432 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2437 [&](
AMM& ammAlice,
Env&) {
2454 [&](
AMM& ammAlice,
Env& env) {
2464 {all, all - fixAMMv1_3});
2469 [&](
AMM& ammAlice,
Env&) {
2473 MPT(ammAlice[1])(100),
2483 [&](
AMM& ammAlice,
Env&) {
2487 MPT(ammAlice[1])(1'700),
2496 [&](
AMM& ammAlice,
Env&) {
2500 MPT(ammAlice[1])(1'000),
2508 [&](
AMM& ammAlice,
Env&) {
2518 [&](
AMM& ammAlice,
Env&) {
2532 [&](
AMM& ammAlice,
Env&) {
2535 STAmount{
MPT(ammAlice[1]), UINT64_C(9'999'999999999999), -12},
2544 [&](
AMM& ammAlice,
Env&) {
2566 MPT(ammAlice[0])(1),
2578 using namespace jtx;
2583 [&](
AMM& ammAlice,
Env& env) {
2609 [&](
AMM& ammAlice,
Env&) {
2620 auto test = [&](
auto&& issue1,
auto&& issue2) {
2624 auto const usd = issue1(
2629 .limit = 1'000'000});
2630 auto const btc = issue2(
2635 .limit = 1'000'000});
2639 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2656 [&](
AMM& ammAlice,
Env&) {
2667 [&](
AMM& ammAlice,
Env&) {
2677 auto test = [&](
auto&& issue1,
auto&& issue2) {
2681 auto const usd = issue1(
2686 .limit = 1'000'000});
2687 auto const btc = issue2(
2692 .limit = 1'000'000});
2696 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2709 [&](
AMM& ammAlice,
Env&) {
2714 MPT(ammAlice[1])(10'000),
2719 [&](
AMM& ammAlice,
Env&) {
2723 XRP(10000),
MPT(ammAlice[1])(9001),
IOUAmount{9'486'832'980505138, -9}));
2727 [&](
AMM& ammAlice,
Env&) {
2731 USD(9'000),
MPT(ammAlice[1])(10'000),
IOUAmount{9486'832980505138, -12}));
2735 [&](
AMM& ammAlice,
Env&) {
2739 USD(10'000),
MPT(ammAlice[1])(9001),
IOUAmount{9486'832980505138, -12}));
2743 [&](
AMM& ammAlice,
Env&) {
2747 MPT(ammAlice[0])(9001),
2748 MPT(ammAlice[1])(10'000),
2755 [&](
AMM& ammAlice,
Env&) {
2764 [&](
AMM& ammAlice,
Env&) {
2773 auto test = [&](
auto&& issue1,
auto&& issue2) {
2777 auto const usd = issue1(
2782 .limit = 1'000'000});
2783 auto const btc = issue2(
2788 .limit = 1'000'000});
2792 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2805 [&](
AMM& ammAlice,
Env& env) {
2817 AMM const ammCarol(env,
carol_,
XRP(10'000),
MPT(ammAlice[1])(10'000));
2825 [&](
AMM& ammAlice,
Env& env) {
2836 [&](
AMM& ammAlice,
Env&) {
2846 [&](
AMM& ammAlice,
Env& env) {
2858 [&](
AMM& ammAlice,
Env& env) {
2870 [&](
AMM& ammAlice,
Env& env) {
2875 MPT(ammAlice[0])(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000, 0}));
2882 [&](
AMM& ammAlice,
Env&) {
2892 [&](
AMM& ammAlice,
Env&) {
2896 STAmount{USD, UINT64_C(9'090'9090909091), -10},
2897 MPT(ammAlice[1])(11000),
2904 [&](
AMM& ammAlice,
Env&) {
2908 STAmount{USD, UINT64_C(10'999'99999999999), -11},
2909 MPT(ammAlice[1])(9091),
2916 [&](
AMM& ammAlice,
Env&) {
2924 MPT(ammAlice[0])(10'000'000'001),
USD(10'000), ammAlice.
tokens()));
2929 [&](
AMM& ammAlice,
Env&) {
2930 auto const& btc =
MPT(ammAlice[1]);
2945 [&](
AMM& ammAlice,
Env&) {
2946 auto const carolTokens = ammAlice.
deposit(
carol_,
MPT(ammAlice[1])(1'000));
2947 auto const aliceTokens = ammAlice.
deposit(
alice_,
MPT(ammAlice[1])(1'000));
2951 XRP(10'000),
MPT(ammAlice[1])(10'001), ammAlice.
tokens()));
2959 [&](
AMM& ammAlice,
Env&) {
2968 auto test = [&](
auto&& issue1,
auto&& issue2) {
2972 auto const usd = issue1(
2977 .limit = 1'000'000});
2978 auto const btc = issue2(
2983 .limit = 1'000'000});
2989 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
3004 [&](
AMM& ammAlice,
Env&) {
3009 STAmount{
MPT(ammAlice[1]), UINT64_C(9'090'909090909092), -12},
3016 [&](
AMM& ammAlice,
Env&) {
3026 [&](
AMM& ammAlice,
Env&) {
3030 STAmount{USD, UINT64_C(9'090'909090909091), -12},
3031 MPT(ammAlice[1])(11'000),
3037 [&](
AMM& ammAlice,
Env&) {
3041 MPT(ammAlice[0])(11'000),
MPT(ammAlice[1])(9'091),
IOUAmount{10'000}));
3049 [&](
AMM& ammAlice,
Env& env) {
3058 MPT(ammAlice[1])(9372781065),
3067 MPT(ammAlice[1])(9372781065),
3071 else if (env.
enabled(fixAMMv1_3))
3076 MPT(ammAlice[1])(9372781066),
3083 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3086 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3090 [&](
AMM& ammAlice,
Env& env) {
3098 MPT(ammAlice[1])(9372781065),
3107 MPT(ammAlice[1])(9372781065),
3111 else if (env.
enabled(fixAMMv1_3))
3116 MPT(ammAlice[1])(9372781066),
3123 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3126 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3130 auto test = [&](
auto&& issue1,
auto&& issue2) {
3134 auto const usd = issue1(
3140 .transferFee = 25'000});
3141 auto const btc = issue2(
3147 .transferFee = 25'000});
3156 AMM ammAlice(env,
alice_, btc(2'000), usd(5));
3179 [&](
AMM& ammAlice,
Env&) {
3183 MPT(ammAlice[0])(9'999'999'999),
3189 [&](
AMM& ammAlice,
Env&) {
3193 MPT(ammAlice[0])(10000'000000),
USD(10'000),
IOUAmount{9'999'999'9995, -4}));
3197 [&](
AMM& ammAlice,
Env&) {
3201 MPT(ammAlice[0])(10'000'000'000),
3207 [&](
AMM& ammAlice,
Env&) {
3218 [&](
AMM& ammAlice,
Env&) {
3226 [&](
AMM& ammAlice,
Env&) {
3234 [&](
AMM& ammAlice,
Env&) {
3242 [&](
AMM& ammAlice,
Env&) {
3250 [&](
AMM& ammAlice,
Env&) {
3253 MPT(ammAlice[0])(10'000'000'000),
3260 [&](
AMM& ammAlice,
Env&) {
3268 [&](
AMM& ammAlice,
Env&) {
3275 [&](
AMM& ammAlice,
Env&) {
3304 AMM ammAlice(env,
alice_, btc(10'000), eth(10'000));
3309 btc.authorize({.account =
alice_, .flags = tfMPTUnauthorize});
3310 eth.authorize({.account =
alice_, .flags = tfMPTUnauthorize});
3316 ammAlice.withdrawAll(
alice_);
3321 BEAST_EXPECT(!ammAlice.ammExists());
3606 using namespace jtx;
3619 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3622 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3629 .bidMin = 1'000'000,
3644 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3647 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3654 .bidMin = STAmount{amm.lptIssue(), UINT64_C(999'999)},
3660 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{999'999}));
3663 BEAST_EXPECT(
amm.expectBalances(
XRP(1'000), btc(1'000),
IOUAmount{1}));
3666 BEAST_EXPECT(
Number{
amm.getLPTokensBalance(
gw_)} == 1);
3679 [&](
AMM& ammAlice,
Env& env) {
3716 .authAccounts = {bob_},
3724 .assets = {{MPT(ammAlice[1]), GBP}},
3728 {{
XRP(10'000), gAmmmpt(10'000)}});
3732 [&](AMM& ammAlice, Env& env) {
3733 ammAlice.withdrawAll(alice_);
3740 {{
XRP(10'000), gAmmmpt(10'000)}});
3745 fund(env, gw_, {alice_, bob_, carol_},
XRP(1'000), {USD(30'000)}, Fund::All);
3746 MPTTester
const btc(
3749 .holders = {alice_, carol_, bob_},
3750 .pay = 30'000'000'000,
3753 AMM ammAlice(env, alice_, btc(10'000'000'000), USD(10'000));
3754 ammAlice.deposit(carol_, 1'000'000);
3755 ammAlice.deposit(bob_, 10);
3758 .bidMin = 1'000'001,
3760 Ter(tecAMM_INVALID_TOKENS));
3763 .bidMax = 1'000'001,
3765 Ter(tecAMM_INVALID_TOKENS));
3770 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0, IOUAmount{1'000}));
3775 Ter(tecAMM_INVALID_TOKENS));
3781 env.fund(
XRP(1'000), gw_, alice_, bob_);
3782 MPTTester
const btc(
3785 .holders = {alice_, bob_},
3788 AMM
amm(env, gw_,
XRP(10), btc(1'000));
3789 auto const lpIssue =
amm.lptIssue();
3790 env.trust(STAmount{lpIssue, 100}, alice_);
3791 env.trust(STAmount{lpIssue, 50}, bob_);
3792 env(
pay(gw_, alice_, STAmount{lpIssue, 100}));
3793 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
3794 env(
amm.bid({.account = alice_, .bidMin = 100}));
3801 Ter(tecAMM_FAILED));
3809 using namespace jtx;
3816 [&](
AMM& ammAlice,
Env& env) {
3818 env(ammAlice.
bid({.account = carol_, .bidMin = 110}));
3828 [&](
AMM& ammAlice,
Env& env) {
3831 env(ammAlice.
bid({.account = carol_, .bidMin = 110, .bidMax = 110}));
3836 env(ammAlice.
bid({.account = alice_, .bidMin = 180, .bidMax = 200}));
3855 ammAlice.deposit(
carol_, 1'000'000);
3857 env(ammAlice.bid({.account = carol_, .bidMin = 110}));
3858 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3860 ammAlice.deposit(
bob_, 1'000'000);
3862 env(ammAlice.bid({.account = bob_}));
3863 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount(1155, -1)));
3872 env(ammAlice.bid({.account = carol_, .bidMax = 600}));
3873 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{121'275, -3}));
3884 env(ammAlice.bid({.account = carol_, .bidMin = 100, .bidMax = 600}));
3885 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{127'33875, -5}));
3900 ammAlice.deposit(
carol_, 1'000'000);
3901 ammAlice.deposit(
bob_, 1'000'000);
3902 BEAST_EXPECT(ammAlice.expectBalances(
3906 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3907 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3910 env(ammAlice.bid({.account = bob_}));
3912 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 1,
IOUAmount{1'155, -1}));
3915 env(ammAlice.bid({.account = carol_}));
3917 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 10,
IOUAmount{121'275, -3}));
3920 env(ammAlice.bid({.account = bob_}));
3922 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{127'33875, -5}));
3925 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3926 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{110}));
3928 BEAST_EXPECT(ammAlice.expectBalances(
3945 .pay = 30'000'000'000});
3951 ammAlice.
deposit(ed, 1'000'000);
3953 ammAlice.
deposit(dan, 500'000);
3958 .authAccounts = {bob_, ed},
3960 auto const slotPrice =
IOUAmount{5'200};
3961 ammTokens -= slotPrice;
3963 BEAST_EXPECT(ammAlice.
expectBalances(btc(13'000'000'003),
USD(13'000), ammTokens));
3965 for (
int i = 0; i < 10; ++i)
3982 btc(13'000'000'003),
STAmount(
USD, UINT64_C(13'002'98282151419), -11), ammTokens));
3986 for (
int i = 0; i < 10; ++i)
3988 auto const tokens = ammAlice.
deposit(dan,
USD(100));
3998 btc(13'000'000'003),
STAmount{
USD, UINT64_C(13'012'92609877021), -11}, ammTokens));
4003 MPT(ammAlice[0])(13'000'000'003),
4011 btc(13'100'000'671),
STAmount{
USD, UINT64_C(13'012'92609877019), -11}, ammTokens));
4021 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'114'03663044931), -11}, ammTokens));
4031 for (
int i = 0; i < 10; ++i)
4042 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'123'98038488356), -11}, ammTokens));
4050 btc(13'100'824'793),
STAmount{
USD, UINT64_C(13'023'98038488356), -11}, ammTokens));
4055 [&](
AMM& ammAlice,
Env& env) {
4058 auto const cleanup340 = env.
current()->rules().enabled(fixCleanup3_4_0);
4060 auto const firstPrice = cleanup340 ? minBidPrice : IOUAmount{tiny};
4061 env(ammAlice.
bid({.account = alice_, .bidMin = IOUAmount{tiny}}));
4064 MPT(ammAlice[0])(10'000'000'000),
4066 cleanup340 ? IOUAmount{Number{ammAlice.
tokens()} - Number{minBidPrice}}
4071 .bidMin = IOUAmount{STAmount::kMinValue, STAmount::kMinOffset},
4075 0, 0, IOUAmount{Number{firstPrice} * Number{105, -2}}));
4077 MPT(ammAlice[0])(10'000'000'000),
4080 ? IOUAmount{Number{ammAlice.
tokens()} - Number{minBidPrice} * Number{11, -1}}
4083 {{gAmmmpt(10'000'000'000), USD(10'000)}});
4087 [&](AMM& ammAlice, Env& env) {
4090 .bidMin = IOUAmount{100},
4091 .authAccounts = {carol_},
4093 BEAST_EXPECT(ammAlice.expectAuctionSlot({carol_}));
4094 env(ammAlice.bid({.account = alice_, .bidMin = IOUAmount{100}}));
4098 fund(env, {bob, dan},
XRP(1'000));
4101 .bidMin = IOUAmount{100},
4102 .authAccounts = {bob, dan},
4106 {{gAmmmpt(10'000'000'000), USD(10'000)}});
4111 env.
fund(
XRP(2'000), gw_, alice_, bob_);
4112 MPTTester
const btc(
4115 .holders = {alice_, bob_},
4116 .pay = 2'000'000'000,
4118 fund(env, gw_, {alice_, bob_}, {USD(2'000)}, Fund::TokenOnly);
4119 AMM
amm(env, gw_, btc(1'000'000'000), USD(1'010),
false, 1'000);
4120 auto const lpIssue =
amm.lptIssue();
4121 env.
trust(STAmount{lpIssue, 500}, alice_);
4122 env.
trust(STAmount{lpIssue, 50}, bob_);
4123 env(
pay(gw_, alice_, STAmount{lpIssue, 500}));
4124 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
4126 env(
amm.bid({.account = alice_, .bidMin = 500}));
4127 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0, IOUAmount{500}));
4128 BEAST_EXPECT(
expectHolding(env, alice_, STAmount{lpIssue, 0}));
4131 env(
pay(alice_, bob_, USD(10)), Path(~USD), Sendmax(btc(11'000'000)));
4132 BEAST_EXPECT(
amm.expectBalances(
4133 btc(1'010'010'011), USD(1'000), IOUAmount{1'004'487'562112089, -9}));
4136 env(
pay(bob_, alice_, btc(10'000'000)), Path(~MPT(btc)), Sendmax(USD(11)));
4138 BEAST_EXPECT(
amm.expectBalances(
4140 STAmount{USD, UINT64_C(1'010'10090898081), -11},
4141 IOUAmount{1'004'487'562112089, -9}));
4146 Env env(*
this, features);
4147 env.
fund(
XRP(2'000), gw_, alice_, bob_);
4148 MPTTester
const btc(
4151 .holders = {alice_, bob_},
4154 AMM
amm(env, gw_,
XRP(1'000), btc(1'010),
false, 1'000);
4155 json::Value const tx =
amm.bid({.account = alice_, .bidMin = 500});
4158 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4160 PreflightContext
const ctx(
4162 auto pf = AMMBid::checkExtraFeatures(ctx);
4163 BEAST_EXPECT(pf ==
false);
4168 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4169 jtx.
jv[
"Asset2"][
"currency"] =
"XRP";
4171 jtx.stx = env.
ust(jtx);
4172 PreflightContext
const ctx(
4174 auto pf = AMMBid::preflight(ctx);
4175 BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
4499 using namespace jtx;
4504 [&](
AMM& ammAlice,
Env& env) {
4514 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4526 auto test = [&](
auto&& issue1,
auto&& issue2) {
4531 auto const usd = issue1(
4536 .limit = 1'000'000});
4537 auto const btc = issue2(
4542 .limit = 1'000'000});
4552 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4558 Txflags(tfNoRippleDirect | tfPartialPayment));
4569 [&](
AMM& ammAlice,
Env& env) {
4576 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4588 auto test = [&](
auto&& issue1,
auto&& issue2) {
4593 auto const usd = issue1(
4598 .limit = 1'000'000});
4599 auto const btc = issue2(
4604 .limit = 1'000'000});
4614 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4629 [&](
AMM& ammAlice,
Env& env) {
4638 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4649 auto test = [&](
auto&& issue1,
auto&& issue2) {
4654 auto const usd = issue1(
4659 .limit = 1'000'000});
4660 auto const btc = issue2(
4665 .limit = 1'000'000});
4675 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4689 [&](
AMM& ammAlice,
Env& env) {
4698 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4701 XRP(10'010),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4714 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4722 auto test = [&](
auto&& issue1,
auto&& issue2) {
4727 auto const usd = issue1(
4732 .limit = 1'000'000});
4733 auto const btc = issue2(
4738 .limit = 1'000'000});
4748 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10010));
4754 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4763 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4779 .transferFee = 10'000,
4780 .pay = 30'000'000'000'000'000,
4782 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(10'010'000'000'000'000));
4791 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4793 BEAST_EXPECT(ammAlice.expectBalances(
4794 XRP(10'010), btc(10'000'000'000'000'000), ammAlice.tokens()));
4802 auto test = [&](
auto&& issue1,
auto&& issue2) {
4807 auto const usd = issue1({
4815 auto const btc = issue2(
4820 .limit = 300'000'000'000'000'000,
4821 .transferFee = 10'000});
4824 env(
pay(
gw_,
bob_, btc(30'000'000'000'000'000)));
4831 auto ammAlice =
AMM(env,
alice_, usd(10'000), btc(10'010'000'000'000'000));
4837 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4840 usd(10'010), btc(10'000'000'000'000'000), ammAlice.
tokens()));
4849 [&](
AMM& ammAlice,
Env& env) {
4861 auto test = [&](
auto&& issue1,
auto&& issue2) {
4866 auto const usd = issue1(
4871 .limit = 1'000'000});
4872 auto const btc = issue2(
4877 .limit = 1'000'000});
4887 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
4908 .pay = 3'000'000'000'000'000'000,
4914 .pay = 3'000'000'000'000'000'000,
4918 auto ammEthXrp =
AMM(env,
alice_,
XRP(10'000), eth(1'000'000'000'000'000'000));
4920 AMM(env,
alice_, eth(1'000'000'000'000'000'000), btc(1'000'000'000'000'000'000));
4928 BEAST_EXPECT(ammEthXrp.expectBalances(
4929 XRPAmount(10'030'082'730), eth(9'970'00749812546872), ammEthXrp.tokens()));
4931 BEAST_EXPECT(ammBtcEth.expectBalances(
4932 btc(9'970'09727766213961), eth(10'029'99250187453128), ammBtcEth.tokens()));
4958 .pay = 3'000'000'000'000'000'000,
4964 .pay = 1'000'000'000'000'000'000,
4966 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(1'000'000'000'000'000'000));
4971 env(
offer(
alice_, eth(10'000'000'000'000'000), btc(10'000'000'000'000'000)),
4979 BEAST_EXPECT(ammAlice.expectBalances(
4980 XRPAmount(10'050'238'637), btc(9'950'01249687578120), ammAlice.tokens()));
4986 Amounts{eth(49'98750312421880), btc(49'98750312421880)}}}));
5006 .pay = 30'000'000'000'000'000,
5008 AMM ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
5016 BEAST_EXPECT(ammAlice.expectBalances(
5017 XRP(10'100),
MPT(ammAlice[1])(10'000'000000000001), ammAlice.tokens()));
5027 2 *
txFee(env, 1)));
5045 AMM const ammAlice(env,
alice_,
XRP(1'000), btc(1'050));
5066 ammAlice.expectBalances(
XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.tokens()));
5085 .transferFee = 25'000,
5086 .pay = 30'000'000'000'000'000,
5092 .transferFee = 25'000,
5093 .pay = 30'000'000'000'000'000,
5095 AMM const ammAlice(env,
alice_, btc(1'000'000'000'000'000), eth(1'100'000'000'000'000));
5100 env(
offer(
carol_, eth(100'000'000'000'000), btc(100'000'000'000'000)));
5103 BEAST_EXPECT(ammAlice.expectBalances(
5104 btc(1'100'000'000'000'000), eth(1'000'000'000'000'000), ammAlice.tokens()));
5122 .pay = 30'000'000'000'000'000,
5129 amm.expectBalances(
XRPAmount(909'090'910), btc(549'999999450001),
amm.tokens()));
5145 .pay = 3'000'000'000'000'000'000,
5151 BEAST_EXPECT(
amm.expectBalances(
XRP(990), btc(505'05050505050506),
amm.tokens()));
5164 .transferFee = 25'000,
5165 .pay = 20'000'000'000'000'000,
5171 .transferFee = 25'000,
5172 .pay = 20'000'000'000'000'000,
5175 env,
alice_, btc(10'000'000'000'000'000), eth(11'000'000'000'000'000));
5178 env(
offer(ed,
XRP(10), eth(100'000'000'000'000)),
Txflags(tfPassive));
5180 env(
offer(
carol_, eth(1'000'000'000'000'000), btc(1'000'000'000'000'000)));
5183 BEAST_EXPECT(ammAlice.expectBalances(
5184 btc(1'060'6848287928025), eth(1'037'0658372213582), ammAlice.tokens()));
5187 env,
carol_, 1, {
Amounts{eth(27'0658372213582), btc(27'0658372213582)}}));
5211 .transferFee = 25'000,
5218 .transferFee = 25'000,
5221 AMM const ammAlice(env,
alice_, btc(1'000), eth(1'100));
5229 BEAST_EXPECT(ammAlice.expectBalances(btc(1'100), eth(1'000), ammAlice.tokens()));
5254 .transferFee = 25'000,
5261 .transferFee = 25'000,
5268 .transferFee = 25'000,
5275 .transferFee = 25'000,
5278 AMM const ammAlice(env,
alice_, gbp(1'000'000), eth(10'125));
5281 env(
offer(dan, can(2'000'000), gbp(20'000)));
5282 env(
offer(ed, eth(200), btc(200)));
5293 BEAST_EXPECT(ammAlice.expectBalances(gbp(1'012'500), eth(10'000), ammAlice.tokens()));
5301 [&](
AMM& ammAlice,
Env& env) {
5302 auto const& btc =
MPT(ammAlice[1]);
5335 .pay = 500'000'000'000'000'000,
5341 .pay = 500'000'000'000'000'000,
5347 .pay = 500'000'000'000'000'000,
5353 .pay = 500'000'000'000'000'000,
5355 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(100'000'000'000'000'000));
5357 env,
alice_, eur(100'000'000'000'000'000), btc(102'000'000'000'000'000));
5359 env,
alice_, btc(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5360 AMM const xrpUsd(env,
alice_,
XRP(10'150), usd(102'000'000'000'000'000));
5361 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(101'000'000'000'000'000));
5363 env,
alice_, eth(109'000'000'000'000'000), eur(110'000'000'000'000'000));
5365 env,
alice_, eur(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5373 XRPAmount(10'026'208'900), eth(10'073'6577924447994), xrpEth.
tokens()));
5375 eth(10'926'3422075552006), eur(10'973'5423207873690), ethEur.
tokens()));
5377 eur(10'126'4576792126310), usd(9'973'9315171207179), eurUsd.
tokens()));
5381 XRPAmount(10'224'106'246), usd(10'126'0684828792821), xrpUsd.
tokens()));
5391 xrpEur.expectBalances(
XRP(10'100), eur(100'000'000'000'000'000), xrpEur.tokens()));
5393 eur(100'000'000'000'000'000), btc(102'000'000'000'000'000), eurBtc.
tokens()));
5395 btc(101'000'000'000'000'000), usd(100'000'000'000'000'000), btcUsd.
tokens()));
5408 .pay = 50'000'000'000'000'000,
5414 .pay = 50'000'000'000'000'000,
5420 .pay = 50'000'000'000'000'000,
5426 .pay = 50'000'000'000'000'000,
5428 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(10'000'000'000'000'000));
5429 AMM const eurBtc(env,
alice_, eur(10'000'000'000'000'000), btc(10'200'000'000'000'000));
5430 AMM const btcUsd(env,
alice_, btc(10'100'000'000'000'000), usd(10'000'000'000'000'000));
5431 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(10'100'000'000'000'000));
5432 AMM const ethEur(env,
alice_, eth(10'900'000'000'000'000), eur(11'000'000'000'000'000));
5438 BEAST_EXPECT(xrpEur.expectBalances(
5439 XRPAmount(10'118'738'472), eur(9'981'544436337981), xrpEur.tokens()));
5441 eur(10'101'160967851758), btc(10'097'914269680647), eurBtc.
tokens()));
5443 btc(10'202'085730319353), usd(9'900'000'000'000'000), btcUsd.
tokens()));
5445 XRPAmount(10'082'446'397), eth(10'017'410727780081), xrpEth.
tokens()));
5447 eth(10'982'589272219919), eur(10'917'294595810261), ethEur.
tokens()));
5461 .pay = 30'000'000'000'000'000,
5467 .pay = 400'000'000'000'000,
5469 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5471 for (
int i = 0; i < 30; ++i)
5472 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5478 Sendmax(eth(400'000'000'000'000)),
5479 Txflags(tfPartialPayment | tfNoRippleDirect));
5482 ammAlice.expectBalances(
XRP(10'030), btc(9'970'089730807592), ammAlice.tokens()));
5497 .pay = 30'000'000'000'000'000,
5503 .pay = 400'000'000'000'000,
5505 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5507 for (
int i = 0; i < 29; ++i)
5508 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5514 Sendmax(eth(400'000'000'000'000)),
5515 Txflags(tfPartialPayment | tfNoRippleDirect));
5516 BEAST_EXPECT(ammAlice.expectBalances(
5517 XRPAmount{10'101'010'102}, btc(9'900'000'000'000'000), ammAlice.tokens()));
5534 .pay = 30'000'000'000'000'000,
5538 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
5542 XRPAmount{10'049'825'372}, btc(10'049'925870493027), ammAlice.
tokens()));
5559 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5561 btc.set({.holder =
carol_, .flags = tfMPTLock});
5566 Txflags(tfNoRippleDirect | tfPartialPayment),
5580 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5582 btc.set({.holder =
alice_, .flags = tfMPTLock});
5587 Txflags(tfNoRippleDirect | tfPartialPayment),
6273 testcase(
"Adjusted Deposit/Withdraw Tokens");
6274 using namespace jtx;
6289 Account const natalie(
"natalie");
6291 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6292 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6299 .pay = 40'000'000000,
6302 auto const usd = gw[
"USD"];
6303 for (
auto const& holder : holders)
6305 env.
trust(usd(1'500'000), holder);
6306 env(
pay(gw, holder, usd(1'500'000)));
6310 auto aliceUSD = env.
balance(alice, usd);
6311 auto bobUSD = env.
balance(bob, usd);
6312 auto carolUSD = env.
balance(carol, usd);
6313 auto edUSD = env.
balance(ed, usd);
6314 auto paulUSD = env.
balance(paul, usd);
6315 auto danUSD = env.
balance(dan, usd);
6316 auto chrisUSD = env.
balance(chris, usd);
6317 auto simonUSD = env.
balance(simon, usd);
6318 auto benUSD = env.
balance(ben, usd);
6319 auto natalieUSD = env.
balance(natalie, usd);
6321 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6325 for (
int i = 0; i < 10; ++i)
6329 ammAlice.
deposit(simon, usd(0.1));
6331 ammAlice.
deposit(chris, usd(1));
6333 ammAlice.
deposit(dan, usd(10));
6335 ammAlice.
deposit(bob, usd(100));
6337 ammAlice.
deposit(carol, usd(1'000));
6339 ammAlice.
deposit(ed, usd(10'000));
6341 ammAlice.
deposit(paul, usd(100'000));
6343 ammAlice.
deposit(natalie, usd(1'000'000));
6349 STAmount{usd, UINT64_C(10000'0000000001), -10},
6380 Account const natalie(
"natalie");
6382 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6383 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6390 .pay = 40'000'000000,
6393 auto const usd = gw[
"USD"];
6394 for (
auto const& holder : holders)
6396 env.
trust(usd(1'500'000), holder);
6397 env(
pay(gw, holder, usd(1'500'000)));
6401 auto aliceBTC = env.
balance(alice, btc);
6402 auto bobBTC = env.
balance(bob, btc);
6403 auto carolBTC = env.
balance(carol, btc);
6404 auto edBTC = env.
balance(ed, btc);
6405 auto paulBTC = env.
balance(paul, btc);
6406 auto danBTC = env.
balance(dan, btc);
6407 auto chrisBTC = env.
balance(chris, btc);
6408 auto simonBTC = env.
balance(simon, btc);
6409 auto benBTC = env.
balance(ben, btc);
6410 auto natalieBTC = env.
balance(natalie, btc);
6412 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6416 for (
int i = 0; i < 10; ++i)
6418 ammAlice.
deposit(ben, btc(1));
6420 ammAlice.
deposit(simon, btc(1'000));
6422 ammAlice.
deposit(chris, btc(1));
6424 ammAlice.
deposit(dan, btc(10));
6426 ammAlice.
deposit(bob, btc(100));
6428 ammAlice.
deposit(carol, btc(1'000));
6430 ammAlice.
deposit(ed, btc(10'000));
6432 ammAlice.
deposit(paul, btc(100'000));
6434 ammAlice.
deposit(natalie, btc(1'000'000));
6516 testcase(
"Offer/Strand Selection");
6517 using namespace jtx;
6538 .transferFee = gwTransferFee,
6539 .pay = 2'000'000'000,
6545 .transferFee = gw1TransferFee,
6546 .pay = 2'000'000'000,
6552 .transferFee = gw1TransferFee,
6553 .pay = 2'000'000'000,
6558 .usd = std::move(usd),
6559 .eth = std::move(eth),
6560 .can = std::move(can),
6566 for (
auto const& rates :
6581 for (
auto i = 0; i < 3; ++i)
6583 Env env(*
this, features);
6584 auto mpts = prep(env, rates.first, rates.second);
6585 auto usd = mpts.usd;
6586 auto eth = mpts.eth;
6587 auto can = mpts.can;
6590 if (i == 0 || i == 2)
6592 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6596 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6606 BEAST_EXPECT(
amm->expectBalances(
6607 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6617 BEAST_EXPECT(q[0] > q[1]);
6619 BEAST_EXPECT(q[0] == q[2]);
6626 for (
auto i = 0; i < 3; ++i)
6628 Env env(*
this, features);
6629 auto mpts = prep(env, rates.first, rates.second);
6630 auto usd = mpts.usd;
6631 auto eth = mpts.eth;
6632 auto can = mpts.can;
6634 if (i == 0 || i == 2)
6636 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6640 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6641 env(
offer(
alice_, usd(400'000'000), eth(400'000'000)));
6648 amm->expectBalances(usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6651 if (i == 0 || i == 2)
6660 env,
alice_, 1, {
Amounts{usd(400'000'000), eth(400'000'000)}}));
6671 for (
auto i = 0; i < 3; ++i)
6673 Env env(*
this, features);
6674 auto mpts = prep(env, rates.first, rates.second);
6675 auto usd = mpts.usd;
6676 auto eth = mpts.eth;
6677 auto can = mpts.can;
6679 if (i == 0 || i == 2)
6681 env(
offer(ed, eth(400'000'000), usd(330'000'000)),
Txflags(tfPassive));
6685 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6694 BEAST_EXPECT(!
amm->expectBalances(
6695 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6701 if (rates.first == kLowRate)
6731 BEAST_EXPECT(q[1] > q[0]);
6733 BEAST_EXPECT(q[2] > q[1]);
6737 for (
auto i = 0; i < 3; ++i)
6739 Env env(*
this, features);
6740 auto mpts = prep(env, rates.first, rates.second);
6741 auto usd = mpts.usd;
6742 auto eth = mpts.eth;
6743 auto can = mpts.can;
6745 if (i == 0 || i == 2)
6747 env(
offer(ed, eth(400'000'000), usd(325'000'002)),
Txflags(tfPassive));
6751 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6752 env(
offer(
alice_, usd(325'000'000), eth(400'000'000)));
6758 BEAST_EXPECT(!
amm->expectBalances(
6759 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6766 if (rates.first == kLowRate)
6815 for (
auto i = 0; i < 3; ++i)
6817 Env env(*
this, features);
6818 auto mpts = prep(env, rates.first, rates.second);
6819 auto usd = mpts.usd;
6820 auto eth = mpts.eth;
6821 auto can = mpts.can;
6824 if (i == 0 || i == 2)
6826 env(
offer(ed, eth(400'000'000), can(375'000'000)),
Txflags(tfPassive));
6827 env(
offer(ed, can(375'000'000), usd(338'000'000))),
Txflags(tfPassive);
6831 amm.emplace(env, ed, eth(1'000'000'000), usd(1'000'000'000));
6845 if (rates.first == kLowRate)
6848 BEAST_EXPECT(
amm->expectBalances(
6849 eth(1'124'584'936), usd(889'999'993),
amm->tokens()));
6853 BEAST_EXPECT(
amm->expectBalances(
6854 eth(1'103'723'909), usd(906'023'688),
amm->tokens()));
6875 BEAST_EXPECT(q[1] > q[0]);
6876 BEAST_EXPECT(q[2] > q[0] && q[2] < q[1]);