410 [&](
AMM& ammAlice,
Env& env) {
421 jv[jss::Account] =
alice_.human();
422 jv[jss::TransactionType] = jss::AMMDeposit;
426 jv[jss::LPTokenOut] =
428 jv[jss::Flags] = tfLPToken;
436 jv[jss::Account] =
alice_.human();
437 jv[jss::TransactionType] = jss::AMMDeposit;
442 jv[jss::Flags] = tfLPToken;
451 MPT(ammAlice[1])(200),
496 MPT(ammAlice[1])(200),
506 .authHolder =
true});
524 MPT(ammAlice[1])(100),
525 MPT(ammAlice[1])(200),
540 MPT(ammAlice[1])(-1'000),
553 MPT(ammAlice[1])(1'000),
571 {{
MPT(btc),
MPT(ammAlice[1])}},
581 MPT(ammAlice[1])(200),
633 MPT(ammAlice[1])(100),
642 [&](
AMM& ammAlice,
Env& env) {
643 auto const enabledV13 = env.
current()->rules().enabled(fixAMMv1_3);
652 {features, features - fixAMMv1_3});
656 [&](
AMM& ammAlice,
Env& env) {
665 [&](
AMM& ammAlice,
Env& env) {
668 MPT(ammAlice[1])(100),
679 MPT(ammAlice[1])(100),
699 btc.set({.flags = tfMPTLock});
715 Env env{*
this, features};
727 btc.set({.holder =
carol_, .flags = tfMPTLock});
737 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
739 ammAlice.deposit(
carol_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
748 ammAlice.deposit(
alice_, btc(100), std::nullopt, std::nullopt, std::nullopt);
749 ammAlice.deposit(
alice_, 1'000, std::nullopt, std::nullopt);
750 ammAlice.deposit(
alice_,
USD(100), std::nullopt, std::nullopt, std::nullopt);
753 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
755 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
756 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
785 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
788 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
806 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
808 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
809 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
832 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
835 btc.set({.holder =
carol_, .flags = tfMPTLock});
843 btc.set({.holder =
carol_, .flags = tfMPTUnlock});
846 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
847 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
850 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
863 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
865 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
866 ammAlice.deposit(
carol_, btc(100), std::nullopt, std::nullopt, std::nullopt);
869 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
882 usd.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
884 ammAlice.deposit(
carol_, 1'000, std::nullopt, std::nullopt);
885 ammAlice.deposit(
carol_, usd(100), std::nullopt, std::nullopt, std::nullopt);
890 Env env{*
this, features};
891 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
892 env.
fund(
XRP(30'000), alice, carol, gw);
895 MPTTester btc(env, gw, {.holders = {alice, carol}, .fund =
false});
897 {.maxAmt = 1'000'000,
898 .authorize = {{alice}},
899 .pay = {{{alice}, 10'000}},
901 .authHolder =
true});
903 AMM amm(env, alice,
XRP(10'000), btc(10'000));
908 if (!features[featureAMMClawback] && !features[fixCleanup3_3_0])
910 amm.deposit(carol,
XRP(10), std::nullopt, std::nullopt, std::nullopt);
921 Env env{*
this, features};
922 Account const gw(
"gateway"), alice{
"alice"}, carol{
"carol"};
923 env.
fund(
XRP(30'000), alice, carol, gw);
931 .flags = tfMPTCanTrade});
933 AMM amm(env, gw,
XRP(10'000), btc(10'000));
935 amm.deposit({.account = alice, .asset1In = btc(10), .err =
Ter(
tecNO_AUTH)});
940 [&](
AMM& ammAlice,
Env& env) {
956 [&](
AMM& ammAlice,
Env& env) {
959 MPT(ammAlice[1])(450'000),
969 [&](
AMM& ammAlice,
Env& env) {
990 .transferFee = 1'500,
1008 Env env(*
this, features);
1009 auto const startingXrp =
reserve(env, 4) + env.
current()->fees().base * 4;
1018 .transferFee = 1'500,
1043 [&](
AMM& ammAlice,
Env& env) {
1051 MPT(ammAlice[1])(100),
1064 MPT(ammAlice[1])(100),
1075 MPT(ammAlice[1])(-1),
1098 [&](
AMM& ammAlice,
Env& env) {
1104 MPT(ammAlice[1])(1'001),
1115 MPT(ammAlice[1])(1'000),
1127 MPT(ammAlice[1])(100),
1154 MPTTester const btc({.env = env, .issuer =
gw_, .holders = {
alice_}, .maxAmt = 100});
1177 using namespace jtx;
1181 [&](
AMM& ammAlice,
Env& env) {
1199 [&](
AMM& ammAlice,
Env& env) {
1202 MPT(ammAlice[1])(100),
1212 MPT(ammAlice[1])(100),
1221 auto test = [&](
auto&& issue1,
auto&& issue2) {
1225 auto const usd = issue1(
1230 .limit = 1'000'000});
1231 auto const btc = issue2(
1236 .limit = 1'000'000});
1243 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1258 [&](
AMM& ammAlice,
Env& env) {
1274 auto test = [&](
auto&& issue1,
auto&& issue2) {
1278 auto const usd = issue1(
1283 .limit = 1'000'000});
1284 auto const btc = issue2(
1289 .limit = 1'000'000});
1296 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1312 [&](
AMM& ammAlice,
Env& env) {
1328 auto test = [&](
auto&& issue1,
auto&& issue2) {
1332 auto const usd = issue1(
1337 .limit = 1'000'000});
1338 auto const btc = issue2(
1343 .limit = 1'000'000});
1350 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1364 [&](
AMM& ammAlice,
Env& env) {
1371 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1380 [&](
AMM& ammAlice,
Env& env) {
1387 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1396 [&](
AMM& ammAlice,
Env& env) {
1402 MPT(ammAlice[0])(11'000),
1403 MPT(ammAlice[1])(10'000),
1413 [&](
AMM& ammAlice,
Env& env) {
1419 MPT(ammAlice[0])(11'000),
USD(10'000),
IOUAmount{10'488'08848170151, -11}));
1428 [&](
AMM& ammAlice,
Env& env) {
1434 MPT(ammAlice[0])(10'000),
1446 [&](
AMM& ammAlice,
Env& env) {
1462 [&](
AMM& ammAlice,
Env& env) {
1479 auto test = [&](
auto&& issue1,
auto&& issue2) {
1483 auto const usd = issue1(
1488 .limit = 1'000'000});
1489 auto const btc = issue2(
1494 .limit = 1'000'000});
1501 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1506 auto deltaUSD = [&]() {
1512 btc(10'000), usd(10'000) + deltaUSD,
IOUAmount{10'100, 0}));
1524 [&](
AMM& ammAlice,
Env& env) {
1527 MPT(ammAlice[1])(100),
1532 XRP(10'000),
MPT(ammAlice[1])(10100),
IOUAmount{10'049'875'62112089, -8}));
1539 [&](
AMM& ammAlice,
Env& env) {
1546 MPT(ammAlice[1])(100),
1551 XRP(10'000),
MPT(ammAlice[1])(10'081),
IOUAmount{10'039'920'31840891, -8}));
1561 [&](
AMM& ammAlice,
Env& env) {
1568 MPT(ammAlice[1])(0),
1573 XRP(10'000),
MPT(ammAlice[1])(10'081),
IOUAmount{10'039'920'31840891, -8}));
1584 [&](
AMM& ammAlice,
Env& env) {
1587 MPT(ammAlice[1])(100),
1592 USD(10'000'000'000),
1593 MPT(ammAlice[1])(10100),
1602 [&](
AMM& ammAlice,
Env& env) {
1606 MPT(ammAlice[1])(10'000'000'000),
1616 [&](
AMM& ammAlice,
Env& env) {
1619 MPT(ammAlice[0])(100),
1624 MPT(ammAlice[1])(10'000'000'000),
1625 MPT(ammAlice[0])(10100),
1640 .transferFee = 25'000,
1647 .transferFee = 25'000,
1650 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1651 BEAST_EXPECT(ammAlice.expectBalances(usd(200'000), btc(5),
IOUAmount{1000, 0}));
1653 ammAlice.deposit(
carol_, 100, std::nullopt, std::nullopt);
1654 BEAST_EXPECT(ammAlice.expectBalances(usd(220'000), btc(6),
IOUAmount{1100, 0}));
1670 .transferFee = 25'000,
1673 auto const usd =
gw_[
"USD"];
1683 AMM ammAlice(env,
alice_, usd(200'000), btc(5));
1692 .transferFee = 25'000,
1696 AMM ammBob(env,
bob_, eth(20'000), usd(0.5));
1697 BEAST_EXPECT(ammBob.expectBalances(eth(20'000), usd(0.5),
IOUAmount{100, 0}));
1698 ammBob.deposit(
carol_, 10);
1699 BEAST_EXPECT(ammBob.expectBalances(eth(22'000), usd(0.55),
IOUAmount{110, 0}));
1704 [&](
AMM& ammAlice,
Env& env) {
1708 STAmount{USD, UINT64_C(10'000'001), -3},
1709 MPT(ammAlice[1])(10'001),
1714 STAmount{USD, UINT64_C(10'001'001), -3},
1715 MPT(ammAlice[1])(10'003),
1720 [&](
AMM& ammAlice,
Env& env) {
1723 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1724 MPT(ammAlice[1])(10'000),
1729 STAmount{USD, UINT64_C(10'000'00000000008), -11},
1730 MPT(ammAlice[1])(10'001),
1737 [&](
AMM& ammAlice,
Env& env) {
1741 MPT(ammAlice[1])(10'000),
1746 [&](
AMM& ammAlice,
Env& env) {
1749 XRP(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000'499'98750062, -8}));
1755 [&](
AMM& ammAlice,
Env& env) {
1759 MPT(ammAlice[0])(10'000),
1760 MPT(ammAlice[1])(10'001),
1771 MPT const btc =
MPTTester({.env = env, .issuer =
gw_, .holders = {}});
1773 AMM ammGw(env,
gw_,
XRP(10'000), btc(10'000'000'000));
1775 ammGw.expectBalances(
XRP(10'000), btc(10'000'000'000),
IOUAmount{10'000'000'000}));
1777 ammGw.deposit(
gw_, 1'000'000);
1779 ammGw.expectBalances(
XRP(10'001), btc(10'001000000),
IOUAmount{10'001000000}));
1781 ammGw.deposit(
gw_, btc(1'000000000));
1782 BEAST_EXPECT(ammGw.expectBalances(
1783 XRP(10'001), btc(11'001000000),
IOUAmount{1048'908'961731188, -5}));
1788 [&](
AMM& ammAlice,
Env& env) {
1791 MPT(ammAlice[0])(1'010'000),
1792 MPT(ammAlice[1])(1'010'000),
1797 MPT(ammAlice[0])(1'010'999),
1798 MPT(ammAlice[1])(1'010'000),
1805 [&](
AMM& ammAlice,
Env& env) {
1811 XRP(11'000),
MPT(ammAlice[1])(12'000),
IOUAmount{11'489'125'29307605, -8}));
1817 [&](
AMM& ammAlice,
Env& env) {
1822 MPT(ammAlice[1])(1'000),
1834 auto test = [&](
auto&& issue1,
auto&& issue2) {
1838 auto const usd = issue1(
1843 .limit = 1'000'000});
1844 auto const btc = issue2(
1849 .limit = 1'000'000});
1856 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1879 [&](
AMM& ammAlice,
Env& env) {
1884 MPT(ammAlice[1])(1'000),
1896 auto test = [&](
auto&& issue1,
auto&& issue2) {
1900 auto const usd = issue1(
1905 .limit = 1'000'000});
1906 auto const btc = issue2(
1911 .limit = 1'000'000});
1917 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
1941 [&](
AMM& ammAlice,
Env& env) {
1952 XRP(11'000),
MPT(ammAlice[1])(10'000),
IOUAmount{10'488'088'48170151, -8}));
1958 [&](
AMM& ammAlice,
Env& env) {
1962 MPT(ammAlice[1])(1'000),
1969 XRP(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -8}));
1975 [&](
AMM& ammAlice,
Env& env) {
1986 STAmount{USD, UINT64_C(10'999'99999999999), -11},
1987 MPT(ammAlice[1])(10'000),
1994 [&](
AMM& ammAlice,
Env& env) {
1998 MPT(ammAlice[1])(1'000),
2005 USD(10'000),
MPT(ammAlice[1])(11'000),
IOUAmount{10'488'088'48170151, -11}));
2011 [&](
AMM& ammAlice,
Env& env) {
2015 MPT(ammAlice[1])(1'000),
2022 MPT(ammAlice[0])(10'000),
2023 MPT(ammAlice[1])(11'000),
2034 using namespace jtx;
2038 [&](
AMM& ammAlice,
Env& env) {
2040 .asset1Out =
XRP(100),
2048 [&](
AMM& ammAlice,
Env& env) {
2050 .asset1Out =
MPT(ammAlice[1])(100),
2068 .authHolder =
true});
2072 .asset1Out = btc(100),
2075 ammAlice.withdraw(args);
2079 [&](
AMM& ammAlice,
Env& env) {
2104 MPT(ammAlice[1])(100),
2105 MPT(ammAlice[1])(100),
2121 MPT(ammAlice[1])(10'000),
2130 MPT(ammAlice[1])(0),
2133 tfOneAssetWithdrawAll,
2168 {{
MPT(ammAlice[1]),
GBP}},
2178 [&](
AMM& ammAlice,
Env& env) {
2188 alice_,
IOUAmount{9'999'999'9999, -4}, std::nullopt, std::nullopt, err);
2198 {all, all - fixAMMv1_3});
2201 [&](
AMM& ammAlice,
Env& env) {
2208 alice_,
IOUAmount{9'999'999'999999999, -9}, std::nullopt, std::nullopt, err);
2218 {all, all - fixAMMv1_3});
2222 [&](
AMM& ammAlice,
Env& env) {
2241 .asset1Out =
MPT(
gw_, 1'000)(10),
2257 .authHolder =
true});
2258 MPT const btc = btcm;
2262 btcm.authorize({.account =
gw_, .holder =
alice_, .flags = tfMPTUnauthorize});
2267 .asset1Out = btc(100),
2268 .assets = {{
XRP, btc}},
2284 .flags = tfMPTCanTrade,
2285 .authHolder =
true});
2289 auto const lpIssue =
amm.lptIssue();
2311 .authHolder =
true});
2314 btc.set({.flags = tfMPTLock});
2321 ammAlice.withdraw({.account =
alice_, .asset1Out =
XRP(100)});
2342 AMM ammAlice(env,
alice_, usd(10'000), btc(10'000));
2345 btc.set({.holder =
alice_, .flags = tfMPTLock});
2350 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2353 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2354 ammAlice.withdraw(
alice_, 1000, std::nullopt, std::nullopt);
2355 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2356 ammAlice.withdraw(
alice_, usd(100), std::nullopt, std::nullopt);
2373 btc.set({.holder =
alice_, .flags = tfMPTLock});
2378 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2381 btc.set({.holder =
alice_, .flags = tfMPTUnlock});
2384 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2385 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2386 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2389 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTLock});
2392 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2399 btc.set({.holder = ammAlice.ammAccount(), .flags = tfMPTUnlock});
2401 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2402 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2410 ammAlice.withdraw(
alice_, btc(100), std::nullopt, std::nullopt);
2424 ammAlice.withdraw(
alice_, 1'000, std::nullopt, std::nullopt);
2425 ammAlice.withdraw(
alice_,
USD(100), std::nullopt, std::nullopt);
2430 [&](
AMM& ammAlice,
Env&) {
2447 [&](
AMM& ammAlice,
Env& env) {
2457 {all, all - fixAMMv1_3});
2462 [&](
AMM& ammAlice,
Env&) {
2466 MPT(ammAlice[1])(100),
2476 [&](
AMM& ammAlice,
Env&) {
2480 MPT(ammAlice[1])(1'700),
2489 [&](
AMM& ammAlice,
Env&) {
2493 MPT(ammAlice[1])(1'000),
2501 [&](
AMM& ammAlice,
Env&) {
2511 [&](
AMM& ammAlice,
Env&) {
2525 [&](
AMM& ammAlice,
Env&) {
2528 STAmount{
MPT(ammAlice[1]), UINT64_C(9'999'999999999999), -12},
2537 [&](
AMM& ammAlice,
Env&) {
2558 MPT(ammAlice[0])(1),
2570 using namespace jtx;
2575 [&](
AMM& ammAlice,
Env& env) {
2601 [&](
AMM& ammAlice,
Env&) {
2612 auto test = [&](
auto&& issue1,
auto&& issue2) {
2616 auto const usd = issue1(
2621 .limit = 1'000'000});
2622 auto const btc = issue2(
2627 .limit = 1'000'000});
2631 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2648 [&](
AMM& ammAlice,
Env&) {
2659 [&](
AMM& ammAlice,
Env&) {
2669 auto test = [&](
auto&& issue1,
auto&& issue2) {
2673 auto const usd = issue1(
2678 .limit = 1'000'000});
2679 auto const btc = issue2(
2684 .limit = 1'000'000});
2688 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2701 [&](
AMM& ammAlice,
Env&) {
2706 MPT(ammAlice[1])(10'000),
2711 [&](
AMM& ammAlice,
Env&) {
2715 XRP(10000),
MPT(ammAlice[1])(9001),
IOUAmount{9'486'832'98050514, -8}));
2719 [&](
AMM& ammAlice,
Env&) {
2723 STAmount{USD, UINT64_C(9000'000000000004), -12},
2724 MPT(ammAlice[1])(10'000),
2729 [&](
AMM& ammAlice,
Env&) {
2733 USD(10'000),
MPT(ammAlice[1])(9001),
IOUAmount{9486'83298050514, -11}));
2737 [&](
AMM& ammAlice,
Env&) {
2741 MPT(ammAlice[0])(9001),
2742 MPT(ammAlice[1])(10'000),
2749 [&](
AMM& ammAlice,
Env&) {
2758 [&](
AMM& ammAlice,
Env&) {
2767 auto test = [&](
auto&& issue1,
auto&& issue2) {
2771 auto const usd = issue1(
2776 .limit = 1'000'000});
2777 auto const btc = issue2(
2782 .limit = 1'000'000});
2786 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2799 [&](
AMM& ammAlice,
Env& env) {
2811 AMM const ammCarol(env,
carol_,
XRP(10'000),
MPT(ammAlice[1])(10'000));
2819 [&](
AMM& ammAlice,
Env& env) {
2830 [&](
AMM& ammAlice,
Env&) {
2840 [&](
AMM& ammAlice,
Env& env) {
2852 [&](
AMM& ammAlice,
Env& env) {
2864 [&](
AMM& ammAlice,
Env& env) {
2869 MPT(ammAlice[0])(10'000),
MPT(ammAlice[1])(10'001),
IOUAmount{10'000, 0}));
2876 [&](
AMM& ammAlice,
Env&) {
2886 [&](
AMM& ammAlice,
Env&) {
2890 STAmount{USD, UINT64_C(9'090'9090909091), -10},
2891 MPT(ammAlice[1])(11000),
2898 [&](
AMM& ammAlice,
Env&) {
2902 STAmount{USD, UINT64_C(10'999'99999999999), -11},
2903 MPT(ammAlice[1])(9091),
2910 [&](
AMM& ammAlice,
Env&) {
2918 MPT(ammAlice[0])(10'000'000'001),
USD(10'000), ammAlice.
tokens()));
2923 [&](
AMM& ammAlice,
Env&) {
2924 auto const& btc =
MPT(ammAlice[1]);
2939 [&](
AMM& ammAlice,
Env&) {
2940 auto const carolTokens = ammAlice.
deposit(
carol_,
MPT(ammAlice[1])(1'000));
2941 auto const aliceTokens = ammAlice.
deposit(
alice_,
MPT(ammAlice[1])(1'000));
2945 XRP(10'000),
MPT(ammAlice[1])(10'001), ammAlice.
tokens()));
2953 [&](
AMM& ammAlice,
Env&) {
2962 auto test = [&](
auto&& issue1,
auto&& issue2) {
2966 auto const usd = issue1(
2971 .limit = 1'000'000});
2972 auto const btc = issue2(
2977 .limit = 1'000'000});
2983 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
2998 [&](
AMM& ammAlice,
Env&) {
3003 STAmount{
MPT(ammAlice[1]), UINT64_C(9'090'909090909092), -12},
3010 [&](
AMM& ammAlice,
Env&) {
3020 [&](
AMM& ammAlice,
Env&) {
3024 STAmount{USD, UINT64_C(9'090'909090909092), -12},
3025 MPT(ammAlice[1])(11'000),
3031 [&](
AMM& ammAlice,
Env&) {
3035 MPT(ammAlice[0])(11'000),
MPT(ammAlice[1])(9'091),
IOUAmount{10'000}));
3043 [&](
AMM& ammAlice,
Env& env) {
3052 MPT(ammAlice[1])(9372781065),
3061 MPT(ammAlice[1])(9372781065),
3065 else if (env.
enabled(fixAMMv1_3))
3070 MPT(ammAlice[1])(9372781066),
3077 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3080 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3084 [&](
AMM& ammAlice,
Env& env) {
3092 MPT(ammAlice[1])(9372781065),
3101 MPT(ammAlice[1])(9372781065),
3105 else if (env.
enabled(fixAMMv1_3))
3110 MPT(ammAlice[1])(9372781066),
3117 {{
XRP(10'000'000'000),
gAmmmpt(10'000'000'000)}},
3120 {all, all - fixAMMv1_3, all - fixAMMv1_1 - fixAMMv1_3});
3124 auto test = [&](
auto&& issue1,
auto&& issue2) {
3128 auto const usd = issue1(
3134 .transferFee = 25'000});
3135 auto const btc = issue2(
3141 .transferFee = 25'000});
3150 AMM ammAlice(env,
alice_, btc(2'000), usd(5));
3173 [&](
AMM& ammAlice,
Env&) {
3177 MPT(ammAlice[0])(9'999'999'999),
3183 [&](
AMM& ammAlice,
Env&) {
3187 MPT(ammAlice[0])(10000'000000),
USD(10'000),
IOUAmount{9'999'999'9995, -4}));
3191 [&](
AMM& ammAlice,
Env&) {
3195 MPT(ammAlice[0])(10'000'000'000),
3201 [&](
AMM& ammAlice,
Env&) {
3212 [&](
AMM& ammAlice,
Env&) {
3220 [&](
AMM& ammAlice,
Env&) {
3228 [&](
AMM& ammAlice,
Env&) {
3236 [&](
AMM& ammAlice,
Env&) {
3244 [&](
AMM& ammAlice,
Env&) {
3247 MPT(ammAlice[0])(10'000'000'000),
3254 [&](
AMM& ammAlice,
Env&) {
3262 [&](
AMM& ammAlice,
Env&) {
3269 [&](
AMM& ammAlice,
Env&) {
3298 AMM ammAlice(env,
alice_, btc(10'000), eth(10'000));
3303 btc.authorize({.account =
alice_, .flags = tfMPTUnauthorize});
3304 eth.authorize({.account =
alice_, .flags = tfMPTUnauthorize});
3310 ammAlice.withdrawAll(
alice_);
3315 BEAST_EXPECT(!ammAlice.ammExists());
3541 using namespace jtx;
3554 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3557 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3564 .bidMin = 1'000'000,
3579 AMM amm(env,
gw_,
XRP(1'000), btc(1'000),
false, 1'000);
3582 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{0}));
3589 .bidMin = STAmount{amm.lptIssue(), UINT64_C(999'999)},
3595 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0,
IOUAmount{999'999}));
3598 BEAST_EXPECT(
amm.expectBalances(
XRP(1'000), btc(1'000),
IOUAmount{1}));
3601 BEAST_EXPECT(
Number{
amm.getLPTokensBalance(
gw_)} == 1);
3614 [&](
AMM& ammAlice,
Env& env) {
3651 .authAccounts = {bob_},
3659 .assets = {{MPT(ammAlice[1]), GBP}},
3663 {{
XRP(10'000), gAmmmpt(10'000)}});
3667 [&](AMM& ammAlice, Env& env) {
3668 ammAlice.withdrawAll(alice_);
3675 {{
XRP(10'000), gAmmmpt(10'000)}});
3680 fund(env, gw_, {alice_, bob_, carol_},
XRP(1'000), {USD(30'000)}, Fund::All);
3681 MPTTester
const btc(
3684 .holders = {alice_, carol_, bob_},
3685 .pay = 30'000'000'000,
3688 AMM ammAlice(env, alice_, btc(10'000'000'000), USD(10'000));
3689 ammAlice.deposit(carol_, 1'000'000);
3690 ammAlice.deposit(bob_, 10);
3693 .bidMin = 1'000'001,
3695 Ter(tecAMM_INVALID_TOKENS));
3698 .bidMax = 1'000'001,
3700 Ter(tecAMM_INVALID_TOKENS));
3705 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0, IOUAmount{1'000}));
3710 Ter(tecAMM_INVALID_TOKENS));
3716 env.fund(
XRP(1'000), gw_, alice_, bob_);
3717 MPTTester
const btc(
3720 .holders = {alice_, bob_},
3723 AMM
amm(env, gw_,
XRP(10), btc(1'000));
3724 auto const lpIssue =
amm.lptIssue();
3725 env.trust(STAmount{lpIssue, 100}, alice_);
3726 env.trust(STAmount{lpIssue, 50}, bob_);
3727 env(
pay(gw_, alice_, STAmount{lpIssue, 100}));
3728 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
3729 env(
amm.bid({.account = alice_, .bidMin = 100}));
3736 Ter(tecAMM_FAILED));
3744 using namespace jtx;
3751 [&](
AMM& ammAlice,
Env& env) {
3753 env(ammAlice.
bid({.account = carol_, .bidMin = 110}));
3763 [&](
AMM& ammAlice,
Env& env) {
3766 env(ammAlice.
bid({.account = carol_, .bidMin = 110, .bidMax = 110}));
3771 env(ammAlice.
bid({.account = alice_, .bidMin = 180, .bidMax = 200}));
3790 ammAlice.deposit(
carol_, 1'000'000);
3792 env(ammAlice.bid({.account = carol_, .bidMin = 110}));
3793 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3795 ammAlice.deposit(
bob_, 1'000'000);
3797 env(ammAlice.bid({.account = bob_}));
3798 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount(1155, -1)));
3807 env(ammAlice.bid({.account = carol_, .bidMax = 600}));
3808 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{121'275, -3}));
3819 env(ammAlice.bid({.account = carol_, .bidMin = 100, .bidMax = 600}));
3820 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{127'33875, -5}));
3835 ammAlice.deposit(
carol_, 1'000'000);
3836 ammAlice.deposit(
bob_, 1'000'000);
3837 BEAST_EXPECT(ammAlice.expectBalances(
3841 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3842 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 0,
IOUAmount{110}));
3845 env(ammAlice.bid({.account = bob_}));
3847 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 1,
IOUAmount{1'155, -1}));
3850 env(ammAlice.bid({.account = carol_}));
3852 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, 10,
IOUAmount{121'275, -3}));
3855 env(ammAlice.bid({.account = bob_}));
3857 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{127'33875, -5}));
3860 env(ammAlice.bid({.account = carol_, .bidMin = 110})).
close();
3861 BEAST_EXPECT(ammAlice.expectAuctionSlot(0, std::nullopt,
IOUAmount{110}));
3863 BEAST_EXPECT(ammAlice.expectBalances(
3880 .pay = 30'000'000'000});
3886 ammAlice.
deposit(ed, 1'000'000);
3888 ammAlice.
deposit(dan, 500'000);
3893 .authAccounts = {bob_, ed},
3895 auto const slotPrice =
IOUAmount{5'200};
3896 ammTokens -= slotPrice;
3898 BEAST_EXPECT(ammAlice.
expectBalances(btc(13'000'000'003),
USD(13'000), ammTokens));
3900 for (
int i = 0; i < 10; ++i)
3917 btc(13'000'000'003),
STAmount(
USD, UINT64_C(13'002'98282151419), -11), ammTokens));
3921 for (
int i = 0; i < 10; ++i)
3923 auto const tokens = ammAlice.
deposit(dan,
USD(100));
3933 btc(13'000'000'003),
STAmount{
USD, UINT64_C(13'012'92609877021), -11}, ammTokens));
3938 MPT(ammAlice[0])(13'000'000'003),
3946 btc(13'100'000'671),
STAmount{
USD, UINT64_C(13'012'92609877019), -11}, ammTokens));
3956 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'114'03663044931), -11}, ammTokens));
3966 for (
int i = 0; i < 10; ++i)
3977 btc(13'000'000'671),
STAmount{
USD, UINT64_C(13'123'98038488356), -11}, ammTokens));
3985 btc(13'100'824'793),
STAmount{
USD, UINT64_C(13'023'98038488356), -11}, ammTokens));
3990 [&](
AMM& ammAlice,
Env& env) {
3993 env(ammAlice.
bid({.account = alice_, .bidMin = IOUAmount{tiny}}));
3999 MPT(ammAlice[0])(10'000'000'000), USD(10'000), ammAlice.
tokens()));
4003 .bidMin = IOUAmount{STAmount::kMinValue, STAmount::kMinOffset},
4006 BEAST_EXPECT(ammAlice.
expectAuctionSlot(0, 0, IOUAmount{tiny * Number{105, -2}}));
4010 MPT(ammAlice[0])(10'000'000'000), USD(10'000), ammAlice.
tokens()));
4012 {{gAmmmpt(10'000'000'000), USD(10'000)}});
4016 [&](AMM& ammAlice, Env& env) {
4019 .bidMin = IOUAmount{100},
4020 .authAccounts = {carol_},
4022 BEAST_EXPECT(ammAlice.expectAuctionSlot({carol_}));
4023 env(ammAlice.bid({.account = alice_, .bidMin = IOUAmount{100}}));
4027 fund(env, {bob, dan},
XRP(1'000));
4030 .bidMin = IOUAmount{100},
4031 .authAccounts = {bob, dan},
4035 {{gAmmmpt(10'000'000'000), USD(10'000)}});
4040 env.
fund(
XRP(2'000), gw_, alice_, bob_);
4041 MPTTester
const btc(
4044 .holders = {alice_, bob_},
4045 .pay = 2'000'000'000,
4047 fund(env, gw_, {alice_, bob_}, {USD(2'000)}, Fund::TokenOnly);
4048 AMM
amm(env, gw_, btc(1'000'000'000), USD(1'010),
false, 1'000);
4049 auto const lpIssue =
amm.lptIssue();
4050 env.
trust(STAmount{lpIssue, 500}, alice_);
4051 env.
trust(STAmount{lpIssue, 50}, bob_);
4052 env(
pay(gw_, alice_, STAmount{lpIssue, 500}));
4053 env(
pay(gw_, bob_, STAmount{lpIssue, 50}));
4055 env(
amm.bid({.account = alice_, .bidMin = 500}));
4056 BEAST_EXPECT(
amm.expectAuctionSlot(100, 0, IOUAmount{500}));
4057 BEAST_EXPECT(
expectHolding(env, alice_, STAmount{lpIssue, 0}));
4060 env(
pay(alice_, bob_, USD(10)), Path(~USD), Sendmax(btc(11'000'000)));
4061 BEAST_EXPECT(
amm.expectBalances(
4062 btc(1'010'010'011), USD(1'000), IOUAmount{1'004'487'562112089, -9}));
4065 env(
pay(bob_, alice_, btc(10'000'000)), Path(~MPT(btc)), Sendmax(USD(11)));
4067 BEAST_EXPECT(
amm.expectBalances(
4069 STAmount{USD, UINT64_C(1'010'10090898081), -11},
4070 IOUAmount{1'004'487'562112089, -9}));
4075 Env env(*
this, features);
4076 env.
fund(
XRP(2'000), gw_, alice_, bob_);
4077 MPTTester
const btc(
4080 .holders = {alice_, bob_},
4083 AMM
amm(env, gw_,
XRP(1'000), btc(1'010),
false, 1'000);
4084 json::Value const tx =
amm.bid({.account = alice_, .bidMin = 500});
4087 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4089 PreflightContext
const ctx(
4091 auto pf = AMMBid::checkExtraFeatures(ctx);
4092 BEAST_EXPECT(pf ==
false);
4097 auto jtx = env.
jt(tx, Seq(1), Fee(10));
4098 jtx.
jv[
"Asset2"][
"currency"] =
"XRP";
4100 jtx.stx = env.
ust(jtx);
4101 PreflightContext
const ctx(
4103 auto pf = AMMBid::preflight(ctx);
4104 BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
4428 using namespace jtx;
4433 [&](
AMM& ammAlice,
Env& env) {
4443 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4455 auto test = [&](
auto&& issue1,
auto&& issue2) {
4460 auto const usd = issue1(
4465 .limit = 1'000'000});
4466 auto const btc = issue2(
4471 .limit = 1'000'000});
4481 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4487 Txflags(tfNoRippleDirect | tfPartialPayment));
4498 [&](
AMM& ammAlice,
Env& env) {
4505 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4517 auto test = [&](
auto&& issue1,
auto&& issue2) {
4522 auto const usd = issue1(
4527 .limit = 1'000'000});
4528 auto const btc = issue2(
4533 .limit = 1'000'000});
4543 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4558 [&](
AMM& ammAlice,
Env& env) {
4567 XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4578 auto test = [&](
auto&& issue1,
auto&& issue2) {
4583 auto const usd = issue1(
4588 .limit = 1'000'000});
4589 auto const btc = issue2(
4594 .limit = 1'000'000});
4604 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10100));
4618 [&](
AMM& ammAlice,
Env& env) {
4627 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4630 XRP(10'010),
MPT(ammAlice[1])(10'000), ammAlice.
tokens()));
4643 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4651 auto test = [&](
auto&& issue1,
auto&& issue2) {
4656 auto const usd = issue1(
4661 .limit = 1'000'000});
4662 auto const btc = issue2(
4667 .limit = 1'000'000});
4677 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10010));
4683 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4692 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality),
4708 .transferFee = 10'000,
4709 .pay = 30'000'000'000'000'000,
4711 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(10'010'000'000'000'000));
4720 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4722 BEAST_EXPECT(ammAlice.expectBalances(
4723 XRP(10'010), btc(10'000'000'000'000'000), ammAlice.tokens()));
4731 auto test = [&](
auto&& issue1,
auto&& issue2) {
4736 auto const usd = issue1({
4744 auto const btc = issue2(
4749 .limit = 300'000'000'000'000'000,
4750 .transferFee = 10'000});
4753 env(
pay(
gw_,
bob_, btc(30'000'000'000'000'000)));
4760 auto ammAlice =
AMM(env,
alice_, usd(10'000), btc(10'010'000'000'000'000));
4766 Txflags(tfNoRippleDirect | tfPartialPayment | tfLimitQuality));
4769 usd(10'010), btc(10'000'000'000'000'000), ammAlice.
tokens()));
4778 [&](
AMM& ammAlice,
Env& env) {
4790 auto test = [&](
auto&& issue1,
auto&& issue2) {
4795 auto const usd = issue1(
4800 .limit = 1'000'000});
4801 auto const btc = issue2(
4806 .limit = 1'000'000});
4816 auto ammAlice =
AMM(env,
alice_, usd(10000), btc(10000));
4837 .pay = 3'000'000'000'000'000'000,
4843 .pay = 3'000'000'000'000'000'000,
4847 auto ammEthXrp =
AMM(env,
alice_,
XRP(10'000), eth(1'000'000'000'000'000'000));
4849 AMM(env,
alice_, eth(1'000'000'000'000'000'000), btc(1'000'000'000'000'000'000));
4857 BEAST_EXPECT(ammEthXrp.expectBalances(
4858 XRPAmount(10'030'082'730), eth(9'970'00749812546872), ammEthXrp.tokens()));
4860 BEAST_EXPECT(ammBtcEth.expectBalances(
4861 btc(9'970'09727766213961), eth(10'029'99250187453128), ammBtcEth.tokens()));
4887 .pay = 3'000'000'000'000'000'000,
4893 .pay = 1'000'000'000'000'000'000,
4895 auto ammAlice =
AMM(env,
alice_,
XRP(10'000), btc(1'000'000'000'000'000'000));
4900 env(
offer(
alice_, eth(10'000'000'000'000'000), btc(10'000'000'000'000'000)),
4908 BEAST_EXPECT(ammAlice.expectBalances(
4909 XRPAmount(10'050'238'637), btc(9'950'01249687578120), ammAlice.tokens()));
4915 Amounts{eth(49'98750312421880), btc(49'98750312421880)}}}));
4935 .pay = 30'000'000'000'000'000,
4937 AMM ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
4945 BEAST_EXPECT(ammAlice.expectBalances(
4946 XRP(10'100),
MPT(ammAlice[1])(10'000'000000000001), ammAlice.tokens()));
4956 2 *
txFee(env, 1)));
4974 AMM const ammAlice(env,
alice_,
XRP(1'000), btc(1'050));
4995 ammAlice.expectBalances(
XRP(10'100),
MPT(ammAlice[1])(10'000), ammAlice.tokens()));
5014 .transferFee = 25'000,
5015 .pay = 30'000'000'000'000'000,
5021 .transferFee = 25'000,
5022 .pay = 30'000'000'000'000'000,
5024 AMM const ammAlice(env,
alice_, btc(1'000'000'000'000'000), eth(1'100'000'000'000'000));
5029 env(
offer(
carol_, eth(100'000'000'000'000), btc(100'000'000'000'000)));
5032 BEAST_EXPECT(ammAlice.expectBalances(
5033 btc(1'100'000'000'000'000), eth(1'000'000'000'000'000), ammAlice.tokens()));
5051 .pay = 30'000'000'000'000'000,
5058 amm.expectBalances(
XRPAmount(909'090'910), btc(549'999999450001),
amm.tokens()));
5074 .pay = 3'000'000'000'000'000'000,
5080 BEAST_EXPECT(
amm.expectBalances(
XRP(990), btc(505'05050505050506),
amm.tokens()));
5093 .transferFee = 25'000,
5094 .pay = 20'000'000'000'000'000,
5100 .transferFee = 25'000,
5101 .pay = 20'000'000'000'000'000,
5104 env,
alice_, btc(10'000'000'000'000'000), eth(11'000'000'000'000'000));
5107 env(
offer(ed,
XRP(10), eth(100'000'000'000'000)),
Txflags(tfPassive));
5109 env(
offer(
carol_, eth(1'000'000'000'000'000), btc(1'000'000'000'000'000)));
5112 BEAST_EXPECT(ammAlice.expectBalances(
5113 btc(1'060'6848287928025), eth(1'037'0658372213582), ammAlice.tokens()));
5116 env,
carol_, 1, {
Amounts{eth(27'0658372213582), btc(27'0658372213582)}}));
5140 .transferFee = 25'000,
5147 .transferFee = 25'000,
5150 AMM const ammAlice(env,
alice_, btc(1'000), eth(1'100));
5158 BEAST_EXPECT(ammAlice.expectBalances(btc(1'100), eth(1'000), ammAlice.tokens()));
5183 .transferFee = 25'000,
5190 .transferFee = 25'000,
5197 .transferFee = 25'000,
5204 .transferFee = 25'000,
5207 AMM const ammAlice(env,
alice_, gbp(1'000'000), eth(10'125));
5210 env(
offer(dan, can(2'000'000), gbp(20'000)));
5211 env(
offer(ed, eth(200), btc(200)));
5222 BEAST_EXPECT(ammAlice.expectBalances(gbp(1'012'500), eth(10'000), ammAlice.tokens()));
5230 [&](
AMM& ammAlice,
Env& env) {
5231 auto const& btc =
MPT(ammAlice[1]);
5264 .pay = 500'000'000'000'000'000,
5270 .pay = 500'000'000'000'000'000,
5276 .pay = 500'000'000'000'000'000,
5282 .pay = 500'000'000'000'000'000,
5284 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(100'000'000'000'000'000));
5286 env,
alice_, eur(100'000'000'000'000'000), btc(102'000'000'000'000'000));
5288 env,
alice_, btc(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5289 AMM const xrpUsd(env,
alice_,
XRP(10'150), usd(102'000'000'000'000'000));
5290 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(101'000'000'000'000'000));
5292 env,
alice_, eth(109'000'000'000'000'000), eur(110'000'000'000'000'000));
5294 env,
alice_, eur(101'000'000'000'000'000), usd(100'000'000'000'000'000));
5302 XRPAmount(10'026'208'900), eth(10'073'6577924447994), xrpEth.
tokens()));
5304 eth(10'926'3422075552006), eur(10'973'5423207873690), ethEur.
tokens()));
5306 eur(10'126'4576792126310), usd(9'973'9315171207179), eurUsd.
tokens()));
5310 XRPAmount(10'224'106'246), usd(10'126'0684828792821), xrpUsd.
tokens()));
5320 xrpEur.expectBalances(
XRP(10'100), eur(100'000'000'000'000'000), xrpEur.tokens()));
5322 eur(100'000'000'000'000'000), btc(102'000'000'000'000'000), eurBtc.
tokens()));
5324 btc(101'000'000'000'000'000), usd(100'000'000'000'000'000), btcUsd.
tokens()));
5337 .pay = 50'000'000'000'000'000,
5343 .pay = 50'000'000'000'000'000,
5349 .pay = 50'000'000'000'000'000,
5355 .pay = 50'000'000'000'000'000,
5357 AMM const xrpEur(env,
alice_,
XRP(10'100), eur(10'000'000'000'000'000));
5358 AMM const eurBtc(env,
alice_, eur(10'000'000'000'000'000), btc(10'200'000'000'000'000));
5359 AMM const btcUsd(env,
alice_, btc(10'100'000'000'000'000), usd(10'000'000'000'000'000));
5360 AMM const xrpEth(env,
alice_,
XRP(10'000), eth(10'100'000'000'000'000));
5361 AMM const ethEur(env,
alice_, eth(10'900'000'000'000'000), eur(11'000'000'000'000'000));
5367 BEAST_EXPECT(xrpEur.expectBalances(
5368 XRPAmount(10'118'738'472), eur(9'981'544436337981), xrpEur.tokens()));
5370 eur(10'101'160967851758), btc(10'097'914269680647), eurBtc.
tokens()));
5372 btc(10'202'085730319353), usd(9'900'000'000'000'000), btcUsd.
tokens()));
5374 XRPAmount(10'082'446'397), eth(10'017'410727780081), xrpEth.
tokens()));
5376 eth(10'982'589272219919), eur(10'917'294595810261), ethEur.
tokens()));
5390 .pay = 30'000'000'000'000'000,
5396 .pay = 400'000'000'000'000,
5398 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5400 for (
int i = 0; i < 30; ++i)
5401 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5407 Sendmax(eth(400'000'000'000'000)),
5408 Txflags(tfPartialPayment | tfNoRippleDirect));
5411 ammAlice.expectBalances(
XRP(10'030), btc(9'970'089730807592), ammAlice.tokens()));
5426 .pay = 30'000'000'000'000'000,
5432 .pay = 400'000'000'000'000,
5434 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000'000'000'000'000));
5436 for (
int i = 0; i < 29; ++i)
5437 env(
offer(
alice_, eth(1'000'000'000'000 + (10'000'000'000 * i)),
XRP(1)));
5443 Sendmax(eth(400'000'000'000'000)),
5444 Txflags(tfPartialPayment | tfNoRippleDirect));
5445 BEAST_EXPECT(ammAlice.expectBalances(
5446 XRPAmount{10'101'010'102}, btc(9'900'000'000'000'000), ammAlice.tokens()));
5463 .pay = 30'000'000'000'000'000,
5467 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'100'000'000'000'000));
5471 XRPAmount{10'049'825'372}, btc(10'049'925870493027), ammAlice.
tokens()));
5488 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5490 btc.set({.holder =
carol_, .flags = tfMPTLock});
5495 Txflags(tfNoRippleDirect | tfPartialPayment),
5509 AMM const ammAlice(env,
alice_,
XRP(10'000), btc(10'000));
5511 btc.set({.holder =
alice_, .flags = tfMPTLock});
5516 Txflags(tfNoRippleDirect | tfPartialPayment),
6202 testcase(
"Adjusted Deposit/Withdraw Tokens");
6203 using namespace jtx;
6218 Account const natalie(
"natalie");
6220 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6221 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6228 .pay = 40'000'000000,
6231 auto const usd = gw[
"USD"];
6232 for (
auto const& holder : holders)
6234 env.
trust(usd(1'500'000), holder);
6235 env(
pay(gw, holder, usd(1'500'000)));
6239 auto aliceUSD = env.
balance(alice, usd);
6240 auto bobUSD = env.
balance(bob, usd);
6241 auto carolUSD = env.
balance(carol, usd);
6242 auto edUSD = env.
balance(ed, usd);
6243 auto paulUSD = env.
balance(paul, usd);
6244 auto danUSD = env.
balance(dan, usd);
6245 auto chrisUSD = env.
balance(chris, usd);
6246 auto simonUSD = env.
balance(simon, usd);
6247 auto benUSD = env.
balance(ben, usd);
6248 auto natalieUSD = env.
balance(natalie, usd);
6250 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6254 for (
int i = 0; i < 10; ++i)
6258 ammAlice.
deposit(simon, usd(0.1));
6260 ammAlice.
deposit(chris, usd(1));
6262 ammAlice.
deposit(dan, usd(10));
6264 ammAlice.
deposit(bob, usd(100));
6266 ammAlice.
deposit(carol, usd(1'000));
6268 ammAlice.
deposit(ed, usd(10'000));
6270 ammAlice.
deposit(paul, usd(100'000));
6272 ammAlice.
deposit(natalie, usd(1'000'000));
6278 STAmount{usd, UINT64_C(10000'0000000001), -10},
6309 Account const natalie(
"natalie");
6311 alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie};
6312 env.
fund(
XRP(100000), gw, alice, bob, carol, ed, paul, dan, chris, simon, ben, natalie);
6319 .pay = 40'000'000000,
6322 auto const usd = gw[
"USD"];
6323 for (
auto const& holder : holders)
6325 env.
trust(usd(1'500'000), holder);
6326 env(
pay(gw, holder, usd(1'500'000)));
6330 auto aliceBTC = env.
balance(alice, btc);
6331 auto bobBTC = env.
balance(bob, btc);
6332 auto carolBTC = env.
balance(carol, btc);
6333 auto edBTC = env.
balance(ed, btc);
6334 auto paulBTC = env.
balance(paul, btc);
6335 auto danBTC = env.
balance(dan, btc);
6336 auto chrisBTC = env.
balance(chris, btc);
6337 auto simonBTC = env.
balance(simon, btc);
6338 auto benBTC = env.
balance(ben, btc);
6339 auto natalieBTC = env.
balance(natalie, btc);
6341 AMM ammAlice(env, alice, btc(10'000'000000), usd(10000));
6345 for (
int i = 0; i < 10; ++i)
6347 ammAlice.
deposit(ben, btc(1));
6349 ammAlice.
deposit(simon, btc(1'000));
6351 ammAlice.
deposit(chris, btc(1));
6353 ammAlice.
deposit(dan, btc(10));
6355 ammAlice.
deposit(bob, btc(100));
6357 ammAlice.
deposit(carol, btc(1'000));
6359 ammAlice.
deposit(ed, btc(10'000));
6361 ammAlice.
deposit(paul, btc(100'000));
6363 ammAlice.
deposit(natalie, btc(1'000'000));
6445 testcase(
"Offer/Strand Selection");
6446 using namespace jtx;
6467 .transferFee = gwTransferFee,
6468 .pay = 2'000'000'000,
6474 .transferFee = gw1TransferFee,
6475 .pay = 2'000'000'000,
6481 .transferFee = gw1TransferFee,
6482 .pay = 2'000'000'000,
6487 .usd = std::move(usd),
6488 .eth = std::move(eth),
6489 .can = std::move(can),
6495 for (
auto const& rates :
6510 for (
auto i = 0; i < 3; ++i)
6512 Env env(*
this, features);
6513 auto mpts = prep(env, rates.first, rates.second);
6514 auto usd = mpts.usd;
6515 auto eth = mpts.eth;
6516 auto can = mpts.can;
6519 if (i == 0 || i == 2)
6521 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6525 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6535 BEAST_EXPECT(
amm->expectBalances(
6536 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6546 BEAST_EXPECT(q[0] > q[1]);
6548 BEAST_EXPECT(q[0] == q[2]);
6555 for (
auto i = 0; i < 3; ++i)
6557 Env env(*
this, features);
6558 auto mpts = prep(env, rates.first, rates.second);
6559 auto usd = mpts.usd;
6560 auto eth = mpts.eth;
6561 auto can = mpts.can;
6563 if (i == 0 || i == 2)
6565 env(
offer(ed, eth(400'000'000), usd(400'000'000)),
Txflags(tfPassive));
6569 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6570 env(
offer(
alice_, usd(400'000'000), eth(400'000'000)));
6577 amm->expectBalances(usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6580 if (i == 0 || i == 2)
6589 env,
alice_, 1, {
Amounts{usd(400'000'000), eth(400'000'000)}}));
6600 for (
auto i = 0; i < 3; ++i)
6602 Env env(*
this, features);
6603 auto mpts = prep(env, rates.first, rates.second);
6604 auto usd = mpts.usd;
6605 auto eth = mpts.eth;
6606 auto can = mpts.can;
6608 if (i == 0 || i == 2)
6610 env(
offer(ed, eth(400'000'000), usd(330'000'000)),
Txflags(tfPassive));
6614 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6623 BEAST_EXPECT(!
amm->expectBalances(
6624 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6630 if (rates.first == kLowRate)
6660 BEAST_EXPECT(q[1] > q[0]);
6662 BEAST_EXPECT(q[2] > q[1]);
6666 for (
auto i = 0; i < 3; ++i)
6668 Env env(*
this, features);
6669 auto mpts = prep(env, rates.first, rates.second);
6670 auto usd = mpts.usd;
6671 auto eth = mpts.eth;
6672 auto can = mpts.can;
6674 if (i == 0 || i == 2)
6676 env(
offer(ed, eth(400'000'000), usd(325'000'002)),
Txflags(tfPassive));
6680 amm.emplace(env, ed, usd(1'000'000'000), eth(1'000'000'000));
6681 env(
offer(
alice_, usd(325'000'000), eth(400'000'000)));
6687 BEAST_EXPECT(!
amm->expectBalances(
6688 usd(1'000'000'000), eth(1'000'000'000),
amm->tokens()));
6695 if (rates.first == kLowRate)
6744 for (
auto i = 0; i < 3; ++i)
6746 Env env(*
this, features);
6747 auto mpts = prep(env, rates.first, rates.second);
6748 auto usd = mpts.usd;
6749 auto eth = mpts.eth;
6750 auto can = mpts.can;
6753 if (i == 0 || i == 2)
6755 env(
offer(ed, eth(400'000'000), can(375'000'000)),
Txflags(tfPassive));
6756 env(
offer(ed, can(375'000'000), usd(338'000'000))),
Txflags(tfPassive);
6760 amm.emplace(env, ed, eth(1'000'000'000), usd(1'000'000'000));
6774 if (rates.first == kLowRate)
6777 BEAST_EXPECT(
amm->expectBalances(
6778 eth(1'124'584'936), usd(889'999'993),
amm->tokens()));
6782 BEAST_EXPECT(
amm->expectBalances(
6783 eth(1'103'723'909), usd(906'023'688),
amm->tokens()));
6804 BEAST_EXPECT(q[1] > q[0]);
6805 BEAST_EXPECT(q[2] > q[0] && q[2] < q[1]);