The _ensureLiquidity() function in LendingPool.sol is responsible for ensuring that enough liquidity is available when a user borrows or withdraws funds. When liquidity is insufficient, it calls _withdrawFromVault() to retrieve funds from the CurveVault(part of the user deposits are send there). The issue arises because the withdrawn funds are sent to the LendingPool.sol contract instead of RToken.sol, which is responsible for transferring funds to users.
The function _ensureLiquidity() checks if there is enough liquidity in the RToken contract before processing a withdrawal:
If there is insufficient liquidity, it calculates the shortfall:
Then, _withdrawFromVault(requiredAmount); is called to withdraw the missing funds from CurveVault.
The _withdrawFromVault() function sends the funds to LendingPool.sol instead of RToken.sol, meaning the borrowed funds do not reach users.
Incorrect Behavior Flow
User requests a withdrawal → _ensureLiquidity(amount) is called.
Liquidity check fails → _withdrawFromVault(requiredAmount) is executed.
Funds are sent to LendingPool.sol instead of RToken.sol.
Withdrawal fails because RToken.sol does not receive the necessary funds.
Transaction failures: Users will experience reverts when trying to withdraw or borrow if the RToken.sol contract does not have sufficient funds.
Potential fund mismanagement: Funds sitting in LendingPool.sol instead of RToken.sol can cause accounting mismatches.
manual review
Modify _withdrawFromVault() to send funds directly to RToken.sol:
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.