Merkle Proof Explained in Detail
A Merkle proof proves that a leaf is part of a tree committed by a Merkle root. The proof contains the sibling hashes needed to recompute the root from the leaf.
Protocols use Merkle proofs for airdrops, allowlists, voting lists, reward claims, bridge messages, and other cases where storing every eligible item on-chain would be too expensive.
Smart contract example
The claim below proves inclusion but does not track whether the user already claimed:
function claim(uint256 amount, bytes32[] calldata proof) external {
bytes32 leaf = keccak256(abi.encode(msg.sender, amount));
require(MerkleProof.verify(proof, merkleRoot, leaf), "not eligible");
token.transfer(msg.sender, amount);
}
If there is no claimed bitmap or mapping, the same valid proof can be reused.
Merkle Proof in Auditing
A Merkle proof proves inclusion in one committed root. It does not prove that the root is correct, current, authorized, or unclaimed.
Auditors review whether the same proof can claim twice, claim in another campaign, claim for another token, or remain valid after root rotation.
Red flags in code
-
Leaf built from ambiguous packed values.
-
No claimed mapping, bitmap, nonce, or epoch separation.
-
Root can be changed by an unauthorized or weakly protected account.
-
Leaf omits claimant, amount, token, chain, campaign, pool ID, epoch, or claim index.
-
Proof verification succeeds for a stale root after a campaign should be closed.
How to test or review it
-
Attempt to claim twice with the same proof.
-
If the leaf uses packed encoding, generate adjacent dynamic values and check for encoding ambiguity.
-
Review who can update the root and whether updates need a timelock or multisig.
-
Test wrong amount, wrong claimant, wrong token, and wrong campaign inputs.
-
Confirm failed transfers or non-standard token behavior cannot desynchronize claim state.
Keep learning this topic
abi.encodePacked
abi.encodePacked is a Solidity encoding function that tightly packs values without the padding, offsets, and dynamic-length delimiters used by abi.encode.
Signature Replay
Signature replay happens when a valid signature can be reused more than once or reused in a different context than the signer intended.
Access Control Vulnerability
An access control vulnerability lets an unauthorized caller perform privileged actions such as moving funds, changing roles, upgrading contracts, or changing protocol settings.
Access Control Attacks
Access control attacks in Solidity: broken authorization patterns, privilege escalation paths, and secure role and ownership design.
Replay Attacks
See how this vulnerability appears in real smart contract audits.
Smart Contract Audit Checklist
Use this SCH tool to turn the concept into practical audit work.
Practice this in real audit scenarios
Definitions help, but auditors need reps. SCH turns concepts like Merkle Proof into exploit labs, code review habits, and report-writing practice.
Start the free trial or see the full smart contract auditing course.