407 [&](
AMM& ammAlice,
Env& env) {
418 jv[jss::Account] =
alice_.human();
419 jv[jss::TransactionType] = jss::AMMDeposit;
423 jv[jss::LPTokenOut] =
425 jv[jss::Flags] = tfLPToken;
433 jv[jss::Account] =
alice_.human();
434 jv[jss::TransactionType] = jss::AMMDeposit;
439 jv[jss::Flags] = tfLPToken;
448 MPT(ammAlice[1])(200),
493 MPT(ammAlice[1])(200),
503 .authHolder =
true});
521 MPT(ammAlice[1])(100),
522 MPT(ammAlice[1])(200),
537 MPT(ammAlice[1])(-1'000),
550 MPT(ammAlice[1])(1'000),
568 {{
MPT(btc),
MPT(ammAlice[1])}},
578 MPT(ammAlice[1])(200),
630 MPT(ammAlice[1])(100),
639 [&](
AMM& ammAlice,
Env& env) {
640 auto const enabledV13 = env.
current()->rules().enabled(fixAMMv1_3);
649 {features, features - fixAMMv1_3});
653 [&](
AMM& ammAlice,
Env& env) {
662 [&](
AMM& ammAlice,
Env& env) {
665 MPT(ammAlice[1])(100),
676 MPT(ammAlice[1])(100),
696 btc.set({.flags = tfMPTLock});
712 Env env{*
this, features};
724 btc.set({.holder =
carol_, .flags = tfMPTLock});
734 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
736 ammAlice.deposit(
carol_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
745 ammAlice.deposit(
alice_, btc(100), std::nullopt, std::nullopt, std::nullopt);
746 ammAlice.deposit(
alice_, 1'000, std::nullopt, std::nullopt);
747 ammAlice.deposit(
alice_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
750 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
752 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
753 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
782 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
785 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
803 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
805 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
806 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
829 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
832 btc.set({.holder =
carol_, .flags = tfMPTLock});
840 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
843 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
844 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
847 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
860 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
862 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
863 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
866 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
879 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
881 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
882 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
887 Env env{*
this, features};
888 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
889 env.
fund(
XRP(30'000), alice, carol, gw);
892 MPTTester btc(env, gw, {.holders = {alice, carol}, .fund =
false});
894 {.maxAmt = 1'000'000,
895 .authorize = {{alice}},
896 .pay = {{{alice}, 10'000}},
898 .authHolder =
true});
900 AMM amm(env, alice,
XRP(10'000), btc(10'000));
905 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
907 amm.deposit(carol,
XRP(10), std::nullopt, std::nullopt, std::nullopt);
918 Env env{*
this, features};
919 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
920 env.
fund(
XRP(30'000), alice, carol, gw);
928 .flags = tfMPTCanTrade});
930 AMM amm(env, gw,
XRP(10'000), btc(10'000));
932 amm.deposit({.account = alice, .asset1In = btc(10), .err =
Ter(
tecNO_AUTH)});
937 [&](
AMM& ammAlice,
Env& env) {
953 [&](
AMM& ammAlice,
Env& env) {
956 MPT(ammAlice[1])(450'000),
966 [&](
AMM& ammAlice,
Env& env) {
987 .transferFee = 1'500,
1006 auto const startingXrp =
reserve(env, 4) + env.
current()->fees().base * 4;
1015 .transferFee = 1'500,
1040 [&](
AMM& ammAlice,
Env& env) {
1048 MPT(ammAlice[1])(100),
1061 MPT(ammAlice[1])(100),
1072 MPT(ammAlice[1])(-1),
1095 [&](
AMM& ammAlice,
Env& env) {
1101 MPT(ammAlice[1])(1'001),
1112 MPT(ammAlice[1])(1'000),
1124 MPT(ammAlice[1])(100),
1151 MPTTester const btc({.env = env, .issuer =
gw_, .holders = {
alice_}, .maxAmt = 100});
1174 using namespace jtx;
1178 [&](
AMM& ammAlice,
Env& env) {
1196 [&](
AMM& ammAlice,
Env& env) {
1199 MPT(ammAlice[1])(100),
1209 MPT(ammAlice[1])(100),
1218 auto test = [&](
auto&& issue1,
auto&& issue2) {
1222 auto const usd = issue1(
1227 .limit = 1'000'000});
1228 auto const btc = issue2(
1233 .limit = 1'000'000});
1240 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1255 [&](
AMM& ammAlice,
Env& env) {
1271 auto test = [&](
auto&& issue1,
auto&& issue2) {
1275 auto const usd = issue1(
1280 .limit = 1'000'000});
1281 auto const btc = issue2(
1286 .limit = 1'000'000});
1293 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1309 [&](
AMM& ammAlice,
Env& env) {
1325 auto test = [&](
auto&& issue1,
auto&& issue2) {
1329 auto const usd = issue1(
1334 .limit = 1'000'000});
1335 auto const btc = issue2(
1340 .limit = 1'000'000});
1347 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1361 [&](
AMM& ammAlice,
Env& env) {
1368 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1377 [&](
AMM& ammAlice,
Env& env) {
1384 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1393 [&](
AMM& ammAlice,
Env& env) {
1399 MPT(ammAlice[0])(11'000),
1400 MPT(ammAlice[1])(10'000),
1410 [&](
AMM& ammAlice,
Env& env) {
1416 MPT(ammAlice[0])(11'000),
USD(10'000),
IOUAmount{10'488'08848170151, -11}));
1425 [&](
AMM& ammAlice,
Env& env) {
1431 MPT(ammAlice[0])(10'000),
1443 [&](
AMM& ammAlice,
Env& env) {
1459 [&](
AMM& ammAlice,
Env& env) {
1476 auto test = [&](
auto&& issue1,
auto&& issue2) {
1480 auto const usd = issue1(
1485 .limit = 1'000'000});
1486 auto const btc = issue2(
1491 .limit = 1'000'000});
1498 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1503 auto deltaUSD = [&]() {
1509 btc(10'000), usd(10'000) + deltaUSD,
IOUAmount{10'100, 0}));
1521 [&](
AMM& ammAlice,
Env& env) {
1524 MPT(ammAlice[1])(100),
1529 XRP(10'000),
MPT(ammAlice[1])(10100),
IOUAmount{10'049'875'62112089, -8}));
1536 [&](
AMM& ammAlice,
Env& env) {
1543 MPT(ammAlice[1])(100),
1548 XRP(10'000),
MPT(ammAlice[1])(10'081),
IOUAmount{10'039'920'31840891, -8}));
1558 [&](
AMM& ammAlice,
Env& env) {
1565 MPT(ammAlice[1])(0),
1570 XRP(10'000),
MPT(ammAlice[1])(10'081),
IOUAmount{10'039'920'31840891, -8}));
1581 [&](
AMM& ammAlice,
Env& env) {
1584 MPT(ammAlice[1])(100),
1589 USD(10'000'000'000),
1590 MPT(ammAlice[1])(10100),
1599 [&](
AMM& ammAlice,
Env& env) {
1603 MPT(ammAlice[1])(10'000'000'000),
1613 [&](
AMM& ammAlice,
Env& env) {
1616 MPT(ammAlice[0])(100),
1621 MPT(ammAlice[1])(10'000'000'000),
1622 MPT(ammAlice[0])(10100),
1637 .transferFee = 25'000,
1644 .transferFee = 25'000,
1647 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1648 BEAST_EXPECT(ammAlice.expectBalances(usd(200'000), btc(5),
IOUAmount{1000, 0}));
1650 ammAlice.deposit(
carol_, 100, std::nullopt, std::nullopt);
1651 BEAST_EXPECT(ammAlice.expectBalances(usd(220'000), btc(6),
IOUAmount{1100, 0}));
1667 .transferFee = 25'000,
1670 auto const usd =
gw_[
"USD"];
1680 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1689 .transferFee = 25'000,
1693 AMM ammBob(env,
bob_, eth(20'000), usd(0.5));
1694 BEAST_EXPECT(ammBob.expectBalances(eth(20'000), usd(0.5),
IOUAmount{100, 0}));
1695 ammBob.deposit(
carol_, 10);
1696 BEAST_EXPECT(ammBob.expectBalances(eth(22'000), usd(0.55),
IOUAmount{110, 0}));
1701 [&](
AMM& ammAlice,
Env& env) {
1705 STAmount{USD, UINT64_C(10'000'001), -3},
1706 MPT(ammAlice[1])(10'001),
1711 STAmount{USD, UINT64_C(10'001'001), -3},
1712 MPT(ammAlice[1])(10'003),
1717 [&](
AMM& ammAlice,
Env& env) {
1720 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1721 MPT(ammAlice[1])(10'000),
1726 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1727 MPT(ammAlice[1])(10'001),
1734 [&](
AMM& ammAlice,
Env& env) {
1738 MPT(ammAlice[1])(10'000),
1743 [&](
AMM& ammAlice,
Env& env) {
1746 XRP(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000'499'98750062, -8}));
1752 [&](
AMM& ammAlice,
Env& env) {
1756 MPT(ammAlice[0])(10'000),
1757 MPT(ammAlice[1])(10'001),
1768 MPT const btc =
MPTTester({.env = env, .issuer =
gw_, .holders = {}});
1770 AMM ammGw(env,
gw_,
XRP(10'000), btc(10'000'000'000));
1772 ammGw.expectBalances(
XRP(10'000), btc(10'000'000'000),
IOUAmount{10'000'000'000}));
1774 ammGw.deposit(
gw_, 1'000'000);
1776 ammGw.expectBalances(
XRP(10'001), btc(10'001000000),
IOUAmount{10'001000000}));
1778 ammGw.deposit(
gw_, btc(1'000000000));
1779 BEAST_EXPECT(ammGw.expectBalances(
1780 XRP(10'001), btc(11'001000000),
IOUAmount{1048'908'961731188, -5}));
1785 [&](
AMM& ammAlice,
Env& env) {
1788 MPT(ammAlice[0])(1'010'000),
1789 MPT(ammAlice[1])(1'010'000),
1794 MPT(ammAlice[0])(1'010'999),
1795 MPT(ammAlice[1])(1'010'000),
1802 [&](
AMM& ammAlice,
Env& env) {
1808 XRP(11'000),
MPT(ammAlice[1])(12'000),
IOUAmount{11'489'125'29307605, -8}));
1814 [&](
AMM& ammAlice,
Env& env) {
1819 MPT(ammAlice[1])(1'000),
1831 auto test = [&](
auto&& issue1,
auto&& issue2) {
1835 auto const usd = issue1(
1840 .limit = 1'000'000});
1841 auto const btc = issue2(
1846 .limit = 1'000'000});
1853 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1876 [&](
AMM& ammAlice,
Env& env) {
1881 MPT(ammAlice[1])(1'000),
1893 auto test = [&](
auto&& issue1,
auto&& issue2) {
1897 auto const usd = issue1(
1902 .limit = 1'000'000});
1903 auto const btc = issue2(
1908 .limit = 1'000'000});
1914 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1938 [&](
AMM& ammAlice,
Env& env) {
1949 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1955 [&](
AMM& ammAlice,
Env& env) {
1959 MPT(ammAlice[1])(1'000),
1966 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1972 [&](
AMM& ammAlice,
Env& env) {
1983 STAmount{USD, UINT64_C(10'999'99999999999), -11},
1984 MPT(ammAlice[1])(10'000),
1991 [&](
AMM& ammAlice,
Env& env) {
1995 MPT(ammAlice[1])(1'000),
2002 USD(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -11}));
2008 [&](
AMM& ammAlice,
Env& env) {
2012 MPT(ammAlice[1])(1'000),
2019 MPT(ammAlice[0])(10'000),
2020 MPT(ammAlice[1])(11'000),
2031 using namespace jtx;
2035 [&](
AMM& ammAlice,
Env& env) {
2037 .asset1Out =
XRP(100),
2045 [&](
AMM& ammAlice,
Env& env) {
2047 .asset1Out =
MPT(ammAlice[1])(100),
2065 .authHolder =
true});
2069 .asset1Out = btc(100),
2072 ammAlice.withdraw(args);
2076 [&](
AMM& ammAlice,
Env& env) {
2101 MPT(ammAlice[1])(100),
2102 MPT(ammAlice[1])(100),
2118 MPT(ammAlice[1])(10'000),
2127 MPT(ammAlice[1])(0),
2130 tfOneAssetWithdrawAll,
2165 {{
MPT(ammAlice[1]),
GBP}},
2175 [&](
AMM& ammAlice,
Env& env) {
2185 alice_,
IOUAmount{9'999'999'9999, -4}, std::nullopt, std::nullopt, err);
2195 {all, all - fixAMMv1_3});
2198 [&](
AMM& ammAlice,
Env& env) {
2205 alice_,
IOUAmount{9'999'999'999999999, -9}, std::nullopt, std::nullopt, err);
2215 {all, all - fixAMMv1_3});
2219 [&](
AMM& ammAlice,
Env& env) {
2238 .asset1Out =
MPT(
gw_, 1'000)(10),
2254 .authHolder =
true});
2255 MPT const btc = btcm;
2259 btcm.authorize({.account =
gw_, .holder =
alice_, .flags = tfMPTUnauthorize});
2264 .asset1Out = btc(100),
2265 .assets = {{
XRP, btc}},
2281 .flags = tfMPTCanTrade,
2282 .authHolder =
true});
2286 auto const lpIssue =
amm.lptIssue();
2308 .authHolder =
true});
2311 btc.set({.flags = tfMPTLock});
2318 ammAlice.withdraw({.account =
alice_, .asset1Out =
XRP(100)});
2339 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
2342 btc.set({.holder =
alice_, .flags = tfMPTLock});
2347 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2350 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2351 ammAlice.withdraw(
alice_, 1000, std::nullopt, std::nullopt);
2352 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2353 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2370 btc.set({.holder =
alice_, .flags = tfMPTLock});
2375 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2378 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2381 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2382 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2383 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2386 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
2389 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2396 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
2398 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2399 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2407 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2421 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2422 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2427 [&](
AMM& ammAlice,
Env&) {
2444 [&](
AMM& ammAlice,
Env& env) {
2454 {all, all - fixAMMv1_3});
2459 [&](
AMM& ammAlice,
Env&) {
2463 MPT(ammAlice[1])(100),
2473 [&](
AMM& ammAlice,
Env&) {
2477 MPT(ammAlice[1])(1'700),
2486 [&](
AMM& ammAlice,
Env&) {
2490 MPT(ammAlice[1])(1'000),
2498 [&](
AMM& ammAlice,
Env&) {
2508 [&](
AMM& ammAlice,
Env&) {
2522 [&](
AMM& ammAlice,
Env&) {
2525 STAmount{
MPT(ammAlice[1]), UINT64_C(9'999'999999999999), -12},
2534 [&](
AMM& ammAlice,
Env&) {
2555 MPT(ammAlice[0])(1),
2567 using namespace jtx;
2572 [&](
AMM& ammAlice,
Env& env) {
2598 [&](
AMM& ammAlice,
Env&) {
2609 auto test = [&](
auto&& issue1,
auto&& issue2) {
2613 auto const usd = issue1(
2618 .limit = 1'000'000});
2619 auto const btc = issue2(
2624 .limit = 1'000'000});
2628 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2645 [&](
AMM& ammAlice,
Env&) {
2656 [&](
AMM& ammAlice,
Env&) {
2666 auto test = [&](
auto&& issue1,
auto&& issue2) {
2670 auto const usd = issue1(
2675 .limit = 1'000'000});
2676 auto const btc = issue2(
2681 .limit = 1'000'000});
2685 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2698 [&](
AMM& ammAlice,
Env&) {
2703 MPT(ammAlice[1])(10'000),
2708 [&](
AMM& ammAlice,
Env&) {
2712 XRP(10000),
MPT(ammAlice[1])(9001),
IOUAmount{9'486'832'98050514, -8}));
2716 [&](
AMM& ammAlice,
Env&) {
2720 STAmount{USD, UINT64_C(9000'000000000004), -12},
2721 MPT(ammAlice[1])(10'000),
2726 [&](
AMM& ammAlice,
Env&) {
2730 USD(10'000),
MPT(ammAlice[1])(9001),
IOUAmount{9486'83298050514, -11}));
2734 [&](
AMM& ammAlice,
Env&) {
2738 MPT(ammAlice[0])(9001),
2739 MPT(ammAlice[1])(10'000),
2746 [&](
AMM& ammAlice,
Env&) {
2755 [&](
AMM& ammAlice,
Env&) {
2764 auto test = [&](
auto&& issue1,
auto&& issue2) {
2768 auto const usd = issue1(
2773 .limit = 1'000'000});
2774 auto const btc = issue2(
2779 .limit = 1'000'000});
2783 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2796 [&](
AMM& ammAlice,
Env& env) {
2808 AMM const ammCarol(env,
carol_,
XRP(10'000),
MPT(ammAlice[1])(10'000));
2816 [&](
AMM& ammAlice,
Env& env) {
2827 [&](
AMM& ammAlice,
Env&) {
2837 [&](
AMM& ammAlice,
Env& env) {
2849 [&](
AMM& ammAlice,
Env& env) {
2861 [&](
AMM& ammAlice,
Env& env) {
2866 MPT(ammAlice[0])(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000, 0}));
2873 [&](
AMM& ammAlice,
Env&) {
2883 [&](
AMM& ammAlice,
Env&) {
2887 STAmount{USD, UINT64_C(9'090'9090909091), -10},
2888 MPT(ammAlice[1])(11000),
2895 [&](
AMM& ammAlice,
Env&) {
2899 STAmount{USD, UINT64_C(10'999'99999999999), -11},
2900 MPT(ammAlice[1])(9091),
2907 [&](
AMM& ammAlice,
Env&) {
2915 MPT(ammAlice[0])(10'000'000'001),
USD(10'000), ammAlice.
tokens()));
2920 [&](
AMM& ammAlice,
Env&) {
2921 auto const& btc =
MPT(ammAlice[1]);
2936 [&](
AMM& ammAlice,
Env&) {
2937 auto const carolTokens = ammAlice.
deposit(
carol_,
MPT(ammAlice[1])(1'000));
2938 auto const aliceTokens = ammAlice.
deposit(
alice_,
MPT(ammAlice[1])(1'000));
2942 XRP(10'000),
MPT(ammAlice[1])(10'001), ammAlice.
tokens()));
2950 [&](
AMM& ammAlice,
Env&) {
2959 auto test = [&](
auto&& issue1,
auto&& issue2) {
2963 auto const usd = issue1(
2968 .limit = 1'000'000});
2969 auto const btc = issue2(
2974 .limit = 1'000'000});
2980 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2995 [&](
AMM& ammAlice,
Env&) {
3000 STAmount{
MPT(ammAlice[1]), UINT64_C(9'090'909090909092), -12},
3007 [&](
AMM& ammAlice,
Env&) {
3017 [&](
AMM& ammAlice,
Env&) {
3021 STAmount{USD, UINT64_C(9'090'909090909092), -12},
3022 MPT(ammAlice[1])(11'000),
3028 [&](
AMM& ammAlice,
Env&) {
3032 MPT(ammAlice[0])(11'000),
MPT(ammAlice[1])(9'091),
IOUAmount{10'000}));
3040 [&](
AMM& ammAlice,
Env& env) {
3049 MPT(ammAlice[1])(9372781065),
3058 MPT(ammAlice[1])(9372781065),
3062 else if (env.
enabled(fixAMMv1_3))
3067 MPT(ammAlice[1])(9372781066),
3074 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3077 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3081 [&](
AMM& ammAlice,
Env& env) {
3089 MPT(ammAlice[1])(9372781065),
3098 MPT(ammAlice[1])(9372781065),
3102 else if (env.
enabled(fixAMMv1_3))
3107 MPT(ammAlice[1])(9372781066),
3114 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3117 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3121 auto test = [&](
auto&& issue1,
auto&& issue2) {
3125 auto const usd = issue1(
3131 .transferFee = 25'000});
3132 auto const btc = issue2(
3138 .transferFee = 25'000});
3147 AMM ammAlice(env,
alice_, btc(2'000), usd(5));
3170 [&](
AMM& ammAlice,
Env&) {
3174 MPT(ammAlice[0])(9'999'999'999),
3180 [&](
AMM& ammAlice,
Env&) {
3184 MPT(ammAlice[0])(10000'000000),
USD(10'000),
IOUAmount{9'999'999'9995, -4}));
3188 [&](
AMM& ammAlice,
Env&) {
3192 MPT(ammAlice[0])(10'000'000'000),
3198 [&](
AMM& ammAlice,
Env&) {
3209 [&](
AMM& ammAlice,
Env&) {
3217 [&](
AMM& ammAlice,
Env&) {
3225 [&](
AMM& ammAlice,
Env&) {
3233 [&](
AMM& ammAlice,
Env&) {
3241 [&](
AMM& ammAlice,
Env&) {
3244 MPT(ammAlice[0])(10'000'000'000),
3251 [&](
AMM& ammAlice,
Env&) {
3259 [&](
AMM& ammAlice,
Env&) {
3266 [&](
AMM& ammAlice,
Env&) {
3496 using namespace jtx;
3509 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3512 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3519 .bidMin = 1'000'000,
3534 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3537 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3544 .bidMin = STAmount{amm.lptIssue(), UINT64_C(999'999)},
3550 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{999'999}));
3553 BEAST_EXPECT(
amm.expectBalances(
XRP(1'000), btc(1'000),
IOUAmount{1}));
3556 BEAST_EXPECT(
Number{
amm.getLPTokensBalance(
gw_)} == 1);
3569 [&](
AMM& ammAlice,
Env& env) {
3606 .authAccounts = {bob_},
3614 .assets = {{MPT(ammAlice[1]), GBP}},
3618 {{
XRP(10'000), gAmmmpt(10'000)}});
3622 [&](AMM& ammAlice, Env& env) {
3623 ammAlice.withdrawAll(alice_);
3630 {{
XRP(10'000), gAmmmpt(10'000)}});
3635 fund(env, gw_, {alice_, bob_, carol_},
XRP(1'000), {USD(30'000)}, Fund::All);
3636 MPTTester
const btc(
3639 .holders = {alice_, carol_, bob_},
3640 .pay = 30'000'000'000,
3643 AMM ammAlice(env, alice_, btc(10'000'000'000), USD(10'000));
3644 ammAlice.deposit(carol_, 1'000'000);
3645 ammAlice.deposit(bob_, 10);
3648 .bidMin = 1'000'001,
3650 Ter(tecAMM_INVALID_TOKENS));
3653 .bidMax = 1'000'001,
3655 Ter(tecAMM_INVALID_TOKENS));
3660 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0, IOUAmount{1'000}));
3665 Ter(tecAMM_INVALID_TOKENS));
3671 env.fund(
XRP(1'000), gw_, alice_, bob_);
3672 MPTTester
const btc(
3675 .holders = {alice_, bob_},
3678 AMM
amm(env, gw_,
XRP(10), btc(1'000));
3679 auto const lpIssue =
amm.lptIssue();
3680 env.trust(STAmount{lpIssue, 100}, alice_);
3681 env.trust(STAmount{lpIssue, 50}, bob_);
3682 env(
pay(gw_, alice_, STAmount{lpIssue, 100}));
3683 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
3684 env(
amm.bid({.account = alice_, .bidMin = 100}));
3691 Ter(tecAMM_FAILED));
3699 using namespace jtx;
3706 [&](
AMM& ammAlice,
Env& env) {
3708 env(ammAlice.
bid({.account = carol_, .bidMin = 110}));
3718 [&](
AMM& ammAlice,
Env& env) {
3721 env(ammAlice.
bid({.account = carol_, .bidMin = 110, .bidMax = 110}));
3726 env(ammAlice.
bid({.account = alice_, .bidMin = 180, .bidMax = 200}));
3745 ammAlice.deposit(
carol_, 1'000'000);
3747 env(ammAlice.bid({.account = carol_, .bidMin = 110}));
3748 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3750 ammAlice.deposit(
bob_, 1'000'000);
3752 env(ammAlice.bid({.account = bob_}));
3753 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount(1155, -1)));
3762 env(ammAlice.bid({.account = carol_, .bidMax = 600}));
3763 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{121'275, -3}));
3774 env(ammAlice.bid({.account = carol_, .bidMin = 100, .bidMax = 600}));
3775 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{127'33875, -5}));
3790 ammAlice.deposit(
carol_, 1'000'000);
3791 ammAlice.deposit(
bob_, 1'000'000);
3792 BEAST_EXPECT(ammAlice.expectBalances(
3796 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3797 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3800 env(ammAlice.bid({.account = bob_}));
3802 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 1,
IOUAmount{1'155, -1}));
3805 env(ammAlice.bid({.account = carol_}));
3807 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 10,
IOUAmount{121'275, -3}));
3810 env(ammAlice.bid({.account = bob_}));
3812 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{127'33875, -5}));
3815 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3816 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{110}));
3818 BEAST_EXPECT(ammAlice.expectBalances(
3835 .pay = 30'000'000'000});
3841 ammAlice.
deposit(ed, 1'000'000);
3843 ammAlice.
deposit(dan, 500'000);
3848 .authAccounts = {bob_, ed},
3850 auto const slotPrice =
IOUAmount{5'200};
3851 ammTokens -= slotPrice;
3853 BEAST_EXPECT(ammAlice.
expectBalances(btc(13'000'000'003),
USD(13'000), ammTokens));
3855 for (
int i = 0; i < 10; ++i)
3872 btc(13'000'000'003),
STAmount(
USD, UINT64_C(13'002'98282151419), -11), ammTokens));
3876 for (
int i = 0; i < 10; ++i)
3878 auto const tokens = ammAlice.
deposit(dan,
USD(100));
3888 btc(13'000'000'003),
STAmount{
USD, UINT64_C(13'012'92609877021), -11}, ammTokens));
3893 MPT(ammAlice[0])(13'000'000'003),
3901 btc(13'100'000'671),
STAmount{
USD, UINT64_C(13'012'92609877019), -11}, ammTokens));
3911 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'114'03663044931), -11}, ammTokens));
3921 for (
int i = 0; i < 10; ++i)
3932 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'123'98038488356), -11}, ammTokens));
3940 btc(13'100'824'793),
STAmount{
USD, UINT64_C(13'023'98038488356), -11}, ammTokens));
3945 [&](
AMM& ammAlice,
Env& env) {
3948 env(ammAlice.
bid({.account = alice_, .bidMin = IOUAmount{tiny}}));
3954 MPT(ammAlice[0])(10'000'000'000), USD(10'000), ammAlice.
tokens()));
3958 .bidMin = IOUAmount{STAmount::kMinValue, STAmount::kMinOffset},
3961 BEAST_EXPECT(ammAlice.
expectAuctionSlot(0, 0, IOUAmount{tiny * Number{105, -2}}));
3965 MPT(ammAlice[0])(10'000'000'000), USD(10'000), ammAlice.
tokens()));
3967 {{gAmmmpt(10'000'000'000), USD(10'000)}});
3971 [&](AMM& ammAlice, Env& env) {
3974 .bidMin = IOUAmount{100},
3975 .authAccounts = {carol_},
3977 BEAST_EXPECT(ammAlice.expectAuctionSlot({carol_}));
3978 env(ammAlice.bid({.account = alice_, .bidMin = IOUAmount{100}}));
3982 fund(env, {bob, dan},
XRP(1'000));
3985 .bidMin = IOUAmount{100},
3986 .authAccounts = {bob, dan},
3990 {{gAmmmpt(10'000'000'000), USD(10'000)}});
3995 env.
fund(
XRP(2'000), gw_, alice_, bob_);
3996 MPTTester
const btc(
3999 .holders = {alice_, bob_},
4000 .pay = 2'000'000'000,
4002 fund(env, gw_, {alice_, bob_}, {USD(2'000)}, Fund::TokenOnly);
4003 AMM
amm(env, gw_, btc(1'000'000'000), USD(1'010),
false, 1'000);
4004 auto const lpIssue =
amm.lptIssue();
4005 env.
trust(STAmount{lpIssue, 500}, alice_);
4006 env.
trust(STAmount{lpIssue, 50}, bob_);
4007 env(
pay(gw_, alice_, STAmount{lpIssue, 500}));
4008 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
4010 env(
amm.bid({.account = alice_, .bidMin = 500}));
4011 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0, IOUAmount{500}));
4012 BEAST_EXPECT(
expectHolding(env, alice_, STAmount{lpIssue, 0}));
4015 env(
pay(alice_, bob_, USD(10)), Path(~USD), Sendmax(btc(11'000'000)));
4016 BEAST_EXPECT(
amm.expectBalances(
4017 btc(1'010'010'011), USD(1'000), IOUAmount{1'004'487'562112089, -9}));
4020 env(
pay(bob_, alice_, btc(10'000'000)), Path(~MPT(btc)), Sendmax(USD(11)));
4022 BEAST_EXPECT(
amm.expectBalances(
4024 STAmount{USD, UINT64_C(1'010'10090898081), -11},
4025 IOUAmount{1'004'487'562112089, -9}));
4030 Env env(*
this, features);
4031 env.
fund(
XRP(2'000), gw_, alice_, bob_);
4032 MPTTester
const btc(
4035 .holders = {alice_, bob_},
4038 AMM
amm(env, gw_,
XRP(1'000), btc(1'010),
false, 1'000);
4039 json::Value const tx =
amm.bid({.account = alice_, .bidMin = 500});
4042 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4044 PreflightContext
const pfctx(
4046 auto pf = AMMBid::checkExtraFeatures(pfctx);
4047 BEAST_EXPECT(pf ==
false);
4052 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4053 jtx.
jv[
"Asset2"][
"currency"] =
"XRP";
4055 jtx.stx = env.
ust(jtx);
4056 PreflightContext
const pfctx(
4058 auto pf = AMMBid::preflight(pfctx);
4059 BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
4383 using namespace jtx;
4388 [&](
AMM& ammAlice,
Env& env) {
4398 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4410 auto test = [&](
auto&& issue1,
auto&& issue2) {
4415 auto const usd = issue1(
4420 .limit = 1'000'000});
4421 auto const btc = issue2(
4426 .limit = 1'000'000});
4436 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4442 Txflags(tfNoRippleDirect | tfPartialPayment));
4453 [&](
AMM& ammAlice,
Env& env) {
4460 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4472 auto test = [&](
auto&& issue1,
auto&& issue2) {
4477 auto const usd = issue1(
4482 .limit = 1'000'000});
4483 auto const btc = issue2(
4488 .limit = 1'000'000});
4498 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4513 [&](
AMM& ammAlice,
Env& env) {
4522 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4533 auto test = [&](
auto&& issue1,
auto&& issue2) {
4538 auto const usd = issue1(
4543 .limit = 1'000'000});
4544 auto const btc = issue2(
4549 .limit = 1'000'000});
4559 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4573 [&](
AMM& ammAlice,
Env& env) {
4582 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4585 XRP(10'010),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4598 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4606 auto test = [&](
auto&& issue1,
auto&& issue2) {
4611 auto const usd = issue1(
4616 .limit = 1'000'000});
4617 auto const btc = issue2(
4622 .limit = 1'000'000});
4632 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10010));
4638 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4647 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4663 .transferFee = 10'000,
4664 .pay = 30'000'000'000'000'000,
4666 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(10'010'000'000'000'000));
4675 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4677 BEAST_EXPECT(ammAlice.expectBalances(
4678 XRP(10'010), btc(10'000'000'000'000'000), ammAlice.tokens()));
4686 auto test = [&](
auto&& issue1,
auto&& issue2) {
4691 auto const usd = issue1({
4699 auto const btc = issue2(
4704 .limit = 300'000'000'000'000'000,
4705 .transferFee = 10'000});
4708 env(
pay(
gw_,
bob_, btc(30'000'000'000'000'000)));
4715 auto ammAlice =
AMM(env,
alice_, usd(10'000), btc(10'010'000'000'000'000));
4721 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4724 usd(10'010), btc(10'000'000'000'000'000), ammAlice.
tokens()));
4733 [&](
AMM& ammAlice,
Env& env) {
4745 auto test = [&](
auto&& issue1,
auto&& issue2) {
4750 auto const usd = issue1(
4755 .limit = 1'000'000});
4756 auto const btc = issue2(
4761 .limit = 1'000'000});
4771 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
4792 .pay = 3'000'000'000'000'000'000,
4798 .pay = 3'000'000'000'000'000'000,
4802 auto ammEthXrp =
AMM(env,
alice_,
XRP(10'000), eth(1'000'000'000'000'000'000));
4804 AMM(env,
alice_, eth(1'000'000'000'000'000'000), btc(1'000'000'000'000'000'000));
4812 BEAST_EXPECT(ammEthXrp.expectBalances(
4813 XRPAmount(10'030'082'730), eth(9'970'00749812546872), ammEthXrp.tokens()));
4815 BEAST_EXPECT(ammBtcEth.expectBalances(
4816 btc(9'970'09727766213961), eth(10'029'99250187453128), ammBtcEth.tokens()));
4842 .pay = 3'000'000'000'000'000'000,
4848 .pay = 1'000'000'000'000'000'000,
4850 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(1'000'000'000'000'000'000));
4855 env(
offer(
alice_, eth(10'000'000'000'000'000), btc(10'000'000'000'000'000)),
4863 BEAST_EXPECT(ammAlice.expectBalances(
4864 XRPAmount(10'050'238'637), btc(9'950'01249687578120), ammAlice.tokens()));
4870 Amounts{eth(49'98750312421880), btc(49'98750312421880)}}}));
4890 .pay = 30'000'000'000'000'000,
4892 AMM ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
4900 BEAST_EXPECT(ammAlice.expectBalances(
4901 XRP(10'100),
MPT(ammAlice[1])(10'000'000000000001), ammAlice.tokens()));
4911 2 *
txFee(env, 1)));
4929 AMM const ammAlice(env,
alice_,
XRP(1'000), btc(1'050));
4950 ammAlice.expectBalances(
XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.tokens()));
4969 .transferFee = 25'000,
4970 .pay = 30'000'000'000'000'000,
4976 .transferFee = 25'000,
4977 .pay = 30'000'000'000'000'000,
4979 AMM const ammAlice(env,
alice_, btc(1'000'000'000'000'000), eth(1'100'000'000'000'000));
4984 env(
offer(
carol_, eth(100'000'000'000'000), btc(100'000'000'000'000)));
4987 BEAST_EXPECT(ammAlice.expectBalances(
4988 btc(1'100'000'000'000'000), eth(1'000'000'000'000'000), ammAlice.tokens()));
5006 .pay = 30'000'000'000'000'000,
5013 amm.expectBalances(
XRPAmount(909'090'909), btc(550'000000055001),
amm.tokens()));
5029 .pay = 3'000'000'000'000'000'000,
5035 BEAST_EXPECT(
amm.expectBalances(
XRP(990), btc(505'05050505050506),
amm.tokens()));
5048 .transferFee = 25'000,
5049 .pay = 20'000'000'000'000'000,
5055 .transferFee = 25'000,
5056 .pay = 20'000'000'000'000'000,
5059 env,
alice_, btc(10'000'000'000'000'000), eth(11'000'000'000'000'000));
5062 env(
offer(ed,
XRP(10), eth(100'000'000'000'000)),
Txflags(tfPassive));
5064 env(
offer(
carol_, eth(1'000'000'000'000'000), btc(1'000'000'000'000'000)));
5067 BEAST_EXPECT(ammAlice.expectBalances(
5068 btc(1'060'6848287928033), eth(1'037'0658372213574), ammAlice.tokens()));
5071 env,
carol_, 1, {
Amounts{eth(27'0658372213574), btc(27'0658372213575)}}));
5095 .transferFee = 25'000,
5102 .transferFee = 25'000,
5105 AMM const ammAlice(env,
alice_, btc(1'000), eth(1'100));
5113 BEAST_EXPECT(ammAlice.expectBalances(btc(1'100), eth(1'000), ammAlice.tokens()));
5138 .transferFee = 25'000,
5145 .transferFee = 25'000,
5152 .transferFee = 25'000,
5159 .transferFee = 25'000,
5162 AMM const ammAlice(env,
alice_, gbp(1'000'000), eth(10'125));
5165 env(
offer(dan, can(2'000'000), gbp(20'000)));
5166 env(
offer(ed, eth(200), btc(200)));
5177 BEAST_EXPECT(ammAlice.expectBalances(gbp(1'012'500), eth(10'000), ammAlice.tokens()));
5185 [&](
AMM& ammAlice,
Env& env) {
5186 auto const& btc =
MPT(ammAlice[1]);
5219 .pay = 500'000'000'000'000'000,
5225 .pay = 500'000'000'000'000'000,
5231 .pay = 500'000'000'000'000'000,
5237 .pay = 500'000'000'000'000'000,
5239 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(100'000'000'000'000'000));
5241 env,
alice_, eur(100'000'000'000'000'000), btc(102'000'000'000'000'000));
5243 env,
alice_, btc(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5244 AMM const xrpUsd(env,
alice_,
XRP(10'150), usd(102'000'000'000'000'000));
5245 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(101'000'000'000'000'000));
5247 env,
alice_, eth(109'000'000'000'000'000), eur(110'000'000'000'000'000));
5249 env,
alice_, eur(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5257 XRPAmount(10'026'208'900), eth(10'073'6577924447994), xrpEth.
tokens()));
5259 eth(10'926'3422075552006), eur(10'973'5423207873690), ethEur.
tokens()));
5261 eur(10'126'4576792126310), usd(9'973'9315171207179), eurUsd.
tokens()));
5265 XRPAmount(10'224'106'246), usd(10'126'0684828792821), xrpUsd.
tokens()));
5275 xrpEur.expectBalances(
XRP(10'100), eur(100'000'000'000'000'000), xrpEur.tokens()));
5277 eur(100'000'000'000'000'000), btc(102'000'000'000'000'000), eurBtc.
tokens()));
5279 btc(101'000'000'000'000'000), usd(100'000'000'000'000'000), btcUsd.
tokens()));
5292 .pay = 50'000'000'000'000'000,
5298 .pay = 50'000'000'000'000'000,
5304 .pay = 50'000'000'000'000'000,
5310 .pay = 50'000'000'000'000'000,
5312 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(10'000'000'000'000'000));
5313 AMM const eurBtc(env,
alice_, eur(10'000'000'000'000'000), btc(10'200'000'000'000'000));
5314 AMM const btcUsd(env,
alice_, btc(10'100'000'000'000'000), usd(10'000'000'000'000'000));
5315 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(10'100'000'000'000'000));
5316 AMM const ethEur(env,
alice_, eth(10'900'000'000'000'000), eur(11'000'000'000'000'000));
5322 BEAST_EXPECT(xrpEur.expectBalances(
5323 XRPAmount(10'118'738'472), eur(9'981'544436337981), xrpEur.tokens()));
5325 eur(10'101'160967851758), btc(10'097'914269680647), eurBtc.
tokens()));
5327 btc(10'202'085730319353), usd(9'900'000'000'000'000), btcUsd.
tokens()));
5329 XRPAmount(10'082'446'397), eth(10'017'410727780081), xrpEth.
tokens()));
5331 eth(10'982'589272219919), eur(10'917'294595810261), ethEur.
tokens()));
5345 .pay = 30'000'000'000'000'000,
5351 .pay = 400'000'000'000'000,
5353 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5355 for (
int i = 0; i < 30; ++i)
5356 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5362 Sendmax(eth(400'000'000'000'000)),
5363 Txflags(tfPartialPayment | tfNoRippleDirect));
5366 ammAlice.expectBalances(
XRP(10'030), btc(9'970'089730807592), ammAlice.tokens()));
5381 .pay = 30'000'000'000'000'000,
5387 .pay = 400'000'000'000'000,
5389 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5391 for (
int i = 0; i < 29; ++i)
5392 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5398 Sendmax(eth(400'000'000'000'000)),
5399 Txflags(tfPartialPayment | tfNoRippleDirect));
5400 BEAST_EXPECT(ammAlice.expectBalances(
5401 XRPAmount{10'101'010'102}, btc(9'900'000'000'000'000), ammAlice.tokens()));
5418 .pay = 30'000'000'000'000'000,
5422 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
5426 XRPAmount{10'049'825'372}, btc(10'049'925870493027), ammAlice.
tokens()));
5443 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5445 btc.set({.holder =
carol_, .flags = tfMPTLock});
5450 Txflags(tfNoRippleDirect | tfPartialPayment),
5464 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5466 btc.set({.holder =
alice_, .flags = tfMPTLock});
5471 Txflags(tfNoRippleDirect | tfPartialPayment),
6076 testcase(
"Adjusted Deposit/Withdraw Tokens");
6077 using namespace jtx;
6092 Account const natalie(
"natalie");
6094 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6095 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6102 .pay = 40'000'000000,
6105 auto const usd = gw[
"USD"];
6106 for (
auto const& holder : holders)
6108 env.
trust(usd(1'500'000), holder);
6109 env(
pay(gw, holder, usd(1'500'000)));
6113 auto aliceUSD = env.
balance(alice, usd);
6114 auto bobUSD = env.
balance(bob, usd);
6115 auto carolUSD = env.
balance(carol, usd);
6116 auto edUSD = env.
balance(ed, usd);
6117 auto paulUSD = env.
balance(paul, usd);
6118 auto danUSD = env.
balance(dan, usd);
6119 auto chrisUSD = env.
balance(chris, usd);
6120 auto simonUSD = env.
balance(simon, usd);
6121 auto benUSD = env.
balance(ben, usd);
6122 auto natalieUSD = env.
balance(natalie, usd);
6124 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6128 for (
int i = 0; i < 10; ++i)
6132 ammAlice.
deposit(simon, usd(0.1));
6134 ammAlice.
deposit(chris, usd(1));
6136 ammAlice.
deposit(dan, usd(10));
6138 ammAlice.
deposit(bob, usd(100));
6140 ammAlice.
deposit(carol, usd(1'000));
6142 ammAlice.
deposit(ed, usd(10'000));
6144 ammAlice.
deposit(paul, usd(100'000));
6146 ammAlice.
deposit(natalie, usd(1'000'000));
6152 STAmount{usd, UINT64_C(10000'0000000001), -10},
6183 Account const natalie(
"natalie");
6185 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6186 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6193 .pay = 40'000'000000,
6196 auto const usd = gw[
"USD"];
6197 for (
auto const& holder : holders)
6199 env.
trust(usd(1'500'000), holder);
6200 env(
pay(gw, holder, usd(1'500'000)));
6204 auto aliceBTC = env.
balance(alice, btc);
6205 auto bobBTC = env.
balance(bob, btc);
6206 auto carolBTC = env.
balance(carol, btc);
6207 auto edBTC = env.
balance(ed, btc);
6208 auto paulBTC = env.
balance(paul, btc);
6209 auto danBTC = env.
balance(dan, btc);
6210 auto chrisBTC = env.
balance(chris, btc);
6211 auto simonBTC = env.
balance(simon, btc);
6212 auto benBTC = env.
balance(ben, btc);
6213 auto natalieBTC = env.
balance(natalie, btc);
6215 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6219 for (
int i = 0; i < 10; ++i)
6221 ammAlice.
deposit(ben, btc(1));
6223 ammAlice.
deposit(simon, btc(1'000));
6225 ammAlice.
deposit(chris, btc(1));
6227 ammAlice.
deposit(dan, btc(10));
6229 ammAlice.
deposit(bob, btc(100));
6231 ammAlice.
deposit(carol, btc(1'000));
6233 ammAlice.
deposit(ed, btc(10'000));
6235 ammAlice.
deposit(paul, btc(100'000));
6237 ammAlice.
deposit(natalie, btc(1'000'000));
6319 testcase(
"Offer/Strand Selection");
6320 using namespace jtx;
6341 .transferFee = gwTransferFee,
6342 .pay = 2'000'000'000,
6348 .transferFee = gw1TransferFee,
6349 .pay = 2'000'000'000,
6355 .transferFee = gw1TransferFee,
6356 .pay = 2'000'000'000,
6361 .usd = std::move(usd),
6362 .eth = std::move(eth),
6363 .can = std::move(can),
6369 for (
auto const& rates :
6384 for (
auto i = 0; i < 3; ++i)
6386 Env env(*
this, features);
6387 auto mpts = prep(env, rates.first, rates.second);
6388 auto usd = mpts.usd;
6389 auto eth = mpts.eth;
6390 auto can = mpts.can;
6393 if (i == 0 || i == 2)
6395 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6399 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6409 BEAST_EXPECT(
amm->expectBalances(
6410 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6420 BEAST_EXPECT(q[0] > q[1]);
6422 BEAST_EXPECT(q[0] == q[2]);
6429 for (
auto i = 0; i < 3; ++i)
6431 Env env(*
this, features);
6432 auto mpts = prep(env, rates.first, rates.second);
6433 auto usd = mpts.usd;
6434 auto eth = mpts.eth;
6435 auto can = mpts.can;
6437 if (i == 0 || i == 2)
6439 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6443 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6444 env(
offer(
alice_, usd(400'000'000), eth(400'000'000)));
6451 amm->expectBalances(usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6454 if (i == 0 || i == 2)
6463 env,
alice_, 1, {
Amounts{usd(400'000'000), eth(400'000'000)}}));
6474 for (
auto i = 0; i < 3; ++i)
6476 Env env(*
this, features);
6477 auto mpts = prep(env, rates.first, rates.second);
6478 auto usd = mpts.usd;
6479 auto eth = mpts.eth;
6480 auto can = mpts.can;
6482 if (i == 0 || i == 2)
6484 env(
offer(ed, eth(400'000'000), usd(330'000'000)),
Txflags(tfPassive));
6488 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6497 BEAST_EXPECT(!
amm->expectBalances(
6498 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6504 if (rates.first == kLowRate)
6534 BEAST_EXPECT(q[1] > q[0]);
6536 BEAST_EXPECT(q[2] > q[1]);
6540 for (
auto i = 0; i < 3; ++i)
6542 Env env(*
this, features);
6543 auto mpts = prep(env, rates.first, rates.second);
6544 auto usd = mpts.usd;
6545 auto eth = mpts.eth;
6546 auto can = mpts.can;
6548 if (i == 0 || i == 2)
6550 env(
offer(ed, eth(400'000'000), usd(325'000'002)),
Txflags(tfPassive));
6554 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6555 env(
offer(
alice_, usd(325'000'000), eth(400'000'000)));
6561 BEAST_EXPECT(!
amm->expectBalances(
6562 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6569 if (rates.first == kLowRate)
6618 for (
auto i = 0; i < 3; ++i)
6620 Env env(*
this, features);
6621 auto mpts = prep(env, rates.first, rates.second);
6622 auto usd = mpts.usd;
6623 auto eth = mpts.eth;
6624 auto can = mpts.can;
6627 if (i == 0 || i == 2)
6629 env(
offer(ed, eth(400'000'000), can(375'000'000)),
Txflags(tfPassive));
6630 env(
offer(ed, can(375'000'000), usd(338'000'000))),
Txflags(tfPassive);
6634 amm.emplace(env, ed, eth(1'000'000'000), usd(1'000'000'000));
6648 if (rates.first == kLowRate)
6651 BEAST_EXPECT(
amm->expectBalances(
6652 eth(1'124'584'936), usd(889'999'993),
amm->tokens()));
6656 BEAST_EXPECT(
amm->expectBalances(
6657 eth(1'103'723'909), usd(906'023'688),
amm->tokens()));
6678 BEAST_EXPECT(q[1] > q[0]);
6679 BEAST_EXPECT(q[2] > q[0] && q[2] < q[1]);