Documenting Smart Contracts: Recommendations and Security¶
Solid documentation is the cornerstone of any successful smart contract audit. It illuminates the design, functionality, and attack surface of a smart contract system, which lets auditors and external contributors evaluate it efficiently. Accessible documentation saves money, since new developers and auditors reach the point of contributing sooner, and it guides the implementation of future features toward more secure choices.
Design Overview¶
Every smart contract system solves a specific problem. High-level documentation starts with a problem description covering why the problem matters and how the system addresses it, then introduces the low-level components and their role in the whole. That progression carries the design rationale and the assumptions made during development. Graphics built during the system design process pair naturally with both halves.
With the moving parts described, the interactions and controls between components need documenting. Every meaningful interaction calls for four clarifications:
- Cross-contract Dependencies: Large smart contract systems often must distribute their business logic across multiple smart contracts. These interdependencies must be outlined and explained, as they can introduce trust assumptions and potentially undesired side effects. This knowledge can help auditors evaluate the impact of particular security vulnerabilities and how their findings affect the overall system. Similarly, when implementing new features, the development team can leverage this documentation to estimate the changes necessary to reflect a new feature in the existing code base.
- System Controls: If a smart contract system contains authorized actions and administrative capabilities, the current system's roles must be introduced and explained. This description should encompass the on-chain related aspects, e.g., what actions a specific role or authorized party can perform in the system and at what time, as well as the off-chain related aspects, such as which party owns private keys to an authorized address, how private keys are secured, or what the specific configuration of a DAO or multisig setup is. In the same spirit as the previous point, this helps outline trust relationships and surface risks that may affect system operations.
- Event Logging: As explained in the monitoring section, events are data stored and indexed on-chain to be consumed by off-chain infrastructure. Since events are a smart contract system's primary means for signaling its state to external entities, it is paramount to thoroughly document what events a smart contract system contains, which components they are raised by, and what data they have. This description should also include an explanation of what the event means and how it should be consumed by off-chain software.
- Invariants: One often overlooked aspect of smart contract documentation is that most business logic can be modeled after a set of properties that must always hold true. When these invariants are adequately documented, they can be leveraged by auditors and developers alike, guiding test suite development and manual code reviews. When invariants are written down in natural language, they can also be translated by professionals into more formal descriptions that can then be consumed by fuzzers to guide automated testing of security-related functionality.
NatSpec and Automation¶
Documentation is unpopular with developers and project managers, because its benefits arrive late and indirectly. High-level documentation is written by hand, while low-level technical documentation is annotated directly in the codebase. These documentation comments can be specified on a contract- and a function level. When written in a standard format like NatSpec, tools like solidity-docgen can parse the code base and automatically generate HTML and PDF documentation. The technical documentation can be generated during the CI and testing workflow and automatically uploaded to a free hosting service such as Github Pages.
The following code snippet taken from the Solidity docs (v0.8.20) is an example of NatSpec notation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | |
To make the automated documentation accessible for auditors and new developers, the smart contract project's README file should elaborate on installing the system's dependencies and generating the documentation. Alternatively, when documentation is automatically generated and hosted, the respective pages for the detailed technical documentation should be referenced wherever possible to help contributors contextualize the system's components more quickly.
The solidity-docgen project's documentation and the tool's help page carry further information, and both change frequently while the tool is under active development. The official OpenZeppelin contracts and documentation can be consulted for detailed syntax since they also adhere to the NatSpec standard and leverage specific features provided by solidity-docgen.
A good template for starting can be found in the official OZ forums.
Deployment¶
When smart contract infrastructure is designed for integration with other systems, a well-documented system provides clear guidance to developers, aiding in a smooth and efficient integration process.
For that purpose, developers need to know the locations of the most recent smart contract deployment. An excellent example of good practice in this area can be seen in the documentation provided by the Compound docs. The Compound developers list their deployments on each chain in their documentation. This practice significantly reduces the risk of developers mistyping an address or accidentally initializing their system to a deprecated contract version. Moreover, with new addresses published on partial updates, this aids in maintaining the consistency and reliability of the system.

An excellent addition for even quicker analysis is that the docs provide links adjacent to each address, directing users to the respective blockchain explorer. Reading, validating, and interacting with the contract then takes minimal effort, which cuts the time developers spend on contract analysis.
The deployment documentation outlines every step leading toward production deployment, ensuring the operations' sequence and outcomes are well understood. Providing and referencing helper scripts within the documentation enhances usability, allowing developers to automate or semi-automate parts of the deployment process. Furthermore, the documentation should comprehensively list system environment variables and smart contract constructor parameters, elucidating their roles in the deployment process and overall system functioning.
State every external contract the system interacts with explicitly. System behavior varies with the blockchain environment, and a contract it integrates with on one chain does not necessarily behave the same on another. An explicit warning that deployment on a different blockchain yields different results gives developers the context they need to plan a multi-chain deployment.
The Deployment section covers smart contract deployment security in more detail.
Contributions¶
Establishing clear contribution guidelines is crucial for fostering an inclusive and secure development environment. The guidelines should outline the process for submitting changes and code review and acceptance standards. This clarity enhances community collaboration, reducing the potential for misunderstanding or disputes.
Running a bug bounty program or having a systematic vulnerability reporting procedure encourages responsible disclosure of any discovered security issues. More details are in the dedicated bug bounty program section.
The documentation should include any previously conducted audits and their corresponding published reports. These provide valuable insights into the system's security posture and demonstrate transparency and dedication to quality, boosting user confidence and trust in the system.