@@ -144,7 +144,7 @@ class Loan_test : public beast::unit_test::suite
144144 using namespace jtx ;
145145
146146 auto const vaultSle = env.le (keylet::vault (vaultID));
147- return getVaultScale (vaultSle);
147+ return getAssetsTotalScale (vaultSle);
148148 }
149149 };
150150
@@ -554,12 +554,15 @@ class Loan_test : public beast::unit_test::suite
554554 broker.vaultScale (env),
555555 state.principalOutstanding .exponent ())));
556556 BEAST_EXPECT (state.paymentInterval == 600 );
557- BEAST_EXPECT (
558- state.totalValue ==
559- roundToAsset (
560- broker.asset ,
561- state.periodicPayment * state.paymentRemaining ,
562- state.loanScale ));
557+ {
558+ NumberRoundModeGuard mg (Number::upward);
559+ BEAST_EXPECT (
560+ state.totalValue ==
561+ roundToAsset (
562+ broker.asset ,
563+ state.periodicPayment * state.paymentRemaining ,
564+ state.loanScale ));
565+ }
563566 BEAST_EXPECT (
564567 state.managementFeeOutstanding ==
565568 computeManagementFee (
@@ -700,7 +703,8 @@ class Loan_test : public beast::unit_test::suite
700703 interval,
701704 total,
702705 feeRate,
703- asset (brokerParams.vaultDeposit ).number ().exponent ());
706+ asset (brokerParams.vaultDeposit ).number ().exponent (),
707+ env.journal );
704708 log << " Loan properties:\n "
705709 << " \t Principal: " << principal << std::endl
706710 << " \t Interest rate: " << interest << std::endl
@@ -1481,7 +1485,8 @@ class Loan_test : public beast::unit_test::suite
14811485 state.paymentInterval ,
14821486 state.paymentRemaining ,
14831487 broker.params .managementFeeRate ,
1484- state.loanScale );
1488+ state.loanScale ,
1489+ env.journal );
14851490
14861491 verifyLoanStatus (
14871492 0 ,
@@ -2452,13 +2457,18 @@ class Loan_test : public beast::unit_test::suite
24522457 // Make all the payments in one transaction
24532458 // service fee is 2
24542459 auto const startingPayments = state.paymentRemaining ;
2455- auto const rawPayoff = startingPayments *
2456- (state.periodicPayment + broker.asset (2 ).value ());
2457- STAmount const payoffAmount{broker.asset , rawPayoff};
2458- BEAST_EXPECT (
2459- payoffAmount ==
2460- broker.asset (Number (1024014840139457 , -12 )));
2461- BEAST_EXPECT (payoffAmount > state.principalOutstanding );
2460+ STAmount const payoffAmount = [&]() {
2461+ NumberRoundModeGuard mg (Number::upward);
2462+ auto const rawPayoff = startingPayments *
2463+ (state.periodicPayment + broker.asset (2 ).value ());
2464+ STAmount const payoffAmount{broker.asset , rawPayoff};
2465+ BEAST_EXPECTS (
2466+ payoffAmount ==
2467+ broker.asset (Number (1024014840139457 , -12 )),
2468+ to_string (payoffAmount));
2469+ BEAST_EXPECT (payoffAmount > state.principalOutstanding );
2470+ return payoffAmount;
2471+ }();
24622472
24632473 singlePayment (
24642474 loanKeylet,
@@ -4013,7 +4023,7 @@ class Loan_test : public beast::unit_test::suite
40134023 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40144024 // Fails in preclaim because principal requested can't be
40154025 // represented as XRP
4016- env (createJson, ter (tecPRECISION_LOSS));
4026+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40174027 env.close ();
40184028
40194029 BEAST_EXPECT (!env.le (keylet));
@@ -4025,7 +4035,7 @@ class Loan_test : public beast::unit_test::suite
40254035 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40264036 // Fails in doApply because the payment is too small to be
40274037 // represented as XRP.
4028- env (createJson, ter (tecPRECISION_LOSS));
4038+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40294039 env.close ();
40304040 }
40314041
@@ -5000,7 +5010,7 @@ class Loan_test : public beast::unit_test::suite
50005010 auto const keylet = keylet::loan (broker.brokerID , loanSequence);
50015011
50025012 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
5003- env (createJson, ter (tecPRECISION_LOSS));
5013+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
50045014 env.close (startDate);
50055015
50065016 auto loanPayTx = env.json (
@@ -6148,15 +6158,16 @@ class Loan_test : public beast::unit_test::suite
61486158 // Accrued + prepayment-penalty interest based on current periodic
61496159 // schedule
61506160 auto const fullPaymentInterest = computeFullPaymentInterest (
6151- after.periodicPayment ,
6161+ detail::loanPrincipalFromPeriodicPayment (
6162+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61526163 periodicRate2,
6153- after.paymentRemaining ,
61546164 env.current ()->parentCloseTime (),
61556165 after.paymentInterval ,
61566166 after.previousPaymentDate ,
61576167 static_cast <std::uint32_t >(
61586168 after.startDate .time_since_epoch ().count ()),
61596169 closeInterestRate);
6170+
61606171 // Round to asset scale and split interest/fee parts
61616172 auto const roundedInterest =
61626173 roundToAsset (asset.raw (), fullPaymentInterest, after.loanScale );
@@ -6184,9 +6195,9 @@ class Loan_test : public beast::unit_test::suite
61846195 // window by clamping prevPaymentDate to 'now' for the full-pay path.
61856196 auto const prevClamped = std::min (after.previousPaymentDate , nowSecs);
61866197 auto const fullPaymentInterestClamped = computeFullPaymentInterest (
6187- after.periodicPayment ,
6198+ detail::loanPrincipalFromPeriodicPayment (
6199+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61886200 periodicRate2,
6189- after.paymentRemaining ,
61906201 env.current ()->parentCloseTime (),
61916202 after.paymentInterval ,
61926203 prevClamped,
0 commit comments