mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 15:05:53 +00:00
Fix RIPD-3901 - faulty assert
- Assert requires that an overpayment reduces the value of a loan. If the overall loan interest is low enough, it could leave it unchanged. Update the assert to require that the overpayment does not increase the value of the loan. - Adds a unit test provided by @gregtatcam to demonstrate this issue.
This commit is contained in:
@@ -6437,6 +6437,67 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testRIPD3901()
|
||||
{
|
||||
testcase("Crash with tfLoanOverpayment");
|
||||
using namespace jtx;
|
||||
using namespace loan;
|
||||
Account const lender{"lender"};
|
||||
Account const issuer{"issuer"};
|
||||
Account const borrower{"borrower"};
|
||||
Account const depositor{"depositor"};
|
||||
auto const txfee = fee(XRP(100));
|
||||
|
||||
Env env(*this);
|
||||
Vault vault(env);
|
||||
|
||||
env.fund(XRP(10'000), lender, issuer, borrower, depositor);
|
||||
env.close();
|
||||
|
||||
auto [tx, vaultKeyLet] =
|
||||
vault.create({.owner = lender, .asset = xrpIssue()});
|
||||
env(tx, txfee);
|
||||
env.close();
|
||||
|
||||
env(vault.deposit(
|
||||
{.depositor = depositor,
|
||||
.id = vaultKeyLet.key,
|
||||
.amount = XRP(1'000)}),
|
||||
txfee);
|
||||
env.close();
|
||||
|
||||
auto const brokerKeyLet =
|
||||
keylet::loanbroker(lender.id(), env.seq(lender));
|
||||
|
||||
env(loanBroker::set(lender, vaultKeyLet.key), txfee);
|
||||
env.close();
|
||||
|
||||
// BrokerInfo brokerInfo{xrpIssue(), keylet, vaultKeyLet, {}};
|
||||
|
||||
STAmount const debtMaximumRequest = XRPAmount(200'000);
|
||||
|
||||
env(set(borrower, brokerKeyLet.key, debtMaximumRequest),
|
||||
sig(sfCounterpartySignature, lender),
|
||||
interestRate(TenthBips32(50'000)),
|
||||
paymentTotal(2),
|
||||
paymentInterval(150),
|
||||
txflags(tfLoanOverpayment),
|
||||
txfee);
|
||||
env.close();
|
||||
|
||||
std::uint32_t const loanSequence = 1;
|
||||
auto const loanKeylet = keylet::loan(brokerKeyLet.key, loanSequence);
|
||||
|
||||
if (auto loan = env.le(loanKeylet); env.test.BEAST_EXPECT(loan))
|
||||
{
|
||||
env(loan::pay(borrower, loanKeylet.key, XRPAmount(150'001)),
|
||||
txflags(tfLoanOverpayment),
|
||||
txfee);
|
||||
env.close();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
@@ -6479,6 +6540,7 @@ public:
|
||||
|
||||
testRIPD3831();
|
||||
testRIPD3459();
|
||||
testRIPD3901();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -663,9 +663,9 @@ tryOverpayment(
|
||||
auto const valueChange =
|
||||
newRounded.interestOutstanding() - rounded.interestOutstanding();
|
||||
XRPL_ASSERT_PARTS(
|
||||
valueChange < beast::zero,
|
||||
valueChange <= beast::zero,
|
||||
"ripple::detail::tryOverpayment",
|
||||
"principal overpayment reduced value of loan");
|
||||
"principal overpayment did not increase value of loan");
|
||||
|
||||
return LoanPaymentParts{
|
||||
.principalPaid =
|
||||
|
||||
@@ -332,7 +332,7 @@ LoanPay::doApply()
|
||||
// It should not be possible to pay 0 total
|
||||
paymentParts->principalPaid + paymentParts->interestPaid > 0,
|
||||
"ripple::LoanPay::doApply",
|
||||
"valid principal paid");
|
||||
"valid total paid");
|
||||
XRPL_ASSERT_PARTS(
|
||||
paymentParts->feePaid >= 0,
|
||||
"ripple::LoanPay::doApply",
|
||||
|
||||
Reference in New Issue
Block a user