@@ -141,7 +141,7 @@ class Loan_test : public beast::unit_test::suite
141141 using namespace jtx ;
142142
143143 auto const vaultSle = env.le (keylet::vault (vaultID));
144- return getVaultScale (vaultSle);
144+ return getAssetsTotalScale (vaultSle);
145145 }
146146 };
147147
@@ -551,12 +551,15 @@ class Loan_test : public beast::unit_test::suite
551551 broker.vaultScale (env),
552552 state.principalOutstanding .exponent ())));
553553 BEAST_EXPECT (state.paymentInterval == 600 );
554- BEAST_EXPECT (
555- state.totalValue ==
556- roundToAsset (
557- broker.asset ,
558- state.periodicPayment * state.paymentRemaining ,
559- state.loanScale ));
554+ {
555+ NumberRoundModeGuard mg (Number::upward);
556+ BEAST_EXPECT (
557+ state.totalValue ==
558+ roundToAsset (
559+ broker.asset ,
560+ state.periodicPayment * state.paymentRemaining ,
561+ state.loanScale ));
562+ }
560563 BEAST_EXPECT (
561564 state.managementFeeOutstanding ==
562565 computeManagementFee (
@@ -697,7 +700,8 @@ class Loan_test : public beast::unit_test::suite
697700 interval,
698701 total,
699702 feeRate,
700- asset (brokerParams.vaultDeposit ).number ().exponent ());
703+ asset (brokerParams.vaultDeposit ).number ().exponent (),
704+ env.journal );
701705 log << " Loan properties:\n "
702706 << " \t Principal: " << principal << std::endl
703707 << " \t Interest rate: " << interest << std::endl
@@ -1478,7 +1482,8 @@ class Loan_test : public beast::unit_test::suite
14781482 state.paymentInterval ,
14791483 state.paymentRemaining ,
14801484 broker.params .managementFeeRate ,
1481- state.loanScale );
1485+ state.loanScale ,
1486+ env.journal );
14821487
14831488 verifyLoanStatus (
14841489 0 ,
@@ -2449,13 +2454,18 @@ class Loan_test : public beast::unit_test::suite
24492454 // Make all the payments in one transaction
24502455 // service fee is 2
24512456 auto const startingPayments = state.paymentRemaining ;
2452- auto const rawPayoff = startingPayments *
2453- (state.periodicPayment + broker.asset (2 ).value ());
2454- STAmount const payoffAmount{broker.asset , rawPayoff};
2455- BEAST_EXPECT (
2456- payoffAmount ==
2457- broker.asset (Number (1024014840139457 , -12 )));
2458- BEAST_EXPECT (payoffAmount > state.principalOutstanding );
2457+ STAmount const payoffAmount = [&]() {
2458+ NumberRoundModeGuard mg (Number::upward);
2459+ auto const rawPayoff = startingPayments *
2460+ (state.periodicPayment + broker.asset (2 ).value ());
2461+ STAmount const payoffAmount{broker.asset , rawPayoff};
2462+ BEAST_EXPECTS (
2463+ payoffAmount ==
2464+ broker.asset (Number (1024014840139457 , -12 )),
2465+ to_string (payoffAmount));
2466+ BEAST_EXPECT (payoffAmount > state.principalOutstanding );
2467+ return payoffAmount;
2468+ }();
24592469
24602470 singlePayment (
24612471 loanKeylet,
@@ -4014,7 +4024,7 @@ class Loan_test : public beast::unit_test::suite
40144024 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40154025 // Fails in preclaim because principal requested can't be
40164026 // represented as XRP
4017- env (createJson, ter (tecPRECISION_LOSS));
4027+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40184028 env.close ();
40194029
40204030 BEAST_EXPECT (!env.le (keylet));
@@ -4026,7 +4036,7 @@ class Loan_test : public beast::unit_test::suite
40264036 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40274037 // Fails in doApply because the payment is too small to be
40284038 // represented as XRP.
4029- env (createJson, ter (tecPRECISION_LOSS));
4039+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40304040 env.close ();
40314041 }
40324042
@@ -5001,7 +5011,7 @@ class Loan_test : public beast::unit_test::suite
50015011 auto const keylet = keylet::loan (broker.brokerID , loanSequence);
50025012
50035013 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
5004- env (createJson, ter (tecPRECISION_LOSS));
5014+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
50055015 env.close (startDate);
50065016
50075017 auto loanPayTx = env.json (
@@ -6149,15 +6159,16 @@ class Loan_test : public beast::unit_test::suite
61496159 // Accrued + prepayment-penalty interest based on current periodic
61506160 // schedule
61516161 auto const fullPaymentInterest = computeFullPaymentInterest (
6152- after.periodicPayment ,
6162+ detail::loanPrincipalFromPeriodicPayment (
6163+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61536164 periodicRate2,
6154- after.paymentRemaining ,
61556165 env.current ()->parentCloseTime (),
61566166 after.paymentInterval ,
61576167 after.previousPaymentDate ,
61586168 static_cast <std::uint32_t >(
61596169 after.startDate .time_since_epoch ().count ()),
61606170 closeInterestRate);
6171+
61616172 // Round to asset scale and split interest/fee parts
61626173 auto const roundedInterest =
61636174 roundToAsset (asset.raw (), fullPaymentInterest, after.loanScale );
@@ -6185,9 +6196,9 @@ class Loan_test : public beast::unit_test::suite
61856196 // window by clamping prevPaymentDate to 'now' for the full-pay path.
61866197 auto const prevClamped = std::min (after.previousPaymentDate , nowSecs);
61876198 auto const fullPaymentInterestClamped = computeFullPaymentInterest (
6188- after.periodicPayment ,
6199+ detail::loanPrincipalFromPeriodicPayment (
6200+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61896201 periodicRate2,
6190- after.paymentRemaining ,
61916202 env.current ()->parentCloseTime (),
61926203 after.paymentInterval ,
61936204 prevClamped,
0 commit comments