Critical vulnerability in PerpetualVault.sol where the emergency state management function setVaultState()
lacks proper validation and safety checks, allowing the admin to set inconsistent states that could lead to system corruption and fund loss.
In PerpetualVault.sol, the setVaultState()
function allows direct manipulation of critical system states:
Key vulnerabilities:
No validation of input parameters
No checks for state consistency
Can directly modify GMX lock state
No event emissions for transparency
Can set contradictory states (e.g. positionIsClosed=true with non-zero curPositionKey)
System state corruption leading to deadlocks
Potential loss of funds due to inconsistent position states
Interference with ongoing GMX operations
No transparency or tracking of emergency changes
Breaking core protocol assumptions and invariants
This PoC demonstrates how the setVaultState
function's lack of validation can lead to system corruption through two critical attack vectors:
This scenario shows how an admin (or compromised admin account) can corrupt the vault's state by setting contradictory values:
Initial Setup:
User deposits 5000 USDC into the vault
System starts in a clean, consistent state
Attack Execution:
Admin calls setVaultState with contradictory parameters
Sets positionIsClosed = true while also setting a non-zero positionKey
This creates an impossible state (closed position should have zero key)
Impact:
Withdrawal functionality breaks due to state inconsistency
System cannot recover without contract upgrade
User funds effectively locked
This scenario demonstrates how the function can be used to interfere with ongoing GMX operations:
Initial Setup:
Start a legitimate GMX operation (position change)
System sets GMX lock as expected
Attack Execution:
Admin interferes mid-operation by calling setVaultState
Removes GMX lock while operation is ongoing
Changes critical state variables during active operation
Impact:
GMX operation atomicity broken
Transaction can fail in unexpected ways
Potential loss of funds due to incomplete operations
The test cases provided in the PoC code systematically demonstrate both scenarios and their impacts on the system's functionality and user funds.
Manual code review
Foundry for testing
Static analysis with Aderyn
Add comprehensive validation and safety checks:
Additional recommendations:
Add timelock for emergency state changes
Implement step-by-step state transition functions
Add comprehensive event logging
Create automated state consistency checks
Add emergency pause functionality instead of direct state manipulation
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."
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.