The _withdrawFromVault
function in LendingPool
incorrectly uses msg.sender
as the owner parameter when withdrawing from Curve vault. During borrowing, the vault attempts to burn shares from the borrower instead of from the LendingPool
, which actually owns them.
When a user attempts to borrow and RToken
does not have enough liquidity (as seen in balanceOf(reserve.reserveRTokenAddress)
), the protocol tries to withdraw from Curve vault:
In _withdrawFromVault
, msg.sender
is incorrectly passed as the owner who owns the shares, whereas LendingPool
actually owns them. It can be seen in _depositIntoVault
that address(this)
(LendingPool
) receives the shares. When borrowing, msg.sender
only seeks to borrow reserve assets using their NFT collateral:
The Curve vault's withdraw function requires the owner to have sufficient shares to burn:
The vault will try to burn shares from msg.sender
(the borrower) who does not own any vault shares as these are held by the LendingPool
.
High: All borrows requiring vault withdrawals will fail as the vault attempts to burn shares from the borrower who owns no shares.
Fix the owner parameter to be the LendingPool's address (address(this)
). Additionally, update the receiver to reserve.reserveRTokenAddress
(see the submission "Incorrect receiver in vault withdrawal" for this vulnerability):
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.