@@ -105,7 +105,7 @@ library MerkleProof {
105
105
* This version handles proofs in calldata with the default hashing function.
106
106
*/
107
107
function verifyCalldata (bytes32 [] calldata proof , bytes32 root , bytes32 leaf ) internal pure returns (bool ) {
108
- return processProof (proof, leaf) == root;
108
+ return processProofCalldata (proof, leaf) == root;
109
109
}
110
110
111
111
/**
@@ -138,7 +138,7 @@ library MerkleProof {
138
138
bytes32 leaf ,
139
139
function (bytes32 , bytes32 ) view returns (bytes32 ) hasher
140
140
) internal view returns (bool ) {
141
- return processProof (proof, leaf, hasher) == root;
141
+ return processProofCalldata (proof, leaf, hasher) == root;
142
142
}
143
143
144
144
/**
@@ -200,15 +200,16 @@ library MerkleProof {
200
200
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
201
201
// the Merkle tree.
202
202
uint256 leavesLen = leaves.length ;
203
+ uint256 proofFlagsLen = proofFlags.length ;
203
204
204
205
// Check proof validity.
205
- if (leavesLen + proof.length != proofFlags. length + 1 ) {
206
+ if (leavesLen + proof.length != proofFlagsLen + 1 ) {
206
207
revert MerkleProofInvalidMultiproof ();
207
208
}
208
209
209
210
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
210
211
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
211
- bytes32 [] memory hashes = new bytes32 [](proofFlags. length );
212
+ bytes32 [] memory hashes = new bytes32 [](proofFlagsLen );
212
213
uint256 leafPos = 0 ;
213
214
uint256 hashPos = 0 ;
214
215
uint256 proofPos = 0 ;
@@ -217,20 +218,20 @@ library MerkleProof {
217
218
// get the next hash.
218
219
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
219
220
// `proof` array.
220
- for (uint256 i = 0 ; i < proofFlags. length ; i++ ) {
221
+ for (uint256 i = 0 ; i < proofFlagsLen ; i++ ) {
221
222
bytes32 a = leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ];
222
223
bytes32 b = proofFlags[i]
223
224
? (leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ])
224
225
: proof[proofPos++ ];
225
226
hashes[i] = Hashes.commutativeKeccak256 (a, b);
226
227
}
227
228
228
- if (proofFlags. length > 0 ) {
229
+ if (proofFlagsLen > 0 ) {
229
230
if (proofPos != proof.length ) {
230
231
revert MerkleProofInvalidMultiproof ();
231
232
}
232
233
unchecked {
233
- return hashes[proofFlags. length - 1 ];
234
+ return hashes[proofFlagsLen - 1 ];
234
235
}
235
236
} else if (leavesLen > 0 ) {
236
237
return leaves[0 ];
@@ -280,15 +281,16 @@ library MerkleProof {
280
281
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
281
282
// the Merkle tree.
282
283
uint256 leavesLen = leaves.length ;
284
+ uint256 proofFlagsLen = proofFlags.length ;
283
285
284
286
// Check proof validity.
285
- if (leavesLen + proof.length != proofFlags. length + 1 ) {
287
+ if (leavesLen + proof.length != proofFlagsLen + 1 ) {
286
288
revert MerkleProofInvalidMultiproof ();
287
289
}
288
290
289
291
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
290
292
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
291
- bytes32 [] memory hashes = new bytes32 [](proofFlags. length );
293
+ bytes32 [] memory hashes = new bytes32 [](proofFlagsLen );
292
294
uint256 leafPos = 0 ;
293
295
uint256 hashPos = 0 ;
294
296
uint256 proofPos = 0 ;
@@ -297,20 +299,20 @@ library MerkleProof {
297
299
// get the next hash.
298
300
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
299
301
// `proof` array.
300
- for (uint256 i = 0 ; i < proofFlags. length ; i++ ) {
302
+ for (uint256 i = 0 ; i < proofFlagsLen ; i++ ) {
301
303
bytes32 a = leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ];
302
304
bytes32 b = proofFlags[i]
303
305
? (leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ])
304
306
: proof[proofPos++ ];
305
307
hashes[i] = hasher (a, b);
306
308
}
307
309
308
- if (proofFlags. length > 0 ) {
310
+ if (proofFlagsLen > 0 ) {
309
311
if (proofPos != proof.length ) {
310
312
revert MerkleProofInvalidMultiproof ();
311
313
}
312
314
unchecked {
313
- return hashes[proofFlags. length - 1 ];
315
+ return hashes[proofFlagsLen - 1 ];
314
316
}
315
317
} else if (leavesLen > 0 ) {
316
318
return leaves[0 ];
@@ -331,9 +333,9 @@ library MerkleProof {
331
333
bytes32 [] calldata proof ,
332
334
bool [] calldata proofFlags ,
333
335
bytes32 root ,
334
- bytes32 [] calldata leaves
336
+ bytes32 [] memory leaves
335
337
) internal pure returns (bool ) {
336
- return processMultiProof (proof, proofFlags, leaves) == root;
338
+ return processMultiProofCalldata (proof, proofFlags, leaves) == root;
337
339
}
338
340
339
341
/**
@@ -351,22 +353,23 @@ library MerkleProof {
351
353
function processMultiProofCalldata (
352
354
bytes32 [] calldata proof ,
353
355
bool [] calldata proofFlags ,
354
- bytes32 [] calldata leaves
356
+ bytes32 [] memory leaves
355
357
) internal pure returns (bytes32 merkleRoot ) {
356
358
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
357
359
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
358
360
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
359
361
// the Merkle tree.
360
362
uint256 leavesLen = leaves.length ;
363
+ uint256 proofFlagsLen = proofFlags.length ;
361
364
362
365
// Check proof validity.
363
- if (leavesLen + proof.length != proofFlags. length + 1 ) {
366
+ if (leavesLen + proof.length != proofFlagsLen + 1 ) {
364
367
revert MerkleProofInvalidMultiproof ();
365
368
}
366
369
367
370
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
368
371
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
369
- bytes32 [] memory hashes = new bytes32 [](proofFlags. length );
372
+ bytes32 [] memory hashes = new bytes32 [](proofFlagsLen );
370
373
uint256 leafPos = 0 ;
371
374
uint256 hashPos = 0 ;
372
375
uint256 proofPos = 0 ;
@@ -375,20 +378,20 @@ library MerkleProof {
375
378
// get the next hash.
376
379
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
377
380
// `proof` array.
378
- for (uint256 i = 0 ; i < proofFlags. length ; i++ ) {
381
+ for (uint256 i = 0 ; i < proofFlagsLen ; i++ ) {
379
382
bytes32 a = leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ];
380
383
bytes32 b = proofFlags[i]
381
384
? (leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ])
382
385
: proof[proofPos++ ];
383
386
hashes[i] = Hashes.commutativeKeccak256 (a, b);
384
387
}
385
388
386
- if (proofFlags. length > 0 ) {
389
+ if (proofFlagsLen > 0 ) {
387
390
if (proofPos != proof.length ) {
388
391
revert MerkleProofInvalidMultiproof ();
389
392
}
390
393
unchecked {
391
- return hashes[proofFlags. length - 1 ];
394
+ return hashes[proofFlagsLen - 1 ];
392
395
}
393
396
} else if (leavesLen > 0 ) {
394
397
return leaves[0 ];
@@ -409,10 +412,10 @@ library MerkleProof {
409
412
bytes32 [] calldata proof ,
410
413
bool [] calldata proofFlags ,
411
414
bytes32 root ,
412
- bytes32 [] calldata leaves ,
415
+ bytes32 [] memory leaves ,
413
416
function (bytes32 , bytes32 ) view returns (bytes32 ) hasher
414
417
) internal view returns (bool ) {
415
- return processMultiProof (proof, proofFlags, leaves, hasher) == root;
418
+ return processMultiProofCalldata (proof, proofFlags, leaves, hasher) == root;
416
419
}
417
420
418
421
/**
@@ -430,23 +433,24 @@ library MerkleProof {
430
433
function processMultiProofCalldata (
431
434
bytes32 [] calldata proof ,
432
435
bool [] calldata proofFlags ,
433
- bytes32 [] calldata leaves ,
436
+ bytes32 [] memory leaves ,
434
437
function (bytes32 , bytes32 ) view returns (bytes32 ) hasher
435
438
) internal view returns (bytes32 merkleRoot ) {
436
439
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
437
440
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
438
441
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
439
442
// the Merkle tree.
440
443
uint256 leavesLen = leaves.length ;
444
+ uint256 proofFlagsLen = proofFlags.length ;
441
445
442
446
// Check proof validity.
443
- if (leavesLen + proof.length != proofFlags. length + 1 ) {
447
+ if (leavesLen + proof.length != proofFlagsLen + 1 ) {
444
448
revert MerkleProofInvalidMultiproof ();
445
449
}
446
450
447
451
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
448
452
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
449
- bytes32 [] memory hashes = new bytes32 [](proofFlags. length );
453
+ bytes32 [] memory hashes = new bytes32 [](proofFlagsLen );
450
454
uint256 leafPos = 0 ;
451
455
uint256 hashPos = 0 ;
452
456
uint256 proofPos = 0 ;
@@ -455,20 +459,20 @@ library MerkleProof {
455
459
// get the next hash.
456
460
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
457
461
// `proof` array.
458
- for (uint256 i = 0 ; i < proofFlags. length ; i++ ) {
462
+ for (uint256 i = 0 ; i < proofFlagsLen ; i++ ) {
459
463
bytes32 a = leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ];
460
464
bytes32 b = proofFlags[i]
461
465
? (leafPos < leavesLen ? leaves[leafPos++ ] : hashes[hashPos++ ])
462
466
: proof[proofPos++ ];
463
467
hashes[i] = hasher (a, b);
464
468
}
465
469
466
- if (proofFlags. length > 0 ) {
470
+ if (proofFlagsLen > 0 ) {
467
471
if (proofPos != proof.length ) {
468
472
revert MerkleProofInvalidMultiproof ();
469
473
}
470
474
unchecked {
471
- return hashes[proofFlags. length - 1 ];
475
+ return hashes[proofFlagsLen - 1 ];
472
476
}
473
477
} else if (leavesLen > 0 ) {
474
478
return leaves[0 ];
0 commit comments