Missing code to delete nextAction
in afterOrderCancellation()
will result incorrect execution of FLOW.COMPOUND
deviating from the intented flow .
It also breaks the key invariant mentioned in the readMe
. (nextAction should be empty when all acitons are completed.
)
afterOrderCancellation()
is a callback fun which is executed by GMXproxy
when the gmxKeeper
cancels its current pending order.
If the pending order is because of the SIGNAL_CHANGE
flow , the code is only deleting the flow
and flowData
. gmxLock
is also disabled allowing the keeper and users to continue their operation , marking the completion of an action.
For a keeper to execute FLOW.COMPUND
, he just needs to call runNextAction()
with no precondition. As a result this code will get executed and COMPOUND FLOW
is generated.
Now lets say the current position is long with 2x leverage.
Keeper calls run() to convert the position to short.
As a result , nextAction.selector
is made to INCREASE_ACTION
and a decrease order is generate to be executed by the GMX.code
But GMX couldnt execute it and hence calls the callback function afterOrderCancellation()
.
Since the flow is SIGNAL_CHANGE
, the nextAction.selector
remains unchanged.
Note : It is mentioned in the dev cmnt that the offchain scripts starts again with the current status. That means next txn can be any action depending on the current state.
Now , the keeper , inorder to execute FLOW.COMPOUND
, calls runNextAction()
.
But, since the nextAction.selector
has the value INCREASE_ACTION
, it will execute the wrong if{}
condition code.
The key invariant in the readMe After all actions completed, nextAction, swapProgressData should be empty. PositionKey is 0 when no position
is broken.
Incorrect flow is executed deviating from the actual flow.
The check isFundIdle()
code is skipped before creating an increase Order. Hence the remaining collateral balance of the perps contract is used for increasing the position without checking the minDeposit threshold.
Manual
delete the nextAction
when the flow is SIGNAL_CHANGE
while the current action ends with afterOrderCancellation()
callback.
Normal behavior, the keeper will retry to increase the position. That’s why there is this condition in `_createIncreasePosition`: ``` if (flow == FLOW.DEPOSIT) { amountIn = depositInfo[counter].amount; flowData = vaultReader.getPositionSizeInTokens(curPositionKey); } else { amountIn = collateralToken.balanceOf(address(this)); } ```
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.