The vulnerability involves miscalculating interest rates in a lending protocol's codebase. The code mistakenly treats the interestRate
meant for per-second calculations as if it's per-year. This results in underestimated interest due to incorrect division by 365 days. The impact is illustrated with a $10,000 loan for a year: correct interest should be $31,536,000, but the flawed code yields $1. Precision loss also arises from omitting 6 hours in a year. Additionally, using 3 decimals for interest rates compounds precision issues. Corrective actions involve adjusting calculations based on intended time units.
In the Structs.sol#L48
the interestRate
variable is defined. The comment mentions its explanation below:
/// @notice the interest rate of the loan per second (in debt tokens)
Then, the interestRate
variable is used in the _calculateInterest()
function in Lender.sol#L720-L727
as below:
We can see that for calculating the interest, the interestRate
which shows the interest rate of the loan per second is divided by 365 days
. Since the interestRate
variable is multiplied by timeElapsed
which is in seconds and divided by 365 days
, means that the interestRate
variable is considered to show the interest Rate per 365 days.
We know that the interestRate
shows the interest rate of a loan per second. Also, we know that 365 days have 31,536,000 seconds. So, the interest rate per 365 days should be 31,536,000 times more than the interest rate per second. However, in the given code, both interest rate per second and interest rate per 365 days, are used interchangeably.
Also, note that 1 year is equal to 365 days and 6 hours. A lack of 6 hours in the computation can lead to precision loss.
The final note regarding calculating the interest is that 3 decimals is way small and can lead to precision loss easily.
This can lead to a huge underestimation of the interest on a loan. Consider the interest rate per second is . Consider three decimals considered for interestRate
, this value should be equal to one. Consider there is a loan with the value of $10,000, which has been given to the borrower for 365 days. Hence, the total interest is:
We can see the interest of this loan must be $31,536,000 for 365 days. However, the implementation calculates the interest like below:
A huge difference can be observed here.
Regarding the second case, consider that 1 year is 365 days and 6 hours. Consider we are calculating the interest using the implementation but with the correct period for a year. In this case, the interest would be:
Since the result should be an integer, we can see adding the exact time of a year can make the interest zero instead of one.
Manual Review, Foundry
In case of using the interest
variable for showing interest per second; change the Lender.sol#L724
to the following:
In case of using the interest
variable for showing interest per year; change the Lender.sol#L724
to the following:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.