The PerpetualVault contract's withdrawal function has a critical state management flaw in its ordering of operations. The contract processes token transfers before updating crucial vault state variables, violating best practices and potentially leading to stuck transactions or locked funds. This directly contradicts a key invariant stated in the protocol documentation: "Withdrawal Locks: No depositor should be able to withdraw their funds before the lockTime period has passed since their deposit."
The issue lies in _handleReturn
and _transferToken
, where state updates occur after external calls. This ordering means the contract's state doesn't accurately reflect the withdrawal process until after potentially risky external interactions complete.
The core issue manifests in the withdrawal flow's state management:
The flow violates best practices in several ways:
Token transfers occur before state updates
Share burning happens after token transfers
Total deposit amount updates after external interactions
Here's a test demonstrating the issue:
This vulnerability is particularly concerning because:
It violates the protocol's documented invariant about deposit/withdrawal consistency
The codebase shows consistent concerns about proper state management elsewhere (e.g., using enumerableSet for deposits)
The protocol documentation emphasizes the importance of "Total Shares Consistency"
Manual Review
Foundry
Implement proper state management order following the Checks-Effects-Interactions pattern.
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.
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.
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.
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.