DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Division by Zero Fallback Creates Critical Share Inflation Vector

Summary

The PerpetualVault contract contains a dangerous fallback mechanism when calculating share ratios. When totalAmountBefore is zero, instead of reverting the transaction, the code sets it to 1, which leads to severe share inflation. This edge case should never occur in normal operation, making it a signal of system compromise rather than a condition to handle gracefully.

Vulnerability Details

In the share calculation logic in the _mint function, the contract attempts to prevent division by zero with the following check:

if (totalAmountBefore == 0) totalAmountBefore = 1;
_shares = amount * totalShares / totalAmountBefore;

This occurs after calculating totalAmountBefore through one of two methods:

  1. totalAmountBefore = IERC20(indexToken).balanceOf(address(this)) - amount; (when position is open and using 1x leverage)

  2. totalAmountBefore = _totalAmount(prices) - amount; (in other cases)

However, if the system is functioning correctly, totalAmountBefore should never be zero because:

• In case 1: If we've swapped collateral for the index token, there must be a positive balance

  • In case 2: _totalAmount(prices) - amount should never in any case return 0 again

    A zero value indicates either:

    • A critical accounting error has occurred

    • The system has been manipulated

    • The price oracle has returned incorrect values

Impact

If this fallback is triggered, the consequences are severe:

  • The depositor would receive an extraordinarily large number of shares (amount * totalShares / 1)

  • This could lead to a single user obtaining control of nearly the entire vault

  • Future depositors would be severely diluted

  • The economic model of the vault would collapse

Tools Used

Manual Review

Recommendations

Replace with Reversion: Instead of handling this edge case with a fallback value, the function should revert the transaction with a clear error message:

if (totalAmountBefore == 0) {
revert Error.InvalidState(); // Or a more specific error
}
Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_totalAmountBefore_is_1_incorrect_calculation_supposition

No proof when this can happen: Most of the time totalAmountBefore equals 0 (balance minus amount sent), it means totalShares equals 0. If it could happen with very specific conditions, report with that tag didn't add the needed details to be validated.

Support

FAQs

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

Give us feedback!