Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

`LendingPool._rebalanceLiquidity()` doesn't work correctly

Summary

LendingPool._rebalanceLiquidity() rebalances liquidity between the buffer and the Curve vault to maintain the desired buffer ratio. However, it doesn't work correctly in case of currentBuffer is larger than desiredBuffer.

Vulnerability Details

When currentBuffer > desiredBuffer, pool deposits excess into the Curve vault.

function _rebalanceLiquidity() internal {
// if curve vault is not set, do nothing
if (address(curveVault) == address(0)) {
return;
}
uint256 totalDeposits = reserve.totalLiquidity; // Total liquidity in the system
uint256 desiredBuffer = totalDeposits.percentMul(liquidityBufferRatio);
uint256 currentBuffer = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
@> if (currentBuffer > desiredBuffer) {
uint256 excess = currentBuffer - desiredBuffer;
// Deposit excess into the Curve vault
_depositIntoVault(excess);
} else if (currentBuffer < desiredBuffer) {
uint256 shortage = desiredBuffer - currentBuffer;
// Withdraw shortage from the Curve vault
_withdrawFromVault(shortage);
}
emit LiquidityRebalanced(currentBuffer, totalVaultDeposits);
}

However, the pool doesn't hold any assets and RToken holds all deposited assets. Therefore, following function will revert and the pool can't deposit excess into Curve vault.

function _depositIntoVault(uint256 amount) internal {
@> IERC20(reserve.reserveAssetAddress).approve(address(curveVault), amount);
curveVault.deposit(amount, address(this));
totalVaultDeposits += amount;
}

We can check deposited assets sent to RToken in following code:

function deposit(ReserveData storage reserve,ReserveRateData storage rateData,uint256 amount,address depositor) internal returns (uint256 amountMinted) {
if (amount < 1) revert InvalidAmount();
// Update reserve interests
updateReserveInterests(reserve, rateData);
// Transfer asset from caller to the RToken contract
>> IERC20(reserve.reserveAssetAddress).safeTransferFrom(
msg.sender, // from
>> reserve.reserveRTokenAddress, // to
amount // amount
);
...
}

Impact

The pool can't deposit excess assets in the Curve vault.

Tools Used

Manual Review

Recommendations

Implement the mechanism which transfers the assets from the RToken to the Curve vault and update _rebalanceLiquidity().

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool::_depositIntoVault and _withdrawFromVault don't transfer tokens between RToken and LendingPool, breaking Curve vault interactions

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool::_depositIntoVault and _withdrawFromVault don't transfer tokens between RToken and LendingPool, breaking Curve vault interactions

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.