diff --git a/src/ripple/app/tx/impl/MPTokenIssuanceCreate.cpp b/src/ripple/app/tx/impl/MPTokenIssuanceCreate.cpp index 5a8abf34f19..8711ee4514a 100644 --- a/src/ripple/app/tx/impl/MPTokenIssuanceCreate.cpp +++ b/src/ripple/app/tx/impl/MPTokenIssuanceCreate.cpp @@ -55,8 +55,16 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - // TODO: check if maximumAmount is within 63 bit range - + // Check if maximumAmount is within 63 bit range + if (auto const maxAmt = ctx.tx[~sfMaximumAmount]) + { + if (maxAmt == 0) + return temMALFORMED; + + // TODO: Improve this check and move the constant elsewhere (STAmount?) + if (maxAmt > 0x7FFFFFFFFFFFFFFFull) + return temMALFORMED; + } return preflight2(ctx); } diff --git a/src/test/app/MPToken_test.cpp b/src/test/app/MPToken_test.cpp index f5c3a492d4a..48cf5666fa8 100644 --- a/src/test/app/MPToken_test.cpp +++ b/src/test/app/MPToken_test.cpp @@ -123,6 +123,14 @@ class MPToken_test : public beast::unit_test::suite // empty metadata returns error env(mpt::create(alice, 100, 0, 0, ""), ter(temMALFORMED)); env.close(); + + // MaximumAmout of 0 returns error + env(mpt::create(alice, 0, 1, 1, "test"), ter(temMALFORMED)); + env.close(); + + // MaximumAmount larger than 63 bit returns errpr + env(mpt::create(alice, 0xFFFFFFFFFFFFFFF0ull, 0, 0, "test"), ter(temMALFORMED)); + env.close(); } } diff --git a/src/test/jtx/impl/mpt.cpp b/src/test/jtx/impl/mpt.cpp index 5426dae4369..cf40aed1c98 100644 --- a/src/test/jtx/impl/mpt.cpp +++ b/src/test/jtx/impl/mpt.cpp @@ -27,6 +27,13 @@ namespace jtx { namespace mpt { +static std::array +uint64ToByteArray(std::uint64_t value) { + std::array result; + std::memcpy(result.data(), &value, sizeof(value)); + return result; +} + Json::Value create(jtx::Account const& account) { @@ -39,7 +46,7 @@ create(jtx::Account const& account) Json::Value create( jtx::Account const& account, - std::uint32_t const maxAmt, + std::uint64_t const maxAmt, std::uint8_t const assetScale, std::uint16_t transferFee, std::string metadata) @@ -47,10 +54,12 @@ create( Json::Value jv; jv[sfAccount.jsonName] = account.human(); jv[sfTransactionType.jsonName] = jss::MPTokenIssuanceCreate; - jv[sfMaximumAmount.jsonName] = maxAmt; jv[sfAssetScale.jsonName] = assetScale; jv[sfTransferFee.jsonName] = transferFee; jv[sfMPTokenMetadata.jsonName] = strHex(metadata); + + // convert maxAmt to hex string, since json doesn't accept 64-bit int + jv[sfMaximumAmount.jsonName] = strHex(uint64ToByteArray(maxAmt)); return jv; } diff --git a/src/test/jtx/mpt.h b/src/test/jtx/mpt.h index 8b164f0dacb..7f77c89ca34 100644 --- a/src/test/jtx/mpt.h +++ b/src/test/jtx/mpt.h @@ -38,7 +38,7 @@ create(jtx::Account const& account); Json::Value create( jtx::Account const& account, - std::uint32_t const maxAmt, + std::uint64_t const maxAmt, std::uint8_t const assetScale, std::uint16_t transferFee, std::string metadata);