@@ -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,
@@ -4010,7 +4020,7 @@ class Loan_test : public beast::unit_test::suite
40104020 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40114021 // Fails in preclaim because principal requested can't be
40124022 // represented as XRP
4013- env (createJson, ter (tecPRECISION_LOSS));
4023+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40144024 env.close ();
40154025
40164026 BEAST_EXPECT (!env.le (keylet));
@@ -4022,7 +4032,7 @@ class Loan_test : public beast::unit_test::suite
40224032 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
40234033 // Fails in doApply because the payment is too small to be
40244034 // represented as XRP.
4025- env (createJson, ter (tecPRECISION_LOSS));
4035+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
40264036 env.close ();
40274037 }
40284038
@@ -4997,7 +5007,7 @@ class Loan_test : public beast::unit_test::suite
49975007 auto const keylet = keylet::loan (broker.brokerID , loanSequence);
49985008
49995009 createJson = env.json (createJson, sig (sfCounterpartySignature, lender));
5000- env (createJson, ter (tecPRECISION_LOSS));
5010+ env (createJson, ter (tecPRECISION_LOSS), THISLINE );
50015011 env.close (startDate);
50025012
50035013 auto loanPayTx = env.json (
@@ -6145,15 +6155,16 @@ class Loan_test : public beast::unit_test::suite
61456155 // Accrued + prepayment-penalty interest based on current periodic
61466156 // schedule
61476157 auto const fullPaymentInterest = computeFullPaymentInterest (
6148- after.periodicPayment ,
6158+ detail::loanPrincipalFromPeriodicPayment (
6159+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61496160 periodicRate2,
6150- after.paymentRemaining ,
61516161 env.current ()->parentCloseTime (),
61526162 after.paymentInterval ,
61536163 after.previousPaymentDate ,
61546164 static_cast <std::uint32_t >(
61556165 after.startDate .time_since_epoch ().count ()),
61566166 closeInterestRate);
6167+
61576168 // Round to asset scale and split interest/fee parts
61586169 auto const roundedInterest =
61596170 roundToAsset (asset.raw (), fullPaymentInterest, after.loanScale );
@@ -6181,9 +6192,9 @@ class Loan_test : public beast::unit_test::suite
61816192 // window by clamping prevPaymentDate to 'now' for the full-pay path.
61826193 auto const prevClamped = std::min (after.previousPaymentDate , nowSecs);
61836194 auto const fullPaymentInterestClamped = computeFullPaymentInterest (
6184- after.periodicPayment ,
6195+ detail::loanPrincipalFromPeriodicPayment (
6196+ after.periodicPayment , periodicRate2, after.paymentRemaining ),
61856197 periodicRate2,
6186- after.paymentRemaining ,
61876198 env.current ()->parentCloseTime (),
61886199 after.paymentInterval ,
61896200 prevClamped,
0 commit comments