@@ -41,7 +41,8 @@ contract ExecutorTest is Test, WormholeTestUtils {
41
41
function testExecute (
42
42
address callAddress ,
43
43
bytes memory callData ,
44
- uint64 sequence
44
+ uint64 sequence ,
45
+ uint value
45
46
) internal returns (bytes memory vaa ) {
46
47
bytes memory payload = abi.encodePacked (
47
48
uint32 (0x5054474d ),
@@ -50,6 +51,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
50
51
CHAIN_ID,
51
52
address (executor),
52
53
callAddress,
54
+ value,
53
55
callData
54
56
);
55
57
@@ -66,7 +68,8 @@ contract ExecutorTest is Test, WormholeTestUtils {
66
68
}
67
69
68
70
function getTestUpgradeVaa (
69
- address newImplementation
71
+ address newImplementation ,
72
+ uint value
70
73
) internal returns (bytes memory vaa ) {
71
74
bytes memory payload = abi.encodePacked (
72
75
uint32 (0x5054474d ),
@@ -75,6 +78,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
75
78
CHAIN_ID,
76
79
address (executor),
77
80
address (executor),
81
+ value,
78
82
abi.encodeWithSelector (
79
83
ExecutorUpgradable.upgradeTo.selector ,
80
84
newImplementation
@@ -101,19 +105,19 @@ contract ExecutorTest is Test, WormholeTestUtils {
101
105
}
102
106
103
107
function testUpgradeCallSucceedsForContractWithCorrectMagic () public {
104
- bytes memory vaa = getTestUpgradeVaa (address (executor2));
108
+ bytes memory vaa = getTestUpgradeVaa (address (executor2), 0 );
105
109
executor.execute (vaa);
106
110
}
107
111
108
112
function testUpgradeCallFailsForNotUUPSContract () public {
109
- bytes memory vaa = getTestUpgradeVaa (address (callable));
113
+ bytes memory vaa = getTestUpgradeVaa (address (callable), 0 );
110
114
111
115
vm.expectRevert ("ERC1967Upgrade: new implementation is not UUPS " );
112
116
executor.execute (vaa);
113
117
}
114
118
115
119
function testUpgradeCallFailsForInvalidMagic () public {
116
- bytes memory vaa = getTestUpgradeVaa (address (executorInvalidMagic));
120
+ bytes memory vaa = getTestUpgradeVaa (address (executorInvalidMagic), 0 );
117
121
118
122
vm.expectRevert (ExecutorErrors.InvalidMagicValue.selector );
119
123
executor.execute (vaa);
@@ -127,14 +131,70 @@ contract ExecutorTest is Test, WormholeTestUtils {
127
131
testExecute (
128
132
address (callable),
129
133
abi.encodeWithSelector (ICallable.foo.selector ),
130
- 1
134
+ 1 ,
135
+ 0
131
136
);
132
137
assertEq (callable.fooCount (), c + 1 );
133
138
assertEq (callable.lastCaller (), address (executor));
134
139
// Sanity check to make sure the check above is meaningful.
135
140
assert (address (executor) != address (this ));
136
141
}
137
142
143
+ function testCallWithValueSucceeds () public {
144
+ callable.reset ();
145
+
146
+ uint32 c = callable.fooCount ();
147
+ assertEq (callable.lastCaller (), address (bytes20 (0 )));
148
+
149
+ uint value = 1 ;
150
+ vm.deal (address (executor), value);
151
+
152
+ testExecute (
153
+ address (callable),
154
+ abi.encodeWithSelector (ICallable.fooPayable.selector ),
155
+ 1 ,
156
+ value
157
+ );
158
+ assertEq (callable.fooCount (), c + 1 );
159
+ assertEq (callable.lastCaller (), address (executor));
160
+ assertEq (address (executor).balance, 0 );
161
+ assertEq (address (callable).balance, value);
162
+ // Sanity check to make sure the check above is meaningful.
163
+ assert (address (executor) != address (this ));
164
+ }
165
+
166
+ function testCallWithValueInsufficientBalance () public {
167
+ callable.reset ();
168
+
169
+ assertEq (callable.lastCaller (), address (bytes20 (0 )));
170
+
171
+ uint value = 5 ;
172
+ vm.deal (address (executor), 1 );
173
+
174
+ bytes memory payload = abi.encodePacked (
175
+ uint32 (0x5054474d ),
176
+ PythGovernanceInstructions.GovernanceModule.EvmExecutor,
177
+ Executor.ExecutorAction.Execute,
178
+ CHAIN_ID,
179
+ address (executor),
180
+ address (callable),
181
+ value,
182
+ abi.encodeWithSelector (ICallable.fooPayable.selector )
183
+ );
184
+
185
+ bytes memory vaa = generateVaa (
186
+ uint32 (block .timestamp ),
187
+ OWNER_CHAIN_ID,
188
+ OWNER_EMITTER,
189
+ 1 ,
190
+ payload,
191
+ NUM_SIGNERS
192
+ );
193
+
194
+ vm.expectRevert ();
195
+ executor.execute (vaa);
196
+ }
197
+
138
198
function testCallWithArgsSucceeds () public {
139
199
callable.reset ();
140
200
@@ -143,10 +203,34 @@ contract ExecutorTest is Test, WormholeTestUtils {
143
203
testExecute (
144
204
address (callable),
145
205
abi.encodeWithSelector (ICallable.fooWithArgs.selector , 17 ),
146
- 1
206
+ 1 ,
207
+ 0
208
+ );
209
+ assertEq (callable.fooCount (), c + 17 );
210
+ assertEq (callable.lastCaller (), address (executor));
211
+ // Sanity check to make sure the check above is meaningful.
212
+ assert (address (executor) != address (this ));
213
+ }
214
+
215
+ function testCallWithArgsAndValueSucceeds () public {
216
+ callable.reset ();
217
+
218
+ uint32 c = callable.fooCount ();
219
+ assertEq (callable.lastCaller (), address (bytes20 (0 )));
220
+
221
+ uint value = 1 ;
222
+ vm.deal (address (executor), value);
223
+
224
+ testExecute (
225
+ address (callable),
226
+ abi.encodeWithSelector (ICallable.fooPayableWithArgs.selector , 17 ),
227
+ 1 ,
228
+ value
147
229
);
148
230
assertEq (callable.fooCount (), c + 17 );
149
231
assertEq (callable.lastCaller (), address (executor));
232
+ assertEq (address (executor).balance, 0 );
233
+ assertEq (address (callable).balance, value);
150
234
// Sanity check to make sure the check above is meaningful.
151
235
assert (address (executor) != address (this ));
152
236
}
@@ -156,7 +240,8 @@ contract ExecutorTest is Test, WormholeTestUtils {
156
240
testExecute (
157
241
address (callable),
158
242
abi.encodeWithSelector (ICallable.foo.selector ),
159
- 1
243
+ 1 ,
244
+ 0
160
245
);
161
246
assertEq (callable.fooCount (), c + 1 );
162
247
}
@@ -178,6 +263,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
178
263
CHAIN_ID,
179
264
address (executor),
180
265
address (callable),
266
+ uint (0 ),
181
267
abi.encodeWithSelector (ICallable.foo.selector )
182
268
);
183
269
@@ -205,6 +291,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
205
291
CHAIN_ID,
206
292
address (executor),
207
293
address (callable),
294
+ uint (0 ),
208
295
abi.encodeWithSelector (ICallable.foo.selector )
209
296
);
210
297
@@ -229,6 +316,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
229
316
CHAIN_ID,
230
317
address (executor),
231
318
address (callable),
319
+ uint (0 ),
232
320
abi.encodeWithSelector (ICallable.foo.selector )
233
321
);
234
322
@@ -249,7 +337,8 @@ contract ExecutorTest is Test, WormholeTestUtils {
249
337
testExecute (
250
338
address (callable),
251
339
abi.encodeWithSelector (ICallable.foo.selector ),
252
- 3
340
+ 3 ,
341
+ 0
253
342
);
254
343
255
344
bytes memory payload = abi.encodePacked (
@@ -259,6 +348,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
259
348
CHAIN_ID,
260
349
address (executor),
261
350
address (callable),
351
+ uint (0 ),
262
352
abi.encodeWithSelector (ICallable.foo.selector )
263
353
);
264
354
@@ -278,7 +368,8 @@ contract ExecutorTest is Test, WormholeTestUtils {
278
368
testExecute (
279
369
address (callable),
280
370
abi.encodeWithSelector (ICallable.foo.selector ),
281
- 4
371
+ 4 ,
372
+ 0
282
373
);
283
374
assertEq (callable.fooCount (), 1 );
284
375
}
@@ -291,6 +382,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
291
382
CHAIN_ID,
292
383
address (executor),
293
384
address (callable),
385
+ uint (0 ),
294
386
abi.encodeWithSelector (ICallable.foo.selector )
295
387
);
296
388
@@ -320,6 +412,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
320
412
uint16 (3 ),
321
413
address (executor),
322
414
address (callable),
415
+ uint (0 ),
323
416
abi.encodeWithSelector (ICallable.foo.selector )
324
417
);
325
418
@@ -344,6 +437,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
344
437
CHAIN_ID,
345
438
address (0x1 ),
346
439
address (callable),
440
+ uint (0 ),
347
441
abi.encodeWithSelector (ICallable.foo.selector )
348
442
);
349
443
@@ -368,6 +462,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
368
462
CHAIN_ID,
369
463
address (executor),
370
464
address (callable),
465
+ uint (0 ),
371
466
abi.encodeWithSelector (ICallable.foo.selector )
372
467
);
373
468
@@ -392,6 +487,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
392
487
CHAIN_ID,
393
488
address (executor),
394
489
address (callable),
490
+ uint (0 ),
395
491
abi.encodeWithSelector (ICallable.reverts.selector )
396
492
);
397
493
@@ -416,6 +512,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
416
512
CHAIN_ID,
417
513
address (executor),
418
514
address (100 ),
515
+ uint (0 ),
419
516
abi.encodeWithSelector (ICallable.foo.selector )
420
517
);
421
518
@@ -436,8 +533,12 @@ contract ExecutorTest is Test, WormholeTestUtils {
436
533
interface ICallable {
437
534
function foo () external ;
438
535
536
+ function fooPayable () external payable ;
537
+
439
538
function fooWithArgs (uint32 inc ) external ;
440
539
540
+ function fooPayableWithArgs (uint32 inc ) external payable ;
541
+
441
542
function reverts () external ;
442
543
443
544
function reset () external ;
@@ -459,11 +560,21 @@ contract TestCallable is ICallable {
459
560
lastCaller = msg .sender ;
460
561
}
461
562
563
+ function fooPayable () external payable override {
564
+ fooCount += 1 ;
565
+ lastCaller = msg .sender ;
566
+ }
567
+
462
568
function fooWithArgs (uint32 inc ) external override {
463
569
fooCount += inc;
464
570
lastCaller = msg .sender ;
465
571
}
466
572
573
+ function fooPayableWithArgs (uint32 inc ) external payable override {
574
+ fooCount += inc;
575
+ lastCaller = msg .sender ;
576
+ }
577
+
467
578
function reverts () external override {
468
579
revert ("call should revert " );
469
580
}
0 commit comments