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

Fee Calculation Manipulation via Artificial Vault Balance Inflation

Summary

A vulnerability exists in the fee calculation mechanism of the PerpetualVault contract. The contract calculates withdrawal amounts and fees based on the total collateral balance of the vault. An attacker can artificially inflate this balance by directly transferring tokens into the vault, which then triggers fee calculations on an inflated "profit" during withdrawals. This manipulation can cause higher fees to be charged to all users, draining the vault’s funds over time.

Vulnerability Details

Mechanism:
The contract computes a user’s withdrawal amount as a share of the current vault balance using:

amount = collateralToken.balanceOf(address(this)) * shares / totalShares;
  • Fee Trigger:
    A fee is applied if:

    if (amount > depositInfo[depositId].amount) {
    fee = (amount - depositInfo[depositId].amount) * governanceFee / BASIS_POINTS_DIVISOR;
    if (fee > 0) { // fee transfer logic } }

    This means any increase in the vault balance—even from unauthorized injections—will be treated as profit.

  • Attack Vector:
    An attacker injects extra collateral tokens directly into the vault. This inflates the vault’s balance and forces the fee condition to trigger when a withdrawal occurs.

  • Impact on Withdrawals:
    Both the attacker and honest users will have a fee calculated on an artificially inflated profit, resulting in a net reduction of the withdrawal amounts relative to the true deposit value.

Impact

For Attackers:
Although they might not profit directly—since they lose on the extra tokens injected—they can force the system to impose high fees on every withdrawal.

  • For Honest Users:
    The inflated vault balance causes higher fees on withdrawals, effectively draining funds from the vault and diluting the value of each depositor's shares.

  • Overall Risk:
    Over time, repeated exploitation can significantly undermine the vault’s financial integrity, leading to systemic losses for all users.

Tools Used

Manual review

Recommendations

Implement an internal variable to track user deposits rather than relying solely on the raw token balance obtained via collateralToken.balanceOf(address(this)).

Updates

Lead Judging Commences

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

invalid_collateral_balanceOf_donation

Prevent tokens from getting stuck. This is a simple donation to every shareholder, and therefore, every share has more value (profit), leading to fewer shares for future users. If this is not intended by the user, it is merely a mistake! For totalAmountBefore > amount * totalShares, Here is the worst-case scenario (with the minimum amount): first deposit 0.001000 (e4) USDC → 1e12 shares. Second deposit: 0.001 (e4) USDC * 1e12 / 0.001 (e4) USDC. So, the attacker would need to donate 1e16 tokens, meaning 1e10 USDC → 10 billion $. Even in the worst case, it's informational.

Support

FAQs

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

Give us feedback!