Browse Source

Add test and docs describing a misuse of MerkleProof (#3090)

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
Doug Hoyte 3 years ago
parent
commit
4f8af2dceb

+ 6 - 1
contracts/utils/cryptography/MerkleProof.sol

@@ -11,6 +11,11 @@ pragma solidity ^0.8.0;
  * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
  *
  * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
+ *
+ * WARNING: You should avoid using leaf values that are 64 bytes long prior to
+ * hashing, or use a hash function other than keccak256 for hashing leaves.
+ * This is because the concatenation of a sorted pair of internal nodes in
+ * the merkle tree could be reinterpreted as a leaf value.
  */
 library MerkleProof {
     /**
@@ -28,7 +33,7 @@ library MerkleProof {
     }
 
     /**
-     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
+     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
      * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
      * hash matches the root of the tree. When processing the proof, the pairs
      * of leafs & pre-images are assumed to be sorted.

+ 6 - 0
test/utils/cryptography/MerkleProof.test.js

@@ -24,6 +24,12 @@ contract('MerkleProof', function (accounts) {
       const proof = merkleTree.getHexProof(leaf);
 
       expect(await this.merkleProof.verify(proof, root, leaf)).to.equal(true);
+
+      // For demonstration, it is also possible to create valid proofs for certain 64-byte values *not* in elements:
+      const noSuchLeaf = keccak256(
+        Buffer.concat([keccak256(elements[0]), keccak256(elements[1])].sort(Buffer.compare)),
+      );
+      expect(await this.merkleProof.verify(proof.slice(1), root, noSuchLeaf)).to.equal(true);
     });
 
     it('returns false for an invalid Merkle proof', async function () {