by
Gracious Igwe

Auditing A Solidity Contract: Episode 4 - Testing

Smart contracts are self-executing codes that form the backbone of the Web3 ecosystem. Smart contracts serve as the foundational threads of the Web3 ecosystem, delicately balancing billions on an open network. Today, we will discuss popular testing tools and techniques used in smart contract development, such as Truffle, Hardhat, Foundry, formal verification, fuzzing, and unit testing. This is a great place to start if you want to learn about Solidity and how to audit smart contracts. This is one article in a series on auditing Solidity smart contracts. The series will cover vulnerabilities and resources that smart contract auditors use.

Testing

Solidity testing entails systematically assessing and validating smart contracts' performance, security, and functionality.

Creating comprehensive test cases requires identifying potential inputs, outputs, and interactions with the contract under various conditions to cover different scenarios and edge cases. Test cases should contain regular use cases and exceptional scenarios to verify the contract's behavior in all situations.

Testing Tools

There are three widely adopted testing frameworks within the Ethereum ecosystem: Truffle, Hardhat, and Foundry.

Testing Techniques

  1. Formal Verification

Formal verification is a mathematical approach used to confirm the correctness of a system, such as software, hardware, or a smart contract. It involves creating a formal model that precisely defines the system's expected behavior and then using mathematical techniques to verify whether the actual implementation adheres to this specification. 

The process of formal verification involves:

Techniques for formal verification

  1. Fuzz Testing

Fuzz testing, commonly known as fuzzing, is a dynamic software testing technique designed to uncover application implementation bugs and vulnerabilities by injecting malformed, unexpected, or random data as inputs. This method operates within a black box framework, focusing on the application's external behavior without requiring insights into its internal code or logic. Fuzzing enhances software security and robustness, offering an automated approach to identifying potential weaknesses that might evade conventional testing methods.

  1. Unit Tests

A unit test checks one piece of code, like a function, to ensure it works correctly. These tests are important because they cover all possible scenarios for that specific piece of code and can find bugs that might not show up in other types of tests. 

When you perform a unit test, you select certain inputs to see if they give the right output. How good your test is depends on what inputs you choose. Selecting the right inputs is easy for expected situations, but experienced testers are good at selecting unexpected inputs because those are the ones that often reveal bugs in your code.

  1. Integration Tests

An integration test tests a combination of units. Even if each part works fine on its own, they might cause unexpected issues when combined. When making integration tests, try to integrate as many parts as possible. However, the more parts you integrate, the harder it is to find out why a test failed. So, a simple strategy is to integrate only parts that affect each other in the final system.

  1. Functional Tests

A functional test tests the system, often called “user-story testing,” based on the user stories outlined during the project's initial requirements phase. These user stories, part of the technical specifications, serve as a guide for writing the code. Functional tests aim to confirm if the system meets these requirements. They're important because even if unit and integration tests pass, failing a functional test means the system doesn't fulfill its intended purpose. On the other hand, if all functional tests pass, a few failed unit or integration tests may not be as critical.

In Conclusion 

Testing tools and techniques are important in ensuring smart contracts' reliability, security, and compliance. Smart contracts' security ultimately contributes to successfully adopting and utilizing blockchain-based applications. This is why smart contract audits, bug bounties, and reviews are crucial in every stage of development. They increase the number of eyes scouting for vulnerabilities and decrease the chance of critical vulnerabilities slipping through.

Stay safe. 

Related Articles:

  1. Auditing A Solidity Contract: Episode 1 - Re-entrancy Attack: Learn about the basics of Re-entrancy attacks and the solutions to them.
  2. Auditing A Solidity Contract: Episode 2 - Delegatecall: Deep dive into deligatecall vulnerability and learn how to best address it as a smart contract auditor. 
  3. Auditing A Solidity Contract: Episode 3 - Security Analysis: Learn about three common smart contracts security vulnerabilities floating pragma, phishing with tx.origin and block timestamp manipulation.
  4. Auditing A Solidity Contract: Episode 5 - Automated Testing Tools

Latest