Fix LoanBrokerSet debtMaximum limits (#6116)

This commit is contained in:
Vito Tumas
2025-12-16 19:19:27 +01:00
committed by GitHub
parent f7a5f35d0e
commit 40c29bbfd6
2 changed files with 85 additions and 0 deletions

View File

@@ -1436,10 +1436,83 @@ class LoanBroker_test : public beast::unit_test::suite
});
}
void
testLoanBrokerSetDebtMaximum()
{
testcase("testLoanBrokerSetDebtMaximum");
using namespace jtx;
using namespace loanBroker;
Account const issuer{"issuer"};
Account const alice{"alice"};
Env env(*this);
Vault vault{env};
env.fund(XRP(100'000), issuer, alice);
env.close();
PrettyAsset const asset = [&]() {
env(trust(alice, issuer["IOU"](1'000'000)), THISLINE);
env.close();
return PrettyAsset(issuer["IOU"]);
}();
env(pay(issuer, alice, asset(100'000)), THISLINE);
env.close();
auto [tx, vaultKeylet] = vault.create({.owner = alice, .asset = asset});
env(tx, THISLINE);
env.close();
auto const le = env.le(vaultKeylet);
VaultInfo vaultInfo = [&]() {
if (BEAST_EXPECT(le))
return VaultInfo{asset, vaultKeylet.key, le->at(sfAccount)};
return VaultInfo{asset, {}, {}};
}();
if (vaultInfo.vaultID == uint256{})
return;
env(vault.deposit(
{.depositor = alice,
.id = vaultKeylet.key,
.amount = asset(50)}),
THISLINE);
env.close();
auto const brokerKeylet =
keylet::loanbroker(alice.id(), env.seq(alice));
env(set(alice, vaultInfo.vaultID), THISLINE);
env.close();
Account const borrower{"borrower"};
env.fund(XRP(1'000), borrower);
env(loan::set(borrower, brokerKeylet.key, asset(50).value()),
sig(sfCounterpartySignature, alice),
fee(env.current()->fees().base * 2),
THISLINE);
auto const broker = env.le(brokerKeylet);
if (!BEAST_EXPECT(broker))
return;
BEAST_EXPECT(broker->at(sfDebtTotal) == 50);
auto debtTotal = broker->at(sfDebtTotal);
auto tx2 = set(alice, vaultInfo.vaultID);
tx2[sfLoanBrokerID] = to_string(brokerKeylet.key);
tx2[sfDebtMaximum] = debtTotal - 1;
env(tx2, ter(tecLIMIT_EXCEEDED), THISLINE);
tx2[sfDebtMaximum] = debtTotal + 1;
env(tx2, ter(tesSUCCESS), THISLINE);
tx2[sfDebtMaximum] = 0;
env(tx2, ter(tesSUCCESS), THISLINE);
}
public:
void
run() override
{
testLoanBrokerSetDebtMaximum();
testLoanBrokerCoverDepositNullVault();
testDisabled();

View File

@@ -89,6 +89,18 @@ LoanBrokerSet::preclaim(PreclaimContext const& ctx)
JLOG(ctx.j.warn()) << "Account is not the owner of the LoanBroker.";
return tecNO_PERMISSION;
}
if (auto const debtMax = tx[~sfDebtMaximum])
{
// Can't reduce the debt maximum below the current total debt
auto const currentDebtTotal = sleBroker->at(sfDebtTotal);
if (*debtMax != 0 && *debtMax < currentDebtTotal)
{
JLOG(ctx.j.warn())
<< "Cannot reduce DebtMaximum below current DebtTotal.";
return tecLIMIT_EXCEEDED;
}
}
}
else
{