Skip to content

Commit e5a92fb

Browse files
Tapanitoximinez
authored andcommitted
Add minimum grace period validation (#6133)
1 parent a743930 commit e5a92fb

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

src/test/app/Loan_test.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4050,7 +4050,6 @@ class Loan_test : public beast::unit_test::suite
40504050

40514051
createJson["CloseInterestRate"] = 55374;
40524052
createJson["ClosePaymentFee"] = "3825205248";
4053-
createJson["GracePeriod"] = 0;
40544053
createJson["LatePaymentFee"] = "237";
40554054
createJson["LoanOriginationFee"] = "0";
40564055
createJson["OverpaymentFee"] = 35167;
@@ -4726,7 +4725,30 @@ class Loan_test : public beast::unit_test::suite
47264725
jtx::fee const& loanSetFee,
47274726
Number const& debtMaximumRequest) {
47284727
// first temBAD_SIGNER: TODO
4728+
// invalid grace period
4729+
{
4730+
// zero grace period
4731+
env(set(borrower, brokerInfo.brokerID, debtMaximumRequest),
4732+
sig(sfCounterpartySignature, lender),
4733+
gracePeriod(0),
4734+
loanSetFee,
4735+
ter(temINVALID));
47294736

4737+
// grace period less than default minimum
4738+
env(set(borrower, brokerInfo.brokerID, debtMaximumRequest),
4739+
sig(sfCounterpartySignature, lender),
4740+
gracePeriod(LoanSet::defaultGracePeriod - 1),
4741+
loanSetFee,
4742+
ter(temINVALID));
4743+
4744+
// grace period greater than payment interval
4745+
env(set(borrower, brokerInfo.brokerID, debtMaximumRequest),
4746+
sig(sfCounterpartySignature, lender),
4747+
paymentInterval(120),
4748+
gracePeriod(121),
4749+
loanSetFee,
4750+
ter(temINVALID));
4751+
}
47304752
// empty/zero broker ID
47314753
{
47324754
auto jv = set(borrower, uint256{}, debtMaximumRequest);
@@ -5027,7 +5049,6 @@ class Loan_test : public beast::unit_test::suite
50275049

50285050
createJson["CloseInterestRate"] = 47299;
50295051
createJson["ClosePaymentFee"] = "3985819770";
5030-
createJson["GracePeriod"] = 0;
50315052
createJson["InterestRate"] = 92;
50325053
createJson["LatePaymentFee"] = "3866894865";
50335054
createJson["LoanOriginationFee"] = "0";
@@ -5180,7 +5201,6 @@ class Loan_test : public beast::unit_test::suite
51805201
json(sfCounterpartySignature, Json::objectValue));
51815202

51825203
createJson["ClosePaymentFee"] = "0";
5183-
createJson["GracePeriod"] = 0;
51845204
createJson["InterestRate"] = 24346;
51855205
createJson["LateInterestRate"] = 65535;
51865206
createJson["LatePaymentFee"] = "0";
@@ -5300,7 +5320,6 @@ class Loan_test : public beast::unit_test::suite
53005320
json(sfCounterpartySignature, Json::objectValue));
53015321

53025322
createJson["ClosePaymentFee"] = "0";
5303-
createJson["GracePeriod"] = 0;
53045323
createJson["InterestRate"] = 12833;
53055324
createJson["LateInterestRate"] = 77048;
53065325
createJson["LatePaymentFee"] = "0";
@@ -5394,7 +5413,7 @@ class Loan_test : public beast::unit_test::suite
53945413
set(borrower, broker.brokerID, Number{55524'81, -2}),
53955414
fee(loanSetFee),
53965415
closePaymentFee(0),
5397-
gracePeriod(0),
5416+
gracePeriod(LoanSet::defaultGracePeriod),
53985417
interestRate(TenthBips32(12833)),
53995418
lateInterestRate(TenthBips32(77048)),
54005419
latePaymentFee(0),
@@ -6484,8 +6503,7 @@ class Loan_test : public beast::unit_test::suite
64846503
.lateFee = Number{200, -6},
64856504
.interest = TenthBips32{50'000},
64866505
.payTotal = 10,
6487-
.payInterval = 150,
6488-
.gracePd = 0};
6506+
.payInterval = 150};
64896507

64906508
auto const assetType = AssetType::XRP;
64916509

@@ -6506,9 +6524,6 @@ class Loan_test : public beast::unit_test::suite
65066524
auto state = getCurrentState(env, broker, loanKeylet);
65076525
if (auto loan = env.le(loanKeylet); BEAST_EXPECT(loan))
65086526
{
6509-
// log << "loan after create: " << to_string(loan->getJson())
6510-
// << std::endl;
6511-
65126527
env.close(tp{d{
65136528
loan->at(sfNextPaymentDueDate) + loan->at(sfGracePeriod) + 1}});
65146529
}
@@ -6523,16 +6538,10 @@ class Loan_test : public beast::unit_test::suite
65236538

65246539
{
65256540
auto const submitParam = to_string(jv);
6526-
// log << "about to submit: " << submitParam << std::endl;
65276541
auto const jr = env.rpc("submit", borrower.name(), submitParam);
65286542

6529-
// log << jr << std::endl;
65306543
BEAST_EXPECT(jr.isMember(jss::result));
65316544
auto const jResult = jr[jss::result];
6532-
// BEAST_EXPECT(jResult[jss::error] == "invalidTransaction");
6533-
// BEAST_EXPECT(
6534-
// jResult[jss::error_exception] ==
6535-
// "fails local checks: Transaction has bad signature.");
65366545
}
65376546

65386547
env.close();
@@ -6568,8 +6577,7 @@ class Loan_test : public beast::unit_test::suite
65686577
.counter = borrower,
65696578
.principalRequest = Number{100'000, -4},
65706579
.interest = TenthBips32{100'000},
6571-
.payTotal = 10,
6572-
.gracePd = 0};
6580+
.payTotal = 10};
65736581

65746582
auto const assetType = AssetType::MPT;
65756583

@@ -7486,6 +7494,8 @@ class Loan_test : public beast::unit_test::suite
74867494
testLoanPayLateFullPaymentBypassesPenalties();
74877495
testLoanCoverMinimumRoundingExploit();
74887496
#endif
7497+
testInvalidLoanSet();
7498+
74897499
testCoverDepositWithdrawNonTransferableMPT();
74907500
testPoC_UnsignedUnderflowOnFullPayAfterEarlyPeriodic();
74917501

@@ -7500,7 +7510,6 @@ class Loan_test : public beast::unit_test::suite
75007510
testInvalidLoanDelete();
75017511
testInvalidLoanManage();
75027512
testInvalidLoanPay();
7503-
testInvalidLoanSet();
75047513

75057514
testBatchBypassCounterparty();
75067515
testLoanPayComputePeriodicPaymentValidRateInvariant();

src/xrpld/app/tx/detail/LoanSet.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ LoanSet::preflight(PreflightContext const& ctx)
8888
if (auto const paymentInterval = tx[~sfPaymentInterval];
8989
!validNumericMinimum(paymentInterval, LoanSet::minPaymentInterval))
9090
return temINVALID;
91-
92-
else if (!validNumericRange(
93-
tx[~sfGracePeriod],
94-
paymentInterval.value_or(LoanSet::defaultPaymentInterval)))
91+
// Grace period is between min default value and payment interval
92+
else if (auto const gracePeriod = tx[~sfGracePeriod]; //
93+
!validNumericRange(
94+
gracePeriod,
95+
paymentInterval.value_or(LoanSet::defaultPaymentInterval),
96+
defaultGracePeriod))
9597
return temINVALID;
9698

9799
// Copied from preflight2

0 commit comments

Comments
 (0)