903        using namespace test::jtx;
 
  912            Env env{*
this, features - featureMPTokensV1};
 
  916            env.fund(
XRP(1'000), alice);
 
  917            env.fund(
XRP(1'000), bob);
 
  925            Env env{*
this, features - featureMPTokensV1};
 
  928            auto const USD = alice[
"USD"];
 
  930            env.fund(
XRP(1'000), alice);
 
  931            env.fund(
XRP(1'000), carol);
 
  935            jv[jss::secret] = alice.
name();
 
  936            jv[jss::tx_json] = 
pay(alice, carol, mpt);
 
  937            jv[jss::tx_json][jss::Fee] = 
to_string(env.current()->fees().base);
 
  938            auto const jrr = env.rpc(
"json", 
"submit", 
to_string(jv));
 
  939            BEAST_EXPECT(jrr[jss::result][jss::engine_result] == 
"temDISABLED");
 
  944            Env env{*
this, features};
 
  946            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
  948            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
  949            auto const MPT = mptAlice[
"MPT"];
 
  951            mptAlice.authorize({.account = bob});
 
  954                env(
pay(alice, bob, 
MPT(10)),
 
  961            Env env{*
this, features};
 
  965            MPTTester mptAlice(env, alice, {.holders = {carol}});
 
  967            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
  969            mptAlice.authorize({.account = carol});
 
  973            auto const MPT = mptAlice[
"MPT"];
 
  974            env(
pay(alice, carol, 
MPT(100)),
 
  977            env(
pay(alice, carol, 
MPT(100)),
 
  981            auto const USD = alice[
"USD"];
 
  982            env(
pay(alice, carol, USD(100)),
 
  985            env(
pay(alice, carol, 
XRP(100)),
 
  988            env(
pay(alice, carol, USD(100)),
 
  991            env(
pay(alice, carol, 
XRP(100)),
 
  996                "MPT", 
makeMptID(env.seq(alice) + 10, alice));
 
  997            env(
pay(alice, carol, MPT1(100)),
 
 1006            Env env{*
this, features};
 
 1010            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1012            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1013            auto const MPT = mptAlice[
"MPT"];
 
 1015            mptAlice.authorize({.account = carol});
 
 1018            payment[jss::secret] = alice.
name();
 
 1019            payment[jss::tx_json] = 
pay(alice, carol, 
MPT(100));
 
 1021            payment[jss::build_path] = 
true;
 
 1022            auto jrr = env.rpc(
"json", 
"submit", 
to_string(payment));
 
 1023            BEAST_EXPECT(jrr[jss::result][jss::error] == 
"invalidParams");
 
 1025                jrr[jss::result][jss::error_message] ==
 
 1026                "Field 'build_path' not allowed in this context.");
 
 1031            Env env{*
this, features};
 
 1033            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1035            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1036            auto const MPT = mptAlice[
"MPT"];
 
 1038            mptAlice.authorize({.account = bob});
 
 1039            mptAlice.authorize({.account = carol});
 
 1052            Env env{*
this, features};
 
 1054            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1056            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1058            mptAlice.authorize({.account = bob});
 
 1067            Env env{*
this, features};
 
 1069            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1071            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1073            mptAlice.authorize({.account = bob});
 
 1086            Env env{*
this, features};
 
 1088            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1095            mptAlice.authorize({.account = bob});
 
 1103            Env env{*
this, features};
 
 1105            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1113            mptAlice.authorize({.account = bob});
 
 1116            mptAlice.authorize({.account = alice, .holder = bob});
 
 1119            mptAlice.pay(alice, bob, 100);
 
 1130        if (features[featureSingleAssetVault] &&
 
 1131            features[featurePermissionedDomains])
 
 1135                Env env{*
this, features};
 
 1137                Account const credIssuer1{
"credIssuer1"};
 
 1138                env.fund(
XRP(1000), credIssuer1, bob);
 
 1140                auto const domainId1 = [&]() {
 
 1142                        {.issuer = credIssuer1, .credType = credType}};
 
 1162                    .domainID = domainId1,
 
 1165                mptAlice.authorize({.account = bob});
 
 1169                mptAlice.pay(alice, bob, 100);
 
 1170                mptAlice.set({.domainID = beast::zero});
 
 1177                Env env{*
this, features};
 
 1179                Account const credIssuer1{
"credIssuer1"};
 
 1180                env.fund(
XRP(1000), credIssuer1, bob);
 
 1182                auto const domainId1 = [&]() {
 
 1184                        {.issuer = credIssuer1, .credType = credType}};
 
 1204                    .domainID = domainId1,
 
 1208                mptAlice.authorize({.account = bob});
 
 1211                mptAlice.authorize({.account = alice, .holder = bob});
 
 1214                mptAlice.pay(alice, bob, 100);
 
 1223                mptAlice.pay(bob, alice, 10);
 
 1225                mptAlice.set({.domainID = beast::zero});
 
 1233                Env env{*
this, features};
 
 1236                Account const credIssuer1{
"credIssuer1"};
 
 1239                Account const credIssuer2{
"credIssuer2"};
 
 1240                env.fund(
XRP(1000), credIssuer1, credIssuer2, bob, carol);
 
 1242                auto const domainId1 = [&]() {
 
 1244                        {.issuer = credIssuer1, .credType = credType}};
 
 1253                auto const domainId2 = [&]() {
 
 1255                        {.issuer = credIssuer1, .credType = credType},
 
 1256                        {.issuer = credIssuer2, .credType = credType}};
 
 1284                    .domainID = domainId1,
 
 1288                mptAlice.authorize({.account = bob});
 
 1289                mptAlice.authorize({.account = carol});
 
 1293                mptAlice.pay(alice, bob, 50);
 
 1304                mptAlice.set({.domainID = domainId2});
 
 1306                mptAlice.pay(alice, carol, 10);
 
 1311                mptAlice.pay(bob, carol, 10);
 
 1316                    credIssuer1, bob, credIssuer1, credType));
 
 1326            Env env(*
this, features);
 
 1331            MPTTester mptAlice(env, alice, {.holders = {bob, cindy}});
 
 1334            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1337            mptAlice.authorize({.account = bob});
 
 1340            mptAlice.authorize({.account = cindy});
 
 1343            mptAlice.pay(alice, bob, 100);
 
 1350            mptAlice.pay(bob, alice, 10);
 
 1355            Env env{*
this, features};
 
 1357            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1374            Env env{*
this, features};
 
 1376            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1380            mptAlice.authorize({.account = bob});
 
 1381            mptAlice.authorize({.account = carol});
 
 1383            mptAlice.pay(alice, bob, 100);
 
 1394            Env env{*
this, features};
 
 1396            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1401            mptAlice.authorize({.account = bob});
 
 1402            mptAlice.authorize({.account = carol});
 
 1404            mptAlice.pay(alice, bob, 100);
 
 1405            mptAlice.pay(alice, carol, 100);
 
 1408            mptAlice.set({.account = alice, .flags = 
tfMPTLock});
 
 1413            mptAlice.pay(alice, bob, 3);
 
 1415            mptAlice.pay(bob, alice, 4);
 
 1418            mptAlice.set({.account = alice, .flags = 
tfMPTUnlock});
 
 1420            mptAlice.set({.account = alice, .holder = bob, .flags = 
tfMPTLock});
 
 1425            mptAlice.pay(alice, bob, 7);
 
 1427            mptAlice.pay(bob, alice, 8);
 
 1432            Env env{*
this, features};
 
 1434            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1438                {.transferFee = 10'000,
 
 1444            mptAlice.authorize({.account = bob});
 
 1445            mptAlice.authorize({.account = carol});
 
 1448            mptAlice.pay(alice, bob, 2'000);
 
 1451            mptAlice.pay(bob, alice, 1'000);
 
 1452            BEAST_EXPECT(mptAlice.checkMPTokenAmount(bob, 1'000));
 
 1462            auto const MPT = mptAlice[
"MPT"];
 
 1464            env(
pay(bob, carol, 
MPT(100)),
 
 1473            BEAST_EXPECT(mptAlice.checkMPTokenAmount(bob, 780));
 
 1474            BEAST_EXPECT(mptAlice.checkMPTokenAmount(carol, 200));
 
 1477            env(
pay(bob, carol, 
MPT(100)),
 
 1482            BEAST_EXPECT(mptAlice.checkMPTokenAmount(bob, 690));
 
 1483            BEAST_EXPECT(mptAlice.checkMPTokenAmount(carol, 282));
 
 1488            Env env{*
this, features};
 
 1490            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1496            mptAlice.authorize({.account = bob});
 
 1497            mptAlice.authorize({.account = carol});
 
 1498            mptAlice.pay(alice, bob, 1'000);
 
 1500            auto const MPT = mptAlice[
"MPT"];
 
 1502            env(
pay(bob, carol, 
MPT(100)),
 
 1505            env(
pay(bob, alice, 
MPT(100)),
 
 1511            BEAST_EXPECT(mptAlice.checkMPTokenAmount(carol, 100));
 
 1513            env(
pay(bob, carol, 
MPT(100)),
 
 1516            BEAST_EXPECT(mptAlice.checkMPTokenAmount(carol, 199));
 
 1521            Env env{*
this, features};
 
 1523            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1529            mptAlice.authorize({.account = bob});
 
 1530            mptAlice.authorize({.account = carol});
 
 1531            mptAlice.pay(alice, bob, 1'000);
 
 1533            auto const MPT = mptAlice[
"MPT"];
 
 1536            env(
pay(bob, alice, 
MPT(100)),
 
 1542            env(
pay(bob, alice, 
MPT(100)),
 
 1550            Env env{*
this, features};
 
 1552            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1560            mptAlice.authorize({.account = bob});
 
 1563            mptAlice.pay(alice, bob, 100);
 
 1572            Env env{*
this, features};
 
 1574            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1576            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1578            mptAlice.authorize({.account = bob});
 
 1590            Env env{*
this, features};
 
 1591            env.fund(
XRP(1'000), alice, bob);
 
 1594            jv[jss::secret] = alice.
name();
 
 1595            jv[jss::tx_json] = 
pay(alice, bob, mpt);
 
 1596            jv[jss::tx_json][jss::Amount][jss::value] =
 
 1598            auto const jrr = env.rpc(
"json", 
"submit", 
to_string(jv));
 
 1599            BEAST_EXPECT(jrr[jss::result][jss::error] == 
"invalidParams");
 
 1605            Env env{*
this, features};
 
 1607            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1615            auto const MPT = mptAlice[
"MPT"];
 
 1617            mptAlice.authorize({.account = bob});
 
 1618            mptAlice.authorize({.account = carol});
 
 1621            mptAlice.pay(alice, bob, 10'000);
 
 1624            env(
pay(bob, carol, 
MPT(10'000)),
 
 1628            auto const meta = env.meta()->getJson(
 
 1632                meta[0u][sfModifiedNode.fieldName][sfFinalFields.fieldName]
 
 1633                    [sfOutstandingAmount.fieldName] == 
"9990");
 
 1636                meta[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName]
 
 1637                    [sfMPTAmount.fieldName] == 
"9990");
 
 1640                meta[2u][sfModifiedNode.fieldName][sfPreviousFields.fieldName]
 
 1641                    [sfMPTAmount.fieldName] == 
"10000");
 
 1643                !meta[2u][sfModifiedNode.fieldName][sfFinalFields.fieldName]
 
 1644                     .isMember(sfMPTAmount.fieldName));
 
 1648            env(
pay(bob, carol, 
MPT(10'000)),
 
 1655            Env env{*
this, features};
 
 1657            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1664            auto const MPT = mptAlice[
"MPT"];
 
 1666            mptAlice.authorize({.account = bob});
 
 1667            mptAlice.authorize({.account = carol});
 
 1680            BEAST_EXPECT(mptAlice.checkMPTokenOutstandingAmount(0));
 
 1685            Env env{*
this, features};
 
 1687            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1689            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1691            mptAlice.authorize({.account = bob});
 
 1694            mptAlice.destroy({.ownerCount = 0});
 
 1703            Env env{*
this, features};
 
 1705            env.fund(
XRP(1'000), alice, bob);
 
 1714            Env env{*
this, features};
 
 1716            MPTTester mptAlice(env, alice, {.holders = {bob}});
 
 1718            mptAlice.
create({.ownerCount = 1, .holderCount = 0});
 
 1721            mptAlice.destroy({.ownerCount = 0});
 
 1731            Env env{*
this, features};
 
 1736            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1741            mptAlice.authorize({.account = bob});
 
 1742            mptAlice.authorize({.account = carol});
 
 1744            mptAlice.pay(alice, bob, 100);
 
 1747            mptAlice.pay(bob, carol, 100);
 
 1752            Env env{*
this, features};
 
 1754            MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
 
 1759            mptAlice.authorize({.account = bob});
 
 1760            mptAlice.authorize({.account = carol});
 
 1763            mptAlice.pay(alice, bob, 100);
 
 1766            mptAlice.pay(bob, alice, 100);
 
 1769            mptAlice.pay(alice, bob, 100);
 
 1770            mptAlice.pay(bob, carol, 50);
 
 
 1929        testcase(
"MPT Issue Invalid in Transaction");
 
 1930        using namespace test::jtx;
 
 1939            for (
auto const& e : format.getSOTemplate())
 
 1945                    e.sField().getName() != jss::Fee &&
 
 1946                    format.getName() != jss::SetFee)
 
 1949                        format.getName() + e.sField().fieldName);
 
 1956        auto const USD = alice[
"USD"];
 
 1959        STAmount mpt{issue, UINT64_C(100)};
 
 1960        auto const jvb = 
bridge(alice, USD, alice, USD);
 
 1961        for (
auto const& feature : {features, features - featureMPTokensV1})
 
 1963            Env env{*
this, feature};
 
 1964            env.fund(
XRP(1'000), alice);
 
 1965            env.fund(
XRP(1'000), carol);
 
 1968                txWithAmounts.
erase(
 
 1969                    jv[jss::TransactionType].asString() + mptField);
 
 1972                auto jtx = env.jt(jv);
 
 1977                    jrr[jss::result][jss::error] == 
"invalidTransaction");
 
 1981                jv1[jss::secret] = alice.
name();
 
 1982                jv1[jss::tx_json] = jv;
 
 1983                jrr = env.rpc(
"json", 
"submit", 
to_string(jv1));
 
 1984                BEAST_EXPECT(jrr[jss::result][jss::error] == 
"invalidParams");
 
 1986                jrr = env.rpc(
"json", 
"sign", 
to_string(jv1));
 
 1987                BEAST_EXPECT(jrr[jss::result][jss::error] == 
"invalidParams");
 
 1989            auto toSFieldRef = [](
SField const& field) {
 
 1992            auto setMPTFields = [&](
SField const& field,
 
 1994                                    bool withAmount = 
true) {
 
 1996                jv[jss::Asset2] = 
to_json(USD.issue());
 
 1998                    jv[field.fieldName] =
 
 2000                if (field == sfAsset)
 
 2002                else if (field == sfAsset2)
 
 2012            auto ammCreate = [&](
SField const& field) {
 
 2014                jv[jss::TransactionType] = jss::AMMCreate;
 
 2015                jv[jss::Account] = alice.
human();
 
 2016                jv[jss::Amount] = (field.fieldName == sfAmount.fieldName)
 
 2019                jv[jss::Amount2] = (field.fieldName == sfAmount2.fieldName)
 
 2022                jv[jss::TradingFee] = 0;
 
 2023                test(jv, field.fieldName);
 
 2025            ammCreate(sfAmount);
 
 2026            ammCreate(sfAmount2);
 
 2028            auto ammDeposit = [&](
SField const& field) {
 
 2030                jv[jss::TransactionType] = jss::AMMDeposit;
 
 2031                jv[jss::Account] = alice.
human();
 
 2033                setMPTFields(field, jv);
 
 2034                test(jv, field.fieldName);
 
 2036            for (
SField const& field :
 
 2037                 {toSFieldRef(sfAmount),
 
 2038                  toSFieldRef(sfAmount2),
 
 2039                  toSFieldRef(sfEPrice),
 
 2040                  toSFieldRef(sfLPTokenOut),
 
 2041                  toSFieldRef(sfAsset),
 
 2042                  toSFieldRef(sfAsset2)})
 
 2045            auto ammWithdraw = [&](
SField const& field) {
 
 2047                jv[jss::TransactionType] = jss::AMMWithdraw;
 
 2048                jv[jss::Account] = alice.
human();
 
 2050                setMPTFields(field, jv);
 
 2051                test(jv, field.fieldName);
 
 2053            ammWithdraw(sfAmount);
 
 2054            for (
SField const& field :
 
 2055                 {toSFieldRef(sfAmount2),
 
 2056                  toSFieldRef(sfEPrice),
 
 2057                  toSFieldRef(sfLPTokenIn),
 
 2058                  toSFieldRef(sfAsset),
 
 2059                  toSFieldRef(sfAsset2)})
 
 2062            auto ammBid = [&](
SField const& field) {
 
 2064                jv[jss::TransactionType] = jss::AMMBid;
 
 2065                jv[jss::Account] = alice.
human();
 
 2066                setMPTFields(field, jv);
 
 2067                test(jv, field.fieldName);
 
 2069            for (
SField const& field :
 
 2070                 {toSFieldRef(sfBidMin),
 
 2071                  toSFieldRef(sfBidMax),
 
 2072                  toSFieldRef(sfAsset),
 
 2073                  toSFieldRef(sfAsset2)})
 
 2076            auto ammClawback = [&](
SField const& field) {
 
 2078                jv[jss::TransactionType] = jss::AMMClawback;
 
 2079                jv[jss::Account] = alice.
human();
 
 2080                jv[jss::Holder] = carol.
human();
 
 2081                setMPTFields(field, jv);
 
 2082                test(jv, field.fieldName);
 
 2084            for (
SField const& field :
 
 2085                 {toSFieldRef(sfAmount),
 
 2086                  toSFieldRef(sfAsset),
 
 2087                  toSFieldRef(sfAsset2)})
 
 2090            auto ammDelete = [&](
SField const& field) {
 
 2092                jv[jss::TransactionType] = jss::AMMDelete;
 
 2093                jv[jss::Account] = alice.
human();
 
 2094                setMPTFields(field, jv, 
false);
 
 2095                test(jv, field.fieldName);
 
 2098            ammDelete(sfAsset2);
 
 2100            auto ammVote = [&](
SField const& field) {
 
 2102                jv[jss::TransactionType] = jss::AMMVote;
 
 2103                jv[jss::Account] = alice.
human();
 
 2104                jv[jss::TradingFee] = 100;
 
 2105                setMPTFields(field, jv, 
false);
 
 2106                test(jv, field.fieldName);
 
 2111            auto checkCash = [&](
SField const& field) {
 
 2113                jv[jss::TransactionType] = jss::CheckCash;
 
 2114                jv[jss::Account] = alice.
human();
 
 2117                test(jv, field.fieldName);
 
 2119            checkCash(sfAmount);
 
 2120            checkCash(sfDeliverMin);
 
 2124                jv[jss::TransactionType] = jss::CheckCreate;
 
 2125                jv[jss::Account] = alice.
human();
 
 2126                jv[jss::Destination] = carol.
human();
 
 2128                test(jv, jss::SendMax.c_str());
 
 2133                test(jv, jss::TakerPays.c_str());
 
 2134                jv = 
offer(alice, mpt, USD(100));
 
 2135                test(jv, jss::TakerGets.c_str());
 
 2140                jv[jss::TransactionType] = jss::PaymentChannelCreate;
 
 2141                jv[jss::Account] = alice.
human();
 
 2142                jv[jss::Destination] = carol.
human();
 
 2143                jv[jss::SettleDelay] = 1;
 
 2146                test(jv, jss::Amount.c_str());
 
 2151                jv[jss::TransactionType] = jss::PaymentChannelFund;
 
 2152                jv[jss::Account] = alice.
human();
 
 2155                test(jv, jss::Amount.c_str());
 
 2160                jv[jss::TransactionType] = jss::PaymentChannelClaim;
 
 2161                jv[jss::Account] = alice.
human();
 
 2164                test(jv, jss::Amount.c_str());
 
 2169                jv[jss::TransactionType] = jss::NFTokenCreateOffer;
 
 2170                jv[jss::Account] = alice.
human();
 
 2173                test(jv, jss::Amount.c_str());
 
 2178                jv[jss::TransactionType] = jss::NFTokenAcceptOffer;
 
 2179                jv[jss::Account] = alice.
human();
 
 2180                jv[sfNFTokenBrokerFee.fieldName] =
 
 2182                test(jv, sfNFTokenBrokerFee.fieldName);
 
 2187                jv[jss::TransactionType] = jss::NFTokenMint;
 
 2188                jv[jss::Account] = alice.
human();
 
 2189                jv[sfNFTokenTaxon.fieldName] = 1;
 
 2191                test(jv, jss::Amount.c_str());
 
 2194            auto trustSet = [&](
SField const& field) {
 
 2196                jv[jss::TransactionType] = jss::TrustSet;
 
 2197                jv[jss::Account] = alice.
human();
 
 2200                test(jv, field.fieldName);
 
 2202            trustSet(sfLimitAmount);
 
 2207                test(jv, jss::Amount.c_str());
 
 2212                test(jv, jss::Amount.c_str());
 
 2218                test(jv, sfSignatureReward.fieldName);
 
 2232                test(jv, jss::Amount.c_str());
 
 2247                for (
auto const& field :
 
 2248                     {sfAmount.fieldName, sfSignatureReward.fieldName})
 
 2257                    alice, jvb, alice, mpt, 
XRP(10));
 
 2258                for (
auto const& field :
 
 2259                     {sfAmount.fieldName, sfSignatureReward.fieldName})
 
 2271                jv[jss::TransactionType] = tt;
 
 2272                jv[jss::Account] = alice.
human();
 
 2273                jv[sfXChainBridge.fieldName] = jvb;
 
 2274                jv[sfSignatureReward.fieldName] =
 
 2276                jv[sfMinAccountCreateAmount.fieldName] =
 
 2280            auto reward = 
STAmount{sfSignatureReward, mpt};
 
 2281            auto minAmount = 
STAmount{sfMinAccountCreateAmount, USD(10)};
 
 2282            for (
SField const& field :
 
 2284                  std::ref(sfMinAccountCreateAmount)})
 
 2287                    jss::XChainCreateBridge,
 
 2292                    jss::XChainModifyBridge,
 
 2296                reward = 
STAmount{sfSignatureReward, USD(10)};
 
 2297                minAmount = 
STAmount{sfMinAccountCreateAmount, mpt};
 
 2300        BEAST_EXPECT(txWithAmounts.
empty());