Summary
Whenever liquidation happens it is processed in afterLiquidationExecution :
function afterLiquidationExecution() external {
if (msg.sender != address(gmxProxy)) {
revert Error.InvalidCall();
}
depositPaused = true;
uint256 sizeInTokens = vaultReader.getPositionSizeInTokens(curPositionKey);
if (sizeInTokens == 0) {
delete curPositionKey;
}
if (flow == FLOW.NONE) {
flow = FLOW.LIQUIDATION;
nextAction.selector = NextActionSelector.FINALIZE;
} else if (flow == FLOW.DEPOSIT) {
flowData = sizeInTokens;
} else if (flow == FLOW.WITHDRAW) {
nextAction.selector = NextActionSelector.WITHDRAW_ACTION;
}
}
First thing that is done is that all deposits are paused so the function can prepare keeper to create order again with liquidated funds.
Vulnerability Details
The issue is that even after order with liquidated funds is created and executed depositing to the protocol still remain paused because depositPaused still remains true.
The owner can change that manually, but it is more efficient and convenient if that is done automatically.
Impact
Deposits will be paused when they should not be.
Tools Used
Manual Review.
Recommendations
Make the following change in finalize function:
function _finalize(bytes memory data) internal {
if (flow == FLOW.WITHDRAW) {
(uint256 prevCollateralBalance, bool positionClosed, bool refundFee) = abi.decode(data, (uint256, bool, bool));
uint256 withdrawn = collateralToken.balanceOf(address(this)) - prevCollateralBalance;
_handleReturn(withdrawn, positionClosed, refundFee);
+ } else if (flow == FLOW.DEPOSIT) {
+ if (depositPaused) {
+ depositPaused = false;
+ }
+ delete swapProgressData;
+ delete flowData;
+ delete flow;
} else {
delete swapProgressData;
delete flowData;
delete flow;
}
}