Skip to content

Commit 0a2378e

Browse files
authored
[entropy] more executor tests (#1162)
1 parent 8a98279 commit 0a2378e

File tree

1 file changed

+269
-2
lines changed

1 file changed

+269
-2
lines changed

target_chains/ethereum/contracts/forge-test/Executor.t.sol

Lines changed: 269 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ contract ExecutorTest is Test, WormholeTestUtils {
4646

4747
vaa = generateVaa(
4848
uint32(block.timestamp),
49-
// TODO: make these arguments so we can do adversarial tests
5049
OWNER_CHAIN_ID,
5150
OWNER_EMITTER,
5251
sequence,
@@ -57,7 +56,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
5756
executor.execute(vaa);
5857
}
5958

60-
function testBasic() public {
59+
function testCallSucceeds() public {
6160
callable.reset();
6261

6362
uint32 c = callable.fooCount();
@@ -69,16 +68,275 @@ contract ExecutorTest is Test, WormholeTestUtils {
6968
assert(address(executor) != address(this));
7069
}
7170

71+
function testCallWithArgsSucceeds() public {
72+
callable.reset();
73+
74+
uint32 c = callable.fooCount();
75+
assertEq(callable.lastCaller(), address(bytes20(0)));
76+
testExecute(
77+
address(callable),
78+
abi.encodeCall(ICallable.fooWithArgs, (17)),
79+
1
80+
);
81+
assertEq(callable.fooCount(), c + 17);
82+
assertEq(callable.lastCaller(), address(executor));
83+
// Sanity check to make sure the check above is meaningful.
84+
assert(address(executor) != address(this));
85+
}
86+
7287
function testCallerAddress() public {
7388
uint32 c = callable.fooCount();
7489
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 1);
7590
assertEq(callable.fooCount(), c + 1);
7691
}
92+
93+
function testIncorrectVaa() public {
94+
string[5] memory forgeItems = [
95+
"vaaSignature",
96+
"vaaVersion",
97+
"vaaGuardianSetIndex",
98+
"vaaNumSigners+",
99+
"vaaNumSigners-"
100+
];
101+
102+
for (uint i = 0; i < forgeItems.length; i++) {
103+
bytes memory payload = abi.encodePacked(
104+
uint32(0x5054474d),
105+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
106+
Executor.ExecutorAction.Execute,
107+
CHAIN_ID,
108+
address(executor),
109+
address(callable),
110+
abi.encodeCall(ICallable.foo, ())
111+
);
112+
113+
bytes memory vaa = forgeVaa(
114+
uint32(block.timestamp),
115+
OWNER_CHAIN_ID,
116+
OWNER_EMITTER,
117+
1,
118+
payload,
119+
NUM_SIGNERS,
120+
bytes(forgeItems[i])
121+
);
122+
123+
// ExecutorErrors.InvalidWormholeVaa.selector
124+
vm.expectRevert();
125+
executor.execute(vaa);
126+
}
127+
}
128+
129+
function testIncorrectOwnerEmitterAddress() public {
130+
bytes memory payload = abi.encodePacked(
131+
uint32(0x5054474d),
132+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
133+
Executor.ExecutorAction.Execute,
134+
CHAIN_ID,
135+
address(executor),
136+
address(callable),
137+
abi.encodeCall(ICallable.foo, ())
138+
);
139+
140+
bytes memory vaa = generateVaa(
141+
uint32(block.timestamp),
142+
OWNER_CHAIN_ID,
143+
bytes32(uint256(2)),
144+
1,
145+
payload,
146+
NUM_SIGNERS
147+
);
148+
149+
vm.expectRevert(ExecutorErrors.UnauthorizedEmitter.selector);
150+
executor.execute(vaa);
151+
}
152+
153+
function testIncorrectOwnerEmitterChainId() public {
154+
bytes memory payload = abi.encodePacked(
155+
uint32(0x5054474d),
156+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
157+
Executor.ExecutorAction.Execute,
158+
CHAIN_ID,
159+
address(executor),
160+
address(callable),
161+
abi.encodeCall(ICallable.foo, ())
162+
);
163+
164+
bytes memory vaa = generateVaa(
165+
uint32(block.timestamp),
166+
8,
167+
OWNER_EMITTER,
168+
1,
169+
payload,
170+
NUM_SIGNERS
171+
);
172+
173+
vm.expectRevert(ExecutorErrors.UnauthorizedEmitter.selector);
174+
executor.execute(vaa);
175+
}
176+
177+
function testOutOfOrder() public {
178+
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 3);
179+
180+
bytes memory payload = abi.encodePacked(
181+
uint32(0x5054474d),
182+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
183+
Executor.ExecutorAction.Execute,
184+
CHAIN_ID,
185+
address(executor),
186+
address(callable),
187+
abi.encodeCall(ICallable.foo, ())
188+
);
189+
190+
bytes memory vaa = generateVaa(
191+
uint32(block.timestamp),
192+
OWNER_CHAIN_ID,
193+
OWNER_EMITTER,
194+
3,
195+
payload,
196+
NUM_SIGNERS
197+
);
198+
199+
vm.expectRevert(ExecutorErrors.MessageOutOfOrder.selector);
200+
executor.execute(vaa);
201+
202+
callable.reset();
203+
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 4);
204+
assertEq(callable.fooCount(), 1);
205+
}
206+
207+
function testInvalidPayload() public {
208+
bytes memory payload = abi.encodePacked(
209+
uint32(0x5054474d),
210+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
211+
Executor.ExecutorAction.Execute,
212+
CHAIN_ID,
213+
address(executor),
214+
address(callable),
215+
abi.encodeCall(ICallable.foo, ())
216+
);
217+
218+
bytes memory shortPayload = BytesLib.slice(
219+
payload,
220+
0,
221+
payload.length - 1
222+
);
223+
bytes memory shortVaa = generateVaa(
224+
uint32(block.timestamp),
225+
OWNER_CHAIN_ID,
226+
OWNER_EMITTER,
227+
1,
228+
shortPayload,
229+
NUM_SIGNERS
230+
);
231+
232+
vm.expectRevert();
233+
executor.execute(shortVaa);
234+
}
235+
236+
function testIncorrectTargetChainId() public {
237+
bytes memory payload = abi.encodePacked(
238+
uint32(0x5054474d),
239+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
240+
Executor.ExecutorAction.Execute,
241+
uint16(3),
242+
address(executor),
243+
address(callable),
244+
abi.encodeCall(ICallable.foo, ())
245+
);
246+
247+
bytes memory vaa = generateVaa(
248+
uint32(block.timestamp),
249+
OWNER_CHAIN_ID,
250+
OWNER_EMITTER,
251+
1,
252+
payload,
253+
NUM_SIGNERS
254+
);
255+
256+
vm.expectRevert(ExecutorErrors.InvalidGovernanceTarget.selector);
257+
executor.execute(vaa);
258+
}
259+
260+
function testIncorrectTargetAddress() public {
261+
bytes memory payload = abi.encodePacked(
262+
uint32(0x5054474d),
263+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
264+
Executor.ExecutorAction.Execute,
265+
CHAIN_ID,
266+
address(0x1),
267+
address(callable),
268+
abi.encodeCall(ICallable.foo, ())
269+
);
270+
271+
bytes memory vaa = generateVaa(
272+
uint32(block.timestamp),
273+
OWNER_CHAIN_ID,
274+
OWNER_EMITTER,
275+
1,
276+
payload,
277+
NUM_SIGNERS
278+
);
279+
280+
vm.expectRevert(ExecutorErrors.DeserializationError.selector);
281+
executor.execute(vaa);
282+
}
283+
284+
function testIncorrectAction() public {
285+
bytes memory payload = abi.encodePacked(
286+
uint32(0x5054474d),
287+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
288+
uint8(17),
289+
CHAIN_ID,
290+
address(executor),
291+
address(callable),
292+
abi.encodeCall(ICallable.foo, ())
293+
);
294+
295+
bytes memory vaa = generateVaa(
296+
uint32(block.timestamp),
297+
OWNER_CHAIN_ID,
298+
OWNER_EMITTER,
299+
1,
300+
payload,
301+
NUM_SIGNERS
302+
);
303+
304+
vm.expectRevert();
305+
executor.execute(vaa);
306+
}
307+
308+
function testCallReverts() public {
309+
bytes memory payload = abi.encodePacked(
310+
uint32(0x5054474d),
311+
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
312+
Executor.ExecutorAction.Execute,
313+
CHAIN_ID,
314+
address(executor),
315+
address(callable),
316+
abi.encodeCall(ICallable.reverts, ())
317+
);
318+
319+
bytes memory vaa = generateVaa(
320+
uint32(block.timestamp),
321+
OWNER_CHAIN_ID,
322+
OWNER_EMITTER,
323+
1,
324+
payload,
325+
NUM_SIGNERS
326+
);
327+
328+
vm.expectRevert("call should revert");
329+
executor.execute(vaa);
330+
}
77331
}
78332

79333
interface ICallable {
80334
function foo() external;
81335

336+
function fooWithArgs(uint32 inc) external;
337+
338+
function reverts() external;
339+
82340
function reset() external;
83341
}
84342

@@ -97,4 +355,13 @@ contract TestCallable is ICallable {
97355
fooCount += 1;
98356
lastCaller = msg.sender;
99357
}
358+
359+
function fooWithArgs(uint32 inc) external override {
360+
fooCount += inc;
361+
lastCaller = msg.sender;
362+
}
363+
364+
function reverts() external override {
365+
revert("call should revert");
366+
}
100367
}

0 commit comments

Comments
 (0)