diff --git a/src/test/Tests/Cheat.hs b/src/test/Tests/Cheat.hs index 9666a7d50..cce8d37dd 100644 --- a/src/test/Tests/Cheat.hs +++ b/src/test/Tests/Cheat.hs @@ -2,7 +2,7 @@ module Tests.Cheat (cheatTests) where import Test.Tasty (TestTree, testGroup) -import Common (testContract', solcV, solved) +import Common (testContract', solcV, solved, passed) import Echidna.Types.Campaign (WorkerType(..)) @@ -15,4 +15,10 @@ cheatTests = [ ("echidna_ffi passed", solved "echidna_ffi") ] , testContract' "cheat/gas.sol" (Just "TestCheatGas") (Just (> solcV (0,5,0))) (Just "cheat/ffi.yaml") False FuzzWorker [ ("echidna_gas_zero passed", solved "echidna_gas_zero") ] + , testContract' "cheat/prank.sol" (Just "TestPrank") (Just (> solcV (0,5,0))) (Just "cheat/prank.yaml") False FuzzWorker + [ ("withPrank failed", passed "withPrank") + , ("withStartPrank failed", passed "withStartPrank") + , ("withStartPrankStopPrank failed", passed "withStartPrankStopPrank") + , ("withNothing failed", passed "withNothing") + ] ] diff --git a/tests/solidity/cheat/prank.sol b/tests/solidity/cheat/prank.sol new file mode 100644 index 000000000..125a8a023 --- /dev/null +++ b/tests/solidity/cheat/prank.sol @@ -0,0 +1,94 @@ +interface IHevm { + function prank(address newSender) external; + function startPrank(address sender) external; + function stopPrank() external; +} + +contract ExpectedCreator { + event Sender(address); + event AssertionFailed(string); + IHevm constant vm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + constructor(address s) public { + if (s != msg.sender) { + emit Sender(msg.sender); + emit AssertionFailed("fail on construct"); + } + } +} + +contract SenderVerifierChild { + event Sender(address); + event AssertionFailed(string); + IHevm constant vm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function verifyMsgSender(address s) public { + if (s != msg.sender) { + emit Sender(msg.sender); + emit AssertionFailed("fail on inner call"); + } + } +} + +contract SenderVerifierParent { + event Sender(address); + event AssertionFailed(string); + IHevm constant vm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + SenderVerifierChild c; + constructor() public { + c = new SenderVerifierChild(); + } + + function verifyMsgSender(address s) public { + if (s != msg.sender) { + emit Sender(msg.sender); + emit AssertionFailed("fail on first call"); + } + c.verifyMsgSender(address(this)); + new ExpectedCreator(address(this)); + } +} + +contract TestPrank { + IHevm constant vm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + SenderVerifierParent p; + constructor() public { + p = new SenderVerifierParent(); + } + + function withPrank() public { + vm.prank(address(0x123)); + p.verifyMsgSender(address(0x123)); + p.verifyMsgSender(address(this)); + + vm.prank(address(0x123)); + new ExpectedCreator(address(0x123)); + new ExpectedCreator(address(this)); + } + + function withStartPrank() public { + vm.startPrank(address(0x123)); + p.verifyMsgSender(address(0x123)); + p.verifyMsgSender(address(0x123)); + new ExpectedCreator(address(0x123)); + new ExpectedCreator(address(0x123)); + } + + function withStartPrankStopPrank() public { + vm.startPrank(address(0x123)); + p.verifyMsgSender(address(0x123)); + p.verifyMsgSender(address(0x123)); + new ExpectedCreator(address(0x123)); + new ExpectedCreator(address(0x123)); + vm.stopPrank(); + p.verifyMsgSender(address(this)); + new ExpectedCreator(address(this)); + } + + function withNothing() public { + p.verifyMsgSender(address(this)); + new ExpectedCreator(address(this)); + } +} diff --git a/tests/solidity/cheat/prank.yaml b/tests/solidity/cheat/prank.yaml new file mode 100644 index 000000000..5311e3c89 --- /dev/null +++ b/tests/solidity/cheat/prank.yaml @@ -0,0 +1,3 @@ +testLimit: 1000 +seqLen: 10 +testMode: assertion \ No newline at end of file