Writing proof of concept (PoC) tests is a crucial part of the security engineering process when auditing code. PoCs are commonly written as unit tests in Foundry to demonstrate exploiting vulnerabilities, and test suggested mitigations. They are a powerful tool for confirming and communicating your findings to project owners and should be a core part of every auditor’s process. Code4rena, Sherlock, CodeHawks, and Immunefi all require or highly recommend including PoCs with your submissions, making test writing a must-have skill for auditors.
Foundry tests can be used not only for proofs of concept, but also for dynamic testing to explore the behavior of a project and critical code paths. A powerful technique for finding vulnerabilities is to write tests for edge cases and uncommon or unexpected inputs. When auditing a project, a simple way to get started with this is to copy existing unit tests and add additional inputs that developers have not already tested for. For example, suppose a developer has written a test for a function that performs a transfer of tokens between two addresses - transferTokens(from, to). In that instance, you might consider reconfiguring it to test the case in which the ‘from’ variable is set to 0x000…000 or the case in which an incomplete address (such as “0x31a2”) is passed as one of the variables. You can observe the behavior of the contracts in these edge cases via testing, which may uncover logic errors made by the developers or reveal subtleties in the underlying functionality of the solidity code that could be otherwise hard to spot in code review.
Another great way to streamline your auditing process is to build a collection of test templates that you apply to each project you audit. You can build generalized tests for demonstrating exploiting issues like reentrancy, oracle manipulation, front-running attacks, timestamp dependence, etc. These test templates can be adapted to your individual audits to quickly test for common vulnerabilities or provide you a good foundation for creating PoC tests when you have identified the possibility of a vulnerability in code review. Here are a couple of examples of existing tests and templates that you can use in your audits:
Using Foundry for testing today requires you to download and build the project you are auditing and run Foundry’s “forge test” in the command line to execute the project's tests. To create and run PoCs, you must add to the test files and re-run “forge test”, filtering to just the tests you added. To dig into the traces to know what is causing a test to pass or fail, you can run the command in verbose mode, which will print a contract trace to the terminal. These traces can be quite extensive and detailed, which can make them difficult to analyze in a terminal window. Testing your PoCs can also be cumbersome because you need to engage with Forge in a separate window from your editor as you write and debug your tests. Thankfully, an alternative to Foundry’s text-based UI has arrived:
We’ve just updated Audit Wizard to include the ability to create and execute tests! You can now run existing tests in Foundry projects, write your own tests from scratch or by duplicating other tests, and even use AI to generate PoCs for any of your findings. You can run tests individually or all at once, and your tests are managed separately from the project code, so it is easy to keep track of your PoCs and existing tests.
Coming next will be a library of PoC templates where you can browse published templates and save your own to use across your projects and to share with others. We’ll also be making trace output from tests more interactive and digestible so you can more easily understand and explore how your tests did at a fine-grained level. Check out our docs to learn more about using the new testing feature.
Check out testing (and many other powerful features) in Audit Wizard today, and start leveling up your audits like a true wizard! 🧙