ethereum / hevm

symbolic EVM evaluator
https://hevm.dev
GNU Affero General Public License v3.0
223 stars 45 forks source link

Added `startPrank()` and `stopPrank()` cheatcodes to hevm. #495

Closed alecmaly closed 2 months ago

alecmaly commented 3 months ago

Description

Added startPrank() and stopPrank() cheatcodes to hevm.

This should assist in testing smart contracts when using tools that rely on hevm such as Echidna or Medusa.

Auditors are creating complex proxy patterns to do external testing of contracts using tools such as Echidna / Medusa: How to set up Multi Actor Invariant Testing

Note Alex The Entrepenerd's response in Discord stating startPrank() would eliminate the need for this testing pattern: link to discord conversation

Testing

Tested locally with

cabal test --test-options='-p /Cheat-Codes-Pass/'

Look for tests prove_startPrank(address) and prove_startPrank_val()

Checklist

Additional Notes

Edge cases such as stacks of startPrank() were not tested/considered. For example, this code will not work - although I am unsure how this operates in Foundry anyway.

.. code 1 ..
hevm.startPrank(address1);
 .. code 2 ..
hevm.startPrank(address2);
 .. code 3 .. 
hevm.stopPrank();
.. code 4 ..
hevm.stopPrank();
.. code 5 ..

While untested, I would expect: code 1 to have msg.sender = default code 2 to have msg.sender = address1 code 3 to have msg.sender = address2 code 4 to have msg.sender = default code 5 to have msg.sender = default


I have never written code in Haskell before nor do I have experience with this codebase, please let me know if there are edge cases to consider or any other styling I should do to conform to this repo's standards.