@@ -10,8 +10,9 @@ import {VectorxMock, IVectorx} from "src/mocks/VectorxMock.sol";
10
10
import {ERC20Mock } from "src/mocks/ERC20Mock.sol " ;
11
11
import {MessageReceiverMock} from "src/mocks/MessageReceiverMock.sol " ;
12
12
import {Vm, Test} from "forge-std/Test.sol " ;
13
+ import {MurkyBase} from "lib/murky/src/common/MurkyBase.sol " ;
13
14
14
- contract AvailBridgeTest is Test {
15
+ contract AvailBridgeTest is Test , MurkyBase {
15
16
AvailBridge public bridge;
16
17
WrappedAvail public avail;
17
18
VectorxMock public vectorx;
@@ -52,8 +53,9 @@ contract AvailBridgeTest is Test {
52
53
bridge.receiveMessage (message, input);
53
54
}
54
55
55
- function test_receiveAVL (bytes32 rangeHash , bytes32 from , address to , uint256 amount , uint64 messageId ) external {
56
- vm.assume (to != address (0 ) && amount != 0 );
56
+ function test_receiveAVL (bytes32 rangeHash , bytes32 from , uint256 amount , uint64 messageId ) external {
57
+ vm.assume (amount != 0 );
58
+ address to = makeAddr ("to " );
57
59
AvailBridge.Message memory message =
58
60
AvailBridge.Message (0x02 , from, bytes32 (bytes20 (to)), 1 , 2 , abi.encode (bytes32 (0 ), amount), messageId);
59
61
bytes32 messageHash = keccak256 (abi.encode (message));
@@ -70,10 +72,9 @@ contract AvailBridgeTest is Test {
70
72
assertEq (avail.totalSupply (), amount);
71
73
}
72
74
73
- function test_receiveETH (bytes32 rangeHash , bytes32 from , address to , uint256 amount , uint64 messageId ) external {
74
- // while technically contracts can receive ETH, foundry fuzzes with a lot of random contracts and precompiles
75
- // that cannot receive ETH
76
- vm.assume (amount != 0 && to.code.length == 0 && uint256 (uint160 (to)) > 9 );
75
+ function test_receiveETH (bytes32 rangeHash , bytes32 from , uint256 amount , uint64 messageId ) external {
76
+ vm.assume (amount != 0 );
77
+ address to = makeAddr ("to " );
77
78
vm.deal (address (bridge), amount);
78
79
AvailBridge.Message memory message = AvailBridge.Message (
79
80
0x02 ,
@@ -102,11 +103,11 @@ contract AvailBridgeTest is Test {
102
103
bytes32 rangeHash ,
103
104
bytes32 assetId ,
104
105
bytes32 from ,
105
- address to ,
106
106
uint256 amount ,
107
107
uint64 messageId
108
108
) external {
109
- vm.assume (amount != 0 && to != address (0 ) && to != address (bridge));
109
+ vm.assume (amount != 0 );
110
+ address to = makeAddr ("to " );
110
111
ERC20Mock token = new ERC20Mock ();
111
112
token.mint (address (bridge), amount);
112
113
bytes32 [] memory assetIdArr = new bytes32 [](1 );
@@ -132,8 +133,9 @@ contract AvailBridgeTest is Test {
132
133
assertEq (newBalance, balance + amount);
133
134
}
134
135
135
- function test_sendAVL (address from , bytes32 to , uint256 amount ) external {
136
- vm.assume (from != address (0 ) && to != bytes32 (0 ) && amount != 0 && from != address (admin));
136
+ function test_sendAVL (bytes32 to , uint256 amount ) external {
137
+ vm.assume (to != bytes32 (0 ) && amount != 0 );
138
+ address from = makeAddr ("from " );
137
139
vm.prank (address (bridge));
138
140
avail.mint (from, amount);
139
141
AvailBridge.Message memory message =
@@ -146,10 +148,9 @@ contract AvailBridgeTest is Test {
146
148
assertEq (avail.totalSupply (), 0 );
147
149
}
148
150
149
- function test_sendETH (address from , bytes32 to , uint256 amount ) external {
150
- vm.assume (
151
- from != address (0 ) && to != bytes32 (0 ) && amount != 0 && from != address (admin) && from != address (bridge)
152
- );
151
+ function test_sendETH (bytes32 to , uint256 amount ) external {
152
+ vm.assume (to != bytes32 (0 ) && amount != 0 );
153
+ address from = makeAddr ("from " );
153
154
vm.deal (from, amount);
154
155
AvailBridge.Message memory message = AvailBridge.Message (
155
156
0x02 ,
@@ -168,8 +169,9 @@ contract AvailBridgeTest is Test {
168
169
assertEq (from.balance, balance - amount);
169
170
}
170
171
171
- function test_sendERC20 (bytes32 assetId , address from , bytes32 to , uint256 amount ) external {
172
- vm.assume (from != address (0 ) && to != bytes32 (0 ) && amount != 0 && from != address (admin));
172
+ function test_sendERC20 (bytes32 assetId , bytes32 to , uint256 amount ) external {
173
+ vm.assume (to != bytes32 (0 ) && amount != 0 );
174
+ address from = makeAddr ("from " );
173
175
ERC20Mock token = new ERC20Mock ();
174
176
token.mint (from, amount);
175
177
bytes32 [] memory assetIdArr = new bytes32 [](1 );
@@ -188,4 +190,66 @@ contract AvailBridgeTest is Test {
188
190
assertEq (token.balanceOf (from), 0 );
189
191
assertEq (token.balanceOf (address (bridge)), amount);
190
192
}
193
+
194
+ function test_verifyBlobLeaf (bytes32 [16 ] calldata preimages , bytes32 [16 ] calldata c_dataRoots , bytes32 rangeHash , uint256 rand , bytes32 bridgeRoot ) external {
195
+ // we use a fixed size array because the fuzzer rejects too many inputs with arbitrary lengths
196
+ bytes32 [] memory dataRoots = new bytes32 [](c_dataRoots.length );
197
+ bytes32 [] memory leaves = new bytes32 [](preimages.length );
198
+ for (uint256 i = 0 ; i < preimages.length ; ) {
199
+ dataRoots[i] = c_dataRoots[i];
200
+ leaves[i] = keccak256 (abi.encode (preimages[i]));
201
+ unchecked {
202
+ ++ i;
203
+ }
204
+ }
205
+ bytes32 blobRoot = getRoot (leaves);
206
+ bytes32 dataRoot = hashLeafPairs (blobRoot, bridgeRoot);
207
+ // set dataRoot at this point in the array
208
+ dataRoots[rand % dataRoots.length ] = dataRoot;
209
+ bytes32 dataRootCommitment = getRoot (dataRoots);
210
+ bytes32 [] memory dataRootProof = getProof (dataRoots, rand % dataRoots.length );
211
+ vectorx.set (rangeHash, dataRootCommitment);
212
+ for (uint256 i = 0 ; i < leaves.length ; ) {
213
+ bytes32 [] memory leafProof = getProof (leaves, i);
214
+ AvailBridge.MerkleProofInput memory input =
215
+ AvailBridge.MerkleProofInput (dataRootProof, leafProof, rangeHash, rand % dataRoots.length , blobRoot, bridgeRoot, preimages[i], i);
216
+ assertTrue (bridge.verifyBlobLeaf (input));
217
+ unchecked {
218
+ ++ i;
219
+ }
220
+ }
221
+ }
222
+
223
+ function test_verifyBridgeLeaf (bytes32 [16 ] calldata c_leaves , bytes32 [16 ] calldata c_dataRoots , bytes32 rangeHash , uint256 rand , bytes32 blobRoot ) external {
224
+ // we use a fixed size array because the fuzzer rejects too many inputs with arbitrary lengths
225
+ bytes32 [] memory dataRoots = new bytes32 [](c_dataRoots.length );
226
+ bytes32 [] memory leaves = new bytes32 [](c_leaves.length );
227
+ for (uint256 i = 0 ; i < c_leaves.length ; ) {
228
+ dataRoots[i] = c_dataRoots[i];
229
+ leaves[i] = c_leaves[i];
230
+ unchecked {
231
+ ++ i;
232
+ }
233
+ }
234
+ bytes32 bridgeRoot = getRoot (leaves);
235
+ bytes32 dataRoot = hashLeafPairs (blobRoot, bridgeRoot);
236
+ // set dataRoot at this point in the array
237
+ dataRoots[rand % dataRoots.length ] = dataRoot;
238
+ bytes32 dataRootCommitment = getRoot (dataRoots);
239
+ bytes32 [] memory dataRootProof = getProof (dataRoots, rand % dataRoots.length );
240
+ vectorx.set (rangeHash, dataRootCommitment);
241
+ for (uint256 i = 0 ; i < leaves.length ; ) {
242
+ bytes32 [] memory leafProof = getProof (leaves, i);
243
+ AvailBridge.MerkleProofInput memory input =
244
+ AvailBridge.MerkleProofInput (dataRootProof, leafProof, rangeHash, rand % dataRoots.length , blobRoot, bridgeRoot, leaves[i], i);
245
+ assertTrue (bridge.verifyBridgeLeaf (input));
246
+ unchecked {
247
+ ++ i;
248
+ }
249
+ }
250
+ }
251
+
252
+ function hashLeafPairs (bytes32 left , bytes32 right ) public pure override returns (bytes32 ) {
253
+ return keccak256 (abi.encode (left, right));
254
+ }
191
255
}
0 commit comments