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.
- package/.codecov.yml +51 -0
- package/.github/CODEOWNERS +7 -0
- package/.github/dependabot.yml +18 -0
- package/.github/workflows/code-analysis.yml +41 -0
- package/.github/workflows/contract-inheritance-check.yml +28 -0
- package/.github/workflows/go-check.yml +25 -0
- package/.github/workflows/labels.yml +19 -0
- package/.github/workflows/lint.yml +37 -0
- package/.github/workflows/tests.yml +72 -0
- package/.gitmodules +12 -0
- package/.golangci.yml +64 -0
- package/.markdownlint.yaml +5 -0
- package/.markdownlint.yml +4 -0
- package/.markdownlintignore +1 -0
- package/.prettierrc.json +11 -0
- package/LICENSE +201 -0
- package/Makefile +18 -0
- package/README.md +102 -5
- package/docs/inclusion-proofs.md +69 -0
- package/foundry.toml +4 -0
- package/go.mod +34 -0
- package/go.sum +212 -0
- package/hardhat.config.ts +46 -0
- package/index.js +94 -0
- package/package.json +31 -3
- package/remappings.txt +6 -0
- package/scripts/Dockerfile_Environment +39 -0
- package/scripts/deploy.ts +12 -0
- package/scripts/gen.sh +34 -0
- package/scripts/upgradability_check.sh +22 -0
- package/slither.config.json +3 -0
- package/src/Blobstream.sol +366 -0
- package/src/Constants.sol +10 -0
- package/src/DataRootTuple.sol +15 -0
- package/src/IDAOracle.sol +18 -0
- package/src/lib/tree/Constants.sol +23 -0
- package/src/lib/tree/Types.sol +37 -0
- package/src/lib/tree/Utils.sol +106 -0
- package/src/lib/tree/binary/BinaryMerkleMultiproof.sol +12 -0
- package/src/lib/tree/binary/BinaryMerkleProof.sol +12 -0
- package/src/lib/tree/binary/BinaryMerkleTree.sol +256 -0
- package/src/lib/tree/binary/TreeHasher.sol +23 -0
- package/src/lib/tree/binary/test/BinaryMerkleTree.t.sol +365 -0
- package/src/lib/tree/binary/test/TreeHasher.t.sol +40 -0
- package/src/lib/tree/namespace/NamespaceMerkleMultiproof.sol +14 -0
- package/src/lib/tree/namespace/NamespaceMerkleProof.sol +14 -0
- package/src/lib/tree/namespace/NamespaceMerkleTree.sol +306 -0
- package/src/lib/tree/namespace/NamespaceNode.sol +23 -0
- package/src/lib/tree/namespace/TreeHasher.sol +69 -0
- package/src/lib/tree/namespace/test/NamespaceMerkleMultiproof.t.sol +108 -0
- package/src/lib/tree/namespace/test/NamespaceMerkleTree.t.sol +644 -0
- package/src/lib/tree/namespace/test/TreeHasher.t.sol +66 -0
- package/src/lib/tree/test/Utils.t.sol +48 -0
- package/src/lib/tree/test/blob.dat +0 -0
- package/src/lib/tree/test/header.dat +0 -0
- package/src/lib/tree/test/proofs.json +1 -0
- package/src/lib/verifier/DAVerifier.sol +328 -0
- package/src/lib/verifier/test/DAVerifier.t.sol +396 -0
- package/src/lib/verifier/test/RollupInclusionProofs.t.sol +589 -0
- package/src/test/Blobstream.t.sol +200 -0
- package/src/test/BlobstreamBenchmark.t.sol +137 -0
- package/tsconfig.json +11 -0
- package/wrappers/Blobstream.sol/wrapper.go +1325 -0
- 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
|
+
}
|