Under an edge case where an order is cancelled , the deposit amounts and total deposited amounts have been accounted correctly , but the totalShares has not been accounted for which would lead to total shares being over inflated.
Consider the following ->
1.) A perp vault position is already open on GMX side.
2.) Alice comes to deposit , calls deposit()
and since positionIsClosed would be false ( as there is a position open on GMX) nextAction would be assigned to INCREASE_ACTION and data to beenLong
and the current flow would be flow = FLOW.DEPOSIT;
(L226 in PerpetualVault.sol)
3.) Keeper would trigger the function runNextAction()
and execution would enter this branch if (_nextAction.selector == NextActionSelector.INCREASE_ACTION) {
and at L369 _createIncreasePosition()
would be invoked.
4.) Inside _createIncreasePosition
firstly since flow is DEPOSIT we would ->
and then create an order on GMX of type MarketIncrease
(L886)
5.) Then the afterOrderExecution()
would be invoked (Callback function that is called when an order on GMX is executed successfully)
and since order type was market increase ->
based on the priceImpact _mint
would be called.
6.) And in _mint
depending on the totalShares and totalAmount new shares would be assigned in L777-L778
7.) And then next action would be assigned as FINALIZE on L495 ->
nextAction.selector = NextActionSelector.FINALIZE;
8.) Now for any reason keeper calls cancelFlow()
(can be called since gmxLock is set to false afterOrderExecution
hence is a possible action that can be taken according to the code) ->
and inside _cancelFlow()
->
9.) We can see that totalDepositAmount decreases and depositInfo
gets deleted (which would set user's shares and amount to 0) but totalShares
have
not been updated/decremented by the user's shares.
10.) This means in this case totalShares
would be overinflated and when the next user deposits he would be minted way higher shares ->
_shares = amount * totalShares / totalAmountBefore;
(inside _mint)
totalShares would be higher than expected and new minted shares would be over inflated
Manual analysis
In the _cancelFlow
if user had non-zero shares (in his depositInfo mapping) , then reduce that amount from the totalShares.
Likelihood: None/Very Low, when the keeper call cancelFlow after an order execution Impact: High, Inflation/deflation of total shares, and too many fees refunded.
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.