Skip to content

Commit 2e9066c

Browse files
committed
fix(L-01): prevent uninitialized roots from being used (#1586)
<!-- 🚨 ATTENTION! 🚨 This PR template is REQUIRED. PRs not following this format will be closed without review. Requirements: - PR title must follow commit conventions: https://www.conventionalcommits.org/en/v1.0.0/ - Label your PR with the correct type (e.g., 🐛 Bug, ✨ Enhancement, 🧪 Test, etc.) - Provide clear and specific details in each section --> **Motivation:** Uninitialized roots can lead to issues like the [Nomad bridge hack](https://medium.com/nomad-xyz-blog/nomad-bridge-hack-root-cause-analysis-875ad2e5aacd). **Modifications:** * New error code and documentation * Added require statements for `verifyInclusion(Keccak|SHA256)` * Updated documentation for existing error code **Result:** Guard against unintialized roots being used in proofs
1 parent 018082b commit 2e9066c

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

src/contracts/libraries/Merkle.sol

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,32 @@ pragma solidity ^0.8.0;
1313
* be reinterpreted as a leaf value.
1414
*/
1515
library Merkle {
16-
// @notice Thrown when the provided proof was not a multiple of 32, or was empty for SHA256.
17-
// @dev Error code: 0x4dc5f6a4
16+
/// @notice Thrown when the provided proof was not a multiple of 32, or was empty for SHA256.
17+
/// @dev Error code: 0x4dc5f6a4
1818
error InvalidProofLength();
1919

20-
// @notice Thrown when the provided index was outside the max index for the tree.
21-
// @dev Error code: 0x63df8171
20+
/// @notice Thrown when the provided index was outside the max index for the tree.
21+
/// @dev Error code: 0x63df8171
2222
error InvalidIndex();
2323

24-
// @notice Thrown when the provided leaves' length was not a power of two.
25-
// @dev Error code: 0xf6558f51
24+
/// @notice Thrown when the provided leaves' length was not a power of two.
25+
/// @dev Error code: 0xf6558f51
2626
error LeavesNotPowerOfTwo();
2727

28-
// @notice Thrown when the provided leaves' length was 0.
29-
// @dev Error code: 0xbaec3d9a
28+
/// @notice Thrown when the provided leaves' length was 0.
29+
/// @dev Error code: 0xbaec3d9a
3030
error NoLeaves();
3131

32-
// @notice Thrown when the provided leaves' length was insufficient.
33-
// @dev Error code: 0xf8ef0367
34-
// @dev This is used for the SHA256 Merkle tree, where the tree must have more than 1 leaf.
32+
/// @notice Thrown when the provided leaves' length was insufficient.
33+
/// @dev Error code: 0xf8ef0367
34+
/// @dev This is used for the SHA256 Merkle tree, where the tree must have more than 1 leaf.
3535
error NotEnoughLeaves();
3636

37+
/// @notice Thrown when the root is empty.
38+
/// @dev Error code: 0x53ce4ece
39+
/// @dev Empty roots should never be valid. We prevent them to avoid issues like the Nomad bridge attack: <https://medium.com/nomad-xyz-blog/nomad-bridge-hack-root-cause-analysis-875ad2e5aacd>
40+
error EmptyRoot();
41+
3742
/**
3843
* @notice Verifies that a given leaf is included in a Merkle tree
3944
* @param proof The proof of inclusion for the leaf
@@ -52,6 +57,7 @@ library Merkle {
5257
bytes32 leaf,
5358
uint256 index
5459
) internal pure returns (bool) {
60+
require(root != bytes32(0), EmptyRoot());
5561
return processInclusionProofKeccak(proof, leaf, index) == root;
5662
}
5763

@@ -123,6 +129,7 @@ library Merkle {
123129
bytes32 leaf,
124130
uint256 index
125131
) internal view returns (bool) {
132+
require(root != bytes32(0), EmptyRoot());
126133
return processInclusionProofSha256(proof, leaf, index) == root;
127134
}
128135

0 commit comments

Comments
 (0)