The LendingPool contract is checking liquidity at one address (reserve.reserveRTokenAddress
- the RToken contract) but actually performing transfers using a different address (address(this)
- the LendingPool contract).
In _ensureLiquidity
, the code checks the balance at reserve.reserveRTokenAddress
:
Similarly in _rebalanceLiquidity, it checks the balance at reserve.reserveRTokenAddress:
uint256 currentBuffer = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
However, in the vault operations, the transfers are happening to/from address(this) (LendingPool):
This is indeed a critical issue because:
The contract is checking liquidity at one address (reserve.reserveRTokenAddress
- the RToken contract) but actually performing transfers using a different address (address(this)
- the LendingPool contract).
This mismatch means that:
The liquidity checks could indicate sufficient funds when there aren't any at the actual transfer location
The liquidity checks could indicate insufficient funds when there are actually funds available at the transfer location
The rebalancing logic would be operating on incorrect balance information
This could lead to:
Failed transfers due to insufficient funds
Incorrect rebalancing decisions
Potential lockup of funds in either contract
Manual code review
Changing the vault deposit/withdraw operations to use reserve.reserveRTokenAddress
as the source/destination
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.