The issue arises when a user borrows or liqidity provider withdraws reserve assets while there is insufficient liquidity in the protocol. The system is designed to withdraw liquidity from the Curve vault to fulfill the borrow request. However, there is a mismatch in where the liquidity is withdrawn to and how it is subsequently transferred to the borrower.
Borrow Function Flow(LendingPool::borrow
):
The user initiates a borrow request.
_ensureLiquidity(amount)
is called to check available liquidity.
If liquidity is insufficient, _withdrawFromVault(amount)
is executed to withdraw funds from the Curve vault.
Issue: The withdrawn funds are sent to address(this)
, which is the lending pool
contract, NOT the RToken
contract.
LendingPool::_ensureLiquidity
:
LendingPool::_withdrawFromVault
:
2.Transfer Mismatch:
After ensuring liquidity, the function LendingPool::borrow
attempts to transfer the borrowed amount to the user:
RToken::transferAsset
:
This function transfers funds from the RToken
contract to the borrower.
Problem: If liquidity was insufficient before the borrow call, the required funds were withdrawn to the Lending Pool, but the transfer still attempts to send them from the RToken
contract.
This results in a revert due to insufficient balance in the RToken
contract, even though the required liquidity exists in the Lending Pool.
Apart from the above the liquidity providers who had initally deposited asset tokens can also call LendingPool::withdraw
to burn their rtokens and get their amount of asset tokens back but even here the _ensureLiquidty is called so if liquidity is less tokens are again transferred to lending pool but to the user tokens are transfeered from RToken contract here.
Borrow transactions will fail when liquidity is low, even though liquidity is correctly withdrawn from Curve Vault.
The system fails to efficiently utilize Curve Vault liquidity, leading to poor capital efficiency.
Users attempting to withdraw their liquidity will experience transaction failures when the RToken contract has insufficient balance.
Even though liquidity was successfully withdrawn from Curve Vault, users cannot access their funds due to the same misalignment in transfer sources.
Manual
Modify _withdrawFromVault
to transfer the withdrawn liquidity directly to the RToken
contract, ensuring it has sufficient balance to process the borrow transaction.
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.