From c304b6710b4b5fcf2a319ad28c36c49df6caef14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernesto=20Garc=C3=ADa?= Date: Fri, 9 Aug 2024 15:03:20 -0600 Subject: [PATCH] Update MerkleProof note clarifying empty set definition (#5144) Co-authored-by: cairo Co-authored-by: sudo rm -rf --no-preserve-root / --- contracts/utils/cryptography/MerkleProof.sol | 36 +++++++++++++------- scripts/generate/templates/MerkleProof.js | 9 +++-- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/contracts/utils/cryptography/MerkleProof.sol b/contracts/utils/cryptography/MerkleProof.sol index f50752fed..6a0bc4d4e 100644 --- a/contracts/utils/cryptography/MerkleProof.sol +++ b/contracts/utils/cryptography/MerkleProof.sol @@ -169,9 +169,8 @@ library MerkleProof { * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * - * NOTE: The _empty set_ (i.e. the case where `proof.length == 0 && leaves.length == 0`) is considered a noop, - * and therefore a valid multiproof (i.e. it returns `true`). Consider disallowing this case if you're not - * validating the leaves elsewhere. + * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. + * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, @@ -193,6 +192,10 @@ library MerkleProof { * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). + * + * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, + * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not + * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, @@ -252,9 +255,8 @@ library MerkleProof { * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * - * NOTE: The _empty set_ (i.e. the case where `proof.length == 0 && leaves.length == 0`) is considered a noop, - * and therefore a valid multiproof (i.e. it returns `true`). Consider disallowing this case if you're not - * validating the leaves elsewhere. + * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. + * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, @@ -277,6 +279,10 @@ library MerkleProof { * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). + * + * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, + * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not + * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, @@ -337,9 +343,8 @@ library MerkleProof { * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * - * NOTE: The _empty set_ (i.e. the case where `proof.length == 0 && leaves.length == 0`) is considered a noop, - * and therefore a valid multiproof (i.e. it returns `true`). Consider disallowing this case if you're not - * validating the leaves elsewhere. + * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. + * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, @@ -361,6 +366,10 @@ library MerkleProof { * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). + * + * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, + * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not + * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, @@ -420,9 +429,8 @@ library MerkleProof { * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * - * NOTE: The _empty set_ (i.e. the case where `proof.length == 0 && leaves.length == 0`) is considered a noop, - * and therefore a valid multiproof (i.e. it returns `true`). Consider disallowing this case if you're not - * validating the leaves elsewhere. + * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. + * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, @@ -445,6 +453,10 @@ library MerkleProof { * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). + * + * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, + * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not + * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, diff --git a/scripts/generate/templates/MerkleProof.js b/scripts/generate/templates/MerkleProof.js index 7247d1626..80df713c7 100644 --- a/scripts/generate/templates/MerkleProof.js +++ b/scripts/generate/templates/MerkleProof.js @@ -89,9 +89,8 @@ const templateMultiProof = ({ suffix, location, visibility, hash }) => `\ * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * - * NOTE: The _empty set_ (i.e. the case where \`proof.length == 0 && leaves.length == 0\`) is considered a noop, - * and therefore a valid multiproof (i.e. it returns \`true\`). Consider disallowing this case if you're not - * validating the leaves elsewhere. + * NOTE: Consider the case where \`root == proof[0] && leaves.length == 0\` as it will return \`true\`. + * The \`leaves\` must be validated independently. See {processMultiProof${suffix}}. */ function multiProofVerify${suffix}(${formatArgsMultiline( `bytes32[] ${location} proof`, @@ -114,6 +113,10 @@ function multiProofVerify${suffix}(${formatArgsMultiline( * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). + * + * NOTE: The _empty set_ (i.e. the case where \`proof.length == 1 && leaves.length == 0\`) is considered a no-op, + * and therefore a valid multiproof (i.e. it returns \`proof[0]\`). Consider disallowing this case if you're not + * validating the leaves elsewhere. */ function processMultiProof${suffix}(${formatArgsMultiline( `bytes32[] ${location} proof`,