Core Contracts

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

Buffer comparisons with incorrect precision in `LendingPool::_rebalanceLiquidity` leads to mismanagement of funds and potential DOS.

Vulnerability Details

The LendingPool::_rebalanceLiquidity is used to rebalance liquidity in order to maintain the desired buffer ratio. It does so by comparing two values and based on that, determines whether to deposit into CurveVault or withdraw from it. The issue is, it's doing a direct comparison between them instead of scaling for precision first. The current situation is, currentBuffer (WAD precision) is compared against desiredBuffer (RAY precision) since reserve.totalLiquidity is in RAY precision (Currently, reserve.totalLiquidity stores wad values which is a separate issue).

uint256 totalDeposits = reserve.totalLiquidity; // Total liquidity in the system -> RAY PRECISION
uint256 desiredBuffer = totalDeposits.percentMul(liquidityBufferRatio); // RAY PRECISION
// @ audit current buffer is in wad precision
uint256 currentBuffer = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
// @ audit wad precision value being compared to ray precision value
@> if (currentBuffer > desiredBuffer) {}

This would resulting in following problems,

  1. If there's no liquidity in CurveVault initially, any function that calls _rebalanceLiquidity would experience
    DOS because, even in case of excess amount that should be deposited into curveVault, this would attempt to withdraw. Plus, it would try to withdraw a larger amount than necessary (RAY precision value) which would automatically result in DOS at later stage. The tests in LendingPool.test.js only work because ReserveLibrary erroneously updates the totalLiquidity by wad value without converting it to ray precision (a separate issue).

  2. The currentBuffer (WAD precision) would always be less than desiredBuffer (RAY) so the current implementation would
    always try to withdraw from the vault even when not needed, unnecessarily draining the vault until it's no longer
    possible, resulting in DOS.

Impact

The protocol will mistakenly withdraw from the vault leading to liquidity shortages and DOS in functions.

Tools Used

Manual Review

Recommendations

Convert desired buffer to wad using WadRayMath::rayToWad first since _depositIntoVault expects wad precision value.

uint256 totalDeposits = reserve.totalLiquidity; // Total liquidity in the system
uint256 desiredBuffer = totalDeposits.percentMul(liquidityBufferRatio);
+ desiredBuffer = desiredBuffer.rayToWad();
uint256 currentBuffer = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
if (currentBuffer > desiredBuffer) {}
Updates

Lead Judging Commences

inallhonesty Lead Judge
5 months ago
inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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