Summary
User call LendingPool.deposit
it invoked _rebalanceLiquidity
, if currentBuffer is higher than desiredBuffer then exess is transferred to curveVault . But asset token in R token contract not Lending Pool. So transaction is reverted.
Vulnerability Details
User call deposit function, the rebalanceLiquidity function will be invoked to rebalance the liquidity.
function _rebalanceLiquidity() internal {
if (address(curveVault) == address(0)) {
return;
}
uint256 totalDeposits = reserve.totalLiquidity;
uint256 desiredBuffer = totalDeposits.percentMul(liquidityBufferRatio);
uint256 currentBuffer = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
if (currentBuffer > desiredBuffer) {
uint256 excess = currentBuffer - desiredBuffer;
_depositIntoVault(excess);
} else if (currentBuffer < desiredBuffer) {
uint256 shortage = desiredBuffer - currentBuffer;
_withdrawFromVault(shortage);
}
emit LiquidityRebalanced(currentBuffer, totalVaultDeposits);
}
It checks the desiredBuffer
with the currentBuffer
, if there is an excess , it deposit the excess funds to curve vault.
function _depositIntoVault(uint256 amount) internal {
IERC20(reserve.reserveAssetAddress).approve(address(curveVault), amount);
curveVault.deposit(amount, address(this));
totalVaultDeposits += amount;
}
The transaction will now revert due to lack of tokens in the lending pool, the tokens are in the rToken
contract.
Impact
_rebalanceLiquidity will revert due to not having funds in the Lending Pool
contract.
Tools Used
Manual review
Recommendations
Consider excess amount is transferred to the lending pool
in _depositIntoVault function.
function _depositIntoVault(uint256 amount) internal {
@> IRToken(reserve.reserveRTokenAddress).transferAsset(address(this), amount);
IERC20(reserve.reserveAssetAddress).approve(address(curveVault), amount);
curveVault.deposit(amount, address(this));
totalVaultDeposits += amount;
}