@@ -8,11 +8,20 @@ import {MockFunctions} from "./MockFunctions.sol";
8
8
import {SigUtils} from "./SigUtils.t.sol " ;
9
9
10
10
contract GuardedMulticallerTest is Test {
11
-
12
11
GuardedMulticaller public gmc;
13
12
MockFunctions public mock;
14
13
SigUtils public sigUtils;
15
-
14
+
15
+ event Multicalled (
16
+ address indexed _multicallSigner ,
17
+ bytes32 indexed _reference ,
18
+ address [] _targets ,
19
+ bytes [] _data ,
20
+ uint256 _deadline
21
+ );
22
+
23
+ event FunctionPermitted (address indexed _target , bytes4 _functionSelector , bool _permitted );
24
+
16
25
address public deployer;
17
26
address public signer;
18
27
uint256 public signerPk;
@@ -21,22 +30,21 @@ contract GuardedMulticallerTest is Test {
21
30
22
31
string public constant MULTICALLER_NAME = "Multicaller " ;
23
32
string public constant MULTICALLER_VERSION = "v1 " ;
24
-
33
+
25
34
bytes32 public ref;
26
35
uint256 public deadline;
27
-
36
+
28
37
function setUp () public {
29
38
deployer = makeAddr ("deployer " );
30
39
(signer, signerPk) = makeAddrAndKey ("signer " );
31
40
(user, userPk) = makeAddrAndKey ("user " );
32
-
41
+
33
42
vm.prank (deployer);
34
43
gmc = new GuardedMulticaller (deployer, MULTICALLER_NAME, MULTICALLER_VERSION);
35
44
vm.prank (deployer);
36
45
gmc.grantMulticallSignerRole (signer);
37
-
38
- sigUtils = new SigUtils (MULTICALLER_NAME, MULTICALLER_VERSION, address (gmc));
39
46
47
+ sigUtils = new SigUtils (MULTICALLER_NAME, MULTICALLER_VERSION, address (gmc));
40
48
41
49
vm.prank (deployer);
42
50
mock = new MockFunctions ();
@@ -55,161 +63,163 @@ contract GuardedMulticallerTest is Test {
55
63
vm.prank (deployer);
56
64
gmc.setFunctionPermits (functionPermits);
57
65
58
-
59
66
deadline = block .timestamp + 30 minutes ;
60
67
ref = keccak256 (abi.encodePacked ("test_ref " ));
61
68
}
62
-
69
+
63
70
function test_SuccessfulExecution () public {
64
71
address [] memory targets = new address [](1 );
65
72
targets[0 ] = address (mock);
66
73
67
74
bytes [] memory data = new bytes [](1 );
68
75
data[0 ] = abi.encodeWithSelector (MockFunctions.succeed.selector );
69
-
76
+
70
77
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
71
-
78
+
72
79
vm.prank (user);
73
80
vm.expectEmit (true , true , true , true );
74
- emit GuardedMulticaller. Multicalled (signer, ref, targets, data, deadline);
81
+ emit Multicalled (signer, ref, targets, data, deadline);
75
82
gmc.execute (signer, ref, targets, data, deadline, signature);
76
83
}
77
-
84
+
78
85
function test_RevertWithCustomError () public {
79
86
address [] memory targets = new address [](1 );
80
87
targets[0 ] = address (mock);
81
-
88
+
82
89
bytes [] memory data = new bytes [](1 );
83
90
data[0 ] = abi.encodeWithSignature ("revertWithNoReason() " );
84
-
91
+
85
92
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
86
-
93
+
87
94
vm.prank (user);
88
95
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.FailedCall.selector , targets[0 ], data[0 ]));
89
96
gmc.execute (signer, ref, targets, data, deadline, signature);
90
97
}
91
-
98
+
92
99
function test_RevertIfDeadlinePassed () public {
93
100
address [] memory targets = new address [](1 );
94
101
targets[0 ] = address (mock);
95
-
102
+
96
103
bytes [] memory data = new bytes [](1 );
97
104
data[0 ] = abi.encodeWithSignature ("succeed() " );
98
-
99
105
100
106
uint256 expiredDeadline = block .timestamp ;
101
107
vm.warp (expiredDeadline + 30 minutes);
102
108
bytes memory signature = signTypedData (signerPk, ref, targets, data, expiredDeadline);
103
-
109
+
104
110
vm.prank (user);
105
111
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.Expired.selector , expiredDeadline));
106
112
gmc.execute (signer, ref, targets, data, expiredDeadline, signature);
107
113
}
108
-
114
+
109
115
function test_RevertIfReferenceReused () public {
110
116
address [] memory targets = new address [](1 );
111
117
targets[0 ] = address (mock);
112
-
118
+
113
119
bytes [] memory data = new bytes [](1 );
114
120
data[0 ] = abi.encodeWithSignature ("succeed() " );
115
-
121
+
116
122
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
117
-
123
+
118
124
vm.prank (user);
119
125
gmc.execute (signer, ref, targets, data, deadline, signature);
120
-
126
+
121
127
vm.prank (user);
122
128
vm.expectRevert (abi.encodePacked (GuardedMulticaller.ReusedReference.selector , ref));
123
129
gmc.execute (signer, ref, targets, data, deadline, signature);
124
130
}
125
-
131
+
126
132
function test_RevertIfInvalidReference () public {
127
133
address [] memory targets = new address [](1 );
128
134
targets[0 ] = address (mock);
129
-
135
+
130
136
bytes [] memory data = new bytes [](1 );
131
137
data[0 ] = abi.encodeWithSignature ("succeed() " );
132
-
138
+
133
139
bytes32 invalidRef = bytes32 (0 );
134
140
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
135
-
141
+
136
142
vm.prank (user);
137
143
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.InvalidReference.selector , invalidRef));
138
144
gmc.execute (signer, invalidRef, targets, data, deadline, signature);
139
145
}
140
-
146
+
141
147
function test_RevertIfUnauthorizedSigner () public {
142
148
address [] memory targets = new address [](1 );
143
149
targets[0 ] = address (mock);
144
-
150
+
145
151
bytes [] memory data = new bytes [](1 );
146
152
data[0 ] = abi.encodeWithSignature ("succeed() " );
147
-
153
+
148
154
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
149
-
155
+
150
156
vm.prank (user);
151
157
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.UnauthorizedSigner.selector , user));
152
- // Note: execute called with user as signer.
158
+ // Note: execute called with user as signer.
153
159
gmc.execute (user, ref, targets, data, deadline, signature);
154
160
}
155
-
161
+
156
162
function test_RevertIfSignatureMismatch () public {
157
163
address [] memory targets = new address [](1 );
158
164
targets[0 ] = address (mock);
159
-
165
+
160
166
bytes [] memory data = new bytes [](1 );
161
167
data[0 ] = abi.encodeWithSignature ("succeed() " );
162
-
168
+
163
169
bytes memory signature = signTypedData (userPk, ref, targets, data, deadline);
164
-
170
+
165
171
vm.prank (user);
166
172
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.UnauthorizedSignature.selector , signature));
167
173
gmc.execute (signer, ref, targets, data, deadline, signature);
168
174
}
169
-
175
+
170
176
function test_RevertIfEmptyTargets () public {
171
177
address [] memory targets = new address [](0 );
172
178
bytes [] memory data = new bytes [](1 );
173
179
data[0 ] = abi.encodeWithSignature ("succeed() " );
174
-
180
+
175
181
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
176
-
182
+
177
183
vm.prank (user);
178
184
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.EmptyAddressArray.selector ));
179
185
gmc.execute (signer, ref, targets, data, deadline, signature);
180
186
}
181
-
187
+
182
188
function test_RevertIfTargetsDataMismatch () public {
183
189
address [] memory targets = new address [](2 );
184
190
targets[0 ] = address (mock);
185
191
targets[1 ] = address (mock);
186
-
192
+
187
193
bytes [] memory data = new bytes [](1 );
188
194
data[0 ] = abi.encodeWithSignature ("succeed() " );
189
-
195
+
190
196
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
191
-
197
+
192
198
vm.prank (user);
193
- vm.expectRevert (abi.encodeWithSelector (
194
- GuardedMulticaller.AddressDataArrayLengthsMismatch.selector ,
195
- targets.length , data.length ));
199
+ vm.expectRevert (
200
+ abi.encodeWithSelector (
201
+ GuardedMulticaller.AddressDataArrayLengthsMismatch.selector ,
202
+ targets.length ,
203
+ data.length
204
+ )
205
+ );
196
206
gmc.execute (signer, ref, targets, data, deadline, signature);
197
207
}
198
208
199
209
function test_RevertIfFunctionNotPermitted () public {
200
210
address [] memory targets = new address [](1 );
201
211
targets[0 ] = address (mock);
202
-
212
+
203
213
bytes [] memory data = new bytes [](1 );
204
214
data[0 ] = abi.encodeWithSignature ("notPermitted() " );
205
-
215
+
206
216
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
207
-
217
+
208
218
vm.prank (user);
209
219
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.UnauthorizedFunction.selector , targets[0 ], data[0 ]));
210
220
gmc.execute (signer, ref, targets, data, deadline, signature);
211
221
}
212
-
222
+
213
223
function test_RevertIfFunctionDisallowed () public {
214
224
GuardedMulticaller.FunctionPermit[] memory functionPermits = new GuardedMulticaller.FunctionPermit [](1 );
215
225
functionPermits[0 ] = GuardedMulticaller.FunctionPermit ({
@@ -219,35 +229,35 @@ contract GuardedMulticallerTest is Test {
219
229
});
220
230
vm.prank (deployer);
221
231
gmc.setFunctionPermits (functionPermits);
222
-
232
+
223
233
address [] memory targets = new address [](1 );
224
234
targets[0 ] = address (mock);
225
-
235
+
226
236
bytes [] memory data = new bytes [](1 );
227
237
data[0 ] = abi.encodeWithSignature ("succeed() " );
228
-
238
+
229
239
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
230
-
240
+
231
241
vm.prank (user);
232
242
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.UnauthorizedFunction.selector , targets[0 ], data[0 ]));
233
243
gmc.execute (signer, ref, targets, data, deadline, signature);
234
244
}
235
-
245
+
236
246
function test_RevertIfInvalidSignature () public {
237
247
address [] memory targets = new address [](1 );
238
248
targets[0 ] = address (mock);
239
-
249
+
240
250
bytes [] memory data = new bytes [](1 );
241
251
data[0 ] = abi.encodeWithSignature ("succeed() " );
242
-
252
+
243
253
bytes32 maliciousRef = keccak256 (abi.encodePacked ("malicious_ref " ));
244
254
bytes memory signature = signTypedData (signerPk, maliciousRef, targets, data, deadline);
245
-
255
+
246
256
vm.prank (user);
247
257
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.UnauthorizedSignature.selector , signature));
248
258
gmc.execute (signer, ref, targets, data, deadline, signature);
249
259
}
250
-
260
+
251
261
function test_EmitFunctionPermittedEvent () public {
252
262
vm.startPrank (deployer);
253
263
GuardedMulticaller.FunctionPermit[] memory functionPermits = new GuardedMulticaller.FunctionPermit [](1 );
@@ -257,26 +267,18 @@ contract GuardedMulticallerTest is Test {
257
267
permitted: true
258
268
});
259
269
vm.expectEmit (true , true , true , true );
260
- emit GuardedMulticaller.FunctionPermitted (
261
- address (mock),
262
- MockFunctions.succeed.selector ,
263
- true
264
- );
270
+ emit FunctionPermitted (address (mock), MockFunctions.succeed.selector , true );
265
271
gmc.setFunctionPermits (functionPermits);
266
-
272
+
267
273
functionPermits[0 ] = GuardedMulticaller.FunctionPermit ({
268
274
target: address (mock),
269
275
functionSelector: MockFunctions.succeed.selector ,
270
276
permitted: false
271
277
});
272
278
vm.expectEmit (true , true , true , true );
273
- emit GuardedMulticaller.FunctionPermitted (
274
- address (mock),
275
- MockFunctions.succeed.selector ,
276
- false
277
- );
279
+ emit FunctionPermitted (address (mock), MockFunctions.succeed.selector , false );
278
280
gmc.setFunctionPermits (functionPermits);
279
-
281
+
280
282
vm.stopPrank ();
281
283
}
282
284
@@ -299,7 +301,6 @@ contract GuardedMulticallerTest is Test {
299
301
gmc.setFunctionPermits (functionPermits);
300
302
}
301
303
302
-
303
304
function test_RevertIfSetFunctionPermitsNonContract () public {
304
305
GuardedMulticaller.FunctionPermit[] memory functionPermits = new GuardedMulticaller.FunctionPermit [](1 );
305
306
functionPermits[0 ] = GuardedMulticaller.FunctionPermit ({
@@ -311,33 +312,33 @@ contract GuardedMulticallerTest is Test {
311
312
vm.expectRevert (abi.encodeWithSelector (GuardedMulticaller.NonContractAddress.selector , deployer));
312
313
gmc.setFunctionPermits (functionPermits);
313
314
}
314
-
315
+
315
316
function test_RevertIfGrantRevokeSignerRoleWithInvalidRole () public {
316
317
vm.startPrank (user);
317
-
318
+
318
319
vm.expectRevert ();
319
320
gmc.grantMulticallSignerRole (user);
320
-
321
+
321
322
vm.expectRevert ();
322
323
gmc.revokeMulticallSignerRole (user);
323
-
324
+
324
325
vm.stopPrank ();
325
326
}
326
-
327
+
327
328
function test_HasBeenExecuted () public {
328
329
address [] memory targets = new address [](1 );
329
330
targets[0 ] = address (mock);
330
-
331
+
331
332
bytes [] memory data = new bytes [](1 );
332
333
data[0 ] = abi.encodeWithSignature ("succeed() " );
333
-
334
+
334
335
bytes memory signature = signTypedData (signerPk, ref, targets, data, deadline);
335
-
336
+
336
337
vm.prank (user);
337
338
gmc.execute (signer, ref, targets, data, deadline, signature);
338
-
339
+
339
340
assertTrue (gmc.hasBeenExecuted (ref));
340
-
341
+
341
342
bytes32 invalidRef = keccak256 (abi.encodePacked ("invalid_ref " ));
342
343
assertFalse (gmc.hasBeenExecuted (invalidRef));
343
344
}
@@ -366,5 +367,4 @@ contract GuardedMulticallerTest is Test {
366
367
(uint8 v , bytes32 r , bytes32 s ) = vm.sign (_signerPk, digest);
367
368
return abi.encodePacked (r, s, v);
368
369
}
369
-
370
- }
370
+ }
0 commit comments