Emergency Closed Vault Can Be Paused Then Resume
The `emergencyClose` function is intended to be a final measure to repay all debts and shut down the vault permanently, as indicated by the function's documentation. This action should be irreversible to ensure the finality and security of the vault's emergency closure process.\\n```\\nFile: GMXVaul.sol\\n  /**\\n    * @notice Repays all debt owed by vault and shut down vault, allowing emergency withdrawals\\n    * @dev Note that this is a one-way irreversible action\\n    * @dev Should be called by approved Owner (Timelock + MultiSig)\\n    * @param deadline Timestamp of swap deadline\\n  */\\n  function emergencyClose(uint256 deadline) external onlyOwner {\\n    GMXEmergency.emergencyClose(_store, deadline);\\n  }\\n```\\n\\nHowever, a pathway exists to effectively reopen a vault after it has been closed using `emergencyClose` by invoking the `emergencyPause` and `emergencyResume` functions. These functions alter the vault's status, allowing for the resumption of operations which contradicts the intended irreversible nature of an emergency close.\\n```\\nFile: GMXEmergency.sol\\n  function emergencyPause(\\n    GMXTypes.Store storage self\\n  ) external {\\n    self.refundee = payable(msg.sender);\\n\\n\\n    GMXTypes.RemoveLiquidityParams memory _rlp;\\n\\n\\n    // Remove all of the vault's LP tokens\\n    _rlp.lpAmt = self.lpToken.balanceOf(address(this));\\n    _rlp.executionFee = msg.value;\\n\\n\\n    GMXManager.removeLiquidity(\\n      self,\\n      _rlp\\n    );\\n\\n\\n    self.status = GMXTypes.Status.Paused;\\n\\n\\n    emit EmergencyPause();\\n  }\\n```\\n\\n```\\nFile: GMXEmergency.sol\\n  function emergencyResume(\\n    GMXTypes.Store storage self\\n  ) external {\\n    GMXChecks.beforeEmergencyResumeChecks(self);\\n\\n\\n    self.status = GMXTypes.Status.Resume;\\n\\n\\n    self.refundee = payable(msg.sender);\\n\\n\\n    GMXTypes.AddLiquidityParams memory _alp;\\n\\n\\n    _alp.tokenAAmt = self.tokenA.balanceOf(address(this));\\n    _alp.tokenBAmt = self.tokenB.balanceOf(address(this));\\n    _alp.executionFee = msg.value;\\n\\n\\n    GMXManager.addLiquidity(\\n      self,\\n      _alp\\n    );\\n  }\\n```\\n\\nAdd this to GMXEmergencyTest.t.sol and test with forge test --mt test_close_then_pause -vv:\\n```\\n  function test_close_then_pause() external {\\n    // Pause the vault\\n    vault.emergencyPause();\\n    console2.log("vault status", uint256(vault.store().status));\\n\\n    // Close the vault\\n    vault.emergencyClose(deadline);\\n    console2.log("vault status", uint256(vault.store().status));\\n\\n    // Pause the vault again\\n    vault.emergencyPause();\\n    console2.log("vault status", uint256(vault.store().status));\\n    assertEq(uint256(vault.store().status), 10, "vault status not set to paused");\\n\\n    // Resume the vault\\n    vault.emergencyResume();\\n    console2.log("vault status", uint256(vault.store().status));\\n  }\\n```\\n
Implement a permanent state or flag within the vault's storage to irrevocably mark the vault as closed after `emergencyClose` is called. This flag should prevent any further state-altering operations.\\nModify the `emergencyPause` and `emergencyResume` functions to check for this permanent closure flag and revert if the vault has been emergency closed.
The impact of this finding is significant, as it undermines the trust model of the emergency close process. Users and stakeholders expect that once a vault is closed in an emergency, it will remain closed as a protective measure. The ability to resume operations after an emergency closure could expose the vault to additional risks and potentially be exploited by malicious actors, especially if the original closure was due to a security threat.
```\\nFile: GMXVaul.sol\\n  /**\\n    * @notice Repays all debt owed by vault and shut down vault, allowing emergency withdrawals\\n    * @dev Note that this is a one-way irreversible action\\n    * @dev Should be called by approved Owner (Timelock + MultiSig)\\n    * @param deadline Timestamp of swap deadline\\n  */\\n  function emergencyClose(uint256 deadline) external onlyOwner {\\n    GMXEmergency.emergencyClose(_store, deadline);\\n  }\\n```\\n