The borrow
function in the LendingPool
contract allows users to borrow more than the value of their collateral, which can lead to protocol insolvency. This critical vulnerability arises due to insufficient validation of the collateral-to-debt ratio during the borrowing process.
The root cause of this vulnerability lies in the LendingPool::borrow
function's logic for validating whether a user has sufficient collateral to cover their debt. Specifically, the function checks if the collateral value is greater than or equal to the user's total debt multiplied by the liquidationThreshold
. However, this logic is flawed because it does not prevent users from borrowing more than the actual value of their collateral.
In the borrow
function, the following check is performed:
Here, collateralValue
represents the total value of the user's collateral, and userTotalDebt
is the sum of the user's existing debt and the new borrowing amount. The liquidationThreshold
is a percentage (e.g., 80%) that determines the maximum allowable debt relative to the collateral value.
The issue is that the liquidationThreshold
is applied to the total debt rather than the borrowing amount. This means that even if the borrowing amount exceeds the collateral value, the check may still pass if the liquidationThreshold
is not restrictive enough. For example:
If the collateral value is 100 ether and the liquidationThreshold
is 80%, the user can borrow up to 125 ether (100 / 0.8 = 125).
This allows users to borrow more than their collateral value, which is unsafe and can lead to protocol insolvency.
A malicious user Deposits Collateral: A malicious user deposits an NFT as collateral, which is valued at 100 crvUSD.
User Borrows Funds: The malicious user attempts to borrow 125 crvUSDagainst the collateral.
Borrowing Succeeds: Despite the collateral being worth only 100 crvUSD, the user successfully borrows 125 crvUSD, exceeding the collateral value.
The vulnerability is demonstrated in the following Foundry test suite. Convert to foundry project using the steps highlighted here. Then in the test/
folder create a Test file named LendingPoolTest.t.sol
and paste the test into it. Make sure the imports path are correct and run the test using forge test --mt testBorrowMoreThanCollateral
:
In this test:
The user deposits an NFT valued at 100 crvUSD as collateral.
The user borrows 125 crvUSD, which exceeds the collateral value.
The borrowing succeeds, demonstrating the vulnerability.
Protocol Insolvency: Allowing users to borrow more than their collateral value can lead to a situation where the protocol cannot cover the outstanding debts, resulting in insolvency.
Loss of Funds: Users can exploit this vulnerability to drain the protocol's funds, leading to significant financial losses for other users and stakeholders.
Foundry: Used to write and execute the test suite that demonstrates the vulnerability.
Manual Review.
Stricter Collateral-to-Debt Ratio: Implement a stricter collateral-to-debt ratio check to ensure that users cannot borrow more than a certain percentage of their collateral value. For example, set a maximum loan-to-value (LTV) ratio of 80% to prevent over-borrowing.
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.