From f50d47ed8f1912aeab334b33f7a7c57c12420e6b Mon Sep 17 00:00:00 2001 From: Vito <5780819+Tapanito@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:05:13 +0100 Subject: [PATCH] adds deep freeze check to LoanBrokerDelete --- src/test/app/LoanBroker_test.cpp | 13 ++++++++++ src/xrpld/app/tx/detail/LoanBrokerDelete.cpp | 25 +++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/test/app/LoanBroker_test.cpp b/src/test/app/LoanBroker_test.cpp index aa5b5519b9..64c787c351 100644 --- a/src/test/app/LoanBroker_test.cpp +++ b/src/test/app/LoanBroker_test.cpp @@ -4,6 +4,8 @@ #include +#include "test/jtx/TestHelpers.h" + namespace ripple { namespace test { @@ -1057,6 +1059,17 @@ class LoanBroker_test : public beast::unit_test::suite // preclaim: tecHAS_OBLIGATIONS env(del(alice, brokerKeylet.key), ter(tecHAS_OBLIGATIONS)); + + // Repay and delete the loan + auto const loanKeylet = keylet::loan(brokerKeylet.key, 1); + env(loan::pay(borrower, loanKeylet.key, asset(50).value())); + env(loan::del(alice, loanKeylet.key)); + + env(trust(issuer, asset(0), alice, tfSetFreeze | tfSetDeepFreeze)); + // preclaim: tecFROZEN (deep frozen) + env(del(alice, brokerKeylet.key), ter(tecFROZEN)); + env(trust( + issuer, asset(0), alice, tfClearFreeze | tfClearDeepFreeze)); } else env(del(alice, brokerKeylet.key)); diff --git a/src/xrpld/app/tx/detail/LoanBrokerDelete.cpp b/src/xrpld/app/tx/detail/LoanBrokerDelete.cpp index bae806b45e..317f2c24fd 100644 --- a/src/xrpld/app/tx/detail/LoanBrokerDelete.cpp +++ b/src/xrpld/app/tx/detail/LoanBrokerDelete.cpp @@ -33,7 +33,10 @@ LoanBrokerDelete::preclaim(PreclaimContext const& ctx) JLOG(ctx.j.warn()) << "LoanBroker does not exist."; return tecNO_ENTRY; } - if (account != sleBroker->at(sfOwner)) + + auto const brokerOwner = sleBroker->at(sfOwner); + + if (account != brokerOwner) { JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker."; return tecNO_PERMISSION; @@ -44,6 +47,26 @@ LoanBrokerDelete::preclaim(PreclaimContext const& ctx) return tecHAS_OBLIGATIONS; } + auto const vault = ctx.view.read(keylet::vault(sleBroker->at(sfVaultID))); + if (!vault) + // Should be impossible + return tefBAD_LEDGER; // LCOV_EXCL_LINE + + Asset const asset = vault->at(sfAsset); + + auto const coverAvailable = + STAmount{asset, sleBroker->at(sfCoverAvailable)}; + // If there are assets in the cover, broker will receive them on deletion. + // So we need to check if the broker owner is deep frozen for that asset. + if (coverAvailable > beast::zero) + { + if (auto const ret = checkDeepFrozen(ctx.view, brokerOwner, asset)) + { + JLOG(ctx.j.warn()) << "Broker owner account is frozen."; + return ret; + } + } + return tesSUCCESS; }