Our Auditing Services

Extropy.IO
7 min readJul 22, 2022

Introduction

One line of defense against exploits is a professional audit of your smart contracts. Sadly there are still too few projects getting their code fully audited, as shown is the rekt.news leaderboard of exploits.

Of course an audit is just one part of development best practices, but it is an essential part that should not be neglected.

At Extropy, we have been auditing contracts since 2017 and the ICO boom, you can see some of the recent audits we have completed here along with more details of the process.

What are smart contract audits?

A smart contract audit is a thorough investigation and examination of a smart contract’s code. An audit aims to uncover any errors, vulnerabilities and security issues and provide remediation or suggestions on how they can be addressed.

However, smart contract audits are not just for testing against possible attacks. They also:

  • Provide checks on the code quality and consistency
  • Analyse the code for common errors (variable types errors, compilation errors etc.)
  • Security audits are necessary as frequently smart contracts deal with financial assets and therefore rigorous checking needs to take place to ensure the safety of those assets.

Smart contracts tend to be complex in nature, normally interacting with other contracts and third party systems. This adds an additional level of potential security implications and therefore audits check those interactions through code analysis and testing.

Types of auditing

There are two types of auditing that are used to check smart contract code. A well rounded audit will consist of both:

  1. Manual Auditing

Manual auditing generally involves a team of auditors that analyse each line of code and check it for possible security issues. This approach is generally seen as the most accurate as it not only provides checking for security errors but also on contract logic. We would also check that the contract does not violate the original intended behaviour that has been outlined by the client.

  1. Automated Auditing

Automated auditing is done by using a wide range of tools that can test for vulnerabilities much quicker than manually auditing a contract. These tools can not only check for existing bugs in the code but also where potential bugs could occur, providing a proactive approach to security management. However, these tools are not foolproof. The speed at which they run can cause them to miss security flaws and also highlight code that there are no issues with.

The benefits of auditing

  • Risk Identification
  • Highlighting any security issues in the contract before it is launch on the blockchain. This can then be address proactively before any serious issues arise (ie. exploits).
  • Code Improvements
  • Checking the quality of the code including adherence to best practices ensures that code is easily readable and maintainable. It also helps to produce a more secure and robust contract.
  • Gas Optimisation
  • An audit can check to see how efficient the contract is with gas and help to provide solutions to improve gas costs.
  • Performance
  • Checking contract executions and any variations that may occur can check for possible unintended outcomes that may arise and to enhance performance
  • Credibility
  • Showing that your contract has passed an audit can offer some credibility to users that the contract is working as intended (however this should not be taken as a guarantee)
  • Compliance
  • A smart contract may need an audit as part of compliance on performing regulated activity(Cryptoassets: AML/CFT regime)

Our auditing process

  • We review the source code and scope of the audit and agree timescale and price
  • We check the code manually to ensure that the logic is resistant to common attack vectors.
  • Use tools to check the contracts for vulnerabilities.
  • Debrief with the development team to discuss findings.
  • We create a number of audit reports that highlight any security risk to the project and its users and recommend remediation. As the client fixes the issues we re test and create a new report.

What we look for during an audit

  1. Sound architecture

Assessments of the overall architecture and design choices. Given the subjective nature of these assessments, it will be up to the development team to determine whether any changes should be made.

2. Smart contract best practices

Checking to see whether the codebase follows the current established best practices for smart contract development. Consensys — Smart Contract Best Practices

3. Code Correctness

Establishing whether the code currently meets its intended purpose. This should be established with the client pre-audit so that there is some understanding of the project and therefore of the code’s purpose. This can also be highlighted by pre-existing testing conducted on the contract.

4. Code Quality

Evaluating the code to check whether it has been written in a way that ensures readability and maintainability. Reducing highly complex or over-engineered code can help reduce the potential for exploits, reduces the amount of gas consumed and makes auditing the contract much easier.

5. Security

Checking for exploitable security vulnerabilities, or other potential threats to the users. We categorise these into different security levels.

Security Level Definition

  • Critical Issue ranked as very serious and dangerous for users and the secure working of the system. It is likely to lead to risk of exposure of sensitive information and of serious financial ramifications for the client and user. Needs immediate improvements and further checking to ensure it has been remedied.
  • High Issue ranked as serious which could lead to unreliable working of the system and has potential to cause moderate financial impact and/or sensitive information leaks. Needs immediate improvements and further checking to ensure it has been remedied.
  • Medium Issue ranked as a medium risk could lead to a potential for a financial loss and a risk of leaking sensitive client and user information. Should be addressed.
  • Low Issue ranked as low has a relatively small chance of being exploited. The issue does not pose an immediate operational threat however it is not in line with best practices.

6. Testing and Testability

Reviewing to see how rigorously the code has been tested and how easy it is for the code to be tested. A smart contract that has been tested with high coverage (as close to 100% as possible), provides some level of proof that the smart contract is working as intended. This also reduces the amount of time the auditor has to focus on checking functionality and more time analysing security issues.

Gas Optimisation

Gas optimisation is an important part of an efficient smart contract. We check the current gas consumption of the smart contracts to ensure that they waste as little gas as possible to reduce operational costs.

Tools that we use for Solidity Audits

  1. Established Checklists

The SWC (Smart Contract Weakness Classification) registry is a very handy resource of known vulnerabilities.

The Smart Contract Weakness Classification Registry is an implementation of the weakness classification scheme proposed in EIP–1470. It is loosely aligned to the terminologies and structure used in the Common Weakness Enumeration (CWE) while overlaying a wide range of weakness variants that are specific to smart contracts.

Example contract weaknesses / vulnerabilities that we look for in audits:

  • SWC–132: Unexpected Ether balance
  • SWC–131: Presence of unused variables
  • SWC–128: DoS With Block Gas Limit
  • SWC–122: Lack of Proper Signature Verification
  • SWC–120: Weak Sources of Randomness from Chain Attributes
  • SWC–119: Shadowing State Variables
  • SWC–118: Incorrect Constructor Name
  • SWC–116: Timestamp Dependence
  • SWC–115: Authorization through tx.origin
  • SWC–114: Transaction Order Dependence
  • SWC–113: DoS with Failed Call
  • SWC–112: Delegatecall to Untrusted Callee
  • SWC–111: Use of Deprecated Solidity Functions
  • SWC–108: State Variable Default Visibility
  • SWC–107: Reentrancy
  • SWC–106: Unprotected SELFDESTRUCT Instruction
  • SWC–104: Unchecked Call Return Value
  • SWC–103: Floating Pragma
  • SWC–102: Outdated Compiler Version
  • SWC–101: Integer Overflow and Underflow

we also use specific checklists for common contracts such as — ERC20 — ERC721

2. Static Analysis Tools

Although we use static analysis tools such as Mythx and Slither, we tend to use these as a backup rather than a primary source of issues. We include the static analysis report in the audit report.

3. Formal Verification tools

If the client requires a higher degree of assurance of the correctness of code, we can also use tools such as Scribble from Consensys or the Solidity SMT Checker.

An Example of a failed verification from Scribble

==== Exception State ==== SWC ID: 110 Severity: Medium Contract: VulnerableToken Function name: transfer(address,uint256) PC address: 2664 Estimated Gas Usage: 19862–63906 A user-provided assertion failed.

A user-provided assertion failed.

In file: ./contracts/vulnerableERC20.sol:56

AssertionFailed(“2: ”)

Initial State:

Account: [CREATOR], balance: 0x4016400000000d403, nonce:0, storage:{} Account: [ATTACKER], balance: 0x0, nonce:0, storage:{}

Transaction Sequence:

Caller: [CREATOR], calldata: , value: 0x0 Caller: [CREATOR], function: transfer(address,uint256), txdata: 0xa9059cbb000000000000000000000000affeaffeaffeaffeaffeaffeaffeaffeaffeaffe0000000000000000000000000000000000000000000000000000000000004f05, value: 0x0

==== Exception State ==== SWC ID: 110 Severity: Medium Contract: VulnerableToken Function name: transfer(address,uint256) PC address: 2671 Estimated Gas Usage: 20628–64928 An assertion violation was triggered.

Fuzz testing

One of the challenges we face when checking projects, particularly DeFi projects is uncovering vulnerabilities in the business logic, or economic attacks. The auditor needs to view the contract in a wider context and look for vulnerabilities at a larger scope than simple coding errors. Obviously this relies on the skill and experience of the auditors, but one beneficial approach is through the use of fuzz testing. Fuzz testing allows the tester to provide a wide range of inputs to the contract, which can

  1. Help find edge cases and improve coverage
  2. Remove any assumptions that the tester and developer may have had about the functionality, assumptions that an attacker might not share.

Foundry has proved to be a fast efficient tool for fuzz testing (and testing in general).

Cairo Audits

Although the majority of our auditing experience has been with Solidity, we can also audit contracts written in Cairo for the Starknet L2.

We are working to improve the community resources in this area, and offer Cairo workshops.

London Blockchain Security Group

We are one of the founders of the London Blockchain Security meetup group and run monthly meetings with talks from leading researchers and security professionals. If you are interested in attending or giving a talk, please contact us.

Contact Us

If you are interested in our auditing services, or just want to learn more about the topics raised, please visit our security site

--

--

Extropy.IO

Oxford-based blockchain and zero knowledge consultancy and auditing firm