Tiny Gingerbread Tarantula
High
The nextDeadline function in the DebitaV3Loan.sol
contract uses the next lowest deadline of all the offers to determine the next deadline. However, when borrowers are paying for the extension, offers with a maximum deadline greater than the next deadline use their values to calculate user fees. This results in unfair fee calculations for the borrower.
The root cause of the issue is the inconsistency between the nextDeadline function, which uses the next lowest deadline of all offers, and the fee calculation during loan extension,
function extendLoan() public {
// ... some code
loanData.extended = true; // set the loan as extended
// calculate interest to pay to Debita and the subtract to the lenders
for (uint i; i < m_loan._acceptedOffers.length; i++) {
infoOfOffers memory offer = m_loan._acceptedOffers[i];
if (!offer.paid) {
// ... some code
uint interestOfUsedTime = calculateInterestToPay(i); // calculate interest to pay based on the time the loan was used for the offer
if (PorcentageOfFeePaid != maxFee) {
// calculate difference from fee paid for the initialDuration vs the extra fee they should pay because of the extras days of extending the loan. MAXFEE shouldnt be higher than extra fee + PorcentageOfFeePaid
uint feeOfMaxDeadline = ((offer.maxDeadline * feePerDay) / 86400); // calculate the fee of the max deadline
// ... some code
}
// ... some code
}
}
}
which uses the maximum deadline of each offer. This discrepancy leads to unfair fee calculations for the borrower.
function nextDeadline() public view returns (uint) {
uint _nextDeadline;
LoanData memory m_loan = loanData;
if (m_loan.extended) {
for (uint i; i < m_loan._acceptedOffers.length; i++) {
if (
_nextDeadline == 0 &&
m_loan._acceptedOffers[i].paid == false
) {
_nextDeadline = m_loan._acceptedOffers[i].maxDeadline;
} else if (
m_loan._acceptedOffers[i].paid == false &&
_nextDeadline > m_loan._acceptedOffers[i].maxDeadline // Use the next lowest deadline
) {
_nextDeadline = m_loan._acceptedOffers[i].maxDeadline;
}
}
} else {
_nextDeadline = m_loan.startedAt + m_loan.initialDuration;
}
return _nextDeadline;
}
The root cause is that while the loan's effective deadline is determined by the next shortest deadline among unpaid offers, fees are calculated using each offer's individual maximum deadline, which could be much longer.
No response
No response
No response
The impact of this issue is that borrowers will end up paying higher fees than expected when extending their loans, as fee calculations are based on unutilized loan durations. Furthermore, when multiple offers with varying deadlines are involved, borrowers face compounded unfair charges, paying for time periods they cannot actually utilize, leading to unfair loan terms and significant financial losses.
uint[] memory deadlines = new uint[](3);
deadlines[0] = block.timestamp + 30 days; // Shortest deadline that will be used for nextDeadline
deadlines[1] = block.timestamp + 60 days;
deadlines[2] = block.timestamp + 90 days;
// However, when extending:
// Offer 1 fees calculated on 30 days
// Offer 2 fees calculated on 60 days
// Offer 3 fees calculated on 90 days
// Despite loan being effectively limited to 30 days
// Borrower pays fees based on 60 and 90 day periods they can't use
Align Fee Calculation with Effective Deadline during loan extension and interest to pay.