From f3677c9bed79f5942f47022e0049c304cb6bd201 Mon Sep 17 00:00:00 2001 From: Ed Hennis Date: Mon, 10 Nov 2025 15:32:32 -0500 Subject: [PATCH] fix: Check for empty or zero VaultID in LoanBrokerSet - Resolves RIPD-4067. --- src/test/app/LoanBroker_test.cpp | 17 +++++++++++++++++ src/xrpld/app/tx/detail/LoanBrokerSet.cpp | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/src/test/app/LoanBroker_test.cpp b/src/test/app/LoanBroker_test.cpp index ff70290331..aa5b5519b9 100644 --- a/src/test/app/LoanBroker_test.cpp +++ b/src/test/app/LoanBroker_test.cpp @@ -915,6 +915,17 @@ class LoanBroker_test : public beast::unit_test::suite // test env(jv, txflags(tfFullyCanonicalSig), ter(temINVALID)); }; + auto testZeroVaultID = [&](auto&& getTxJv) { + auto jv = getTxJv(); + // empty broker ID + jv[sfVaultID] = ""; + env(jv, ter(temINVALID)); + // zero broker ID + jv[sfVaultID] = to_string(uint256{}); + // needs a flag to distinguish the parsed STTx from the prior + // test + env(jv, txflags(tfFullyCanonicalSig), ter(temINVALID)); + }; if (brokerTest == CoverDeposit) { @@ -1058,6 +1069,12 @@ class LoanBroker_test : public beast::unit_test::suite set(alice, vaultInfo.vaultID), loanBrokerID(brokerKeylet.key)); }); + // preflight: temINVALID (empty/zero vault id) + testZeroVaultID([&]() { + return env.json( + set(alice, vaultInfo.vaultID), + loanBrokerID(brokerKeylet.key)); + }); if (asset.holds()) { diff --git a/src/xrpld/app/tx/detail/LoanBrokerSet.cpp b/src/xrpld/app/tx/detail/LoanBrokerSet.cpp index c9843d6c6e..c5b6891cb8 100644 --- a/src/xrpld/app/tx/detail/LoanBrokerSet.cpp +++ b/src/xrpld/app/tx/detail/LoanBrokerSet.cpp @@ -40,6 +40,12 @@ LoanBrokerSet::preflight(PreflightContext const& ctx) return temINVALID; } + if (auto const vaultID = tx.at(~sfVaultID)) + { + if (*vaultID == beast::zero) + return temINVALID; + } + { auto const minimumZero = tx[~sfCoverRateMinimum].value_or(0) == 0; auto const liquidationZero =