Debugging Smart Contracts with Foundry
Posted on Sun 24 November 2024 in tech
Debugging in Foundry and Forge: Techniques for Solidity Developers
In this video, I walk through four essential debugging techniques in Foundry and Forge, as outlined in my YouTube video. These techniques include:
- Verbose Test Output
- Foundry Interactive Debugging
- Printf Debugging
- Event Logging
1. Verbose Test Output
Verbose test output is your first step in gaining visibility into what’s happening during your tests. Foundry’s forge
command allows you to run tests with detailed output that includes stack traces, failing assertions, and function calls.
How to Use
Run the following command to enable verbose output:
$ forge test -vvvv
The -vvvv flag sets the verbosity level to maximum, providing comprehensive details about test execution. This helps you pinpoint the exact location and nature of a failure, especially in large test suites.
Benefits
• Clear stack traces for failed tests.
• Insight into contract calls and execution flow.
• Quick identification of failing assertions.
Verbose output is a great starting point when a test doesn’t behave as expected.
2. Foundry Interactive Debugging
Foundry offers an interactive debugging mode that allows you to step through transactions and examine state changes. This feature is invaluable for complex debugging scenarios where simple test outputs aren’t enough.
How to Use
Enable debugging with:
$ forge test --debug
When a failing test is encountered, the debugger will pause execution, letting you: • Inspect variables and memory. • Step through execution one instruction at a time. • Evaluate expressions interactively.
Benefits
• Detailed view of the EVM state during execution.
• Fine-grained control over the debugging process.
• Ideal for deep dives into unexpected behavior.
Interactive debugging provides an advanced level of insight, making it perfect for diagnosing subtle issues.
3. Printf Debugging
Printf debugging is a simple yet effective approach where you insert logging statements into your contracts. Foundry supports emitting logs during test execution, which can help you trace execution flow and variable values.
How to Use
Add the following to your Solidity code:
emit log_named_uint("Variable Name", variable); emit log_named_address("Address", userAddress);
Run your tests with:
$ forge test -vvv
The output will include your custom logs, helping you trace what’s happening in your contract.
Benefits
• Quick to implement and easy to understand.
• Effective for tracing specific values.
• Can be combined with other debugging techniques.
This method is great for quick checks when you suspect an issue with specific variables or functions.
4. Event Logging
Event logging leverages Solidity events to record significant occurrences in your contracts. Unlike printf debugging, events are a core feature of Solidity and can be used for debugging and production purposes.
How to Use
Define events in your contract:
event DebugEvent(string message, uint256 value);
function someFunction(uint256 value) public { emit DebugEvent("Value passed to function", value); }
Run your tests as usual, and the emitted events will appear in the output.
Benefits
• Provides structured logs for both debugging and production monitoring.
• Easier to analyze than raw logs, especially in larger systems.
• Useful for identifying patterns and anomalies in your contract’s behavior.
Events are a robust solution for debugging and monitoring deployed contracts.
Conclusion
Debugging smart contracts is a critical skill, and Foundry and Forge provide a rich set of tools to help you identify and resolve issues efficiently. Whether you start with verbose test output or dive deep with interactive debugging, mastering these techniques will make you a more effective Solidity developer.
If you’d like a more detailed walkthrough, check out my YouTube video where I demonstrate these techniques in action.
What are your go-to debugging strategies in Solidity? Let me know in the comments or reach out on social media!