A critical vulnerability has been identified in the LendingPool
contract where operations relying on _withdrawFromVault
can either cause a DoS or, in worse cases, lead to the burning of user funds. The root cause is an incorrect parameter being passed to the Curve vault's withdraw function, where the owner parameter is set to msg.sender
instead of address(this)
.
Root cause: In _withdrawFromVault
, the withdrawal call is made with:
Notice the third parameter (msg.sender
) incorrectly specifies the owner of the funds to be withdrawn, but the LendingPool (address(this)
) is the actual depositor and owner of the vault shares, not the end user.
Proof here:
This will cause all the functions that use _withdrawFromVault
to be DoS whenever there is a need to withdraw asset tokens from the Curve Vault:
As a result of this, we have the following issues:
The transaction will fail since the LendingPool lacks authorization to spend the user's vault shares
If a user authorizes share spending, their funds are permanently lost as their shares will be burned instead of LendingPool shares.
Users with existing deposits cannot withdraw their funds
All borrowing functionality is blocked
Before running the PoC we have to implement another related to the curveVault. Related submission here:
Or by the title "LendingPool deposits do not work with CurveVault due to lack of funds".
In the function _rebalanceLiquidity
from LendingPool
add the following line:
Install foundry through:
npm i --save-dev @nomicfoundation/hardhat-foundry
Add require("@nomicfoundation/hardhat-foundry");
on hardhat config file
Run npx hardhat init-foundry
and forge install foundry-rs/forge-std --no-commit
Create a file called LendingPool.t.sol
in the test
folder
Paste the code below:
run: forge test --match-test test_ensureLiquidityCauseDoS_dueToBurnSharesFromTheUser -vv
Result: LendingPool tries to burn user shares and revert:
DoS
Users attempting to withdraw or borrow will have their transactions revert
This occurs because users typically don't have Curve vault shares
Even if they do have shares, they haven't approved the LendingPool to spend them
Loss of Funds
If a user has Curve vault shares AND has approved the LendingPool to spend them
The transaction will succeed but burn the user's personal vault shares instead of the pool's shares
This results in a direct loss of user funds
Manual Review & Foundry
Related submission "LendingPool deposits do not work with CurveVault due to lack of funds"
In _withdrawFromVault
modify the withdraw call to use address(this)
as the owner parameter and send the withdrawn funds to the RToken contract. The fix will:
Burn the LendingPool shares
Send the assetToken
which is the crvUSD to RToken
.
Run the PoC again.
Result: LendingPool liquidity management works as expected.
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.