Core Contracts

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

Arithmetic Underflow in \_withdrawFromVault Due to Insufficient Total Vault Deposits Check

Summary

The _withdrawFromVault function in the LendingPool contract is designed to withdraw liquidity from an external Curve vault and update the internal tracking variable totalVaultDeposits. However, the function does not validate whether totalVaultDeposits is at least as large as the withdrawal amount. This omission can lead to an arithmetic underflow during the subtraction (totalVaultDeposits -= amount) if the amount requested exceeds the current totalVaultDeposits. Such an underflow may result in a transaction revert or other unexpected behavior, disrupting the liquidity rebalancing process.

Vulnerability Details

How It Begins

  • Function Behavior:

    The _withdrawFromVault function is implemented as follows:

    function _withdrawFromVault(uint256 amount) internal {
    curveVault.withdraw(amount, address(this), msg.sender, 0, new address[](0));
    // @info: not check if totalVaultDeposits is smaller than amount
    // @danger: an arithmetic underflow could occur
    totalVaultDeposits -= amount;
    }
  • Issue:

    The function lacks a check to ensure that totalVaultDeposits is greater than or equal to amount before performing the subtraction. If amount is greater than totalVaultDeposits, an arithmetic underflow will occur, which could revert the transaction and potentially leave the system in an inconsistent state.

Proof of Concept

Scenario Example

  1. Setup:

    • Assume that due to prior withdrawals or misconfiguration, totalVaultDeposits is recorded as 500e18.

    • A rebalancing operation or an external call triggers _withdrawFromVault with an amount of 600e18.

  2. Underflow Occurrence:

    • Without checking that totalVaultDeposits >= amount, the subtraction totalVaultDeposits -= amount attempts to subtract 600e18 from 500e18.

    • This operation results in an arithmetic underflow, which will revert the transaction and block the liquidity rebalancing process.

How to Run the Test

  1. Create a Foundry Project:
    Open your terminal and run:

    forge init my-foundry-project
  2. Place Contract Files:
    Place all relevant contract files (e.g., LendingPool.sol, CurveVault.sol, etc.) in the src directory of your project.

  3. Create Test Directory:
    Create a directory named test adjacent to the src directory, and add a test file (e.g., PoolsTest.t.sol) that includes a test simulating a scenario where totalVaultDeposits is less than the withdrawal amount.

  4. Run the Test:
    Execute the following command in your terminal:

    forge test --mt testWithdrawFromVaultUnderflow -vv

    This command will run the specific test case with verbose output, allowing you to verify that an arithmetic underflow occurs when attempting to withdraw more than the recorded totalVaultDeposits.

Impact

  • Transaction Reversion:
    An arithmetic underflow will revert the transaction, potentially preventing successful liquidity rebalancing.

  • Liquidity Disruption:
    Critical operations that rely on accurate tracking of vault deposits may fail, leading to broader liquidity and stability issues within the protocol.

  • Operational Instability:
    Repeated underflow conditions could lead to a denial of service (DoS) in liquidity management, adversely affecting both protocol performance and user experience.

Tools Used

  • Manual Review

  • Foundry (Forge)

Recommendations

To remediate this vulnerability, add a validation check in _withdrawFromVault to ensure that totalVaultDeposits is sufficient before proceeding with the withdrawal:

Recommended Diff

@@ In LendingPool.sol, function _withdrawFromVault:
- curveVault.withdraw(amount, address(this), msg.sender, 0, new address[](0));
- // @info: not check if totalVaultDeposits is smaller than amount
- // @danger: an arithmetic underflow could occur
- totalVaultDeposits -= amount;
+ // Ensure there is enough recorded deposit to cover the withdrawal
+ require(totalVaultDeposits >= amount, "Insufficient vault deposits");
+ curveVault.withdraw(amount, address(this), msg.sender, 0, new address[](0));
+ totalVaultDeposits -= amount;

By implementing this check, the function will revert with a clear error message if the withdrawal amount exceeds the available vault deposits, preventing an arithmetic underflow and maintaining system stability.

Updates

Lead Judging Commences

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

LendingPool::totalVaultDeposits can underflow when withdrawing yield-inclusive amounts and vault yield isn't factored into interest rate calculations

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

LendingPool::totalVaultDeposits can underflow when withdrawing yield-inclusive amounts and vault yield isn't factored into interest rate calculations

Support

FAQs

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

Give us feedback!