Skip to content

Commit be34d3d

Browse files
committed
more tests
1 parent 11e73be commit be34d3d

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

src/test/unit/libraries/Merkle.t.sol

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,65 @@ abstract contract MerkleBaseTest is Test, MurkyBase {
1515
/// Keccak + Sha256 Tests
1616
/// -----------------------------------------------------------------------
1717

18-
/// @notice Verifies that Murky's proofs are compatible with our tree and proof verification.
19-
function test_verifyInclusion_ValidProof() public {
20-
assertValidProofs();
18+
/// @notice Verifies that (Murky's) proofs are compatible with our implementation.
19+
function testFuzz_verifyInclusion_ValidProof(uint) public {
20+
checkAllProofs(true);
2121
}
2222

2323
/// @notice Verifies that an empty proof(s) is invalid.
24-
function test_verifyInclusion_EmptyProofs() public {
24+
function testFuzz_verifyInclusion_EmptyProofs(uint) public {
2525
proofs = new bytes[](proofs.length);
26-
assertInvalidProofs();
26+
checkAllProofs(false);
27+
}
28+
29+
/// @notice Verifies valid proofs cannot be used to prove invalid leaves.
30+
function testFuzz_verifyInclusion_WrongProofs(uint) public {
31+
bytes memory proof0 = proofs[0];
32+
bytes memory proof1 = proofs[1];
33+
(proofs[0], proofs[1]) = (proof1, proof0);
34+
checkSingleProof(false, 0);
35+
checkSingleProof(false, 1);
36+
}
37+
38+
/// @notice Verifies that a valid proof with excess data appended is invalid.
39+
function testFuzz_verifyInclusion_ExcessProofLength(uint) public {
40+
unchecked {
41+
proofs[0] = abi.encodePacked(proofs[0], vm.randomBytes(vm.randomUint(1, 10) * 32));
42+
}
43+
checkSingleProof(false, 0);
44+
}
45+
46+
/// @notice Verifies that a valid proof with a manipulated word is invalid.
47+
function testFuzz_verifyInclusion_ManipulatedProof(uint) public {
48+
bytes memory proof = proofs[0];
49+
/// @solidity memory-safe-assembly
50+
assembly {
51+
let m := add(proof, 0x20)
52+
let manipulated := shr(8, mload(m)) // Shift the first word to the right by 8 bits.
53+
mstore(m, manipulated)
54+
}
55+
proofs[0] = proof;
56+
checkSingleProof(false, 0);
2757
}
2858

2959
/// -----------------------------------------------------------------------
3060
/// Assertions
3161
/// -----------------------------------------------------------------------
3262

3363
/// @dev Checks that all proofs are valid for their respective leaves.
34-
function assertValidProofs() internal virtual {
64+
function checkAllProofs(bool status) internal virtual {
3565
function (bytes memory proof, bytes32 root, bytes32 leaf, uint256 index) returns (bool) verifyInclusion =
3666
usingSha ? Merkle.verifyInclusionSha256 : Merkle.verifyInclusionKeccak;
3767
for (uint i = 0; i < leaves.length; ++i) {
38-
assertTrue(verifyInclusion(proofs[i], root, leaves[i], i), "invalid proof");
68+
assertEq(verifyInclusion(proofs[i], root, leaves[i], i), status);
3969
}
4070
}
4171

42-
/// @dev Checks that all proofs are invalid for their respective leaves.
43-
function assertInvalidProofs() internal virtual {
72+
/// @dev Checks that a single proof is valid for its respective leaf.
73+
function checkSingleProof(bool status, uint index) internal virtual {
4474
function (bytes memory proof, bytes32 root, bytes32 leaf, uint256 index) returns (bool) verifyInclusion =
4575
usingSha ? Merkle.verifyInclusionSha256 : Merkle.verifyInclusionKeccak;
46-
for (uint i = 0; i < leaves.length; ++i) {
47-
assertFalse(verifyInclusion(proofs[i], root, leaves[i], i), "valid proof");
48-
}
76+
assertEq(verifyInclusion(proofs[index], root, leaves[index], index), status);
4977
}
5078

5179
/// -----------------------------------------------------------------------

0 commit comments

Comments
 (0)