08 Сер, 2023

What is Smart Contract Audit

Introduction to Smart Contract

Back in 2014, the first announcement of Web 3.0, an Internet technology that relies on machine learning and blockchain technology, was unveiled. The main difference between Web 2.0 and Web 3.0 is that while the former focuses on user-generated content on centralized sites, the latter promises to give users full control over their data online. This concept aims to create open, connected, smart sites and applications with improved machine data analysis. Decentralization and the digital economy are also inherent features of Web 3.0, as they give value to the content created online. It is important to note that Web 3.0 is an ever-changing concept. It still does not have a single definition, and currently everyone interprets it differently. To perform transactions in Web 3.0 applications it is necessary to use a smart contract, but because of the direct operation of these contracts with money, they can often be subject to cyberattacks, so it is necessary to periodically audit their security.

Before we start auditing, we first need to understand what Smart Contracts are.

A smart contract is code in a blockchain. It is executed by a virtual machine when it receives a transaction with the right parameters, using the processing power of the blockchain: smart contracts use all nodes in the network, but only the fastest one writes the result to the block. To write smart contracts for Ethereum, most of the developers use Solidity language or consider writing byte code in Michelson.

Smart contracts allow the exchange of money, goods, real estate, securities, and other assets. The contract is stored and repeated in a decentralized book, where information cannot be falsified or deleted. In addition, there is data encryption, which ensures the anonymity of the parties to the agreement. An important feature of smart contracts is that they can only work with assets in their digital ecosystem.

Pros of smart contracts

1. Smart contracts are automated, which speeds up the transaction process to a high level.

2. Lack of additional personnel for the transaction and, accordingly, saving on intermediary fees, transaction costs, and the lack of the possibility of third-party intervention.

3. Increased security by storing the contract in encrypted form in a distributed registry.

4. All documents have a large number of copies, which eliminates the problems associated with loss or alteration of the document content.

5. Absence of problems associated with the human factor, due to the exclusion of the need to fill in manually different data at the risk of making a mistake.

Disadvantages of smart contracts

1. The difficulty in implementation – to implement such a solution, requires a considerable amount of resources, such as money and time.

2. No change in the terms of the contract, in a situation where there was a bargain or both parties found a more favorable option.

Smart contracts are most effective in industries such as finance, e-commerce, and taxation.

Audit of smart contracts

The main task of auditing smart contracts is to thoroughly check the code in order to find and fix flaws, vulnerabilities.

Stages of the audit:

1. Gathering requirements – before starting the audit, you need to gather the following information: what is or is not included in the scope, timing and expected results.

2. Static code analysis – special tools such as Slither, Mythril are used for this task.

3. Deep сode сheck – a thorough check of the code line by line.

4. Unit tests are needed to identify problems in the code production process.

5. Report generation – eventually you need to generate an audit report with all the required attachments, for example: general final report, unit tests, scanner execution report.

During the smart contract security audit itself, you need to make sure there are no critical vulnerabilities. Below are the DASP top ten attack vectors for smart contracts and defense techniques.

DASP Top Ten

1. Reentrancy – the first place on this list is Reentrancy, another name for recursive calling. Whenever one smart contract makes an external call to another smart contract, a reentry to the original function can be performed. In addition, when a smart contract makes an external call, EVM execution is transferred from the smart contract making the call to the one being called.

Sending money on the blockchain is a longer operation (minutes) compared to calling smart contract functions (fractions of a second). This difference creates the condition for multiple calls to a vulnerable smart contract, which does not have time to realize that it has already sent money, so it executes the command to send it to the same address multiple times.

Example of a reentrancy attack scenario

This attack is implemented involving two contracts, the screenshot above shows the contract of the victim (A) and the contract of the attacker with the vulnerable function (B).

1. Contract A calls the receive function in contract B “receivefunds”.

2. In turn, contract B calls contract A again while the “sendfunds” and “updatebalance” functions are still in progress. This step is performed quickly a maximum number of times.

The “callback” function of contract B calls contract A again to abuse the order in which it calls the “updatebalance” function, which updates the balance. Thus, the “callback” function has time to call the “checkbalance” and “sendfunds” functions several times before the “updatebalance” function is executed.           To protect yourself, it is recommended that you first complete all internal work (i.e., change state), and only then call the external function. For example, you want to make sure that the balance check is done before the transaction takes place. By following this principle, you avoid reentrancy vulnerabilities. Another method of protection against this attack is mutual exclusion and definition of the synchronization primitive providing mutual exclusion of the execution of critical code sections. It works on the principle of blocking some state so that only the owner of the blocking can change it. However, when using this method, you should be careful in the implementation, because the wrong design can lead to a contract lock.

2. Access Control – the vulnerability of access control is that the attacker has the ability to gain access to someone else’s contract.

There are visibility specifiers for functions in Solidity: private, public, internal, external. A function without a specifier is automatically considered public, i.e., it can be called from anywhere. Using inappropriate specifiers or not using them at all can lead to unfavorable consequences. For example, calling a contract owner change function with a public specifier allows any account to become a contract owner.

These vulnerabilities can occur when contracts use the deprecated “tx.origin” to validate callers, handle large authorization logic with lengthy “require” and make reckless use of “delegatecall” in proxy libraries or proxy contracts.

Methods of protection

Do not use the obsolete “tx.origin” to validate subscribers, you must use the variable “msg.sender”.

Using the private specifier.

Avoid using the “delegatecall” function.

3. Arithmetic Issues (also known as integer overflow/underflow) – the essence of the process is to overflow the uint size into bytes, hence the next increment of the variable will return it to its initial state. For example, the maximum number that can be stored uint8 consisting of 8 bits in binary is 1111111111, in decimal 255, if you add 1 to 255 it will be 00000000. Such overflows without proper checks lead to unexpected variable values, and thus to unexpected consequences of a smart contract, up to and including the complete loss of the money it manages.

To avoid such vulnerabilities, it is recommended to use OpenZeppelin’s SafeMath library.

4. Unchecked return values for low level calls (also known as or related to silent failing sends, unchecked-send) – to send ether to a third-party account, you can use the basic 3 methods – “transfer()”, “send()” and “call()”. The “send()” and “call()” functions will return “false” when an error occurs, but the transaction still continues to run. The “transfer()” function will in turn rollback the transaction. It is also necessary to monitor the return values of low-level functions such as “callcode()” and “delegatecall()”, they also do not roll back the transaction if the result is “false”.

As protection, it is recommended to use the “transfer()” function for all fund transfers, and to check the return value by using the “require” function.

5. Denial of Service – include gas limit reached, unexpected throw, unexpected kill, access control breached. There are many ways to disable a smart contract, there are no general methods to find such a vulnerability since every smart contract has its own operating logic, but there is the problem of loops through externally accessible arrays. This vulnerability occurs most often in situations where the contract holder distributes tokens to investors using the “distribute()” function. When using this function, a loop will be executed for every element of the array, and since the size of the array can be increased, an attacker may create too many accounts, leading to the fact that at one moment the whole number of accounts will be used to execute this loop, making further execution of the algorithm impossible.

A defense against such an attack is to break up one big loop into several loops, each of which will be executed in a separate transaction.

6. Bad Randomness (also known as nothing is secret) – pseudorandom number prediction. Their sources must not be contract variables, even if the private specifier, block variables and the hash of the previous/future block are involved. Otherwise, pseudorandom numbers may be predetermined.

For protection, it is recommended to use proven and reliable ways of generating pseudorandom numbers, namely external sources, signidice algorithm, Commit – Reveal approach. It is also necessary to avoid using time block labels for generating random numbers or at least not to use them in sensitive places, such as changing the contract balance.              

7. Front running (also known as time-of-check vs time-of-use (TOCTOU), race condition, transaction ordering dependence (TOD)) – all transactions are first added to the pool, which is visible to all network participants, and then miners add them to the block in random order. An attacker can spy the response in the transaction pool and send the same response with more gas, thus being ahead of the participant who requested it first, which increases the probability of adding the transaction to the block sooner. Thus, whoever assigned more gas per transaction will be ahead.

Adding a gas price restriction to the contract can partially help protect you. However, a better solution would be to use, as in the previous problem, Commit – Reveal.

8. Time manipulation (also known as timestamp dependence) – the essence of the vulnerability is that if a contract uses the “block.timestamp” function to display StartTime and EndTime, a malicious miner can manipulate the timestamp for a few seconds and change the result in its favor.

As a safeguard, it is not recommended to use “block.timestamp” to get the current time because of the decentralized blockchain system, or to allow an error in the +900 second range, so if the timestamp value returned by a node increases by between 1 and 900 seconds, it will not have much impact on the contract. It is also desirable not to use it in critical components of the contract.

9. Short address attack (also known as or related to off-chain issues, client vulnerabilities) – this vulnerability arises when a contract uses a short address, or an address that has less than 20 bytes, as an input or output value. To attack an attacker needs to generate an address that ends with a null byte, for example “abcdabcdabcdabcdabcdabcdabcdabcdabcdab00”, basically the function call to translate 1 ether will look like this:

				
					a9059cbb|000000000000000000000000abcdabcdabcdabcdabcdabcdabcdabcdabcdab00|0000000000000000000000000000000000000000000000000000000000000001
				
			


However, if we specify the address “abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdab” without the last byte, the missing byte will be taken from the next argument and EVM will append a null byte at the end:

				
					a9059cbb|000000000000000000000000abcdabcdabcdabcdabcdabcdabcdabcdabcdab|000000000000000000000000000000000000000000000000000000000000000100
				
			


The victim will send 0x100=256 ether instead of 1 ether. The only way to protect against such an attack is to carefully check the parameters before uploading them to the blockchain.

10. Unknown unknowns – as the field is still developing and the Solidity programming language is constantly releasing updates, the authors of DASP believe that new types of vulnerabilities will still be found, which will add to this top list.

Висновок

To summarize, smart contracts are rapidly gaining popularity, and mistakes in them can lead to the loss of millions of dollars. To avoid them, you need to conduct regular security audits. Our service { https://cqr.company/service/smart-contract-audit/} for smart contracts audit will cover all steps and will provide a report with all the vulnerability findings and recommendations for fixing them. By choosing our service you get a guarantee that your smart contracts will be safe for use in business tasks.

Інші Послуги

Готові до безпеки?

зв'язатися з нами