QuillAudits Smart contracts Audit Check List
The increased adoption of smart contracts demands strong security guarantees. Unfortunately, it is challenging to create smart contracts that are free of security bugs. As a consequence, critical vulnerabilities in smart contracts are discovered and exploited every few months. So auditing a smart contract is itself a very challenging job as there is no reliable automated tool yet to analyze the security of smart contracts. There are many automated tools available but they can not be relied upon, the challenge in creating an effective security analyzer for smart contracts is the Turing-completeness of the programming language, which renders automated verification of
arbitrary properties undecidable. As a result, most of the audit process of smart contract is done manually which requires domain specific knowledge and staying up to dated with every new security findings coming in the ecosystem and most important thing is humans can make mistake and so auditors are not exceptions. We at quillhash, try our best to keep us most up to date with latest security practices.
I am writing this blog to share our checklist and framework to audit every contract. This checklist can be applied to any smart contract but we use other strategies to ensure the security of smart contract based on the business logic of contract.
These are basic checks to undertake with any smart contract :-
To ensure your code is easily followable by auditors, team members, automated tools , and the wider community, you should follow style guide based on Solium’s standards. Having a set and automatically enforced style guide will additionally make it easier to spot erroneous code.
1. Correct Functions Visibility:-
Functions in solidity can have four visibility specifiers:
public being the default . State variables can be
internal being the default. Explicitly specifying the visibility of functions and state variables is a security best practice.
Absent specifiers can be dangerous especially in the case of functions where the default is public accessibility. If such a function has critical logic then it can be triggered from any external address to potentially misuse the contract. The first hack on the Parity multisign wallet exploited such missing function visibility specifiers leading to the attacker stealing $31M worth of Ether.
2. Data Storage :-
In solidity data can be stored in memory which is non-persistent and less expensive or in storage which is persistent and very expensive.While writing smart contracts one should properly analyze that where the data should be stored.By default state variables and local variables are stored in storage and function parameters are stored in memory.
3. Prevent overflow and underflow:-
An overflow is when a number gets incremented above its maximum value. Solidity can handle up to 256 bit numbers (up to ²²⁵⁶-1), so incrementing by 1 would result into 0.
Likewise, in the inverse case, when the number is unsigned, decrementing will underflow the number, resulting in the maximum possible value.
Underflow and overflow can be prevented by using SafeMath library to perform math operations in smart contracts.
4. External Calls — Every external contract call is a risk:-
External calls to untrusted contracts can bring certain risks and errors. External calls may execute malicious code in that contract or any other contract that it depends upon. As such, every external call should be treated as a potential security risk. When it is not possible, or undesirable to remove external calls, use the recommendations.
5. Check for re-enterancy and ensure state committed before external call.
The Reentrancy attack, probably the most famous Ethereum vulnerability, surprised everyone when discovered for the first time. It was first unveiled during a multi-million dollar heist which led to a hard fork of Ethereum. Reentrancy occurs when external contract calls are allowed to make new calls to the calling contract before the initial execution is complete. For a function, this means that the contract state may change in the middle of its execution as a result of a call to an untrusted contract or the use of a low level function with an external address.
Loss: estimated at 3.5M ETH (~50M USD at the time)
6. Don’t delegatecall to untrusted code
delegatecall function is used to call functions from other contracts as if they belong to the caller contract. Thus the caller may change the state of the calling address. This may be insecure.
7. Save Gas on smart contracts
Saving gas is necessary to build an efficient smart contract. It is one of the main issues that the developers face because not all of them know how to do it correctly. Auditors at Quillhash understands well which instructions consume more gas and how we can avoid or minimize them.
8. Timestamp Dependence
If the contract function can tolerate a 15-second drift in time, it is safe to use
9. Compiler warnings
All the compiler warnings are serious issue sometimes developer ignore warnings and deploy contract without considering them as a big threat to their smart contract, we recommend necessary action to be taken to remove all the warnings.
10. Ownership of the deployed contract
It is very important to provide ownership to a contract at the time of deployment or a restriction to function calls else attacker may call those function or transfer ownership function before you or if you are required to give ownership of a contract later, most famous bug of this kind is oyster-pearl because ownership of smart contract was open attacker transfer ownership to himself and able to mint tokens of worth ~$300,000.
11. Oracle calls
Blockchains cannot access data outside their network. An oracle is a data feed provided by third party service designed for use in smart contracts on the blockchain.
Oracles are third party services which are not part of the blockchain consensus mechanism. The main challenge with oracles is that people need to trust these sources of information.
12. Lock pragmas to specific compiler version:
pragma solidity ^0.4.4; this is bad
pragma solidity 0.4.4; this is good
13. Security Tools
After manual and unit testing , your smart contract undergoes automation testing that is done using many open source security tools.
Static and Dynamic Analysis:
Linters improve the code quality
We at Quillhash use multiple in-house automated tools in addition to tools listed, to secure your smart contract and to find whether your smart contract can fulfill your business requirements. apart from automated tools your smart contract code goes under multiple testing phases like static testing which is done manually by our expert audit team thereafter smart contract comes under unit testing which is done using truffle, test suite is prepared for each and every function in your smart contract to know whether your function is capable of handling overflow, underflow condition, reflected variable in that function should maintain their value properly, then Solidity-coverage is used to know how much our test cases are penetrating your smart contract functions, final report after reviewed at multiple level is delivered to client including all the possible suggestions and severity issues raised during audit.
Some recent Audit reports, Audited by Quillhash are :
We welcome feedback on the procedures so we can keep iterating and improving .
Convinced? Request your contract security audit now!