MerkleRootUpdated Declared but Never Emitted, Signals Missing FunctionalityFile: src/MerkleAirdrop.sol (line 21)
The contract declares a MerkleRootUpdated(bytes32 newMerkleRoot) event but there is no function that emits it, and i_merkleRoot is immutable — it can never change. This orphaned event declaration reveals a design inconsistency: either the developer intended to allow Merkle root updates (which would be a critical admin privilege vulnerability), or it is dead code left from a template. In either scenario, it represents a logic error.
i_merkleRoot is declared immutable:
Immutable variables in Solidity can only be set in the constructor and cannot be changed afterward. There is no setMerkleRoot() function anywhere. The event will never be emitted.
Why this matters from a security perspective:
Suggests planned but unimplemented functionality. If there was a setMerkleRoot() function that was accidentally removed/forgotten, the contract is missing an intended admin capability — potentially preventing recovery from the CRITICAL-3 decimal mismatch.
If a setMerkleRoot() function were added (e.g., in an upgrade), it would be a critical vulnerability: the owner could replace the Merkle root mid-airdrop, invalidate existing proofs, and create new ones pointing to attacker-controlled addresses, effectively stealing all remaining tokens.
ABI/tooling confusion: Off-chain indexers and monitoring tools that track MerkleRootUpdated events will never trigger, creating false confidence that the root is stable.
Dead code creates confusion and audit surface.
Signals incomplete implementation.
If root mutability was the intent, the current immutable design blocks emergency recovery from CRITICAL-3.
Severity: Medium (code quality / potential design flaw)
Manual analysis
grep / AST analysis
Remove the unused event entirely. If root updates are needed (e.g., for emergency recovery), implement properly with time-locks and governance:
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.