No doubt—writing secure smart contracts is hard. Even smart contracts written by senior developers can get hacked. And since these smart contracts often hold a high monetary value, the incentive to hack them is also high. Add in the immutability of web3, and getting security right becomes even more important. As a smart contract developer, smart contract security should be your top priority. In this article, I will walk through a recently published guide, by ConsenSys Diligence. It details 22 security tools from across web3 available at each stage of smart contract development. Security Tooling Guide for Smart Contracts I’ll highlight several important tools to help make your next smart contract even more secure. So, let’s walk through the guide one development stage at a time. Preparing for Development As you begin developing your smart contracts, security should be top-of-mind. My favorite sections of the guide are the tools that can help even as you prepare to code. This includes documentation, linting, and writing reusable code. First, is key to any development project, and smart contract development is no exception. The (NatSpec) is a great way to document smart contracts. documentation Ethereum Natural Specification Format NatSpec is a special form of comments added to provide rich documentation for contracts, interfaces, libraries, functions, and events. Consider the following solidity code snippet for a Tree : Contract // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 < 0.9.0; /// @title A simulator for trees /// @author Larry A. Gardner /// @notice You can use this contract for only the most basic simulation contract Tree { /// @notice Calculate tree age in years, rounded up, for live trees /// @dev The Alexandr N. Tetearing algorithm could increase precision /// @param rings The number of rings from dendrochronological sample /// @return Age in years, rounded up for partial years function age(uint256 rings) external virtual pure returns (uint256) { return rings + 1; } } NatSpec commented Solidity Contract By making use of NatSpec annotations, code can be easily explained to other developers, auditors, or someone just looking to interact with the contract. Simply put, it is clean, readable, and easy to understand. Next, is another proven way to reduce the risk of vulnerabilities in your smart contracts. reusing battle-tested code There are many widely-used open-source smart contract libraries available, such as with pre-written logic for implementing access control, pause functions, upgrades, and more, and for optimizing gas usage. OpenZeppelin Solmate Contracts Finally, is a valuable tool for finding potential issues in smart contract code. It can find stylistic errors, violations of programming conventions, and unsafe constructs in your code. There are many great linters available, such as (Formerly Solium). linting ETHLint Linting can help find potential problems—even security problems such as re-entrancy vulnerabilities—before they become costly mistakes. By considering documentation, linting, and reusable code during smart contract development, you can help ensure a more secure contract. Taking the time to set these up properly will pay off in the long run, both in terms of security and efficiency. Development Now let’s look at two categories of tools that can help you while you’re coding—unit tests and property-based testing. are clearly a vital part of creating secure and reliable code. By testing individual units of code, we can ensure that our contracts are functioning as intended and hopefully catch any potential issues before they cause problems in production. Unit tests There are several different tools available for writing unit tests for smart contracts. , , and are all popular framework choices that support various programming languages. Foundry Truffle Brownie (written in Rust) is a framework for writing smart contracts that include the testing framework . Foundry Forge Forge unit tests can be written directly in Solidity and include many that give you assertions, the ability to alter the state of the EVM, mock data, and more. Foundry also comes with built-in Fuzzing (which we discuss in more detail later in the post). cheat codes // SPDX-License-Identifier: Unlicense pragma solidity 0.8.10; import "ds-test/test.sol"; import "../StakeContract.sol"; import "./mocks/MockERC20.sol"; contract StakeContractTest is DSTest { StakeContract public stakeContract; MockERC20 public mockToken; function setUp() public { stakeContract = new StakeContract(); mockToken = new MockERC20(); } /// @notice Test token staking with different amount function test_staking_tokens() public { uint256 amount = 10e18; mockToken.approve(address(stakeContract), amount); bool stakePassed = stakeContract.stake(amount, address(mockToken)); assertTrue(stakePassed); } } A sample Solidity unit test in Foundry is also a framework for building smart contracts. Unit tests in Truffle can be written in Solidity or JavaScript. Often, developers use JavaScript-based tests for external interactions with a contract and Solidity tests for assessing a contract’s behavior on the actual blockchain. Truffle Truffle uses Mocha for async testing and Chai for assertions. is a Python-based framework for developing and testing smart contracts. Brownie integrates with pytest for unit testing and has a stack trace analysis tool for measuring code coverage. Brownie When writing unit tests, aim for high-test coverage by testing as many different parts of the code as possible to ensure that all the functionality works as expected. Foundry does not require an extra plugin to measure test coverage; for other frameworks, there is likely at least one plugin you can add to measure this. While unit testing is a reliable approach to ensure the correctness of smart contracts, allows for the deeper verification of smart contracts. This is a relatively new concept, and it offers a range of advantages over traditional unit testing. property-based testing Property-based testing focuses on testing the—you guessed it— of a smart contract rather than its individual components. properties From the guide, “Properties describe the expected behavior of a smart contract and state logical assertions about its execution.” A property must hold true at all times. “Property-based testing tools take a smart contract’s code and a collection of user-defined properties as inputs and check if execution violates them at any point in time.” Property-based testing is based on the notion of , which is a technique for testing a system by introducing random inputs. This means that property-based testing can check a smart contract on a much broader level, as it does not rely on specific inputs provided by the developer. fuzzing Because of this, it is becoming an increasingly popular method for testing smart contracts. Using our previous contract as an example, let us use a property-based approach to test a simple function. For this, we will use , a specification language and runtime tool that makes this a whole lot easier. staking Scribble // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; error TransferFailed(); contract StakeContract { mapping(address => uint256) public s_balances; /// #if_succeeds {:msg "Stake created successfully"} $result == true; function stake(uint256 amount, address token) external returns (bool){ s_balances[msg.sender] += amount; bool success = IERC20(token).transferFrom(msg.sender, address(this), amount); if (!success) revert TransferFailed(); return success; } } A sample solidity property test in Scribble Notation Different tools can use Scribble specifications for property testing To assess our staking function, we must check that it returns in the event of successful execution. This can be done by adding a comment to the stake function code, as directed above, without the need for a separate test file. true The Scribble CLI tool can then be run to convert the scribble annotations into assertions. Next, these assertions must be run through a fuzzer such as or to determine if there are any property violations. Diligence Fuzzing Mythril Reports from an example Diligence Fuzzing campaign There are several other tools available for property-based testing, such as Foundry. Scribble (used above), Diligence Fuzzing, and Mythril are some of the most recommended. Scribble and Diligence Fuzzing are free and open-source tools built by ConsenSys Diligence. Mythril is a tool designed to detect potential vulnerabilities in Ethereum smart contracts. I particularly enjoy Scribble because putting together these tests is as simple as adding function annotations. Post-Development Finally, let’s look at the last group of tools—post-development. Specifically, monitoring. Because smart contract code on most blockchains is immutable, you have little to no control over your code once it’s pushed to mainnet. can help you be aware of any issues or changes in your code so that you can address them quickly. Not only will this help you improve the security of your contracts, but it will also help you optimize and improve their functionality. Monitoring Tools like OpenZepplin’s and are great for monitoring on-chain contracts and wallets. Defender Sentinels Tenderly’s Real-Time Alerting provides a collection of custom triggers to choose from, allowing you to quickly set up alerts for a variety of activities, such as when a new contract is deployed, when a transaction is sent or received, and when a certain address is targeted. Tenderly Alerts provides real-time security monitoring and alerts through a series of custom parameters that you define—such as if withdrawals cross a specific threshold, if someone performs a critical action like calling transferOwnership, or if a blacklisted address attempts to interact with your contract. Defender Sentinel What Else? These are some of the essential parts of smart contract security, but there are numerous other considerations I haven’t covered. For example, secure access control and administration, bug bounties and vulnerability reports, and strategies and contingencies for responding to security incidents. These considerations, and more, are covered in detail in the full guide. Conclusion Smart contract security tooling is Hopefully, this overview has helped in your quest for understanding the right tools available to you in order to write more secure smart contracts. For more detailed information, check out the . really important. complete ConsenSys Diligence guide here Photo by on Elena Rouame Unsplash