Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[entropy] More executor tests #1162

Merged
merged 1 commit into from
Dec 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
more executor tests
  • Loading branch information
jayantk committed Dec 2, 2023
commit d02911543e8e3051cead2505fe391f2e5fb29445
271 changes: 269 additions & 2 deletions target_chains/ethereum/contracts/forge-test/Executor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ contract ExecutorTest is Test, WormholeTestUtils {

vaa = generateVaa(
uint32(block.timestamp),
// TODO: make these arguments so we can do adversarial tests
OWNER_CHAIN_ID,
OWNER_EMITTER,
sequence,
Expand All @@ -57,7 +56,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
executor.execute(vaa);
}

function testBasic() public {
function testCallSucceeds() public {
callable.reset();

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

function testCallWithArgsSucceeds() public {
callable.reset();

uint32 c = callable.fooCount();
assertEq(callable.lastCaller(), address(bytes20(0)));
testExecute(
address(callable),
abi.encodeCall(ICallable.fooWithArgs, (17)),
1
);
assertEq(callable.fooCount(), c + 17);
assertEq(callable.lastCaller(), address(executor));
// Sanity check to make sure the check above is meaningful.
assert(address(executor) != address(this));
}

function testCallerAddress() public {
uint32 c = callable.fooCount();
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 1);
assertEq(callable.fooCount(), c + 1);
}

function testIncorrectVaa() public {
string[5] memory forgeItems = [
"vaaSignature",
"vaaVersion",
"vaaGuardianSetIndex",
"vaaNumSigners+",
"vaaNumSigners-"
];

for (uint i = 0; i < forgeItems.length; i++) {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = forgeVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS,
bytes(forgeItems[i])
);

// ExecutorErrors.InvalidWormholeVaa.selector
vm.expectRevert();
executor.execute(vaa);
}
}

function testIncorrectOwnerEmitterAddress() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
bytes32(uint256(2)),
1,
payload,
NUM_SIGNERS
);

vm.expectRevert(ExecutorErrors.UnauthorizedEmitter.selector);
executor.execute(vaa);
}

function testIncorrectOwnerEmitterChainId() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
8,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS
);

vm.expectRevert(ExecutorErrors.UnauthorizedEmitter.selector);
executor.execute(vaa);
}

function testOutOfOrder() public {
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 3);

bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
3,
payload,
NUM_SIGNERS
);

vm.expectRevert(ExecutorErrors.MessageOutOfOrder.selector);
executor.execute(vaa);

callable.reset();
testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 4);
assertEq(callable.fooCount(), 1);
}

function testInvalidPayload() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory shortPayload = BytesLib.slice(
payload,
0,
payload.length - 1
);
bytes memory shortVaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
shortPayload,
NUM_SIGNERS
);

vm.expectRevert();
executor.execute(shortVaa);
}

function testIncorrectTargetChainId() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
uint16(3),
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS
);

vm.expectRevert(ExecutorErrors.InvalidGovernanceTarget.selector);
executor.execute(vaa);
}

function testIncorrectTargetAddress() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(0x1),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS
);

vm.expectRevert(ExecutorErrors.DeserializationError.selector);
executor.execute(vaa);
}

function testIncorrectAction() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
uint8(17),
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.foo, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS
);

vm.expectRevert();
executor.execute(vaa);
}

function testCallReverts() public {
bytes memory payload = abi.encodePacked(
uint32(0x5054474d),
PythGovernanceInstructions.GovernanceModule.EvmExecutor,
Executor.ExecutorAction.Execute,
CHAIN_ID,
address(executor),
address(callable),
abi.encodeCall(ICallable.reverts, ())
);

bytes memory vaa = generateVaa(
uint32(block.timestamp),
OWNER_CHAIN_ID,
OWNER_EMITTER,
1,
payload,
NUM_SIGNERS
);

vm.expectRevert("call should revert");
executor.execute(vaa);
}
}

interface ICallable {
function foo() external;

function fooWithArgs(uint32 inc) external;

function reverts() external;

function reset() external;
}

Expand All @@ -97,4 +355,13 @@ contract TestCallable is ICallable {
fooCount += 1;
lastCaller = msg.sender;
}

function fooWithArgs(uint32 inc) external override {
fooCount += inc;
lastCaller = msg.sender;
}

function reverts() external override {
revert("call should revert");
}
}
Loading