š” Solidity Tip of the Week Debugging the fuzzing process is essential for ensuring the effective testing of smart contract properties. With that in mind, here are some tips for debugging with Echidna: šØšš¶š»š“ šš¼šš²šæš®š“š² š„š²š½š¼šæš A Coverage report is a file containing information on which parts of the code were covered during fuzzing. We can see in the first image a snippet of a coverage report containing only one function that is responsible for testing a specific property. The `*` on the left tells us that the fuzzer was capable of successfully executing all lines of code. There are other symbols, such as: ⢠`r`, if execution finished with REVERT ⢠`o`, if execution finished with out-of-gas error ⢠`e`, if execution finished with another error It's possible to see more than one symbol in a single line, such as `*r`. In this case, `*r` indicates the fuzzer executed that line despite having reverted at another point. š”š¼šš²: To generate reports, you must set the coverage flag to true. See link: lnkd.in/d6ux9DcA. But how do these coverage reports help us debug? š¤ They will help us in two ways: 1ļøā£ To verify if the tests are well implemented Echidna may show a test as successful even if it's a false positive. This happens when the property assertion isn't executed, often due to business logic errors in the test. Always verify test coverage to ensure assertions are executed and tests are correctly implemented.ļø 2ļøā£ To verify the coverage of the smart contracts that are subject to testing The coverage report gives us which lines of code were tested by the fuzzer. Therefore, it makes sense to verify if the fuzzer has covered as many lines of code as possible. The more coverage, the more reliable the tests are likely to be. šØšš¶š»š“ `š®ššš²šæš(š³š®š¹šš²)` & ššš²š»š ššŗš¶ššš¶š¼š» Why `assert(false)`? Simple, is to intentionally break the execution so that we can observe the stack trace. This gives more detailed information about the execution flow, helping in the debugging process. We can combine `assert(false)` with event emission to log relevant values, as we can see in the second image. These events are also prompted in the stack trace, and this can be useful for comparing the obtained values with the expected ones. We can conclude the property failed because the obtained value was lower than expected. With this info, we can focus on why this situation occurred and investigate the code scope where this problem might originate. See Trail of Bits properties lib: lnkd.in/dDDhckyN. š We've got you covered! Follow us for the latest updates, tips, and insights on blockchain security and development!