Skip to content

Commit

Permalink
Fix merkle multiProof for single leaf tree (OpenZeppelin#3446)
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx authored Jun 1, 2022
1 parent 6766b2d commit 2b0b0bb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
8 changes: 7 additions & 1 deletion contracts/utils/cryptography/MerkleProof.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ library MerkleProof {
hashes[i] = _hashPair(a, b);
}

return hashes[totalHashes - 1];
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leafsLen > 0) {
return leafs[0];
} else {
return proofs[0];
}
}

function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
Expand Down
20 changes: 20 additions & 0 deletions test/utils/cryptography/MerkleProof.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,25 @@ contract('MerkleProof', function (accounts) {
'reverted with panic code 0x32',
);
});

it('limit case: works for tree containing a single leaf', async function () {
const leaves = ['a'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });

const root = merkleTree.getRoot();
const proofLeaves = ['a'].map(keccak256).sort(Buffer.compare);
const proof = merkleTree.getMultiProof(proofLeaves);
const proofFlags = merkleTree.getProofFlags(proofLeaves, proof);

expect(await this.merkleProof.multiProofVerify(root, proofLeaves, proof, proofFlags)).to.equal(true);
});

it('limit case: can prove empty leaves', async function () {
const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare);
const merkleTree = new MerkleTree(leaves, keccak256, { sort: true });

const root = merkleTree.getRoot();
expect(await this.merkleProof.multiProofVerify(root, [], [ root ], [])).to.equal(true);
});
});
});

0 comments on commit 2b0b0bb

Please sign in to comment.