2#include <test/jtx/AMM.h> 
    3#include <test/jtx/AMMTest.h> 
    4#include <test/jtx/PathSet.h> 
    5#include <test/jtx/amount.h> 
    6#include <test/jtx/sendmax.h> 
    8#include <xrpld/app/misc/AMMUtils.h> 
    9#include <xrpld/app/paths/AMMContext.h> 
   10#include <xrpld/app/paths/AMMOffer.h> 
   11#include <xrpld/app/paths/Flow.h> 
   12#include <xrpld/app/paths/detail/StrandFlow.h> 
   14#include <xrpl/ledger/PaymentSandbox.h> 
   15#include <xrpl/protocol/Feature.h> 
   16#include <xrpl/protocol/STParsedJSON.h> 
   33        testcase(
"Incorrect Removal of Funded Offers");
 
   45        Env env{*
this, features};
 
   52            {
USD(200'000), 
BTC(2'000)});
 
   75        if (!features[fixAMMv1_1])
 
   78                STAmount{BTC, UINT64_C(1'001'000000374812), -12},
 
   85                STAmount{BTC, UINT64_C(1'001'000000374815), -12},
 
 
  102            Env env{*
this, features};
 
  107            auto const USD1 = gw1[
"USD"];
 
  108            auto const USD2 = gw2[
"USD"];
 
  118            env(
pay(gw1, dan, USD1(10'000)));
 
  119            env(
pay(gw1, 
bob, USD1(50)));
 
  120            env(
pay(gw2, 
bob, USD2(50)));
 
  123            AMM ammDan(env, dan, 
XRP(10'000), USD1(10'000));
 
  134            Env env{*
this, features};
 
  139            auto const USD1 = gw1[
"USD"];
 
  140            auto const USD2 = gw2[
"USD"];
 
  143            env.fund(
XRP(20'000), dan);
 
  149            env(
pay(gw1, dan, USD1(10'050)));
 
  150            env(
pay(gw1, 
bob, USD1(50)));
 
  151            env(
pay(gw2, 
bob, USD2(50)));
 
  154            AMM ammDan(env, dan, 
XRP(10'000), USD1(10'050));
 
  161                XRP(10'050), USD1(10'000), ammDan.
tokens()));
 
 
  177        auto const startBalance = 
XRP(1'000'000);
 
  183            [&](
AMM& ammAlice, 
Env& env) {
 
  209            {{
XRP(10'100), 
USD(10'000)}},
 
  217            [&](
AMM& ammAlice, 
Env& env) {
 
  233            {{
XRP(10'100), 
USD(10'000)}},
 
  240            [&](
AMM& ammAlice, 
Env& env) {
 
  250            {{
XRP(10'100), 
USD(10'000)}},
 
  257            [&](
AMM& ammAlice, 
Env& env) {
 
  272            {{
XRP(11'000), 
USD(9'000)}},
 
 
  281        testcase(
"Offer Crossing with XRP, Normal order");
 
  285        Env env{*
this, features};
 
  294        auto const xrpTransferred = 
XRPAmount{3'061'224'490};
 
  297        BEAST_EXPECT(ammAlice.expectBalances(
 
  298            XRP(150'000) + xrpTransferred,
 
  304            env, 
bob, 
XRP(300'000) - xrpTransferred - 
txfee(env, 1)));
 
 
  311        testcase(
"Offer Crossing with Limit Override");
 
  315        Env env{*
this, features};
 
  331        BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == 
"-1");
 
  334            jrr[jss::node][sfBalance.fieldName] ==
 
  336                (
XRP(200'000) - 
XRP(3'000) - env.current()->fees().base * 1)
 
 
  343        testcase(
"Currency Conversion: Entire Offer");
 
  347        Env env{*
this, features};
 
  369            jrr[jss::node][sfBalance.fieldName] ==
 
 
  377        testcase(
"Currency Conversion: In Parts");
 
  382            [&](
AMM& ammAlice, 
Env& env) {
 
  406            {{
XRP(10'000), 
USD(10'000)}},
 
 
  415        testcase(
"Cross Currency Payment: Start with XRP");
 
  420            [&](
AMM& ammAlice, 
Env& env) {
 
  430            {{
XRP(10'000), 
USD(10'100)}},
 
 
  439        testcase(
"Cross Currency Payment: End with XRP");
 
  444            [&](
AMM& ammAlice, 
Env& env) {
 
  455            {{
XRP(10'100), 
USD(10'000)}},
 
 
  464        testcase(
"Cross Currency Payment: Bridged");
 
  468        Env env{*
this, features};
 
  470        auto const gw1 = 
Account{
"gateway_1"};
 
  471        auto const gw2 = 
Account{
"gateway_2"};
 
  472        auto const dan = 
Account{
"dan"};
 
  473        auto const USD1 = gw1[
"USD"];
 
  474        auto const EUR1 = gw2[
"EUR"];
 
  483        env(
trust(dan, EUR1(1'000)));
 
  489        env(
pay(gw2, dan, dan[
"EUR"](400)));
 
  492        AMM ammCarol(env, 
carol, USD1(5'000), 
XRP(50'000));
 
  494        env(
offer(dan, 
XRP(500), EUR1(50)));
 
  498        jtp[0u][0u][jss::currency] = 
"XRP";
 
  500            json(jss::Paths, jtp),
 
  505            STAmount{USD1, UINT64_C(5'030'181086519115), -12},
 
 
  514        testcase(
"Offer Fees Consume Funds");
 
  518        Env env{*
this, features};
 
  520        auto const gw1 = 
Account{
"gateway_1"};
 
  521        auto const gw2 = 
Account{
"gateway_2"};
 
  522        auto const gw3 = 
Account{
"gateway_3"};
 
  525        auto const USD1 = gw1[
"USD"];
 
  526        auto const USD2 = gw2[
"USD"];
 
  527        auto const USD3 = gw3[
"USD"];
 
  535        auto const starting_xrp = 
XRP(100) +
 
  536            env.current()->fees().accountReserve(3) +
 
  537            env.current()->fees().base * 4;
 
  539        env.fund(starting_xrp, gw1, gw2, gw3, 
alice);
 
  540        env.fund(
XRP(2'000), 
bob);
 
  551        AMM ammBob(env, 
bob, 
XRP(1'000), USD1(1'200));
 
  560            STAmount{USD1, UINT64_C(1'090'909090909091), -12},
 
  565            jrr[jss::node][sfBalance.fieldName][jss::value] ==
 
  569            jrr[jss::node][sfBalance.fieldName] == 
XRP(350).value().getText());
 
 
  575        testcase(
"Offer Create, then Cross");
 
  579        Env env{*
this, features};
 
  600            jrr[jss::node][sfBalance.fieldName][jss::value] == 
"-0.8995000001");
 
 
  606        testcase(
"Offer tfSell: Basic Sell");
 
  611            [&](
AMM& ammAlice, 
Env& env) {
 
  621            {{
XRP(9'900), 
USD(10'100)}},
 
 
  630        testcase(
"Offer tfSell: 2x Sell Exceed Limit");
 
  634        Env env{*
this, features};
 
  636        auto const starting_xrp =
 
  637            XRP(100) + 
reserve(env, 1) + env.current()->fees().base * 2;
 
  639        env.fund(starting_xrp, 
gw, 
alice);
 
  640        env.fund(
XRP(2'000), 
bob);
 
 
  665        testcase(
"Client Issue: Gateway Cross Currency");
 
  669        Env env{*
this, features};
 
  671        auto const XTS = 
gw[
"XTS"];
 
  672        auto const XXX = 
gw[
"XXX"];
 
  674        auto const starting_xrp =
 
  675            XRP(100.1) + 
reserve(env, 1) + env.current()->fees().base * 2;
 
  681            {XTS(100), XXX(100)},
 
  684        AMM ammAlice(env, 
alice, XTS(100), XXX(100));
 
  688        payment[jss::id] = env.seq(
bob);
 
  689        payment[jss::build_path] = 
true;
 
  691        payment[jss::tx_json][jss::Sequence] =
 
  694                ->getFieldU32(sfSequence);
 
  695        payment[jss::tx_json][jss::Fee] = 
to_string(env.current()->fees().base);
 
  696        payment[jss::tx_json][jss::SendMax] =
 
  699        auto const jrr = env.rpc(
"json", 
"submit", 
to_string(payment));
 
  700        BEAST_EXPECT(jrr[jss::result][jss::status] == 
"success");
 
  701        BEAST_EXPECT(jrr[jss::result][jss::engine_result] == 
"tesSUCCESS");
 
  702        if (!features[fixAMMv1_1])
 
  704            BEAST_EXPECT(ammAlice.expectBalances(
 
  705                STAmount(XTS, UINT64_C(101'010101010101), -12),
 
  709                env, 
bob, 
STAmount{XTS, UINT64_C(98'989898989899), -12}));
 
  713            BEAST_EXPECT(ammAlice.expectBalances(
 
  714                STAmount(XTS, UINT64_C(101'0101010101011), -13),
 
  718                env, 
bob, 
STAmount{XTS, UINT64_C(98'9898989898989), -13}));
 
 
  731            Env env{*
this, features};
 
  737                {
USD(15'000), 
EUR(15'000)},
 
  754            BEAST_EXPECT(ammAlice.expectBalances(
 
  755                XRP(10'100), 
USD(10'000), ammAlice.tokens()));
 
  764            Env env{*
this, features};
 
  770                {
USD(15'000), 
EUR(15'000)},
 
  789            BEAST_EXPECT(ammAlice.expectBalances(
 
  790                XRP(10'100), 
USD(10'000), ammAlice.tokens()));
 
  798            Env env{*
this, features};
 
  804                {
USD(15'000), 
EUR(15'000)},
 
 
  837        testcase(
"Combine tfSell with tfFillOrKill");
 
  845            Env env{*
this, features};
 
  853                ammBob.expectBalances(
XRP(20'000), 
USD(200), ammBob.tokens()));
 
  857            Env env{*
this, features};
 
  864            BEAST_EXPECT(ammBob.expectBalances(
 
  875            Env env{*
this, features};
 
  882            BEAST_EXPECT(ammBob.expectBalances(
 
  896            Env env{*
this, features};
 
 
  917            [&](
AMM& ammAlice, 
Env& env) {
 
  930            {{
XRP(10'000), 
USD(10'100)}},
 
  938            [&](
AMM& ammAlice, 
Env& env) {
 
  951            {{
XRP(10'100), 
USD(10'000)}},
 
  958            Env env{*
this, features};
 
  963                {
USD(15'000), 
EUR(15'000)},
 
  995            Env env{*
this, features};
 
 1000                {
USD(15'000), 
EUR(15'000)},
 
 1037            Env env{*
this, features};
 
 1081            Env env{*
this, features};
 
 
 1127        using namespace jtx;
 
 1129        Env env{*
this, features};
 
 1131        auto const USD_bob = 
bob[
"USD"];
 
 1132        auto const f = env.current()->fees().base;
 
 1136        AMM ammBob(env, 
bob, 
XRP(10'000), USD_bob(10'100));
 
 1142            XRP(10'100), USD_bob(10'000), ammBob.
tokens()));
 
 
 1155        using namespace jtx;
 
 1157        Env env{*
this, features};
 
 1160        auto const fee = env.current()->fees().base;
 
 1163            auto const ann = 
Account(
"ann");
 
 1164            auto const A_BUX = ann[
"BUX"];
 
 1166            auto const cam = 
Account(
"cam");
 
 1167            auto const dan = 
Account(
"dan");
 
 1168            auto const D_BUX = dan[
"BUX"];
 
 1176            env(
trust(cam, D_BUX(100)));
 
 1178            env(
pay(dan, 
bob, D_BUX(100)));
 
 1194            AMM ammBob(env, 
bob, A_BUX(30), D_BUX(30));
 
 1196            env(
trust(ann, D_BUX(100)));
 
 1200            env(
pay(ann, ann, D_BUX(30)),
 
 
 1226        using namespace jtx;
 
 1228        Env env{*
this, features};
 
 1230        auto const ann = 
Account(
"ann");
 
 1232        auto const cam = 
Account(
"cam");
 
 1234        auto const A_BUX = ann[
"BUX"];
 
 1235        auto const B_BUX = 
bob[
"BUX"];
 
 1237        auto const fee = env.current()->fees().base;
 
 1242        env(
trust(ann, B_BUX(40)));
 
 1243        env(
trust(cam, A_BUX(40)));
 
 1245        env(
trust(cam, B_BUX(40)));
 
 1250        env(
pay(ann, cam, A_BUX(35)));
 
 1251        env(
pay(
bob, cam, B_BUX(35)));
 
 1255        AMM ammCarol(env, 
carol, A_BUX(300), B_BUX(330));
 
 1262        env.require(
balance(cam, A_BUX(35)));
 
 1263        env.require(
balance(cam, B_BUX(35)));
 
 1264        env.require(
offers(cam, 1));
 
 1267        env(
offer(cam, B_BUX(30), A_BUX(30)));
 
 1270        if (!features[fixAMMv1_1])
 
 1273                STAmount{A_BUX, UINT64_C(309'3541659651605), -13},
 
 1274                STAmount{B_BUX, UINT64_C(320'0215509984417), -13},
 
 1281                    STAmount{B_BUX, UINT64_C(20'0215509984417), -13},
 
 1282                    STAmount{A_BUX, UINT64_C(20'0215509984417), -13}}}}));
 
 1287                STAmount{A_BUX, UINT64_C(309'3541659651604), -13},
 
 1288                STAmount{B_BUX, UINT64_C(320'0215509984419), -13},
 
 1295                    STAmount{B_BUX, UINT64_C(20'0215509984419), -13},
 
 1296                    STAmount{A_BUX, UINT64_C(20'0215509984419), -13}}}}));
 
 
 1305        using namespace jtx;
 
 1307        Env env{*
this, features};
 
 1309        auto const aliceUSD = 
alice[
"USD"];
 
 1310        auto const bobUSD = 
bob[
"USD"];
 
 
 1354        using namespace jtx;
 
 1356        Env env{*
this, features};
 
 
 1420        using namespace jtx;
 
 
 1454        using namespace jtx;
 
 1471        BEAST_EXPECT(st.
empty());
 
 1479        BEAST_EXPECT(sa == 
XRP(100'000'000));
 
 1483            da, 
STAmount{
bob[
"USD"].issue(), UINT64_C(99'9999000001), -10}));
 
 
 1493        using namespace jtx;
 
 1496        auto const AUD = 
gw[
"AUD"];
 
 
 1520        using namespace jtx;
 
 1521        auto const charlie = 
Account(
"charlie");
 
 1526            AMM ammCharlie(env, charlie, 
XRP(10), 
USD(11));
 
 1529            BEAST_EXPECT(sa == 
XRP(1));
 
 1531            if (BEAST_EXPECT(st.size() == 1 && st[0].size() == 1))
 
 1533                auto const& pathElem = st[0][0];
 
 1535                    pathElem.isOffer() && pathElem.getIssuerID() == 
gw.
id() &&
 
 1543            AMM ammCharlie(env, charlie, 
XRP(11), 
USD(10));
 
 1547            BEAST_EXPECT(sa == 
USD(1));
 
 1549            if (BEAST_EXPECT(st.size() == 1 && st[0].size() == 1))
 
 1551                auto const& pathElem = st[0][0];
 
 1553                    pathElem.isOffer() &&
 
 
 1563        testcase(
"Path Find: XRP -> XRP and XRP -> IOU");
 
 1564        using namespace jtx;
 
 1576        env.
fund(
XRP(1'000), A3, G1, G2, G3);
 
 1580        env.
trust(G1[
"XYZ"](5'000), A1);
 
 1581        env.
trust(G3[
"ABC"](5'000), A1);
 
 1582        env.
trust(G2[
"XYZ"](5'000), A2);
 
 1583        env.
trust(G3[
"ABC"](5'000), A2);
 
 1584        env.
trust(A2[
"ABC"](1'000), A3);
 
 1585        env.
trust(G1[
"XYZ"](100'000), M1);
 
 1586        env.
trust(G2[
"XYZ"](100'000), M1);
 
 1587        env.
trust(G3[
"ABC"](100'000), M1);
 
 1590        env(
pay(G1, A1, G1[
"XYZ"](3'500)));
 
 1591        env(
pay(G3, A1, G3[
"ABC"](1'200)));
 
 1592        env(
pay(G1, M1, G1[
"XYZ"](25'000)));
 
 1593        env(
pay(G2, M1, G2[
"XYZ"](25'000)));
 
 1594        env(
pay(G3, M1, G3[
"ABC"](25'000)));
 
 1597        AMM ammM1_G1_G2(env, M1, G1[
"XYZ"](1'000), G2[
"XYZ"](1'000));
 
 1598        AMM ammM1_XRP_G3(env, M1, 
XRP(10'000), G3[
"ABC"](1'000));
 
 1604            auto const& send_amt = 
XRP(10);
 
 1607            BEAST_EXPECT(
equal(da, send_amt));
 
 1608            BEAST_EXPECT(st.
empty());
 
 1614            auto const& send_amt = 
XRP(200);
 
 1617            BEAST_EXPECT(
equal(da, send_amt));
 
 1618            BEAST_EXPECT(st.
empty());
 
 1622            auto const& send_amt = G3[
"ABC"](10);
 
 1625            BEAST_EXPECT(
equal(da, send_amt));
 
 1631            auto const& send_amt = A2[
"ABC"](1);
 
 1634            BEAST_EXPECT(
equal(da, send_amt));
 
 1640            auto const& send_amt = A3[
"ABC"](1);
 
 1643            BEAST_EXPECT(
equal(da, send_amt));
 
 
 1652        testcase(
"Path Find: non-XRP -> XRP");
 
 1653        using namespace jtx;
 
 1660        env.
fund(
XRP(1'000), A1, A2, G3);
 
 1664        env.
trust(G3[
"ABC"](1'000), A1, A2);
 
 1665        env.
trust(G3[
"ABC"](100'000), M1);
 
 1668        env(
pay(G3, A1, G3[
"ABC"](1'000)));
 
 1669        env(
pay(G3, A2, G3[
"ABC"](1'000)));
 
 1670        env(
pay(G3, M1, G3[
"ABC"](1'200)));
 
 1673        AMM ammM1(env, M1, G3[
"ABC"](1'000), 
XRP(10'010));
 
 1678        auto const& send_amt = 
XRP(10);
 
 1681        BEAST_EXPECT(
equal(da, send_amt));
 
 1682        BEAST_EXPECT(
equal(sa, A1[
"ABC"](1)));
 
 
 1689        testcase(
"Path Find: non-XRP -> non-XRP, same currency");
 
 1690        using namespace jtx;
 
 1703        env.
fund(
XRP(1'000), A1, A2, A3, G1, G2, G3, G4);
 
 1705        env.
fund(
XRP(21'000), M1, M2);
 
 1708        env.
trust(G1[
"HKD"](2'000), A1);
 
 1709        env.
trust(G2[
"HKD"](2'000), A2);
 
 1710        env.
trust(G1[
"HKD"](2'000), A3);
 
 1711        env.
trust(G1[
"HKD"](100'000), M1);
 
 1712        env.
trust(G2[
"HKD"](100'000), M1);
 
 1713        env.
trust(G1[
"HKD"](100'000), M2);
 
 1714        env.
trust(G2[
"HKD"](100'000), M2);
 
 1717        env(
pay(G1, A1, G1[
"HKD"](1'000)));
 
 1718        env(
pay(G2, A2, G2[
"HKD"](1'000)));
 
 1719        env(
pay(G1, A3, G1[
"HKD"](1'000)));
 
 1720        env(
pay(G1, M1, G1[
"HKD"](1'200)));
 
 1721        env(
pay(G2, M1, G2[
"HKD"](5'000)));
 
 1722        env(
pay(G1, M2, G1[
"HKD"](1'200)));
 
 1723        env(
pay(G2, M2, G2[
"HKD"](5'000)));
 
 1726        AMM ammM1(env, M1, G1[
"HKD"](1'010), G2[
"HKD"](1'000));
 
 1727        AMM ammM2XRP_G2(env, M2, 
XRP(10'000), G2[
"HKD"](1'010));
 
 1728        AMM ammM2G1_XRP(env, M2, G1[
"HKD"](1'010), 
XRP(10'000));
 
 1736            auto const& send_amt = G1[
"HKD"](10);
 
 1738                env, A1, G1, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1739            BEAST_EXPECT(st.
empty());
 
 1740            BEAST_EXPECT(
equal(da, send_amt));
 
 1741            BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
 
 1747            auto const& send_amt = A1[
"HKD"](10);
 
 1749                env, A1, G1, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1750            BEAST_EXPECT(st.
empty());
 
 1751            BEAST_EXPECT(
equal(da, send_amt));
 
 1752            BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
 
 1758            auto const& send_amt = A3[
"HKD"](10);
 
 1760                env, A1, A3, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1761            BEAST_EXPECT(
equal(da, send_amt));
 
 1762            BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
 
 1769            auto const& send_amt = G2[
"HKD"](10);
 
 1771                env, G1, G2, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1772            BEAST_EXPECT(
equal(da, send_amt));
 
 1773            BEAST_EXPECT(
equal(sa, G1[
"HKD"](10)));
 
 1785            auto const& send_amt = G2[
"HKD"](10);
 
 1787                env, A1, G2, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1788            BEAST_EXPECT(
equal(da, send_amt));
 
 1789            BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
 
 1802            auto const& send_amt = A2[
"HKD"](10);
 
 1804                env, A1, A2, send_amt, 
std::nullopt, G1[
"HKD"].currency);
 
 1805            BEAST_EXPECT(
equal(da, send_amt));
 
 1806            BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
 
 
 1819        testcase(
"Path Find: non-XRP -> non-XRP, same currency");
 
 1820        using namespace jtx;
 
 1830        env.
fund(
XRP(1'000), A1, A2, A3, G1, G2);
 
 1833        env.
trust(G1[
"HKD"](2'000), A1);
 
 1834        env.
trust(G2[
"HKD"](2'000), A2);
 
 1835        env.
trust(A2[
"HKD"](2'000), A3);
 
 1836        env.
trust(G1[
"HKD"](100'000), M1);
 
 1837        env.
trust(G2[
"HKD"](100'000), M1);
 
 1840        env(
pay(G1, A1, G1[
"HKD"](1'000)));
 
 1841        env(
pay(G2, A2, G2[
"HKD"](1'000)));
 
 1842        env(
pay(G1, M1, G1[
"HKD"](5'000)));
 
 1843        env(
pay(G2, M1, G2[
"HKD"](5'000)));
 
 1846        AMM ammM1(env, M1, G1[
"HKD"](1'010), G2[
"HKD"](1'000));
 
 1850        auto const& send_amt = A2[
"HKD"](10);
 
 1855        BEAST_EXPECT(
equal(da, send_amt));
 
 1856        BEAST_EXPECT(
equal(sa, G1[
"HKD"](10)));
 
 
 1865        using namespace jtx;
 
 1867        Env env(*
this, features);
 
 1873        auto const AMMXRPPool = env.
current()->fees().increment * 2;
 
 1890        AMM ammBob(env, 
bob, AMMXRPPool, 
USD(150));
 
 1898        BEAST_EXPECT(carolUSD > 
USD(0) && carolUSD < 
USD(50));
 
 
 1906        using namespace jtx;
 
 1910            Env env(*
this, features);
 
 1929                ammBob.expectBalances(
BTC(150), 
USD(100), ammBob.tokens()));
 
 1933            Env env(*
this, features);
 
 1952            BEAST_EXPECT(ammBobBTC_XRP.expectBalances(
 
 1953                BTC(150), 
XRP(100), ammBobBTC_XRP.tokens()));
 
 1959            Env env(*
this, features);
 
 1980                ammBob.expectBalances(
XRP(150), 
USD(100), ammBob.tokens()));
 
 1984            Env env(*
this, features);
 
 2004                ammBob.expectBalances(
USD(150), 
XRP(100), ammBob.tokens()));
 
 2008            Env env(*
this, features);
 
 2061            Env env(*
this, features);
 
 2095            auto const flowResult = [&] {
 
 2110                    paths.push_back(p1);
 
 2113                    paths.push_back(p2);
 
 2132            BEAST_EXPECT(flowResult.removableOffers.size() == 1);
 
 2135                    if (flowResult.removableOffers.empty())
 
 2138                    for (
auto const& o : flowResult.removableOffers)
 
 2161            Env env(*
this, features);
 
 2184            BEAST_EXPECT(ammBob.expectBalances(
 
 
 2193        using namespace jtx;
 
 2197            Env env(*
this, features);
 
 2204                {
USD(1'000), 
GBP(1'000)});
 
 2219            if (!features[fixAMMv1_1])
 
 2222                BEAST_EXPECT(amm.expectBalances(
 
 2229                BEAST_EXPECT(amm.expectBalances(
 
 2242            Env env(*
this, features);
 
 2276            BEAST_EXPECT(amm.expectBalances(
 
 2286            Env env(*
this, features);
 
 2299            AMM amm2(env, ed, 
EUR(1'000), 
USD(1'000));
 
 2308            if (!features[fixAMMv1_1])
 
 2346            Env env(*
this, features);
 
 2358                amm.expectBalances(
USD(1'100), 
EUR(1'000), amm.tokens()));
 
 2366            Env env(*
this, features);
 
 2373                {
USD(1'000), 
GBP(1'000)});
 
 2393            BEAST_EXPECT(amm.expectBalances(
 
 2394                STAmount{GBP, UINT64_C(1'142'857142857143), -12},
 
 2404            Env env(*
this, features);
 
 2411                {
USD(1'200), 
GBP(1'200)});
 
 2425            if (!features[fixAMMv1_1])
 
 2432                BEAST_EXPECT(amm.expectBalances(
 
 2433                    GBP(1'024), 
USD(1'171.875), amm.tokens()));
 
 2443                    STAmount{
GBP, UINT64_C(1'169'999999999999), -12}));
 
 2445                BEAST_EXPECT(amm.expectBalances(
 
 2446                    STAmount{GBP, UINT64_C(1'024'000000000001), -12},
 
 2457            Env env(*
this, features);
 
 2482            if (!features[fixAMMv1_1])
 
 2490                    STAmount{
GBP, UINT64_C(1'311'973684210527), -12}));
 
 2497                    STAmount{
GBP, UINT64_C(1'470'421052631579), -12}));
 
 2504                        STAmount{
EUR, UINT64_C(929'5789473684212), -13}}}));
 
 2507                BEAST_EXPECT(amm.expectBalances(
 
 2508                    STAmount{EUR, UINT64_C(1'056'336842105263), -12},
 
 2509                    STAmount{USD, UINT64_C(1'325'334821428571), -12},
 
 2520                    STAmount{
GBP, UINT64_C(1'311'973684210525), -12}));
 
 2527                    STAmount{
GBP, UINT64_C(1'470'42105263158), -11}));
 
 2534                        STAmount{
EUR, UINT64_C(929'57894736842), -11}}}));
 
 2537                BEAST_EXPECT(amm.expectBalances(
 
 2538                    STAmount{EUR, UINT64_C(1'056'336842105264), -12},
 
 2539                    STAmount{USD, UINT64_C(1'325'334821428571), -12},
 
 2549            Env env(*
this, features);
 
 2574            if (!features[fixAMMv1_1])
 
 2582                    STAmount{
GBP, UINT64_C(1'329'578947368421), -12}));
 
 2586                BEAST_EXPECT(amm.expectBalances(
 
 2587                    STAmount{GBP, UINT64_C(1'056'336842105263), -12},
 
 2588                    STAmount{EUR, UINT64_C(946'6677295918366), -13},
 
 2599                    STAmount{
GBP, UINT64_C(1'329'57894736842), -11}));
 
 2603                BEAST_EXPECT(amm.expectBalances(
 
 2604                    STAmount{GBP, UINT64_C(1'056'336842105264), -12},
 
 2605                    STAmount{EUR, UINT64_C(946'6677295918366), -13},
 
 2614                STAmount{
EUR, UINT64_C(1'442'665816326531), -12}));
 
 2621                    STAmount{
USD, UINT64_C(1'340'267857142857), -12}}}));
 
 2629            Env env(*
this, features);
 
 2642            AMM amm2(env, ed, 
EUR(1'000), 
USD(1'400));
 
 2652            if (!features[fixAMMv1_1])
 
 2660                    STAmount{
GBP, UINT64_C(1'292'469135802469), -12}));
 
 2663                    STAmount{GBP, UINT64_C(1'086'024691358025), -12},
 
 2664                    STAmount{EUR, UINT64_C(920'78937795562), -11},
 
 2669                    STAmount{EUR, UINT64_C(1'063'368497635504), -12},
 
 2670                    STAmount{USD, UINT64_C(1'316'570881226053), -12},
 
 2681                    STAmount{
GBP, UINT64_C(1'292'469135802466), -12}));
 
 2684                    STAmount{GBP, UINT64_C(1'086'024691358027), -12},
 
 2685                    STAmount{EUR, UINT64_C(920'7893779556188), -13},
 
 2690                    STAmount{EUR, UINT64_C(1'063'368497635505), -12},
 
 2691                    STAmount{USD, UINT64_C(1'316'570881226053), -12},
 
 2701            Env env(*
this, features);
 
 2723            if (!features[fixAMMv1_1])
 
 2727                    STAmount{GBP, UINT64_C(1'108'148148148149), -12},
 
 2728                    STAmount{EUR, UINT64_C(902'4064171122988), -13},
 
 2733                    STAmount{EUR, UINT64_C(1'078'074866310161), -12},
 
 2734                    STAmount{USD, UINT64_C(1'298'611111111111), -12},
 
 2741                    STAmount{GBP, UINT64_C(1'108'148148148151), -12},
 
 2742                    STAmount{EUR, UINT64_C(902'4064171122975), -13},
 
 2747                    STAmount{EUR, UINT64_C(1'078'074866310162), -12},
 
 2748                    STAmount{USD, UINT64_C(1'298'611111111111), -12},
 
 
 2765        using namespace jtx;
 
 2781                ammBob.expectBalances(
XRP(1'050), 
USD(1'000), ammBob.tokens()));
 
 
 2792        using namespace jtx;
 
 2842            auto const JPY = 
gw[
"JPY"];
 
 2851                {
USD(200), 
EUR(200), JPY(200)},
 
 2856            AMM ammAliceXRP_JPY(env, 
alice, 
XRP(100), JPY(100));
 
 
 2871        using namespace jtx;
 
 2872        Env env(*
this, features);
 
 2873        auto const dan = 
Account(
"dan");
 
 2874        auto const ed = 
Account(
"ed");
 
 2890        if (!features[fixAMMv1_1])
 
 
 2916        testcase(
"Convert all of an asset using DeliverMin");
 
 2918        using namespace jtx;
 
 2921            Env env(*
this, features);
 
 2953                drops(10'000'000'000 - env.
current()->fees().base.drops())));
 
 2958            Env env(*
this, features);
 
 2972            Env env(*
this, features);
 
 2994            auto const dan = 
Account(
"dan");
 
 2995            Env env(*
this, features);
 
 3003            AMM ammDan(env, dan, 
XRP(1'000), 
USD(1'100));
 
 3004            if (!features[fixAMMv1_1])
 
 3028                    STAmount{USD, UINT64_C(999'99999909091), -11},
 
 
 3039        using namespace jtx;
 
 3042        bool const supportsPreauth = {features[featureDepositPreauth]};
 
 3047        Env env(*
this, features);
 
 3076        env(
pay(becky, becky, 
USD(10)),
 
 
 3091        using namespace jtx;
 
 3112        auto failedIouPayments = [
this, &env]() {
 
 3136        failedIouPayments();
 
 3153        failedIouPayments();
 
 3160        failedIouPayments();
 
 
 3183        using namespace test::jtx;
 
 3184        Env env(*
this, features);
 
 3197        env(
pay(G1, 
bob, G1[
"USD"](10)));
 
 3198        env(
pay(G1, 
alice, G1[
"USD"](205)));
 
 3201        AMM ammAlice(env, 
alice, 
XRP(500), G1[
"USD"](105));
 
 3207            BEAST_EXPECT(
lines[jss::lines][0u][jss::account] == G1.human());
 
 3208            BEAST_EXPECT(
lines[jss::lines][0u][jss::limit] == 
"100");
 
 3209            BEAST_EXPECT(
lines[jss::lines][0u][jss::balance] == 
"10");
 
 3216            BEAST_EXPECT(
lines[jss::lines][0u][jss::account] == G1.human());
 
 3217            BEAST_EXPECT(
lines[jss::lines][0u][jss::limit] == 
"205");
 
 3219            BEAST_EXPECT(
lines[jss::lines][0u][jss::balance] == 
"100");
 
 3241                XRP(525), G1[
"USD"](100), ammAlice.
tokens()));
 
 3260            for (
auto const& it : 
lines[jss::lines])
 
 3262                if (it[jss::account] == 
bob.
human())
 
 3268            if (!BEAST_EXPECT(bobLine))
 
 3270            BEAST_EXPECT(bobLine[jss::freeze] == 
true);
 
 3271            BEAST_EXPECT(bobLine[jss::balance] == 
"-16");
 
 3278            for (
auto const& it : 
lines[jss::lines])
 
 3280                if (it[jss::account] == G1.human())
 
 3286            if (!BEAST_EXPECT(g1Line))
 
 3288            BEAST_EXPECT(g1Line[jss::freeze_peer] == 
true);
 
 3289            BEAST_EXPECT(g1Line[jss::balance] == 
"16");
 
 3296            auto affected = env.
meta()->getJson(
 
 3301                affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
 
 3303                ff[sfLowLimit.fieldName] ==
 
 3305            BEAST_EXPECT(!(ff[jss::Flags].asUInt() & 
lsfLowFreeze));
 
 
 3316        using namespace test::jtx;
 
 3317        Env env(*
this, features);
 
 3327        env.
fund(
XRP(20'000), A2, A3, A4);
 
 3330        env.
trust(G1[
"USD"](1'200), A1);
 
 3331        env.
trust(G1[
"USD"](200), A2);
 
 3332        env.
trust(G1[
"BTC"](100), A3);
 
 3333        env.
trust(G1[
"BTC"](100), A4);
 
 3336        env(
pay(G1, A1, G1[
"USD"](1'000)));
 
 3337        env(
pay(G1, A2, G1[
"USD"](100)));
 
 3338        env(
pay(G1, A3, G1[
"BTC"](100)));
 
 3339        env(
pay(G1, A4, G1[
"BTC"](100)));
 
 3342        AMM ammG1(env, G1, 
XRP(10'000), G1[
"USD"](100));
 
 3354                "XRP")[jss::result][jss::offers];
 
 3362            BEAST_EXPECT(accounts.
find(A2.human()) != 
std::end(accounts));
 
 3368                std::string(
"USD/") + G1.human())[jss::result][jss::offers];
 
 3376            BEAST_EXPECT(accounts.
find(A1.human()) != 
std::end(accounts));
 
 3383            AMM ammA3(env, A3, G1[
"BTC"](1), 
XRP(1));
 
 3389            env(
pay(G1, A2, G1[
"USD"](1)));
 
 3392            env(
pay(A2, G1, G1[
"USD"](1)));
 
 3395            env(
pay(A2, A1, G1[
"USD"](1)));
 
 3398            env(
pay(A1, A2, G1[
"USD"](1)));
 
 3424                std::string(
"USD/") + G1.human())[jss::result][jss::offers];
 
 3431                "XRP")[jss::result][jss::offers];
 
 3439            env(
pay(G1, A2, G1[
"USD"](1)));
 
 3442            env(
pay(A2, G1, G1[
"USD"](1)));
 
 
 3452        testcase(
"Offers for Frozen Trust Lines");
 
 3454        using namespace test::jtx;
 
 3455        Env env(*
this, features);
 
 3462        env.
fund(
XRP(2'000), G1, A3, A4);
 
 3466        env.
trust(G1[
"USD"](1'000), A2);
 
 3467        env.
trust(G1[
"USD"](2'000), A3);
 
 3468        env.
trust(G1[
"USD"](2'001), A4);
 
 3471        env(
pay(G1, A3, G1[
"USD"](2'000)));
 
 3472        env(
pay(G1, A4, G1[
"USD"](2'001)));
 
 3475        AMM ammA3(env, A3, 
XRP(1'000), G1[
"USD"](1'001));
 
 3486        env(
offer(A4, 
XRP(999), G1[
"USD"](999)));
 
 3497        BEAST_EXPECT(info[jss::amm][jss::asset2_frozen].asBool());
 
 3513        env(
offer(A2, G1[
"USD"](999), 
XRP(999)));
 
 
 3525        testcase(
"Multisign AMM Transactions");
 
 3527        using namespace jtx;
 
 3528        Env env{*
this, features};
 
 3543        int const signerListOwners{features[featureMultiSignReserve] ? 2 : 5};
 
 3546        msig const ms{becky, bogie};
 
 3572        ammAlice.
vote({}, 1'000);
 
 3575        env(ammAlice.
bid({.account = alice, .bidMin = 100}), ms).close();
 
 
 3587        using namespace jtx;
 
 3591        Env env(*
this, features);
 
 3598            {
USD(2'000), 
EUR(1'000)});
 
 
 3614        using namespace jtx;
 
 3618            Env env(*
this, features);
 
 3619            auto const BobUSD = 
bob[
"USD"];
 
 3620            auto const BobEUR = 
bob[
"EUR"];
 
 3629                {BobUSD(100), BobEUR(100)},
 
 3633            AMM ammBobXRP_USD(env, 
bob, 
XRP(100), BobUSD(100));
 
 3636            AMM ammBobUSD_EUR(env, 
bob, BobUSD(100), BobEUR(100));
 
 3639            Path const p = [&] {
 
 3656            Env env(*
this, features);
 
 3670            Env env(*
this, features);
 
 
 3689        using namespace jtx;
 
 3691        auto const CNY = 
gw[
"CNY"];
 
 3694            Env env(*
this, features);
 
 3715            Env env(*
this, features);
 
 3729            AMM ammBobEUR_CNY(env, 
bob, 
EUR(100), CNY(100));
 
 
 3755        using namespace jtx;
 
 
 3769        using namespace jtx;
 
 
 3778        using namespace jtx;
 
 
 3796        using namespace test::jtx;
 
 
 3806        using namespace jtx;
 
 3810            all - featureMultiSignReserve - featureExpandedSignerList);
 
 
 3818        using namespace jtx;
 
 
 
 3841BEAST_DEFINE_TESTSUITE_PRIO(AMMExtended, app, 
ripple, 1);
 
A generic endpoint for log messages.
 
testcase_t testcase
Memberspace for declaring test cases.
 
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
 
virtual OpenLedger & openLedger()=0
 
Floating point representation of amounts with high dynamic range.
 
A currency issued by an account.
 
beast::Journal journal(std::string const &name)
 
bool modify(modify_type const &f)
Modify the open ledger.
 
Writable ledger view that accumulates state and tx changes.
 
A wrapper which makes credits unavailable to balances.
 
Discardable, editable view to a ledger.
 
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
 
Path & push_back(Issue const &iss)
 
void testAMM(std::function< void(jtx::AMM &, jtx::Env &)> &&cb, std::optional< std::pair< STAmount, STAmount > > const &pool=std::nullopt, std::uint16_t tfee=0, std::optional< jtx::ter > const &ter=std::nullopt, std::vector< FeatureBitset > const &features={testable_amendments()})
testAMM() funds 30,000XRP and 30,000IOU for each non-XRP asset to Alice and Carol
 
std::tuple< STPathSet, STAmount, STAmount > find_paths(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax=std::nullopt, std::optional< Currency > const &saSrcCurrency=std::nullopt)
 
XRPAmount ammCrtFee(jtx::Env &env) const
 
XRPAmount reserve(jtx::Env &env, std::uint32_t count) const
 
Convenience class to test AMM functionality.
 
Json::Value ammRpcInfo(std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< Issue > issue1=std::nullopt, std::optional< Issue > issue2=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt, bool ignoreParams=false, unsigned apiVersion=RPC::apiInvalidVersion) const
Send amm_info RPC command.
 
void vote(std::optional< Account > const &account, std::uint32_t feeVal, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< jtx::seq > const &seq=std::nullopt, std::optional< std::pair< Issue, Issue > > const &assets=std::nullopt, std::optional< ter > const &ter=std::nullopt)
 
bool expectAuctionSlot(std::uint32_t fee, std::optional< std::uint8_t > timeSlot, IOUAmount expectedPrice) const
 
AccountID const & ammAccount() const
 
bool expectTradingFee(std::uint16_t fee) const
 
IOUAmount withdraw(std::optional< Account > const &account, std::optional< LPToken > const &tokens, std::optional< STAmount > const &asset1OutDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< ter > const &ter=std::nullopt)
 
bool expectBalances(STAmount const &asset1, STAmount const &asset2, IOUAmount const &lpt, std::optional< AccountID > const &account=std::nullopt) const
Verify the AMM balances.
 
IOUAmount deposit(std::optional< Account > const &account, LPToken tokens, std::optional< STAmount > const &asset1InDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< ter > const &ter=std::nullopt)
 
Json::Value bid(BidArg const &arg)
 
IOUAmount withdrawAll(std::optional< Account > const &account, std::optional< STAmount > const &asset1OutDetails=std::nullopt, std::optional< ter > const &ter=std::nullopt)
 
Immutable cryptographic account descriptor.
 
AccountID id() const
Returns the Account ID.
 
std::string const & human() const
Returns the human readable public key.
 
A transaction testing environment.
 
void require(Args const &... args)
Check a set of requirements.
 
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
 
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
 
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
 
ripple::Currency currency
 
Sets the DeliverMin on a JTx.
 
Set a multisignature on a JTx.
 
Match clear account flags.
 
Match the number of items in the account's owner directory.
 
Set Paths, SendMax on a JTx.
 
Sets the QualityIn on a trust JTx.
 
Sets the QualityOut on a trust JTx as a percentage.
 
Check a set of conditions.
 
Sets the SendMax on a JTx.
 
Set the regular signature on a JTx.
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
@ arrayValue
array value (ordered list)
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
 
bool checkArraySize(Json::Value const &val, unsigned int size)
 
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
 
Json::Value ledgerEntryRoot(Env &env, Account const &acct)
 
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
 
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
 
owner_count< ltOFFER > offers
Match the number of offers in the account's owner directory.
 
bool expectOffers(Env &env, AccountID const &account, std::uint16_t size, std::vector< Amounts > const &toMatch)
 
PrettyAmount xrpMinusFee(Env const &env, std::int64_t xrpAmount)
 
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
 
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
 
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
 
Json::Value getAccountLines(Env &env, AccountID const &acctId)
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
bool same(STPathSet const &st1, Args const &... args)
 
Json::Value ledgerEntryState(Env &env, Account const &acct_a, Account const &acct_b, std::string const ¤cy)
 
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
 
void n_offers(Env &env, std::size_t n, Account const &account, STAmount const &in, STAmount const &out)
 
FeatureBitset testable_amendments()
 
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
 
STPathElement IPE(Issue const &iss)
 
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
 
bool expectHolding(Env &env, AccountID const &account, STAmount const &value, bool defaultLimits)
 
STPathElement cpe(Currency const &c)
 
bool expectLedgerEntryRoot(Env &env, Account const &acct, STAmount const &expectedValue)
 
STPathElement allpe(AccountID const &a, Issue const &iss)
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
XRPAmount txfee(Env const &env, std::uint16_t n)
 
STPath stpath(Args const &... args)
 
Json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
 
bool isOffer(jtx::Env &env, jtx::Account const &account, STAmount const &takerPays, STAmount const &takerGets)
An offer exists.
 
bool equal(std::unique_ptr< Step > const &s1, DirectStepInfo const &dsi)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
 
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
 
constexpr std::uint32_t asfGlobalFreeze
 
constexpr std::uint32_t asfDepositAuth
 
AccountID const & xrpAccount()
Compute AccountID from public key.
 
constexpr std::uint32_t asfNoFreeze
 
constexpr std::uint32_t tfFillOrKill
 
StrandResult< TInAmt, TOutAmt > flow(PaymentSandbox const &baseView, Strand const &strand, std::optional< TInAmt > const &maxIn, TOutAmt const &out, beast::Journal j)
Request out amount from a strand.
 
constexpr std::uint32_t tfPassive
 
constexpr std::uint32_t tfImmediateOrCancel
 
constexpr std::uint32_t asfDisableMaster
 
constexpr std::uint32_t tfPartialPayment
 
constexpr std::uint32_t tfSetfAuth
 
Currency const & xrpCurrency()
XRP currency.
 
constexpr std::uint32_t tfClearFreeze
 
constexpr std::uint32_t tfNoRippleDirect
 
constexpr std::uint32_t tfLimitQuality
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
constexpr std::uint32_t tfSell
 
constexpr std::uint32_t asfRequireAuth
 
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
 
constexpr std::uint32_t tfSetFreeze
 
constexpr std::uint32_t tfSetNoRipple
 
TER offerDelete(ApplyView &view, std::shared_ptr< SLE > const &sle, beast::Journal j)
Delete an offer.
 
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
 
Tests of AMM that use offers too.
 
void testGlobalFreeze(FeatureBitset features)
 
void testOfferCrossWithXRP(FeatureBitset features)
 
void testCurrencyConversionEntire(FeatureBitset features)
 
void testCrossingLimits()
 
void testFalseDry(FeatureBitset features)
 
void testOfferCrossWithLimitOverride(FeatureBitset features)
 
void testTransferRateOffer(FeatureBitset features)
 
void testBookStep(FeatureBitset features)
 
void testBridgedCross(FeatureBitset features)
 
void test_convert_all_of_an_asset(FeatureBitset features)
 
void testGatewayCrossCurrency(FeatureBitset features)
 
void testRequireAuth(FeatureBitset features)
 
void testPayment(FeatureBitset features)
 
void testOfferFeesConsumeFunds(FeatureBitset features)
 
void testOffersWhenFrozen(FeatureBitset features)
 
void testSellFlagExceedLimit(FeatureBitset features)
 
void testCrossCurrencyBridged(FeatureBitset features)
 
void testBadPathAssert(FeatureBitset features)
 
void testLoop(FeatureBitset features)
 
void via_offers_via_gateway()
 
void testOfferCreateThenCross(FeatureBitset features)
 
void testToStrand(FeatureBitset features)
 
void run() override
Runs the suite.
 
void testFillModes(FeatureBitset features)
 
void testMissingAuth(FeatureBitset features)
 
void path_find_consume_all()
 
void testRIPD1373(FeatureBitset features)
 
void testCrossCurrencyEndXRP(FeatureBitset features)
 
void testCurrencyConversionInParts(FeatureBitset features)
 
void testTransferRateNoOwnerFee(FeatureBitset features)
 
void testRippleState(FeatureBitset features)
 
void testRmFundedOffer(FeatureBitset features)
 
void testSelfIssueOffer(FeatureBitset features)
 
void testDirectToDirectPath(FeatureBitset features)
 
void testStepLimit(FeatureBitset features)
 
void testEnforceNoRipple(FeatureBitset features)
 
void testCrossCurrencyStartXRP(FeatureBitset features)
 
void testSellWithFillOrKill(FeatureBitset features)
 
void testTxMultisign(FeatureBitset features)
 
void testSellFlagBasic(FeatureBitset features)
 
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
 
STAmount const & value() const