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

Issue in Fee Denomination

Summary

The Perpetual Vault Protocol's withdrawal mechanism has a flaw in its fee and negative PnL adjustment process. Fees and losses are initially calculated in USD and later converted into collateral token units (USDC) using the oracle price of the short token. If the oracle price deviates from the intended 1:1 peg (even slightly, such as 0.98 instead of 1), this conversion results in an excessive deduction of collateral during withdrawals. This miscalculation disrupts the invariant ensuring that a depositor's share value remains unchanged, leading to an unfair redistribution of value among users.


Vulnerability Details

In the _withdraw function, fees and negative PnL are deducted from a user’s proportional collateral withdrawal amount (collateralDeltaAmount) as follows:

uint256 feeAmount = vaultReader.getPositionFeeUsd(market, sizeDeltaInUsd, false) / prices.shortTokenPrice.max;
int256 pnl = vaultReader.getPnl(curPositionKey, prices, sizeDeltaInUsd);
if (pnl < 0) {
collateralDeltaAmount = collateralDeltaAmount - feeAmount - uint256(-pnl) / prices.shortTokenPrice.max;
} else {
collateralDeltaAmount = collateralDeltaAmount - feeAmount;
}

Issue Explanation

  • Unit Mismatch:

    • vaultReader.getPositionFeeUsd(...) returns a fee in USD.

    • The fee is converted to collateral tokens by dividing by prices.shortTokenPrice.max.

    • If USDC is the collateral token, its expected value is 1 USD per token. However, if the oracle price deviates (e.g., 0.98 USD per USDC), the conversion leads to an excessive token deduction.

  • Negative PnL Conversion:

    • The negative profit/loss (pnl) is also converted using the same price factor.

    • This results in an overestimated loss deduction, exacerbating the issue.

Real-Life Scenario Simulation

Consider a user with a 10% share in a vault where:

  • The user’s rightful collateral amount is 1,000 USDC.

  • The position fee is 100 USD.

  • The user's negative PnL is 50 USD.

  • The oracle price for USDC is 0.98 USD per USDC.

What Happens with the Current Code

  • If the fee and PnL deductions are incorrectly calculated, they may result in more collateral being removed than intended.

  • Over multiple withdrawals, even minor discrepancies (e.g., 3–4 USDC per withdrawal) accumulate, unfairly reducing future withdrawals.


Impact

  • Breaks Value Invariance:
    This vulnerability violates the principle that each depositor’s share value should remain intact. Improper fee and loss deductions reduce the effective worth of each share.

  • Unfair Withdrawals:
    Users may withdraw less than their actual entitlement, while remaining vault funds appear inflated. Future depositors and withdrawers bear the burden of this discrepancy, leading to unintended losses.


Tools Used

  • Manual Code Review


Recommendations

  1. Ensure Consistent Unit Conversion:

    • Convert USD-based values (fees and PnL) using the collateral token price rather than the short token price.

    • Example Fix:

      uint256 feeAmountInCollateral = vaultReader.getPositionFeeUsd(market, sizeDeltaInUsd, false) / prices.collateralTokenPrice.max;
      uint256 pnlInCollateral = uint256(-pnl) / prices.collateralTokenPrice.max;
      if (pnl < 0) {
      collateralDeltaAmount -= (feeAmountInCollateral + pnlInCollateral);
      } else {
      collateralDeltaAmount -= feeAmountInCollateral;
      }
Updates

Lead Judging Commences

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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

Give us feedback!