MerkleProof.sol 24 KB

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