A smart contract audit is a line-by-line inspection of a contract’s source code. At CertiK, our team of experienced auditors manually review smart contracts, identifying code errors and potential risks. We also use advanced mathematical approaches such as formal verification to analyze the logical soundness of contracts.
Smart contracts secure hundreds of billions of dollars of value, but they’re mostly unintelligible to anyone who hasn’t learned one of the programming languages they’re written in. And these languages are brand new: Solidity – the first fully-featured smart contract programming language – is less than a decade old.
As most people who interact with smart contracts are unable to read them, there is a strong and growing need for third-party security assurances via smart contract audits.
At CertiK, we’ve audited nearly two thousand decentralized finance (DeFi) and NFT projects. We’re committed to raising the standard of security and transparency across the industry. In pursuit of this mission, we’ve developed and released freely-available tools such as the Security Leaderboard and Skytrace that make it easy to do your own research, and our Community Alerts resource that is often first to sound the alarm when a DeFi platform is compromised.
Smart contract audits cannot be treated as an afterthought. Security should be integrated into all steps of the development process from the very beginning. This ensures that there is sufficient time for a maximally thorough audit, and time for any issues to be resolved before a project goes to launch.
The smart contract auditing process is a very collaborative one, and utilizes a number of different inspection techniques. First, we receive the contracts to be audited from the client. Next, we begin our vulnerability inspection. This has two parts: formal verification and manual review.
Our formal verification engine is an automated process that checks every variable of a smart contract against each possible value it may have. It calculates every possible state of a smart contract. Imagine visualizing thousands of parallel universes simultaneously, each with one specific thing changed. The formal verification engine raises the alarm about issues that may affect the logical integrity of the contract.
Manual review is just what it sounds like: our team of auditors go through each line of code and meticulously inspect it for known vulnerabilities and code errors. You’ll find a list of some of the most common vulnerabilities we encounter in the course of our smart contract audits below.
After preparing a vulnerability summary, our auditors send their report to the client, along with their recommendations for alleviating any issues found. If the client resolves these issues, we mark them as such. If not, we highlight all outstanding risks in our final report.
A security vulnerability is anything that has the potential to affect the smooth and safe functioning of a smart contract. This could be an error in the calculation of a variable, unnecessary privileges granted to a centralized address, and much more.
Our smart contract audit reports classify risks into five categories:
Critical risks are those that impact the safe functioning of a platform and must be addressed before launch. Users should not invest in any project with outstanding critical risks.
Major risks can include centralization issues and logical errors. Under specific circumstances, these major risks can lead to loss of funds and/or control of the project.
Medium risks may not pose a direct risk to users’ funds, but they can affect the overall functioning of a platform.
Minor risks can be any of the above, but on a smaller scale. They generally do not compromise the overall integrity of the project, but they may be less efficient than other solutions.
Informational errors are often recommendations to improve the style of the code or certain operations to fall within industry best practices. They usually do not affect the overall functioning of the code.
Our auditors find vulnerabilities of all severities during their inspections. The top five most common vulnerabilities found during a smart contract audit are:
Centralization is a risk both to project owners and users. If a single address is granted executive privileges and later has its private key compromised, developers are at risk of losing control of their project and users are at risk of losing control of their money.
Projects that rugpull their investors’ funds often take advantage of centralized privileges. Avoiding unnecessary centralization is one way that newly-launched projects can begin building trust with their community.
Giving executive privilege to a decentralized autonomous organization (DAO) is one way to allow a project’s tokenholders to control its future. Timelocks are another option, though they do not necessarily reduce centralization. Instead, they set a minimum amount of time (e.g. 24 hours) before any changes to the protocol can be enacted. This gives users time to review the changes and, if needed, safeguard their liquidity.
Certain smart contract functions should emit events after they are called. These emissions change the status of sensitive variables or call important processes. They are not necessarily required for a function to execute properly the first time, but they are needed for it to execute every other time.
A compiler converts high level source code to a lower level language so that it may run as an executable. Solidity – the language in which Ethereum-compatible smart contracts are written – utilizes a compiler, as does CertiK’s own DeepSEA programming language. There are a number of versions of the Solidity compiler, and new versions are frequently released with new features.
Smart contracts should specify and lock the version of the compiler they use. An unlocked compiler version in the source code of a contract permits a user to compile it at or above a particular version. This leads to differences in the generated bytecode between compilations due to differing compiler version numbers.
Validating inputs (e.g. ensuring that a certain variable in a function is greater than zero) limits the functionality of an executable to a set of known possibilities. Since smart contracts are deployed in their entirety and users can view and interact with every variable, limiting their ability to create unknown, potentially malicious events is an essential process.
Reliance on third-party dependencies should be avoided as much as possible. A developer can only control the security of their own code, not that of the external contracts with which theirs interact. While tools such as the Security Oracle can act as a failsafe by ensuring external contracts meet a predetermined level of security before an interaction is approved, the goal of DeFi is to remove centralization in all its forms. Interoperability magnifies the power and potential of smart contracts, but it also requires that they all meet a certain standard of security and decentralization.
You might have noticed that projects on the Security Leaderboard are ranked according to their security score. A project that resolves any vulnerabilities found during its smart contract audit prior to launch will score higher than one that goes live with unaddressed risks. Enabling real time monitoring solutions such as Skynet and the Security Oracle will also boost a project’s ranking, as it allows for a wide range of up to the minute data to be taken into account. You can check out the factors that influence a project’s security score on its page on the Security Leaderboard.