@@ -105,9 +105,29 @@ library TreeNodeLib {
105105 // Type flags occupy bits 247 down to (247 - proof.length + 1)
106106 // This validates that bits (247 - proof.length) down to 0 are all zero
107107 if (proof.length < 247 ) {
108+ // --- Bit manipulation explanation for unused type flags ---
109+ // proofStructure layout (bytes32, 256 bits):
110+ // - Bits 255-248: Position index (8 bits, currently unused)
111+ // - Bits 247-0: Type flags (1 bit per proof element, up to 247 bits)
112+ //
113+ // For proof.length = N:
114+ // - Type flags use bits 247 down to (247 - N + 1)
115+ // - Unused type flag bits are (247 - N) down to 0, and must be zero
116+ //
117+ // Example: proof.length = 2
118+ // - mask = 0xFF00000000000000000000000000000000000000000000000000000000000000
119+ // (keeps bits 255-248 position index, plus bits 247-246 for 2 type flags)
120+ // - flagBits extracts bits 247-0 (all type flag bits)
121+ // - unusedMask = 0x0000000000000000000000000000000000000000000000000000003FFFFFFFFFFF
122+ // (checks bits 245-0 are zero, since bits 247-246 are used)
123+ //
124+ // Step 1: Create mask to keep position index and used type flag bits
108125 uint256 mask = type (uint256 ).max << (256 - 8 - proof.length );
126+ // Step 2: Extract only the type flag bits (bits 247-0)
109127 uint256 flagBits = uint256 (proofStructure) & ~ mask;
128+ // Step 3: Create mask for unused type flag bits (bits below used flags)
110129 uint256 unusedMask = type (uint256 ).max >> (8 + proof.length );
130+ // Step 4: Require that all unused type flag bits are zero
111131 require ((flagBits & unusedMask) == 0 , "Unused type flags must be zero " );
112132 }
113133
@@ -132,12 +152,11 @@ library TreeNodeLib {
132152 currentHash = combineLeafAndLeaf (typehash, currentHash, proof[i]);
133153 } else if (currentIsNode && proofIsNode) {
134154 currentHash = combineNodeAndNode (typehash, currentHash, proof[i]);
155+ } else if (currentIsNode && ! proofIsNode) {
156+ currentHash = combineNodeAndLeaf (typehash, currentHash, proof[i]);
135157 } else {
136- if (currentIsNode) {
137- currentHash = combineNodeAndLeaf (typehash, currentHash, proof[i]);
138- } else {
139- currentHash = combineNodeAndLeaf (typehash, proof[i], currentHash);
140- }
158+ // !currentIsNode && proofIsNode
159+ currentHash = combineNodeAndLeaf (typehash, proof[i], currentHash);
141160 }
142161
143162 // After first combine, result is always a Node
0 commit comments