You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
Borrowers can circumvent fees by calling OCC_Modular::callLoan when the grace period exceeds the payment interval
Summary
The grace period may be longer than the payment interval, and the borrower may miss serveral loan payments before a loan enters default (You can check it here).
In this scenario, the borrower is required to pay the principal amount, accrued interest, and applicable late fees for any missed payments. However, the borrower may be able to circumvent a portion of the interest and late fees by calling the OCC_Modular::callLoan function, potentially resulting in financial loss to the protocol.
Vulnerability Detail
When borrowers make a payment to the protocol using the makePayment function, they are required to pay the prinicipalOwed, the interestOwed and the lateFee, all of which are calculated at L578. Additionally, the paymentDueBy timestamp is updated by adding the paymentInterval.
The prinicipalOwed, interestOwed, and lateFee are calculated within the amountOwed function as follows:
zivoe-core-foundry\src\lockers\OCC\OCC_Modular.sol
440: function amountOwed(uint256id) publicviewreturns (
441: uint256principal, uint256interest, uint256lateFee, uint256total442: ) {
443: // 0 == Bullet.444: if (loans[id].paymentSchedule ==0) {
445: if (loans[id].paymentsRemaining ==1) { principal = loans[id].principalOwed; }
446: }
447: // 1 == Amortization (only two options, use else here).448: else { principal = loans[id].principalOwed / loans[id].paymentsRemaining; }
449:
450: // Add late fee if past loans[id].paymentDueBy.451: if (block.timestamp> loans[id].paymentDueBy && loans[id].state == LoanState.Active) {
452: lateFee = loans[id].principalOwed * (block.timestamp- loans[id].paymentDueBy) *//@audit late fee453: loans[id].APRLateFee / (86400*365* BIPS);
454: }
455: interest = loans[id].principalOwed * loans[id].paymentInterval * loans[id].APR / (86400*365* BIPS); //@audit interest of the interval456: total = principal + interest + lateFee;
457: }
As shown in the previous code snippet, the lateFee is calculated based on the difference between the current timestamp and the paymentDueBy timestamp. Additionally, the interest is calculated for the duration of the paymentInterval.
Let's consider the following scenario:
Alice has a bullet loan with a grace period of 14 days and a payment interval of 7 days. The loan term is 5 periods.
Alice has missed the third paymentDueBy, and the 14-day grace period is nearly expired. At this stage, near the end of the loan term, Alice should be required to call the makePayment function three times, repaying the principal amount, the interest accrued over the three missed payment intervals, and the applicable late fees.
In the first makePayment call, Alice would owe 14 days' worth of late fees, the interest for one payment interval, and the paymentDueBy timestamp would be updated by another 7-day interval.
For the second makePayment call, the late fees would be 7 days, with interest for another payment interval, and the paymentDueBy would be updated again.
On the final call, there would be no late fees, only the principal and interest for the last payment interval.
In total, Alice should be required to pay the principal amount, the interest accrued over the three missed payment intervals, and the late fees accumulated over 21 days.
However, instead of making these three separate makePayment calls, Alice has opted to call the callLoan function.
This allows her to repay only the interest for one payment interval and the 14-day late fee, rather than the full interest and late fees owed over the three missed payments. This action by Alice results in a financial loss to the protocol. This issue arises because the amountOwed function does not account for the potential scenario where there are multiple missed payments during the grace period.
Impact
By exploiting the callLoan function, borrowers can circumvent the full payment of fees owed to the protocol, resulting in financial losses for the protocol.
In the callLoan function, it is recommended to account for and require payment of any missed interest and late fees that occurred during the delinquency period
1 comment(s) were left on this issue during the judging contest.
panprog commented:
medium, dup of #97, if there are more than 1 interest payments missed by borrower, then callLoan takes only 1 period payment, allowing borrower to skip paying the other periods interest and lateFee payments.
sherlock-admin2
changed the title
Decent Chiffon Wolf - Borrowers can circumvent fees by calling OCC_Modular::callLoan when the grace period exceeds the payment interval
KupiaSec - Borrowers can circumvent fees by calling OCC_Modular::callLoan when the grace period exceeds the payment interval
May 11, 2024
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
KupiaSec
high
Borrowers can circumvent fees by calling
OCC_Modular::callLoan
when the grace period exceeds the payment intervalSummary
The grace period may be longer than the payment interval, and the borrower may miss serveral loan payments before a loan enters default (You can check it here).
In this scenario, the borrower is required to pay the principal amount, accrued interest, and applicable late fees for any missed payments. However, the borrower may be able to circumvent a portion of the interest and late fees by calling the OCC_Modular::callLoan function, potentially resulting in financial loss to the protocol.
Vulnerability Detail
When borrowers make a payment to the protocol using the makePayment function, they are required to pay the
prinicipalOwed
, theinterestOwed
and thelateFee
, all of which are calculated at L578. Additionally, thepaymentDueBy
timestamp is updated by adding thepaymentInterval
.The
prinicipalOwed
,interestOwed
, andlateFee
are calculated within the amountOwed function as follows:As shown in the previous code snippet, the
lateFee
is calculated based on the difference between the current timestamp and thepaymentDueBy
timestamp. Additionally, theinterest
is calculated for the duration of thepaymentInterval
.Let's consider the following scenario:
Alice has a bullet loan with a grace period of 14 days and a payment interval of 7 days. The loan term is 5 periods.
Alice has missed the third
paymentDueBy
, and the 14-day grace period is nearly expired. At this stage, near the end of the loan term, Alice should be required to call themakePayment
function three times, repaying the principal amount, the interest accrued over the three missed payment intervals, and the applicable late fees.In the first
makePayment
call, Alice would owe 14 days' worth of late fees, the interest for one payment interval, and thepaymentDueBy
timestamp would be updated by another 7-day interval.For the second
makePayment
call, the late fees would be 7 days, with interest for another payment interval, and thepaymentDueBy
would be updated again.On the final call, there would be no late fees, only the principal and interest for the last payment interval.
In total, Alice should be required to pay the principal amount, the interest accrued over the three missed payment intervals, and the late fees accumulated over 21 days.
However, instead of making these three separate
makePayment
calls, Alice has opted to call the callLoan function.This allows her to repay only the interest for one payment interval and the 14-day late fee, rather than the full interest and late fees owed over the three missed payments. This action by Alice results in a financial loss to the protocol. This issue arises because the
amountOwed
function does not account for the potential scenario where there are multiple missed payments during the grace period.Impact
By exploiting the
callLoan
function, borrowers can circumvent the full payment of fees owed to the protocol, resulting in financial losses for the protocol.Tool used
Manual Review
Code Snippet
https://github.com/sherlock-audit/2024-03-zivoe/blob/d4111645b19a1ad3ccc899bea073b6f19be04ccd/zivoe-core-foundry/src/lockers/OCC/OCC_Modular.sol#L500
Recommendation
In the
callLoan
function, it is recommended to account for and require payment of any missed interest and late fees that occurred during the delinquency periodDuplicate of #97
The text was updated successfully, but these errors were encountered: