浏览代码

[entropy] more executor tests (#1162)

Jayant Krishnamurthy 1 年之前
父节点
当前提交
0a2378e94c
共有 1 个文件被更改,包括 269 次插入2 次删除
  1. 269 2
      target_chains/ethereum/contracts/forge-test/Executor.t.sol

+ 269 - 2
target_chains/ethereum/contracts/forge-test/Executor.t.sol

@@ -46,7 +46,6 @@ contract ExecutorTest is Test, WormholeTestUtils {
 
 
         vaa = generateVaa(
         vaa = generateVaa(
             uint32(block.timestamp),
             uint32(block.timestamp),
-            // TODO: make these arguments so we can do adversarial tests
             OWNER_CHAIN_ID,
             OWNER_CHAIN_ID,
             OWNER_EMITTER,
             OWNER_EMITTER,
             sequence,
             sequence,
@@ -57,7 +56,7 @@ contract ExecutorTest is Test, WormholeTestUtils {
         executor.execute(vaa);
         executor.execute(vaa);
     }
     }
 
 
-    function testBasic() public {
+    function testCallSucceeds() public {
         callable.reset();
         callable.reset();
 
 
         uint32 c = callable.fooCount();
         uint32 c = callable.fooCount();
@@ -69,16 +68,275 @@ contract ExecutorTest is Test, WormholeTestUtils {
         assert(address(executor) != address(this));
         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 {
     function testCallerAddress() public {
         uint32 c = callable.fooCount();
         uint32 c = callable.fooCount();
         testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 1);
         testExecute(address(callable), abi.encodeCall(ICallable.foo, ()), 1);
         assertEq(callable.fooCount(), c + 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 {
 interface ICallable {
     function foo() external;
     function foo() external;
 
 
+    function fooWithArgs(uint32 inc) external;
+
+    function reverts() external;
+
     function reset() external;
     function reset() external;
 }
 }
 
 
@@ -97,4 +355,13 @@ contract TestCallable is ICallable {
         fooCount += 1;
         fooCount += 1;
         lastCaller = msg.sender;
         lastCaller = msg.sender;
     }
     }
+
+    function fooWithArgs(uint32 inc) external override {
+        fooCount += inc;
+        lastCaller = msg.sender;
+    }
+
+    function reverts() external override {
+        revert("call should revert");
+    }
 }
 }