`emergencyPause` does not check the state before running && can cause loss of funds for users
The `emergencyPause` function in the GMX smart contract can be called by the keeper at any time without pre-transaction checks. In some cases this could result in financial loss for users if the function is executed before the callbacks have executed.\\nThe emergencyPause function lacks a control mechanism to prevent execution before callbacks execution. While it is designed to halt all contract activities in an emergency, its unrestricted execution could disrupt ongoing transactions. For example, if a user calls a function like deposit which involves multiple steps and expects a callback, and emergencyPause is invoked before the callback is executed, the user might lose his funds as he will not be able to mint svTokens.\\nSince `emergencyPause` updates the state of the Vault to `GMXTypes.Status.Paused`, when the callback from GMX executes the `afterDepositExecution` nothing will happen since the conditions are not met. Which means that any deposit amount will not be met by a mint of svTokens.\\n```\\n  function afterDepositExecution(\\n    bytes32 depositKey,\\n    IDeposit.Props memory /* depositProps */,\\n    IEvent.Props memory /* eventData */\\n  ) external onlyController {\\n    GMXTypes.Store memory _store = vault.store();\\n\\n    if (\\n      _store.status == GMXTypes.Status.Deposit &&\\n      _store.depositCache.depositKey == depositKey\\n    ) {\\n      vault.processDeposit();\\n    } else if (\\n      _store.status == GMXTypes.Status.Rebalance_Add &&\\n      _store.rebalanceCache.depositKey == depositKey\\n    ) {\\n      vault.processRebalanceAdd();\\n    } else if (\\n      _store.status == GMXTypes.Status.Compound &&\\n      _store.compoundCache.depositKey == depositKey\\n    ) {\\n      vault.processCompound();\\n    } else if (\\n      _store.status == GMXTypes.Status.Withdraw_Failed &&\\n      _store.withdrawCache.depositKey == depositKey\\n    ) {\\n      vault.processWithdrawFailureLiquidityAdded();\\n    } else if (_store.status == GMXTypes.Status.Resume) {\\n      // This if block is to catch the Deposit callback after an\\n      // emergencyResume() to set the vault status to Open\\n      vault.processEmergencyResume();\\n    }\\n    \\n\\n@ > // The function does nothing as the conditions are not met\\n  }\\n```\\n\\nIf by any chance, the `processDeposit` function is executed (or any other function from the callback) it will still revert in the beforeChecks (like the beforeProcessDepositChecks).\\n```\\n  function beforeProcessDepositChecks(\\n    GMXTypes.Store storage self\\n  ) external view {\\n    if (self.status != GMXTypes.Status.Deposit)\\n      revert Errors.NotAllowedInCurrentVaultStatus();\\n  }\\n```\\n
To mitigate this risk, the following recommendations should be implemented:\\nIntroduce a state check mechanism that prevents emergencyPause from executing if there are pending critical operations that must be completed to ensure the integrity of in-progress transactions.\\nImplement a secure check that allows emergencyPause to queue behind critical operations, ensuring that any ongoing transaction can complete before the pause takes effect.
If the emergency pause is triggered at an inopportune time, it could:\\nPrevent the completion of in-progress transactions.\\nLead to loss of funds if the transactions are not properly rolled back.\\nErode user trust in the system due to potential for funds to be stuck without recourse.\\nPOC :\\nYou can copy this test in the file GMXEmergencyTest.t.sol then execute the test with the command forge test --mt\\n```\\n  function test_UserLosesFundsAfterEmergencyPause() external {\\n    deal(address(WETH), user1, 20 ether);\\n    uint256 wethBalanceBefore = IERC20(WETH).balanceOf(user1);\\n    vm.startPrank(user1);\\n    _createDeposit(address(WETH), 10e18, 1, SLIPPAGE, EXECUTION_FEE);\\n     vm.stopPrank();\\n\\n    vm.prank(owner);\\n    vault.emergencyPause();\\n\\n    vm.prank(user1);\\n    mockExchangeRouter.executeDeposit(\\n      address(WETH),\\n      address(USDC),\\n      address(vault),\\n      address(callback)\\n    );\\n    uint256 wethBalanceAfter = IERC20(WETH).balanceOf(user1);\\n    //Check that no tokens have been minted to user while user loses funds = 10 eth\\n    assertEq(IERC20(vault).balanceOf(user1), 0);\\n    assertEq(wethBalanceAfter, wethBalanceBefore - 10 ether);\\n\\n  }\\n```\\n
```\\n  function afterDepositExecution(\\n    bytes32 depositKey,\\n    IDeposit.Props memory /* depositProps */,\\n    IEvent.Props memory /* eventData */\\n  ) external onlyController {\\n    GMXTypes.Store memory _store = vault.store();\\n\\n    if (\\n      _store.status == GMXTypes.Status.Deposit &&\\n      _store.depositCache.depositKey == depositKey\\n    ) {\\n      vault.processDeposit();\\n    } else if (\\n      _store.status == GMXTypes.Status.Rebalance_Add &&\\n      _store.rebalanceCache.depositKey == depositKey\\n    ) {\\n      vault.processRebalanceAdd();\\n    } else if (\\n      _store.status == GMXTypes.Status.Compound &&\\n      _store.compoundCache.depositKey == depositKey\\n    ) {\\n      vault.processCompound();\\n    } else if (\\n      _store.status == GMXTypes.Status.Withdraw_Failed &&\\n      _store.withdrawCache.depositKey == depositKey\\n    ) {\\n      vault.processWithdrawFailureLiquidityAdded();\\n    } else if (_store.status == GMXTypes.Status.Resume) {\\n      // This if block is to catch the Deposit callback after an\\n      // emergencyResume() to set the vault status to Open\\n      vault.processEmergencyResume();\\n    }\\n    \\n\\n@ > // The function does nothing as the conditions are not met\\n  }\\n```\\n