Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
060b6d3
Revert "Remove the shortage code completely"
ximinez Nov 5, 2025
0008e2d
Revert "Partially revert aed8e2b166 Fill in payment computation short…
ximinez Nov 5, 2025
fe8d931
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 12, 2025
b44859f
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 13, 2025
5a3df22
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 13, 2025
c8394eb
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 13, 2025
4719e05
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 13, 2025
5e860ec
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 15, 2025
27af46b
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 19, 2025
11479cd
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 21, 2025
3249461
Merge remote-tracking branch 'XRPLF/ximinez/lending-XLS-66' into ximi…
ximinez Nov 25, 2025
4760885
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 25, 2025
c58f5ab
Merge remote-tracking branch 'XRPLF/ximinez/lending-XLS-66' into ximi…
ximinez Nov 26, 2025
3b1bc3d
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Nov 28, 2025
0749732
Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2
ximinez Dec 1, 2025
19c72b3
Merge branch 'develop' into ximinez/lending-XLS-66
ximinez Dec 1, 2025
b9ca539
Merge branch 'ximinez/lending-XLS-66' into ximinez/lending-shortages
ximinez Dec 1, 2025
f447827
Fix overpayment asserts (#6084)
Tapanito Dec 1, 2025
da9a483
Merge branch 'ximinez/develop-nolending' into ximinez/lending-XLS-66-2
ximinez Dec 1, 2025
abff92d
Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-shortages
ximinez Dec 1, 2025
aa12341
Review feedback from @dangell7: early return & coverage
ximinez Dec 1, 2025
1f3ded7
Test updates - show balances in runLoan()
ximinez Dec 2, 2025
8e4be94
Merge remote-tracking branch 'XRPLF/ximinez/develop-nolending' into x…
ximinez Dec 2, 2025
bb5585e
Merge branch 'ximinez/lending-XLS-66-2' into ximinez/lending-shortages
ximinez Dec 2, 2025
89d1744
Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-sh…
ximinez Dec 3, 2025
5aab5de
Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-sh…
ximinez Dec 6, 2025
3d41fab
Merge branch 'ximinez/lending-XLS-66-ongoing' into ximinez/lending-sh…
ximinez Dec 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/test/app/Loan_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2738,8 +2738,12 @@ class Loan_test : public beast::unit_test::suite
broker.params.managementFeeRate);

BEAST_EXPECT(
paymentComponents.trackedValueDelta <=
roundedPeriodicPayment);
paymentComponents.trackedValueDelta ==
roundedPeriodicPayment ||
(paymentComponents.specialCase ==
detail::PaymentSpecialCase::final &&
paymentComponents.trackedValueDelta <
roundedPeriodicPayment));

ripple::LoanState const nextTrueState = computeRawLoanState(
state.periodicPayment,
Expand Down
6 changes: 3 additions & 3 deletions src/test/rpc/Feature_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ class Feature_test : public beast::unit_test::suite
BEAST_EXPECTS(jrr[jss::status] == jss::success, "status");
jrr.removeMember(jss::status);
BEAST_EXPECT(jrr.size() == 1);
BEAST_EXPECT(
jrr.isMember("12523DF04B553A0B1AD74F42DDB741DE8DC06A03FC089A0EF197E"
"2A87F1D8107"));
BEAST_EXPECT(jrr.isMember(
"740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D6"
"28A06927F11"));
auto feature = *(jrr.begin());

BEAST_EXPECTS(feature[jss::name] == "fixAMMOverflowOffer", "name");
Expand Down
41 changes: 39 additions & 2 deletions src/xrpld/app/misc/detail/LendingHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,23 @@ computePaymentComponents(
"ripple::detail::computePaymentComponents",
"excess non-negative");
};
auto giveTo =
[](Number& component, Number& shortage, Number const& maximum) {
if (shortage > beast::zero)
{
// Put as much of the shortage as we can into the provided part
// and the total
auto part = std::min(maximum - component, shortage);
component += part;
shortage -= part;
}
// If the shortage goes negative, we put too much, which should be
// impossible
XRPL_ASSERT_PARTS(
shortage >= beast::zero,
"ripple::detail::computePaymentComponents",
"excess non-negative");
};
// Helper to reduce deltas when they collectively exceed a limit.
// Order matters: we prefer to reduce interest first (most flexible),
// then management fee, then principal (least flexible).
Expand All @@ -1084,6 +1101,19 @@ computePaymentComponents(
takeFrom(deltas.managementFee, excess);
takeFrom(deltas.principal, excess);
};
// Helper to increase deltas when they collectively do not reach an
// expected value.
// Order matters: we prefer to increase interest first (most flexible),
// then management fee, then principal (least flexible).
auto addressShortage = [&giveTo](
LoanDeltas& deltas,
Number& shortage,
LoanState const& current) {
giveTo(deltas.interestDueDelta, shortage, current.interestDue);
giveTo(
deltas.managementFeeDueDelta, shortage, current.managementFeeDue);
giveTo(deltas.principalDelta, shortage, current.principalOutstanding);
};

// Check if deltas exceed the total outstanding value. This should never
// happen due to earlier caps, but handle it defensively.
Expand Down Expand Up @@ -1115,12 +1145,19 @@ computePaymentComponents(
addressExcess(deltas, excess);
shortage = -excess;
}
else if (shortage > beast::zero && totalOverpayment < beast::zero)
{
// If there's a shortage, and there's room in the loan itself, we can
// top up the parts to make the payment correct.
shortage = std::min(-totalOverpayment, shortage);
addressShortage(deltas, shortage, currentLedgerState);
}

// At this point, shortage >= 0 means we're paying less than the full
// periodic payment (due to rounding or component caps).
// shortage < 0 would mean we're trying to pay more than allowed (bug).
// shortage < 0 means mean we're trying to pay more than allowed (bug).
XRPL_ASSERT_PARTS(
shortage >= beast::zero,
shortage == beast::zero,
"ripple::detail::computePaymentComponents",
"no shortage or excess");

Expand Down
Loading