The _withdraw
function incorrectly will use the position's whole PnL instead of the user's proportional PnL. This will result in incorrectly overcharging users and inability to withdraw in some cases.
The _withdraw
function will try to deduct the user's proportional PnL from the collateral being withdrawn:
Here pnl is supposed to be only the pnl portion for the user. This is why sizeDeltaInUsd
is passed which is meant to reflect the user's portion of the position size:
However when we check out the vaultReader::getPnl
function we see that the following call to the gmxReader
is made:
However, here we can see that there is a hardcoded true
for the usePositionSizeAsSizeDeltaUsd
:
As a result the getPnl
will return the whole position Pnl instead of the Pnl corresponding to the user's share:
In case of a negative Pnl this will result in the user paying for the whole negative Pnl of the position here:
https://github.com/CodeHawks-Contests/2025-02-gamma/blob/84b9da452fc84762378481fa39b4087b10bab5e0/contracts/PerpetualVault.sol#L1112
In case the negative Pnl of the protocol is more than the position, users might be unable to withdraw during an active position, due to underflow.
Users who withdraw during an active position, will be overcharged in case of a negative Pnl.
Manual Review
Users should pay the negative Pnl based on their share, not the whole Pnl of the protocol's position in the gmx.
Likelihood: Medium/High, every withdrawal from a short or leveraged vault that is not liquidated and has a negative PnL. Impact: High, subtract collateralDeltaAmount from the entire PnL of the position instead of the delta amount PnL. DoS or loss of funds
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.