Commit Graph

73 Commits

Author SHA1 Message Date
Ed Hennis
348e7f7cfc 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.
2025-11-12 18:42:03 -05:00
Ed Hennis
43174d31d1 Update the test case for RIPD-3459 with more detailed output data 2025-11-12 18:42:02 -05:00
Ed Hennis
4fbf687166 Add test case to reproduce RIPD-3459
- Improve a few loan test helper functions.
- Make Loan.GracePeriod a default field.
2025-11-12 18:42:02 -05:00
Ed Hennis
e485d5d6ad Add Grace Period to testLoanNextPaymentDueDateOverflow
- Demonstrates that Grace Period can overflow.
- Expected to fail.
2025-11-12 18:42:02 -05:00
Gregory Tsipenyuk
54d738b93e Implicitly authorize Vault and LoanBroker pseudo-accounts (#5976)
- Vault and LoanBroker pseudo-accounts can hold MPTs, regardless of MPTRequireAuth setting.
- Add requireAuth check in LoanBrokerCoverDeposit and LoanPay.
- Fail attempts to unauthorize pseudo-accounts by MPT issuers.
2025-11-12 18:42:02 -05:00
Ed Hennis
3fdd3cb495 Refactor loan test helpers into reusable functions
- Try to reproduce RIPD-3831
2025-11-12 18:42:02 -05:00
Gregory Tsipenyuk
2a9eec6c4f Fix empty/zero broker ID in LoanBrokerSet and LoanSet (#5977)
- Add checks for empty/zero brokerID where needed
- Extend unit-tests.
2025-11-12 18:42:02 -05:00
Ed Hennis
e001681ada fix: Improve rounding for IOU loans
- Scale the loan to the Vault, so that amounts moving to the vault are
  less likely to have rounding errors.
- Similar to LoanPay, when LoanManage defaults a loan, round the amounts
  to the Vault scale (because the Vault scale can change) before
  applying them to the Vault.
2025-11-12 18:05:59 -05:00
Ed Hennis
d2f8e3817e Another arbitrary test case to try 2025-11-12 18:05:59 -05:00
Ed Hennis
a38e09e327 Add testDustManipulation test, which is expected to fail 2025-11-12 18:05:59 -05:00
Ed Hennis
165478b929 Remove the shortage code completely 2025-11-05 13:28:03 -05:00
Ed Hennis
95fdbe520f Partially revert aed8e2b166 Fill in payment computation shortages (#5941)
- Do not attempt to fill in payment computation shortages. Fixes, tests,
  and optimizations are left intact.
2025-11-05 12:48:14 -05:00
Ed Hennis
34db04ffc1 Update Lending files for the xrpl rename 2025-11-04 19:37:58 -05:00
Ed Hennis
aed8e2b166 Fill in payment computation shortages (#5941)
- Ensures a consistent fixed payment amount for the entire life of the
  loan, except the final payment, which is guaranteed to be the same or
  smaller.
- Convert some Loan structs to compute values that had need manual
  updates to stay consistent.
- Fail the transaction in `LoanPay` if it violates the Vault `assetsAvailable <=
  assetsTotal` invariant.
- Use constexpr to check that min mantissa value for Number and STAmount
  is a power of 10, and compute the max in terms of the min.
- Improve unit tests:
  - Use BrokerParameters and Loan Parameters instead of semi-global
    class values
  - In tests, check that the expected number of loan payments are made.
  - Add LoanBatch manual test to generate a set number of random loans,
    set them up, and pay them off.
  - Add LoanArbitrary manual test to run a single test with specific
    (hard-coded for now) parameters.
  - Add Number support to XRP_t.
2025-11-04 22:56:16 +00:00
Ed Hennis
cdd6ad4ba4 test: Fix test set up, since the order of preclaim checks changed
- Need to have multisign set up to get to the fee check
2025-11-03 18:00:10 -05:00
Ed Hennis
4920e65b14 fix: LoanBrokerSet is malformed if Cover fields don't align
- sfCoverRateMinimum and sfCoverRateLiquidation must be both zero or
  both non-zero, because both are used in the default amount
  calculations, which is the only place they're really meaningful.
2025-11-03 12:31:20 -05:00
Bronek Kozicki
b472cc3493 Unit tests for multisigned LoanSet counterparty 2025-10-31 16:51:37 -04:00
Ed Hennis
d0c60cdf59 Fix broken unit test case 2025-10-28 18:47:52 -04:00
Ed Hennis
310852ba2d refactor: Payment component calculation will target next true state
- Compute the next "true" state, round the values off, then compute the
  deltas needed to get the current state to that state. Plus some data
  integrity checks.
- Add `Number::zero`, which is longer to type, but more readable than
  `Number{}`.
- Prepare to improve Loan unit tests: track managementFeeRate in
  BrokerInfo, define a LoanParameters object for creation options and
  start adding support for it, track and verify loan state while making
  payments.
2025-10-28 16:27:44 -04:00
Ed Hennis
da14c6f018 Prevent numerical overflow of payment due dates
- Addresses FIND-013 from audit.
- Bases the limit on the current ledger time, and ensures that
  "payments * interval <= limit". This allows a loan to potentially run through
  "the end of time" successfully, but not go a second over.
- Wrote several test cases, including a few that go right to "the end of
  time".
2025-10-26 18:57:16 -04:00
Ed Hennis
5ceefdfbd5 Add repro unit test for FIND-008, with modifications, from audit 2025-10-26 16:03:59 -04:00
Ed Hennis
b8b9e7a51e Add repro unit tests, with modifications, from audit
- FIND-005, FIND-009, and FIND-010.
- Add the finding number to existing tests - FIND-001, FIND-003,
  FIND-012, FIND-007.
- Tweak the interest rate failure log messages in LoanSet.
2025-10-26 15:31:32 -04:00
Ed Hennis
269fb44cd7 Add unit test from security audit (FIND-007)
- The issue identified in this finding had previously been fixed, but
  the test is useful to verify.
2025-10-26 13:51:46 -04:00
Ed Hennis
40ef91e7e0 Limit how many payments can be made in a single LoanPay
- Addresses FIND-005 from audit.
- Tuning values defined in Protocol.h. Optimal values TBD.
  - loanPaymentsPerFeeIncrement: calculateBaseFee estimates the number
    of payments included in the Amount and charges
    "baseFee * number / loanPaymentsPerFeeIncrement".
  - loanMaximumPaymentsPerTransaction: If the number of payments
    (including overpayments if applicable) hits this limit, stop
    processing more payments, but DO NOT FAIL.
- Fix the rounding in LoanSet for Guard 4 (sufficient computed payments)
- Tweak several test parameters to account for the new limits.
- Change payment component rounding for IOUs to "towards_zero".
- Add some safety limits to loan calculations to prevent nonsensical
  values.
2025-10-26 13:09:35 -04:00
Ed Hennis
fe4269cf8b Avoid negative payments: limit origination fee to the loan principal
- Addresses FIND-006 from audit.
- Removes the "minimum" check for sfLoanOriginationFee, and replaces it
  with a "valid range" check with the max value being
  sfPrincipalRequested.
- Reuses the test from the report, with some modifications.
- Also adds some more test cases for existing interest rate tests.
2025-10-24 18:33:57 -04:00
Ed Hennis
0950d41fce refactor: De-templatize and move LendingHelper functions from .h to .cpp
- Changes:
  1. Removed the `AssetType` template parameter from all functions in
     favor of just using the `Asset` class.
  2. Fully moved all `ripple::detail` functions from .h to .cpp.
  3. Moved all definitions of non `detail` functions from .h to .cpp,
     except roundPeriodicPayment, just because it's small and I want it
     to be visible. Left declarations in .h
  4. Moved `PaymentSpecialCase`, `PaymentComponents` and
     `computePaymentComponents` into `detail` and updated references.
2025-10-24 15:44:46 -04:00
Ed Hennis
83e249eb8a refactor: change what values are tracked as Payment Components - Part 1
- This is an intermediate commit. It leaves the old variables in place,
  so I can do verifications that the new computations are correct. They
  will be removed in the next commit.
- PaymentComponents is an class used internally to break a payment value
  into principal, interest, and fees.
2025-10-24 15:09:35 -04:00
Bronek Kozicki
07fcbd5498 Add authorization check to LoanSet (#5875)
- Add tests for unauthorized borrower and lender
2025-10-24 13:27:27 -04:00
Gregory Tsipenyuk
88a770c71b Don't create empty holding for MPT or trust line issuer (#5877)
- Adds a check to the MPToken creation invariant to ensure none are created for the issuer.
- `addEmptyHolding()` will return success without doing anything for these scenarios. There is nothing to do, as with XRP.

---------

Co-authored-by: Ed Hennis <ed@ripple.com>
2025-10-24 12:32:26 -04:00
Gregory Tsipenyuk
f60e298627 Extend LoanBroaker and Loan unit-tests. (#5863)
- Add convenience functions to MPT test-framework.
2025-10-23 19:51:30 +00:00
Ed Hennis
9814ec0309 Implement tfLoanFullPayment; use updated full payment calculations 2025-10-23 00:54:58 -04:00
Ed Hennis
30e2650ff9 Use a loan scale of 0 for integral asset types
- Loan scale is completely irrelevant to integral types (XRP, MPT), and
  the field is "soeDEFAULT", so when set to 0, it won't be stored on
  ledger, saving a little bit of space.
2025-10-22 17:15:34 -04:00
Ed Hennis
92144efbdf Check that the borrower has sufficient funds to make the LoanPay 2025-10-22 00:38:05 -04:00
Ed Hennis
5da586bffc Add support for explicit overpayment flag in LoanPay
- Uses the same name and value as for LoanSet: tfLoanOverpayment.
- Untested.
- Also create several placeholders for missing test cases.
2025-10-21 23:55:46 -04:00
Ed Hennis
f6098fd80b Expand use of Asset::integral() 2025-10-21 20:01:55 -04:00
Gregory Tsipenyuk
8757022312 test: Add unit-test to verify correct behavior on broker deep freeze (#5904)
* Add unit-test to verify correct behavior on broker deep freeze
2025-10-21 23:23:27 +00:00
Ed Hennis
dfc4933c3b Convert Loans to track management fee and use updated rounding
- Move management fee calculations out of transactors an into the
  appropriate functions in LendingHelpers.h.
- Rewrite how overpayments are handled. May changed based on numerical
  analysis.
- Update, fix, and clean up unit tests. Includes adding tolerances for
  some checks where an exact match is unlikely.
- Add "integral()" function to Asset to simplify a common check.
2025-10-21 17:47:13 -04:00
Ed Hennis
baabf142e4 Fix some build errors 2025-10-17 18:29:09 -04:00
Ed Hennis
f9bd9f390a Remove some unused variables, increase rounding tolerance 2025-10-17 18:29:09 -04:00
Ed Hennis
d7196a8e56 Get remaining Loan unit tests working
- Rename some of the helper functions / lambdas.
- Update tracked interestOwed field better at final payoff.
- Add checks in LoanSet that the fields can be represented in the asset
  type, and update test that fails those checks
  (testLoanPayComputePeriodicPaymentValidRateInvariant)
- Also check that the computed periodic payment can be represented as
  the asset type, and doesn't round _UP_ to 0.
- Update asserts to account for more scenarios, including initial loan
  computation.
2025-10-17 18:29:09 -04:00
Ed Hennis
bda6bb46d1 Fix the singlePayment test helper lambda 2025-10-17 18:29:09 -04:00
Ed Hennis
1efc532b21 Implement Vito's new loan payment part rounding algorithm, and more
- Implement AccountSendMulti
- Document the derivations of loan components.
- Add "loanPrincipalFromPeriodicPayment" helper.
- Removed sfReferencePrincipal
- LoanSet and LoanPay can create MPTokens as a side effect
- LoanPay will send the fee to cover if the broker owner is deep frozen,
  and fail if both of them are deep frozen.
- LoanPay will check auth for the receivers, or create holdings for the
  submitting account if needed.
- LoanSet will fail if principal requested is not positive
- Handle overpayment in a separate function
- Add a test helper to check that balance changes went as expected
- Fix more tests
2025-10-17 18:29:08 -04:00
Ed Hennis
2dd239c59f Update payment component computation and rounding, and more tests
- Tests not expected to pass.
- Check in LoanSet if a loan with interest actually has interest.
  tecPRECISION_LOSS if not.
- Add checks in LoanPay for deep froze broker owner and pseudoaccount.
- Fix management fee calculations in LoanPay and associated LoanBroker
  and Vault data updates.
- Make state tracking next payment due date optional.
- Add a test case showing multiple payments combined.
- Update more tests to work with the new fields.
2025-10-17 18:29:08 -04:00
Ed Hennis
fc2163708a Update InvariantCheck, LoanManage, and LoanPay to make tests work
- Primarily updating tests, and fixing stuff that didn't work.
- Tests still not expected to pass.
- Add Json::Value::isMember(StaticString) so SFields can be used.
- Validate more fields in ValidLoan Invariant
2025-10-17 18:29:08 -04:00
Ed Hennis
e1939d0d20 Convert LoanSet to precomputed all values
- Tests are not expected to pass
2025-10-17 18:29:06 -04:00
Ed Hennis
2509293943 Disable blocks of code using #if LOANCOMPLETE to enable build
- Will add those back later as the appropriate helpers are updated.
- Tests are not expected to pass.
2025-10-17 18:29:06 -04:00
Ed Hennis
63edf035a6 Start converting Loans to use fixed payments and track value
- Not expected to build
2025-10-17 18:29:06 -04:00
Ed Hennis
d353f4a2e6 Remove conditional LoanDraw code 2025-10-17 18:29:06 -04:00
Ed Hennis
66dbc05a9f Update ValidVault to allow LoanPay to change LossUnrealized
- Making a payment on an impaired loan will unimpair the loan, which
  changes Vault.LossUnrealized.
- Add a step in unit tests to impair a loan before making a payment, to
  verify, and prevent future similar regressions.
- Resolves regression RIPD-3650
2025-10-10 13:15:28 -04:00
Ed Hennis
b127b24dae Addressed review feedback from @gregtatcam:
- All current items are done
- Mostly comments
- Restructured PaymentParts (formerly PeriodicPaymentParts) to bring
  along fees, and removed the computed / combined PeriodicPayment from
  places that should be using PaymentParts instead.
2025-09-30 22:25:53 -04:00