Skip to content

Commit

Permalink
🦹 further merkleproofverification fuzz test
Browse files Browse the repository at this point in the history
Signed-off-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch>
  • Loading branch information
pcaversaccio committed Jan 30, 2023
1 parent e6ff4a5 commit 4d185d3
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 5 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
node_modules
lib/create-util
lib/murky
lib/prb-test
lib/forge-std
lib/create-util
lib/solidity-bytes-utils
lib/openzeppelin-contracts
bin
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
url = https://github.com/paulrberg/prb-test.git
[submodule "lib/murky"]
path = lib/murky
url = https://github.com/dmfxyz/murky
url = https://github.com/dmfxyz/murky.git
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
lib/murky
lib/prb-test
lib/forge-std
lib/create-util
Expand Down
1 change: 1 addition & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
lib/murky
lib/prb-test
lib/forge-std
lib/create-util
Expand Down
1 change: 1 addition & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
utils/=lib/utils/
murky/=lib/murky/src/
prb/test/=lib/prb-test/src/
forge-std/=lib/forge-std/src/
create-util/=lib/create-util/contracts/
Expand Down
146 changes: 143 additions & 3 deletions test/utils/MerkleProofVerification.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ pragma solidity ^0.8.17;
import {Test} from "forge-std/Test.sol";
import {VyperDeployer} from "utils/VyperDeployer.sol";

import {Merkle} from "murky/Merkle.sol";

import {IMerkleProofVerification} from "./interfaces/IMerkleProofVerification.sol";

contract MerkleProofVerificationTest is Test {
VyperDeployer private vyperDeployer = new VyperDeployer();

IMerkleProofVerification private merkleProofVerification;
Merkle private merkleGenerator;

/**
* @dev An `internal` helper function that converts the JavaScript-based
Expand Down Expand Up @@ -278,6 +281,7 @@ contract MerkleProofVerificationTest is Test {
"MerkleProofVerification"
)
);
merkleGenerator = new Merkle();
}

function testVerify() public {
Expand Down Expand Up @@ -541,11 +545,147 @@ contract MerkleProofVerificationTest is Test {
);
}

/**
* @notice Forked and adjusted accordingly from here:
* https://github.com/Vectorized/solady/blob/main/test/MerkleProofLib.t.sol.
*/
function testFuzzVerify(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
bytes32[] calldata data,
uint256 randomness
) public {
vm.assume(data.length > 1);
uint256 nodeIndex = randomness % data.length;
bytes32 root = merkleGenerator.getRoot(data);
bytes32[] memory proof = merkleGenerator.getProof(data, nodeIndex);
bytes32 leaf = data[nodeIndex];
assertTrue(merkleProofVerification.verify(proof, root, leaf));
assertTrue(
!merkleProofVerification.verify(
proof,
bytes32(uint256(root) ^ 1),
leaf
)
);

proof[0] = bytes32(uint256(proof[0]) ^ 1);
assertTrue(!merkleProofVerification.verify(proof, root, leaf));
assertTrue(
!merkleProofVerification.verify(
proof,
bytes32(uint256(root) ^ 1),
leaf
)
);
}

/**
* @notice Forked and adjusted accordingly from here:
* https://github.com/Vectorized/solady/blob/main/test/MerkleProofLib.t.sol.
*/
function testFuzzMultiProofVerifySingleLeaf(
bytes32[] calldata data,
uint256 randomness
) public {
vm.assume(data.length > 1);
uint256 nodeIndex = randomness % data.length;
bytes32 root = merkleGenerator.getRoot(data);
bytes32[] memory proof = merkleGenerator.getProof(data, nodeIndex);
bytes32[] memory leaves = new bytes32[](1);
leaves[0] = data[nodeIndex];
bool[] memory proofFlags = new bool[](proof.length);
assertTrue(
merkleProofVerification.multi_proof_verify(
proof,
proofFlags,
root,
leaves
)
);
assertTrue(
!merkleProofVerification.multi_proof_verify(
proof,
proofFlags,
bytes32(uint256(root) ^ 1),
leaves
)
);

proof[0] = bytes32(uint256(proof[0]) ^ 1);
assertTrue(
!merkleProofVerification.multi_proof_verify(
proof,
proofFlags,
root,
leaves
)
);
assertTrue(
!merkleProofVerification.multi_proof_verify(
proof,
proofFlags,
bytes32(uint256(root) ^ 1),
leaves
)
);
}

/**
* @notice Forked and adjusted accordingly from here:
* https://github.com/Vectorized/solady/blob/main/test/MerkleProofLib.t.sol.
*/
function testFuzzVerifyMultiProofMultipleLeaves(
bool damageProof,
bool damageRoot,
bool damageLeaves
) public {
bool noDamage = true;

bytes32 root = merkleGenerator.hashLeafPairs(
merkleGenerator.hashLeafPairs(
merkleGenerator.hashLeafPairs(bytes32("a"), bytes32("b")),
merkleGenerator.hashLeafPairs(bytes32("c"), bytes32("d"))
),
merkleGenerator.hashLeafPairs(bytes32("e"), bytes32("f"))
);

bytes32[] memory leaves = new bytes32[](3);
leaves[0] = bytes32("d");
leaves[1] = bytes32("e");
leaves[2] = bytes32("f");

bytes32[] memory proof = new bytes32[](2);
proof[0] = bytes32("c");
proof[1] = merkleGenerator.hashLeafPairs(bytes32("b"), bytes32("a"));

bool[] memory flags = new bool[](4);
flags[0] = false;
flags[1] = true;
flags[2] = false;
flags[3] = true;

if (damageRoot) {
noDamage = false;
root = bytes32(uint256(root) ^ 1);
}

if (damageLeaves) {
noDamage = false;
leaves[0] = bytes32(uint256(leaves[0]) ^ 1);
}

if (damageProof && proof.length != 0) {
noDamage = false;
proof[0] = bytes32(uint256(proof[0]) ^ 1);
}

assertEq(
merkleProofVerification.multi_proof_verify(
proof,
flags,
root,
leaves
),
noDamage
);
}
}

0 comments on commit 4d185d3

Please sign in to comment.