Description:
In PerpetualVault::_withdraw function, if there is an open GMX position and if pnl gets calculated as negative, when adjusting collateralDeltaAmount the negative PnL gets divided by prices.shortTokenPrice.max:
This is wrong, because dividing by a bigger value leads to smaller negative pnl and this goes against the protocol and in favor of the user. Instead, prices.shortTokenPrice.min should be used. This way the subtracted pnl will be bigger, and the collateralDeltaAmount will be in favor of the protocol.
Consider this example:
collateralDeltaAmount = 10000
feeAmount = 10
pnl = -1000
shortTokenPrice.max = 1.02
shortTokenPrice.min = 0.98
Current result (in favor of user):
collateralDeltaAmount = 10000 - 10 - 1000 / 1.02 = 9009,61
Correct result (in favor of protocol):
collateralDeltaAmount = 10000 - 10 - 1000 / 0.98 = 8 969,6
Difference between results = 9009,61 - 8 969,6 = 40,01
Of course the difference between results would be smaller if the gap bettwen min and max prices is smaller, but my point still stands.
Impact:
Users receive more funds than they should by not paying a part of their negative PnL.
Recommended Mitigation:
Divide the negative PnL by prices.shortTokenPrice.min, instead of prices.shortTokenPrice.max.
Example fix:
Likelihood: Low/Medium, every withdraw, position opened, not liquidated, beenShort or not 1, and the difference between minPrice and maxPrice is significant. Impact: Low, small part of feeAmount and PnL not deducted from collateralDeltaAmount.
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.