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

Pnl of the currentposition is not accounted while deposit shares are calculated resulting in the correct share of pnl while withdrawing

Summary

Pnl of the currentposition is not accounted while deposit shares are calculated

Vulnerability Details

When calculating shares for deposits, the code uses:

if (totalShares == 0) {
_shares = depositInfo[depositId].amount * 1e8;
} else {
=> uint256 totalAmountBefore = _totalAmount(prices) - amount;
if (totalAmountBefore == 0) totalAmountBefore = 1;
_shares = amount * totalShares / totalAmountBefore;
}

And the _totalAmount() function:

function _totalAmount(MarketPrices memory prices) internal view returns (uint256) {
if (positionIsClosed) {
return collateralToken.balanceOf(address(this));
} else {
IVaultReader.PositionData memory positionData = vaultReader.getPositionInfo(curPositionKey, prices);
uint256 total = IERC20(indexToken).balanceOf(address(this)) * prices.indexTokenPrice.min / prices.shortTokenPrice.min
+ collateralToken.balanceOf(address(this))
=> + positionData.netValue / prices.shortTokenPrice.min;
return total;
}
}

Here, positionData.netValue includes: code

  • Collateral amount

  • Claimable funding fees

  • Minus pending fees to be paid

But crucially, it doesn't incorporate unrealized PnL from the position.

This creates a disparity:

  1. When users deposit, they receive shares based on the collateral amount only

  2. When users withdraw, their payout includes their proportion of both collateral and PnL

This means early depositors could end up sharing their profits with later depositors who didn't actually contribute to earning that profit. Similarly, if the position is losing money, later depositors would be unfairly diluted by bearing losses they weren't part of creating.

For example:

  • User A deposits 1000 USDC, gets 1000 shares

  • Position gains 500 USDC in profit

  • User B deposits 1000 USDC, gets ~1000 shares (not accounting for profit)

  • Total: 2000 shares for 2500 USDC value

  • If both withdraw, they each get 1250 USDC

This unfairly gives User B half of User A's profits, even though User B just deposited.

This represents a significant design flaw in the vault's share calculation mechanism that could lead to unfair profit/loss distribution among depositors.

Impact

Pnl is distributed incorrectly among withdraweers leading last withdrawers to gain more if the position is in profit.

Tools Used

Manual

Recommendations

Add position pnl also while calculating totalAMountBefore()

Updates

Lead Judging Commences

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

Support

FAQs

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