Critical vulnerability in PerpetualVault.sol where the state transition of withdrawal flows can permanently lock user funds due to incorrect state management in the withdraw process.
In PerpetualVault.sol, the withdrawal process involves multiple state transitions through the flow
variable. If a withdrawal is initiated while the previous action is being settled, the contract enters an unrecoverable state:
The vulnerability occurs because:
Flow state is changed to WITHDRAW before position settlement
If settlement fails, the flow remains in WITHDRAW state
No mechanism exists to reset the flow state
Future withdrawals are blocked due to _noneFlow()
check
User funds can become permanently locked
No way to recover from failed settlement state
Entire vault functionality can be blocked
Potential loss of all deposited funds in worst case
Scenario:
Initial vault setup with deposits
Failed settlement during withdrawal
Demonstration of permanent lock state
Here's a complete test case that demonstrates the vulnerability:
Initial Setup (Steps 1-2):
User1 deposits 5000 USDC
A long position is opened to create settlement requirement
This simulates normal vault operation
Settlement Failure (Steps 3-4):
GMX settlement is mocked to fail
User1's withdrawal attempt triggers state change to WITHDRAW
Settlement fails but state remains in WITHDRAW
Permanent Lock (Steps 5-8):
System enters unrecoverable state
All new deposits are blocked
All withdrawals are blocked
State persists even after GMX settlement is fixed
Impact Demonstration:
User funds are locked
No administrative function exists to reset state
Contract requires redeployment to recover
This POC uses Foundry's testing framework and demonstrates how a simple GMX settlement failure can lead to a complete vault lockdown with no recovery mechanism.
The most critical aspect demonstrated here is that even after the underlying GMX issue is resolved, the vault remains in an unrecoverable state, requiring contract redeployment to fix.
Manual code review
Foundry for testing
Add flow state rollback mechanism and move state transition after successful settlement:
This ensures that:
Flow state only changes after successful settlement
Failed settlements don't corrupt the flow state
Users can retry withdrawals if settlement fails
Adds proper error handling and state recovery
There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.
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.