Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Valid

Keeper can call Pause on closed vault

Summary

Closed market can be paused again

Vulnerability Details

For a market to be closed it should first be paused. However a closed market can be paused again which is something that shouldn't be possible. Since there are no checks for the emergencyPause(), meaning that it can be imposed on any state, which makes sense for most cases since it is used for emergency cases. However, the protocol shouldn't be able to be reverted from Closed to Paused, because closed is definitive, this is why we have the emergencyResume() function, to revert from Pause.

##POC

// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;
import { console, console2 } from "forge-std/Test.sol";
import { TestUtils } from "../../helpers/TestUtils.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { GMXMockVaultSetup } from "./GMXMockVaultSetup.t.sol";
import { GMXTypes } from "../../../contracts/strategy/gmx/GMXTypes.sol";
import { GMXTestHelper } from "./GMXTestHelper.sol";
contract GMXEmergencyTest is GMXMockVaultSetup, GMXTestHelper, TestUtils {
uint256 deadline = block.timestamp + 1000;
function test_emergencyClose() external {
vm.startPrank(owner);
_createAndExecuteDeposit(
address(WETH),
address(USDC),
address(WETH),
2e18,
0,
SLIPPAGE,
EXECUTION_FEE
);
vault.emergencyPause();
mockExchangeRouter.executeWithdrawal(
address(WETH),
address(USDC),
address(vault),
address(callback)
);
vault.emergencyClose(deadline);
(uint256 debtAAfter, uint256 debtBAfter) = vault.debtAmt();
assertEq(debtAAfter, 0, "debtAAfter not zero");
assertEq(debtBAfter, 0, "debtBAfter not zero");
assertEq(uint256(vault.store().status), 12, "vault status not set to closed");
vault.emergencyPause();
assertEq(uint256(vault.store().status), 10, "vault status not set to Paused");
}
}

Impact

Closed market can be paused after it has been closed. If such event were to happen it would be a further annoyance to the protocol users that cannot withdraw their funds anymore because the status has been reverted to Paused.

Tools Used

Manual review

Recommendations

Implement some checks before executing the Paused state to make sure the market isn't closed such as :

if (self.status == GMXTypes.Status.Closed) {
revert marketIsClosed();
}
Updates

Lead Judging Commences

hans Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Vault can be opened again after close

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.