The LendingPool aligns with Aave protocol contracts so they are similar in operations, but since RAAC protocol stores values in RAY precision instead, it introduces vulnerabilities in the contract.
The amount argument that LendingPool::borrow takes is in wad precision. It's used in the following places without getting converted to RAY precision first,
To calculate userTotalDebt - The userTotalDebt is a ray-precision value calculated by adding two values,
Actual debt so far (scaledDebtBalance * usageIndex). This is ray precision value since it uses rayMul which multiplies 2 ray values.
amount - wad precision value that user wants to borrow.
Adding wad value to ray value would result in a lower userTotalDebt value. This gets compared to collateralValue to check if user has enough collateral in value to borrow more. A lower userTotalDebt would allow user to borrow more than what their collateral is worth.
To update scaledDebtBalance - This requires normalizing the amount first before storing it. The issue is,
amount is directly used with rayDiv without getting converted to RAY first.
This results in an incorrect scaledDebtBalance in wad precision when it should be in RAY precision. Furthermore, this issue of amount being directly used is present in the following functions with following problems,
LendingPool::_repay - wad amount is compared against userScaledDebt (ray) leading to the actualRepayAmount always being the
complete debt of user resulting in only the complete repayment even if user intended to repay partially
because amount (wad) would always be less than scaledDebtBalance(supposed to be a ray value)
Not converting wad values to ray would lead to tiny rounding errors that can snowball into massive inaccuracies over time and it's important to maintain the precision of the values in a protocol that deals with linear and compounded interest and records values in RAY precision. In addition, it introduces other problems, such as full repay of debt even when repay was triggered for partial repayment.
Manual Review
In LendingPool::borrow, LendingPool::withdraw and other parts of the protocol, convert the amount argument to ray first before using with rayDiv or rayMul,
LendingPool::borrow:
LendingPool::_repay:
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.