blobstream-contracts 0.0.1-security → 3.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of blobstream-contracts might be problematic. Click here for more details.

Files changed (64) hide show
  1. package/.codecov.yml +51 -0
  2. package/.github/CODEOWNERS +7 -0
  3. package/.github/dependabot.yml +18 -0
  4. package/.github/workflows/code-analysis.yml +41 -0
  5. package/.github/workflows/contract-inheritance-check.yml +28 -0
  6. package/.github/workflows/go-check.yml +25 -0
  7. package/.github/workflows/labels.yml +19 -0
  8. package/.github/workflows/lint.yml +37 -0
  9. package/.github/workflows/tests.yml +72 -0
  10. package/.gitmodules +12 -0
  11. package/.golangci.yml +64 -0
  12. package/.markdownlint.yaml +5 -0
  13. package/.markdownlint.yml +4 -0
  14. package/.markdownlintignore +1 -0
  15. package/.prettierrc.json +11 -0
  16. package/LICENSE +201 -0
  17. package/Makefile +18 -0
  18. package/README.md +102 -5
  19. package/docs/inclusion-proofs.md +69 -0
  20. package/foundry.toml +4 -0
  21. package/go.mod +34 -0
  22. package/go.sum +212 -0
  23. package/hardhat.config.ts +46 -0
  24. package/index.js +94 -0
  25. package/package.json +31 -3
  26. package/remappings.txt +6 -0
  27. package/scripts/Dockerfile_Environment +39 -0
  28. package/scripts/deploy.ts +12 -0
  29. package/scripts/gen.sh +34 -0
  30. package/scripts/upgradability_check.sh +22 -0
  31. package/slither.config.json +3 -0
  32. package/src/Blobstream.sol +366 -0
  33. package/src/Constants.sol +10 -0
  34. package/src/DataRootTuple.sol +15 -0
  35. package/src/IDAOracle.sol +18 -0
  36. package/src/lib/tree/Constants.sol +23 -0
  37. package/src/lib/tree/Types.sol +37 -0
  38. package/src/lib/tree/Utils.sol +106 -0
  39. package/src/lib/tree/binary/BinaryMerkleMultiproof.sol +12 -0
  40. package/src/lib/tree/binary/BinaryMerkleProof.sol +12 -0
  41. package/src/lib/tree/binary/BinaryMerkleTree.sol +256 -0
  42. package/src/lib/tree/binary/TreeHasher.sol +23 -0
  43. package/src/lib/tree/binary/test/BinaryMerkleTree.t.sol +365 -0
  44. package/src/lib/tree/binary/test/TreeHasher.t.sol +40 -0
  45. package/src/lib/tree/namespace/NamespaceMerkleMultiproof.sol +14 -0
  46. package/src/lib/tree/namespace/NamespaceMerkleProof.sol +14 -0
  47. package/src/lib/tree/namespace/NamespaceMerkleTree.sol +306 -0
  48. package/src/lib/tree/namespace/NamespaceNode.sol +23 -0
  49. package/src/lib/tree/namespace/TreeHasher.sol +69 -0
  50. package/src/lib/tree/namespace/test/NamespaceMerkleMultiproof.t.sol +108 -0
  51. package/src/lib/tree/namespace/test/NamespaceMerkleTree.t.sol +644 -0
  52. package/src/lib/tree/namespace/test/TreeHasher.t.sol +66 -0
  53. package/src/lib/tree/test/Utils.t.sol +48 -0
  54. package/src/lib/tree/test/blob.dat +0 -0
  55. package/src/lib/tree/test/header.dat +0 -0
  56. package/src/lib/tree/test/proofs.json +1 -0
  57. package/src/lib/verifier/DAVerifier.sol +328 -0
  58. package/src/lib/verifier/test/DAVerifier.t.sol +396 -0
  59. package/src/lib/verifier/test/RollupInclusionProofs.t.sol +589 -0
  60. package/src/test/Blobstream.t.sol +200 -0
  61. package/src/test/BlobstreamBenchmark.t.sol +137 -0
  62. package/tsconfig.json +11 -0
  63. package/wrappers/Blobstream.sol/wrapper.go +1325 -0
  64. package/wrappers/ERC1967Proxy.sol/wrapper.go +668 -0
@@ -0,0 +1,365 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.22;
3
+
4
+ import "ds-test/test.sol";
5
+ import "forge-std/Vm.sol";
6
+
7
+ import "../BinaryMerkleProof.sol";
8
+ import "../BinaryMerkleTree.sol";
9
+ import "../BinaryMerkleMultiproof.sol";
10
+
11
+ /**
12
+ * TEST VECTORS
13
+ *
14
+ * 0x01
15
+ * 0x02
16
+ * 0x03
17
+ * 0x04
18
+ * 0x05
19
+ * 0x06
20
+ * 0x07
21
+ * 0x08
22
+ *
23
+ * 0xb413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2
24
+ * 0xfcf0a6c700dd13e274b6fba8deea8dd9b26e4eedde3495717cac8408c9c5177f
25
+ * 0x583c7dfb7b3055d99465544032a571e10a134b1b6f769422bbb71fd7fa167a5d
26
+ * 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4
27
+ * 0x9f1afa4dc124cba73134e82ff50f17c8f7164257c79fed9a13f5943a6acb8e3d
28
+ * 0x40d88127d4d31a3891f41598eeed41174e5bc89b1eb9bbd66a8cbfc09956a3fd
29
+ * 0x2ecd8a6b7d2845546659ad4cf443533cf921b19dc81fa83934e83821b4dfdcb7
30
+ * 0xb4c43b50bf245bd727623e3c775a8fcfb8d823d00b57dd65f7f79dd33f126315
31
+ *
32
+ * 0x6bcf0e2e93e0a18e22789aee965e6553f4fbe93f0acfc4a705d691c8311c4965
33
+ * 0x78850a5ab36238b076dd99fd258c70d523168704247988a94caa8c9ccd056b8d
34
+ * 0x90eeb2c4a04ec33ee4dd2677593331910e4203db4fcc120a6cdb95b13cfe83f0
35
+ * 0x28c01722dd8dd05b63bcdeb6878bc2c083118cc2b170646d6b842d0bdbdc9d29
36
+ *
37
+ * 0xfa02d31a63cc11cc624881e52af14af7a1c6ab745efa71021cb24086b9b1793f
38
+ * 0x4301a067262bbb18b4919742326f6f6d706099f9c0e8b0f2db7b88f204b2cf09
39
+ *
40
+ * 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071
41
+ *
42
+ */
43
+
44
+ // Intermediate mock contract that calls the library function
45
+ // and returns the result.
46
+ // This is done because of the expectRevert v1 behaviour change:
47
+ // https://github.com/foundry-rs/book/pull/922
48
+ contract BinaryMerkleTreeLibMock {
49
+ function slice(bytes32[] memory _data, uint256 _begin, uint256 _end) external returns (bytes32[] memory) {
50
+ return BinaryMerkleTree.slice(_data, _begin, _end);
51
+ }
52
+ }
53
+
54
+ contract BinaryMerkleProofTest is DSTest {
55
+ Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
56
+ BinaryMerkleTreeLibMock public binaryMerkleTreeMock;
57
+
58
+ function setUp() external {
59
+ binaryMerkleTreeMock = new BinaryMerkleTreeLibMock();
60
+ }
61
+
62
+ function testVerifyNone() external {
63
+ bytes32 root = sha256("");
64
+ bytes32[] memory sideNodes;
65
+ uint256 key = 0;
66
+ uint256 numLeaves = 0;
67
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
68
+ bytes memory data;
69
+ (bool isValid,) = BinaryMerkleTree.verify(root, proof, data);
70
+ assertTrue(!isValid);
71
+ }
72
+
73
+ function testVerifyOneLeafEmpty() external {
74
+ bytes32 root = 0x6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d;
75
+ bytes32[] memory sideNodes;
76
+ uint256 key = 0;
77
+ uint256 numLeaves = 1;
78
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
79
+ bytes memory data;
80
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
81
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
82
+ assertTrue(isValid);
83
+ }
84
+
85
+ function testVerifyOneLeafSome() external {
86
+ bytes32 root = 0x48c90c8ae24688d6bef5d48a30c2cc8b6754335a8db21793cc0a8e3bed321729;
87
+ bytes32[] memory sideNodes;
88
+ uint256 key = 0;
89
+ uint256 numLeaves = 1;
90
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
91
+ bytes memory data = hex"deadbeef";
92
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
93
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
94
+ assertTrue(isValid);
95
+ }
96
+
97
+ function testVerifyOneLeaf01() external {
98
+ bytes32 root = 0xb413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2;
99
+ bytes32[] memory sideNodes;
100
+ uint256 key = 0;
101
+ uint256 numLeaves = 1;
102
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
103
+ bytes memory data = hex"01";
104
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
105
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
106
+ assertTrue(isValid);
107
+ }
108
+
109
+ function testVerifyLeafOneOfEight() external {
110
+ bytes32 root = 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071;
111
+ bytes32[] memory sideNodes = new bytes32[](3);
112
+ sideNodes[0] = 0xfcf0a6c700dd13e274b6fba8deea8dd9b26e4eedde3495717cac8408c9c5177f;
113
+ sideNodes[1] = 0x78850a5ab36238b076dd99fd258c70d523168704247988a94caa8c9ccd056b8d;
114
+ sideNodes[2] = 0x4301a067262bbb18b4919742326f6f6d706099f9c0e8b0f2db7b88f204b2cf09;
115
+
116
+ uint256 key = 0;
117
+ uint256 numLeaves = 8;
118
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
119
+ bytes memory data = hex"01";
120
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
121
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
122
+ assertTrue(isValid);
123
+ }
124
+
125
+ function testVerifyLeafTwoOfEight() external {
126
+ bytes32 root = 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071;
127
+ bytes32[] memory sideNodes = new bytes32[](3);
128
+ sideNodes[0] = 0xb413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2;
129
+ sideNodes[1] = 0x78850a5ab36238b076dd99fd258c70d523168704247988a94caa8c9ccd056b8d;
130
+ sideNodes[2] = 0x4301a067262bbb18b4919742326f6f6d706099f9c0e8b0f2db7b88f204b2cf09;
131
+
132
+ uint256 key = 1;
133
+ uint256 numLeaves = 8;
134
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
135
+ bytes memory data = hex"02";
136
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
137
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
138
+ assertTrue(isValid);
139
+ }
140
+
141
+ function testVerifyLeafThreeOfEight() external {
142
+ bytes32 root = 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071;
143
+ bytes32[] memory sideNodes = new bytes32[](3);
144
+ sideNodes[0] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
145
+ sideNodes[1] = 0x6bcf0e2e93e0a18e22789aee965e6553f4fbe93f0acfc4a705d691c8311c4965;
146
+ sideNodes[2] = 0x4301a067262bbb18b4919742326f6f6d706099f9c0e8b0f2db7b88f204b2cf09;
147
+
148
+ uint256 key = 2;
149
+ uint256 numLeaves = 8;
150
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
151
+ bytes memory data = hex"03";
152
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
153
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
154
+ assertTrue(isValid);
155
+ }
156
+
157
+ function testVerifyLeafSevenOfEight() external {
158
+ bytes32 root = 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071;
159
+ bytes32[] memory sideNodes = new bytes32[](3);
160
+ sideNodes[0] = 0xb4c43b50bf245bd727623e3c775a8fcfb8d823d00b57dd65f7f79dd33f126315;
161
+ sideNodes[1] = 0x90eeb2c4a04ec33ee4dd2677593331910e4203db4fcc120a6cdb95b13cfe83f0;
162
+ sideNodes[2] = 0xfa02d31a63cc11cc624881e52af14af7a1c6ab745efa71021cb24086b9b1793f;
163
+
164
+ uint256 key = 6;
165
+ uint256 numLeaves = 8;
166
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
167
+ bytes memory data = hex"07";
168
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
169
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
170
+ assertTrue(isValid);
171
+ }
172
+
173
+ function testVerifyLeafEightOfEight() external {
174
+ bytes32 root = 0xc1ad6548cb4c7663110df219ec8b36ca63b01158956f4be31a38a88d0c7f7071;
175
+ bytes32[] memory sideNodes = new bytes32[](3);
176
+ sideNodes[0] = 0x2ecd8a6b7d2845546659ad4cf443533cf921b19dc81fa83934e83821b4dfdcb7;
177
+ sideNodes[1] = 0x90eeb2c4a04ec33ee4dd2677593331910e4203db4fcc120a6cdb95b13cfe83f0;
178
+ sideNodes[2] = 0xfa02d31a63cc11cc624881e52af14af7a1c6ab745efa71021cb24086b9b1793f;
179
+
180
+ uint256 key = 7;
181
+ uint256 numLeaves = 8;
182
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
183
+ bytes memory data = hex"08";
184
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
185
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
186
+ assertTrue(isValid);
187
+ }
188
+
189
+ // Test vectors:
190
+ // 0x00
191
+ // 0x01
192
+ // 0x02
193
+ // 0x03
194
+ // 0x04
195
+ function testVerifyProofOfFiveLeaves() external {
196
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
197
+ bytes32[] memory sideNodes = new bytes32[](3);
198
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
199
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
200
+ sideNodes[2] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
201
+
202
+ uint256 key = 1;
203
+ uint256 numLeaves = 5;
204
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
205
+ bytes memory data = bytes(hex"01");
206
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
207
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
208
+ assertTrue(isValid);
209
+ }
210
+
211
+ function testVerifyInvalidProofRoot() external {
212
+ // correct root: 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
213
+ bytes32 root = 0xc855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
214
+ bytes32[] memory sideNodes = new bytes32[](3);
215
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
216
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
217
+ sideNodes[2] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
218
+
219
+ uint256 key = 1;
220
+ uint256 numLeaves = 5;
221
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
222
+ bytes memory data = bytes(hex"01");
223
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
224
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
225
+ assertTrue(!isValid);
226
+ }
227
+
228
+ function testVerifyInvalidProofKey() external {
229
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
230
+ bytes32[] memory sideNodes = new bytes32[](3);
231
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
232
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
233
+ sideNodes[2] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
234
+
235
+ // correct key: 1
236
+ uint256 key = 2;
237
+ uint256 numLeaves = 5;
238
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
239
+ bytes memory data = bytes(hex"01");
240
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
241
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
242
+ assertTrue(!isValid);
243
+ }
244
+
245
+ function testVerifyInvalidProofNumberOfLeaves() external {
246
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
247
+ bytes32[] memory sideNodes = new bytes32[](3);
248
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
249
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
250
+ sideNodes[2] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
251
+
252
+ uint256 key = 1;
253
+ // correct numLeaves: 5
254
+ uint256 numLeaves = 200;
255
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
256
+ bytes memory data = bytes(hex"01");
257
+ (bool isValid,) = BinaryMerkleTree.verify(root, proof, data);
258
+ assertTrue(!isValid);
259
+ }
260
+
261
+ function testVerifyInvalidProofSideNodes() external {
262
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
263
+ bytes32[] memory sideNodes = new bytes32[](3);
264
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
265
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
266
+ // correct side node: 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
267
+ sideNodes[2] = 0x5f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
268
+
269
+ uint256 key = 1;
270
+ uint256 numLeaves = 5;
271
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
272
+ bytes memory data = bytes(hex"01");
273
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
274
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
275
+ assertTrue(!isValid);
276
+ }
277
+
278
+ function testVerifyInvalidProofData() external {
279
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
280
+ bytes32[] memory sideNodes = new bytes32[](3);
281
+ sideNodes[0] = 0x96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7;
282
+ sideNodes[1] = 0x52c56b473e5246933e7852989cd9feba3b38f078742b93afff1e65ed46797825;
283
+ sideNodes[2] = 0x4f35212d12f9ad2036492c95f1fe79baf4ec7bd9bef3dffa7579f2293ff546a4;
284
+
285
+ uint256 key = 1;
286
+ uint256 numLeaves = 5;
287
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
288
+ // correct data: 01
289
+ bytes memory data = bytes(hex"012345");
290
+ (bool isValid, BinaryMerkleTree.ErrorCodes error) = BinaryMerkleTree.verify(root, proof, data);
291
+ assertEq(uint256(BinaryMerkleTree.ErrorCodes.NoError), uint256(error));
292
+ assertTrue(!isValid);
293
+ }
294
+
295
+ function testValidSlice() public {
296
+ bytes32[] memory data = new bytes32[](4);
297
+ data[0] = "a";
298
+ data[1] = "b";
299
+ data[2] = "c";
300
+ data[3] = "d";
301
+
302
+ bytes32[] memory result = BinaryMerkleTree.slice(data, 1, 3);
303
+
304
+ assertEq(result[0], data[1]);
305
+ assertEq(result[1], data[2]);
306
+ }
307
+
308
+ function testSameKeyAndLeavesNumber() external {
309
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
310
+ bytes32[] memory sideNodes = new bytes32[](0);
311
+ uint256 key = 3;
312
+ uint256 numLeaves = 3;
313
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
314
+ bytes memory data = bytes(hex"01");
315
+ (bool isValid,) = BinaryMerkleTree.verify(root, proof, data);
316
+ assertTrue(!isValid);
317
+ }
318
+
319
+ function testConsecutiveKeyAndNumberOfLeaves() external {
320
+ bytes32 root = 0xb855b42d6c30f5b087e05266783fbd6e394f7b926013ccaa67700a8b0c5a596f;
321
+ bytes32[] memory sideNodes = new bytes32[](0);
322
+ uint256 key = 6;
323
+ uint256 numLeaves = 7;
324
+ BinaryMerkleProof memory proof = BinaryMerkleProof(sideNodes, key, numLeaves);
325
+ bytes memory data = bytes(hex"01");
326
+ (bool isValid,) = BinaryMerkleTree.verify(root, proof, data);
327
+ assertTrue(!isValid);
328
+ }
329
+
330
+ function testInvalidSliceBeginEnd() public {
331
+ bytes32[] memory data = new bytes32[](4);
332
+ data[0] = "a";
333
+ data[1] = "b";
334
+ data[2] = "c";
335
+ data[3] = "d";
336
+
337
+ vm.expectRevert("Invalid range: _begin is greater than _end");
338
+ binaryMerkleTreeMock.slice(data, 2, 1);
339
+ }
340
+
341
+ function testOutOfBoundsSlice() public {
342
+ bytes32[] memory data = new bytes32[](4);
343
+ data[0] = "a";
344
+ data[1] = "b";
345
+ data[2] = "c";
346
+ data[3] = "d";
347
+
348
+ vm.expectRevert("Invalid range: _begin or _end are out of bounds");
349
+ binaryMerkleTreeMock.slice(data, 2, 5);
350
+ }
351
+
352
+ // header.dat, blob.dat, and proofs.json test vectors included in ../../test/ and serialized to hex bytes using Rust
353
+ // The hard-coded serialized proofs and data were generated in Rust, with this code
354
+ // https://github.com/S1nus/hyperchain-da/blob/main/src/clients/celestia/evm_types.rs#L132
355
+ function testMultiproof() public {
356
+ bytes memory proofData =
357
+ hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000006ce29bcde696f84e35c5626904542a549b080e92603243b34794242473940706917519bf954f5b30495af5c8cdb9983e6319104badc1ea811ed2c421018a3ad7821ea268d3540deab8f9b2024464618610c9a7083620badcf505bda647cc8e9f82bfc87d990d8344f6efd44fcb09b46b87f9a92230d41329452efee8656c6760a9ad9f3a95af971e89e2a80b255bb56d5aae15de69803b52aa5079b33374b16e16178fc62a2f2ce6bf21909c0a0edea9525486e0ece65bff23499342cca38dd62";
358
+ BinaryMerkleMultiproof memory multiproof = abi.decode(proofData, (BinaryMerkleMultiproof));
359
+ bytes32 dataroot = hex"ef8920d86519bd5f8ce3c802b84fc9b9512483e4d4a5c9608b44af4d6639f7d1";
360
+ bytes memory leafData =
361
+ hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000520000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000102030405746e218305fe3dbbef65feceed939fe8dd93c88b06c95473fbe344fb864060f3000000000000000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000102030405000000000000000000000000000000000000000000000000010203040555cd7fb524ae792c9d4bc8946d07209728c533a3e14d4e7c0c95c0b150d0c284000000000000000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000001020304050000000000000000000000000000000000000000000000000102030405505c1e7c897461a152e152f1ff3ecc358fefdf1f69448ab1165b6ca76836933b000000000000000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000001020304050000000000000000000000000000000000000000000000000102030405100a0548893d8eab0322f34f45ac84785cdf50dfab5102a12d958e6031bacebe000000000000000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000102030405000000000000000000000000000000000000000000000000010203040566e5eb1da67430f204a3c5615591f71316695c7ec1f1f713cde7e936d4a43ec1000000000000000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000001020304050000000000000000000000000000000000000000000000000102030405d2a5de6299e28c2fec359a2718599f5ac22c2948a71d26a438295e531b6f4cb5000000000000000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000001020304050000000000000000000000000000000000000000000000000102030405688c5238e50c0a8a556bfabff31bef1fa9cdd812c9fd4dcee5c2a0836f687fbf000000000000000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000001020304050000000000000000000000000000000000000000000000000102030405b55a5b1efc2a22cdbfa21d050bd67147ff2b936c68354eb1a83bcdf14eb57e38000000000000000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000010203040500000000000000000000000000000000000000000067480c4a88c4d129947e11c33fa811daa791771e591dd933498d1212d46b8cde9c34c28831b0b532000000000000";
362
+ bytes[] memory leaves = abi.decode(leafData, (bytes[]));
363
+ assertTrue(BinaryMerkleTree.verifyMulti(dataroot, multiproof, leaves));
364
+ }
365
+ }
@@ -0,0 +1,40 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.22;
3
+
4
+ import "ds-test/test.sol";
5
+
6
+ import "../TreeHasher.sol";
7
+
8
+ contract TreeHasherTest is DSTest {
9
+ function setUp() external {}
10
+
11
+ function testLeafDigestEmpty() external {
12
+ bytes32 expected = 0x6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d;
13
+ bytes memory data;
14
+ bytes32 digest = leafDigest(data);
15
+ assertEq(digest, expected);
16
+ }
17
+
18
+ function testLeafDigestSome() external {
19
+ bytes32 expected = 0x48c90c8ae24688d6bef5d48a30c2cc8b6754335a8db21793cc0a8e3bed321729;
20
+ bytes memory data = hex"deadbeef";
21
+ bytes32 digest = leafDigest(data);
22
+ assertEq(digest, expected);
23
+ }
24
+
25
+ function testNodeDigestEmptyChildren() external {
26
+ bytes32 expected = 0xfe43d66afa4a9a5c4f9c9da89f4ffb52635c8f342e7ffb731d68e36c5982072a;
27
+ bytes32 left = 0x6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d;
28
+ bytes32 right = 0x6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d;
29
+ bytes32 digest = nodeDigest(left, right);
30
+ assertEq(digest, expected);
31
+ }
32
+
33
+ function testNodeDigestSomeChildren() external {
34
+ bytes32 expected = 0x62343bba7c4d6259f0d4863cdf476f1c0ac1b9fbe9244723a9b8b5c8aae72c38;
35
+ bytes32 left = 0xdb55da3fc3098e9c42311c6013304ff36b19ef73d12ea932054b5ad51df4f49d;
36
+ bytes32 right = 0xc75cb66ae28d8ebc6eded002c28a8ba0d06d3a78c6b5cbf9b2ade051f0775ac4;
37
+ bytes32 digest = nodeDigest(left, right);
38
+ assertEq(digest, expected);
39
+ }
40
+ }
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.22;
3
+
4
+ import "./NamespaceNode.sol";
5
+
6
+ /// @notice Namespace Merkle Tree Multiproof structure. Proves multiple leaves.
7
+ struct NamespaceMerkleMultiproof {
8
+ // The (included) beginning key of the leaves to verify.
9
+ uint256 beginKey;
10
+ // The (excluded) ending key of the leaves to verify.
11
+ uint256 endKey;
12
+ // List of side nodes to verify and calculate tree.
13
+ NamespaceNode[] sideNodes;
14
+ }
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.22;
3
+
4
+ import "./NamespaceNode.sol";
5
+
6
+ /// @notice Namespace Merkle Tree Proof structure.
7
+ struct NamespaceMerkleProof {
8
+ // List of side nodes to verify and calculate tree.
9
+ NamespaceNode[] sideNodes;
10
+ // The key of the leaf to verify.
11
+ uint256 key;
12
+ // The number of leaves in the tree
13
+ uint256 numLeaves;
14
+ }