MerkleProof.sol 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol)
  3. // This file was procedurally generated from scripts/generate/templates/MerkleProof.js.
  4. pragma solidity ^0.8.20;
  5. import {Hashes} from "./Hashes.sol";
  6. /**
  7. * @dev These functions deal with verification of Merkle Tree proofs.
  8. *
  9. * The tree and the proofs can be generated using our
  10. * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
  11. * You will find a quickstart guide in the readme.
  12. *
  13. * WARNING: You should avoid using leaf values that are 64 bytes long prior to
  14. * hashing, or use a hash function other than keccak256 for hashing leaves.
  15. * This is because the concatenation of a sorted pair of internal nodes in
  16. * the Merkle tree could be reinterpreted as a leaf value.
  17. * OpenZeppelin's JavaScript library generates Merkle trees that are safe
  18. * against this attack out of the box.
  19. *
  20. * IMPORTANT: Consider memory side-effects when using custom hashing functions
  21. * that access memory in an unsafe way.
  22. *
  23. * NOTE: This library supports proof verification for merkle trees built using
  24. * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving
  25. * leaf inclusion in trees built using non-commutative hashing functions requires
  26. * additional logic that is not supported by this library.
  27. */
  28. library MerkleProof {
  29. /**
  30. *@dev The multiproof provided is not valid.
  31. */
  32. error MerkleProofInvalidMultiproof();
  33. /**
  34. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  35. * defined by `root`. For this, a `proof` must be provided, containing
  36. * sibling hashes on the branch from the leaf to the root of the tree. Each
  37. * pair of leaves and each pair of pre-images are assumed to be sorted.
  38. *
  39. * This version handles proofs in memory with the default hashing function.
  40. */
  41. function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
  42. return processProof(proof, leaf) == root;
  43. }
  44. /**
  45. * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
  46. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  47. * hash matches the root of the tree. When processing the proof, the pairs
  48. * of leaves & pre-images are assumed to be sorted.
  49. *
  50. * This version handles proofs in memory with the default hashing function.
  51. */
  52. function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
  53. bytes32 computedHash = leaf;
  54. for (uint256 i = 0; i < proof.length; i++) {
  55. computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);
  56. }
  57. return computedHash;
  58. }
  59. /**
  60. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  61. * defined by `root`. For this, a `proof` must be provided, containing
  62. * sibling hashes on the branch from the leaf to the root of the tree. Each
  63. * pair of leaves and each pair of pre-images are assumed to be sorted.
  64. *
  65. * This version handles proofs in memory with a custom hashing function.
  66. */
  67. function verify(
  68. bytes32[] memory proof,
  69. bytes32 root,
  70. bytes32 leaf,
  71. function(bytes32, bytes32) view returns (bytes32) hasher
  72. ) internal view returns (bool) {
  73. return processProof(proof, leaf, hasher) == root;
  74. }
  75. /**
  76. * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
  77. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  78. * hash matches the root of the tree. When processing the proof, the pairs
  79. * of leaves & pre-images are assumed to be sorted.
  80. *
  81. * This version handles proofs in memory with a custom hashing function.
  82. */
  83. function processProof(
  84. bytes32[] memory proof,
  85. bytes32 leaf,
  86. function(bytes32, bytes32) view returns (bytes32) hasher
  87. ) internal view returns (bytes32) {
  88. bytes32 computedHash = leaf;
  89. for (uint256 i = 0; i < proof.length; i++) {
  90. computedHash = hasher(computedHash, proof[i]);
  91. }
  92. return computedHash;
  93. }
  94. /**
  95. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  96. * defined by `root`. For this, a `proof` must be provided, containing
  97. * sibling hashes on the branch from the leaf to the root of the tree. Each
  98. * pair of leaves and each pair of pre-images are assumed to be sorted.
  99. *
  100. * This version handles proofs in calldata with the default hashing function.
  101. */
  102. function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
  103. return processProofCalldata(proof, leaf) == root;
  104. }
  105. /**
  106. * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
  107. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  108. * hash matches the root of the tree. When processing the proof, the pairs
  109. * of leaves & pre-images are assumed to be sorted.
  110. *
  111. * This version handles proofs in calldata with the default hashing function.
  112. */
  113. function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
  114. bytes32 computedHash = leaf;
  115. for (uint256 i = 0; i < proof.length; i++) {
  116. computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);
  117. }
  118. return computedHash;
  119. }
  120. /**
  121. * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
  122. * defined by `root`. For this, a `proof` must be provided, containing
  123. * sibling hashes on the branch from the leaf to the root of the tree. Each
  124. * pair of leaves and each pair of pre-images are assumed to be sorted.
  125. *
  126. * This version handles proofs in calldata with a custom hashing function.
  127. */
  128. function verifyCalldata(
  129. bytes32[] calldata proof,
  130. bytes32 root,
  131. bytes32 leaf,
  132. function(bytes32, bytes32) view returns (bytes32) hasher
  133. ) internal view returns (bool) {
  134. return processProofCalldata(proof, leaf, hasher) == root;
  135. }
  136. /**
  137. * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
  138. * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
  139. * hash matches the root of the tree. When processing the proof, the pairs
  140. * of leaves & pre-images are assumed to be sorted.
  141. *
  142. * This version handles proofs in calldata with a custom hashing function.
  143. */
  144. function processProofCalldata(
  145. bytes32[] calldata proof,
  146. bytes32 leaf,
  147. function(bytes32, bytes32) view returns (bytes32) hasher
  148. ) internal view returns (bytes32) {
  149. bytes32 computedHash = leaf;
  150. for (uint256 i = 0; i < proof.length; i++) {
  151. computedHash = hasher(computedHash, proof[i]);
  152. }
  153. return computedHash;
  154. }
  155. /**
  156. * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
  157. * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
  158. *
  159. * This version handles multiproofs in memory with the default hashing function.
  160. *
  161. * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
  162. *
  163. * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
  164. * The `leaves` must be validated independently. See {processMultiProof}.
  165. */
  166. function multiProofVerify(
  167. bytes32[] memory proof,
  168. bool[] memory proofFlags,
  169. bytes32 root,
  170. bytes32[] memory leaves
  171. ) internal pure returns (bool) {
  172. return processMultiProof(proof, proofFlags, leaves) == root;
  173. }
  174. /**
  175. * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
  176. * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
  177. * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
  178. * respectively.
  179. *
  180. * This version handles multiproofs in memory with the default hashing function.
  181. *
  182. * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
  183. * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
  184. * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
  185. *
  186. * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
  187. * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
  188. * validating the leaves elsewhere.
  189. */
  190. function processMultiProof(
  191. bytes32[] memory proof,
  192. bool[] memory proofFlags,
  193. bytes32[] memory leaves
  194. ) internal pure returns (bytes32 merkleRoot) {
  195. // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
  196. // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
  197. // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
  198. // the Merkle tree.
  199. uint256 leavesLen = leaves.length;
  200. uint256 proofFlagsLen = proofFlags.length;
  201. // Check proof validity.
  202. if (leavesLen + proof.length != proofFlagsLen + 1) {
  203. revert MerkleProofInvalidMultiproof();
  204. }
  205. // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
  206. // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
  207. bytes32[] memory hashes = new bytes32[](proofFlagsLen);
  208. uint256 leafPos = 0;
  209. uint256 hashPos = 0;
  210. uint256 proofPos = 0;
  211. // At each step, we compute the next hash using two values:
  212. // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
  213. // get the next hash.
  214. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
  215. // `proof` array.
  216. for (uint256 i = 0; i < proofFlagsLen; i++) {
  217. bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
  218. bytes32 b = proofFlags[i]
  219. ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
  220. : proof[proofPos++];
  221. hashes[i] = Hashes.commutativeKeccak256(a, b);
  222. }
  223. if (proofFlagsLen > 0) {
  224. if (proofPos != proof.length) {
  225. revert MerkleProofInvalidMultiproof();
  226. }
  227. unchecked {
  228. return hashes[proofFlagsLen - 1];
  229. }
  230. } else if (leavesLen > 0) {
  231. return leaves[0];
  232. } else {
  233. return proof[0];
  234. }
  235. }
  236. /**
  237. * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
  238. * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
  239. *
  240. * This version handles multiproofs in memory with a custom hashing function.
  241. *
  242. * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
  243. *
  244. * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
  245. * The `leaves` must be validated independently. See {processMultiProof}.
  246. */
  247. function multiProofVerify(
  248. bytes32[] memory proof,
  249. bool[] memory proofFlags,
  250. bytes32 root,
  251. bytes32[] memory leaves,
  252. function(bytes32, bytes32) view returns (bytes32) hasher
  253. ) internal view returns (bool) {
  254. return processMultiProof(proof, proofFlags, leaves, hasher) == root;
  255. }
  256. /**
  257. * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
  258. * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
  259. * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
  260. * respectively.
  261. *
  262. * This version handles multiproofs in memory with a custom hashing function.
  263. *
  264. * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
  265. * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
  266. * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
  267. *
  268. * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
  269. * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
  270. * validating the leaves elsewhere.
  271. */
  272. function processMultiProof(
  273. bytes32[] memory proof,
  274. bool[] memory proofFlags,
  275. bytes32[] memory leaves,
  276. function(bytes32, bytes32) view returns (bytes32) hasher
  277. ) internal view returns (bytes32 merkleRoot) {
  278. // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
  279. // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
  280. // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
  281. // the Merkle tree.
  282. uint256 leavesLen = leaves.length;
  283. uint256 proofFlagsLen = proofFlags.length;
  284. // Check proof validity.
  285. if (leavesLen + proof.length != proofFlagsLen + 1) {
  286. revert MerkleProofInvalidMultiproof();
  287. }
  288. // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
  289. // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
  290. bytes32[] memory hashes = new bytes32[](proofFlagsLen);
  291. uint256 leafPos = 0;
  292. uint256 hashPos = 0;
  293. uint256 proofPos = 0;
  294. // At each step, we compute the next hash using two values:
  295. // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
  296. // get the next hash.
  297. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
  298. // `proof` array.
  299. for (uint256 i = 0; i < proofFlagsLen; i++) {
  300. bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
  301. bytes32 b = proofFlags[i]
  302. ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
  303. : proof[proofPos++];
  304. hashes[i] = hasher(a, b);
  305. }
  306. if (proofFlagsLen > 0) {
  307. if (proofPos != proof.length) {
  308. revert MerkleProofInvalidMultiproof();
  309. }
  310. unchecked {
  311. return hashes[proofFlagsLen - 1];
  312. }
  313. } else if (leavesLen > 0) {
  314. return leaves[0];
  315. } else {
  316. return proof[0];
  317. }
  318. }
  319. /**
  320. * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
  321. * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
  322. *
  323. * This version handles multiproofs in calldata with the default hashing function.
  324. *
  325. * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
  326. *
  327. * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
  328. * The `leaves` must be validated independently. See {processMultiProofCalldata}.
  329. */
  330. function multiProofVerifyCalldata(
  331. bytes32[] calldata proof,
  332. bool[] calldata proofFlags,
  333. bytes32 root,
  334. bytes32[] memory leaves
  335. ) internal pure returns (bool) {
  336. return processMultiProofCalldata(proof, proofFlags, leaves) == root;
  337. }
  338. /**
  339. * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
  340. * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
  341. * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
  342. * respectively.
  343. *
  344. * This version handles multiproofs in calldata with the default hashing function.
  345. *
  346. * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
  347. * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
  348. * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
  349. *
  350. * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
  351. * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
  352. * validating the leaves elsewhere.
  353. */
  354. function processMultiProofCalldata(
  355. bytes32[] calldata proof,
  356. bool[] calldata proofFlags,
  357. bytes32[] memory leaves
  358. ) internal pure returns (bytes32 merkleRoot) {
  359. // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
  360. // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
  361. // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
  362. // the Merkle tree.
  363. uint256 leavesLen = leaves.length;
  364. uint256 proofFlagsLen = proofFlags.length;
  365. // Check proof validity.
  366. if (leavesLen + proof.length != proofFlagsLen + 1) {
  367. revert MerkleProofInvalidMultiproof();
  368. }
  369. // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
  370. // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
  371. bytes32[] memory hashes = new bytes32[](proofFlagsLen);
  372. uint256 leafPos = 0;
  373. uint256 hashPos = 0;
  374. uint256 proofPos = 0;
  375. // At each step, we compute the next hash using two values:
  376. // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
  377. // get the next hash.
  378. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
  379. // `proof` array.
  380. for (uint256 i = 0; i < proofFlagsLen; i++) {
  381. bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
  382. bytes32 b = proofFlags[i]
  383. ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
  384. : proof[proofPos++];
  385. hashes[i] = Hashes.commutativeKeccak256(a, b);
  386. }
  387. if (proofFlagsLen > 0) {
  388. if (proofPos != proof.length) {
  389. revert MerkleProofInvalidMultiproof();
  390. }
  391. unchecked {
  392. return hashes[proofFlagsLen - 1];
  393. }
  394. } else if (leavesLen > 0) {
  395. return leaves[0];
  396. } else {
  397. return proof[0];
  398. }
  399. }
  400. /**
  401. * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
  402. * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
  403. *
  404. * This version handles multiproofs in calldata with a custom hashing function.
  405. *
  406. * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
  407. *
  408. * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.
  409. * The `leaves` must be validated independently. See {processMultiProofCalldata}.
  410. */
  411. function multiProofVerifyCalldata(
  412. bytes32[] calldata proof,
  413. bool[] calldata proofFlags,
  414. bytes32 root,
  415. bytes32[] memory leaves,
  416. function(bytes32, bytes32) view returns (bytes32) hasher
  417. ) internal view returns (bool) {
  418. return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == root;
  419. }
  420. /**
  421. * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
  422. * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
  423. * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
  424. * respectively.
  425. *
  426. * This version handles multiproofs in calldata with a custom hashing function.
  427. *
  428. * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
  429. * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
  430. * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
  431. *
  432. * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,
  433. * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not
  434. * validating the leaves elsewhere.
  435. */
  436. function processMultiProofCalldata(
  437. bytes32[] calldata proof,
  438. bool[] calldata proofFlags,
  439. bytes32[] memory leaves,
  440. function(bytes32, bytes32) view returns (bytes32) hasher
  441. ) internal view returns (bytes32 merkleRoot) {
  442. // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
  443. // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
  444. // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
  445. // the Merkle tree.
  446. uint256 leavesLen = leaves.length;
  447. uint256 proofFlagsLen = proofFlags.length;
  448. // Check proof validity.
  449. if (leavesLen + proof.length != proofFlagsLen + 1) {
  450. revert MerkleProofInvalidMultiproof();
  451. }
  452. // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
  453. // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
  454. bytes32[] memory hashes = new bytes32[](proofFlagsLen);
  455. uint256 leafPos = 0;
  456. uint256 hashPos = 0;
  457. uint256 proofPos = 0;
  458. // At each step, we compute the next hash using two values:
  459. // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
  460. // get the next hash.
  461. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
  462. // `proof` array.
  463. for (uint256 i = 0; i < proofFlagsLen; i++) {
  464. bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
  465. bytes32 b = proofFlags[i]
  466. ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
  467. : proof[proofPos++];
  468. hashes[i] = hasher(a, b);
  469. }
  470. if (proofFlagsLen > 0) {
  471. if (proofPos != proof.length) {
  472. revert MerkleProofInvalidMultiproof();
  473. }
  474. unchecked {
  475. return hashes[proofFlagsLen - 1];
  476. }
  477. } else if (leavesLen > 0) {
  478. return leaves[0];
  479. } else {
  480. return proof[0];
  481. }
  482. }
  483. }