diff --git a/foundry.lock b/foundry.lock new file mode 100644 index 0000000..13ce27d --- /dev/null +++ b/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/forge-std": { + "rev": "e4aef94c1768803a16fe19f7ce8b65defd027cfd" + }, + "lib/openzeppelin-contracts": { + "rev": "cb2aaaa04a292887c49839cd958b08a83979d746" + } +} \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 0ec2c24..cdc0038 100644 --- a/foundry.toml +++ b/foundry.toml @@ -5,5 +5,6 @@ libs = ['lib'] fuzz_runs=5000 fuzz.max_test_rejects=500000 fs_permissions = [{ access = "read-write", path = "./"}] +ffi = true # See more config options https://github.com/gakonst/foundry/tree/master/config \ No newline at end of file diff --git a/src/common/MurkyBase.sol b/src/common/MurkyBase.sol index d9344e9..6a6a491 100644 --- a/src/common/MurkyBase.sol +++ b/src/common/MurkyBase.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.4; abstract contract MurkyBase { + /// @dev Thrown when trying to generate a root or proof for a single leaf array + error SingleLeaf(); /** * * CONSTRUCTOR * @@ -21,7 +23,7 @@ abstract contract MurkyBase { * PROOF VERIFICATION * * */ - function verifyProof(bytes32 root, bytes32[] memory proof, bytes32 valueToProve) + function verifyProof(bytes32 root, bytes32[] calldata proof, bytes32 valueToProve) external pure virtual @@ -44,7 +46,7 @@ abstract contract MurkyBase { * */ function getRoot(bytes32[] memory data) public pure virtual returns (bytes32) { - require(data.length > 1, "won't generate root for single leaf"); + if (data.length <= 1) revert SingleLeaf(); while (data.length > 1) { data = hashLevel(data); } @@ -52,7 +54,7 @@ abstract contract MurkyBase { } function getProof(bytes32[] memory data, uint256 node) public pure virtual returns (bytes32[] memory) { - require(data.length > 1, "won't generate proof for single leaf"); + if (data.length <= 1) revert SingleLeaf(); // The size of the proof is equal to the ceiling of log2(numLeaves) bytes32[] memory result = new bytes32[](log2ceilBitMagic(data.length)); uint256 pos = 0; diff --git a/src/test/Merkle.t.sol b/src/test/Merkle.t.sol index 252a1f6..9d2083a 100644 --- a/src/test/Merkle.t.sol +++ b/src/test/Merkle.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.4; import "../Merkle.sol"; +import "../common/MurkyBase.sol"; import "forge-std/Test.sol"; import "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol"; @@ -68,14 +69,14 @@ contract ContractTest is Test { function testWontGetRootSingleLeaf() public { bytes32[] memory data = new bytes32[](1); data[0] = bytes32(0x0); - vm.expectRevert("won't generate root for single leaf"); + vm.expectRevert(MurkyBase.SingleLeaf.selector); m.getRoot(data); } function testWontGetProofSingleLeaf() public { bytes32[] memory data = new bytes32[](1); data[0] = bytes32(0x0); - vm.expectRevert("won't generate proof for single leaf"); + vm.expectRevert(MurkyBase.SingleLeaf.selector); m.getProof(data, 0x0); } diff --git a/src/test/Xorkle.t.sol b/src/test/Xorkle.t.sol index 6137817..b42c871 100644 --- a/src/test/Xorkle.t.sol +++ b/src/test/Xorkle.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.4; import "../Xorkle.sol"; +import "../common/MurkyBase.sol"; import "forge-std/Test.sol"; contract ContractTest is Test { @@ -52,14 +53,14 @@ contract ContractTest is Test { function testWontGetRootSingleLeaf() public { bytes32[] memory data = new bytes32[](1); data[0] = bytes32(0x0); - vm.expectRevert("won't generate root for single leaf"); + vm.expectRevert(MurkyBase.SingleLeaf.selector); m.getRoot(data); } function testWontGetProofSingleLeaf() public { bytes32[] memory data = new bytes32[](1); data[0] = bytes32(0x0); - vm.expectRevert("won't generate proof for single leaf"); + vm.expectRevert(MurkyBase.SingleLeaf.selector); m.getProof(data, 0x0); }