The _calculateInterest
function is vulnerable to precision loss. Due to dividing twice the function will return zero for both interest and protocolInterest
. This could lead to a lender giving their loan to another pool that doesn't have the balance to cover it. Leading to a loss for them and a gain for the future pools as they will have debts greater than their balance.
giveLoans()
calls _calculateInterest()
which then returns the amount of interest the protocol fee and adds that to the loan (debt) in order to calculate the totalDebt
.
However, we already determined that these values are vulnerable to precision loss leading them to return 0 in some cases or be smaller than expected. That would lead to an inaccurate totalDebt
allowing us to bypass the check in giveLoans
that requires poolBalance
to be greater than totalDebt
.
Alice creates a pool with 100 dollars in it.
Let's say Bob takes out a loan for 100 dollars in debt.
This loan has a five percent interest rate leaving Bob owing a total of 105 after a year.
Alice decides she wants to get rid of the loan so she looks for another pool to give it to.
In theory, the protocol should only allow Alice to give the loan to a pool that has greater then a 105 dollar balance.
However when calling giveloans
the function will call calculateInterest
to calculate the interest to be 0 and assume totalDebt
is 100. This would allow Alice to give her loan to a pool that has 101 or more dollars in it which isn't the intended behavior. The effect here would be that the user would be able to get an interest-free loan and the outstandingLoans
value would be incorrect. Alice of course would lose the interest and now you have a loans that have bad debt or miscalculated values in outstandingLoans
breaking trust in the entire system. This is also true of the buyLoans
function refinanceFunction
and any other function that calls _calculateInterest
in order to calculate the totalDebt
. There are multiple values throughout the contract that depend on totalDebt
to be accurate as you can see below from the giveLoan
function.
Verifying that neither the interest rate nor the fees are zero can help prevent precision loss and trigger a reversal if necessary. Additionally, establishing a minimum loan size could ensure that the left side of the equation consistently exceeds the right side.
Another solution is creating a formula that always rounds up. This is in favor of the lender and the protocol as well. Something like this would suffice.
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.