In proxy-based architectures, the logic implementation contract behind the proxy must be locked or initialized using _disableInitializers() to prevent unauthorized actors from claiming ownership.
In ThunderLoan.sol, the logic contract constructor omits _disableInitializers(). Any attacker can call initialize() directly on the implementation contract, become the owner, and execute upgradeToAndCall() with selfdestruct to permanently brick all active proxies.
Likelihood:
Occurs immediately upon contract deployment on mainnet or any EVM-compatible chain.
Attackers continuously scan mempools for uninitialized UUPS implementation contracts.
Impact:
Complete takeover of the logic implementation contract by an arbitrary attacker.
Permanent Denial of Service (DoS) if the implementation contract is destroyed or corrupted.
The exploit operates through the following steps:
Deployer deploys the ThunderLoan logic implementation contract.
An attacker detects that the logic implementation contract was left uninitialized.
The attacker calls ThunderLoan(implementation).initialize(address(0)).
The attacker is registered as owner and can upgrade the logic contract maliciously.
Add _disableInitializers() inside the constructor of ThunderLoan to permanently lock the logic implementation contract.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.