The PerpetualVault contract is designed as an upgradeable contract but lacks a critical safeguard in its constructor: disabling the initializer. Without this measure, the initializer function remains callable after deployment, which can allow an attacker to front-run or maliciously reinitialize the contract, leading to unauthorized state changes.
Missing Constructor Safeguard:
Upgradeable contracts require the use of an initializer function rather than a constructor to set up state variables. However, if the initializer remains accessible, an attacker can call it after deployment, potentially taking control of the contract.
Risk of Unauthorized Reinitialization:
Without a constructor call to _disableInitializers(), the contract's initializer function can be invoked by any external actor. This can lead to an attacker setting undesirable initial values or gaining ownership, which undermines the integrity of the contract.
Front-Running Risk:
Attackers might monitor pending transactions and reinitialize the contract before the legitimate owner, effectively hijacking the contract’s intended initialization process.
Loss of Control:
Unauthorized reinitialization may result in the attacker seizing control over critical functions, including those that manage funds and access controls.
State Corruption:
An attacker may corrupt or manipulate the initial state of the contract, leading to unintended behavior or complete operational failure.
Financial Loss:
With control over the contract’s initialization, an attacker could potentially redirect funds or disrupt operations, resulting in financial losses for users and stakeholders.
Manual Code Review:
Detailed examination of the contract structure revealed the absence of a constructor that disables initializers.
Implement Constructor Safeguard:
Add a constructor that calls _disableInitializers() to ensure the initializer function cannot be called after deployment. This is a standard security measure recommended by OpenZeppelin for upgradeable contracts.
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.
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.