Detailed Explanation of DeFi Protocol Smart Contract Vulnerabilities: 4 Major Categories and 38 Situations

WeBlock
2021-03-08 12:27:22
Collection
In a decentralized blockchain network, it is impossible to modify or upgrade deployed smart contracts in a real-time network unless extreme measures are taken.

The author of this article is WeBlock CTO Abba Garba, translated by HAO.

Blockchain is a new type of distributed system architecture that uses P2P peer-to-peer network communication, block storage, distributed algorithm consensus, and cryptographic algorithms to prevent tampering.

Essentially, blockchain can be viewed as a distributed database maintained collectively by all network nodes. Compared to traditional distributed databases, blockchain is more suitable for applications that have explicit requirements for decentralized trust due to its complete data backup, open and transparent network, immutability, complete information traceability, and weak trust model.

In particular, typical blockchain application scenarios include digital payments, product traceability, copyright protection, and supply chain finance. In blockchain systems, smart contracts play an extremely important role in implementing decentralized application deployment and extending application functionality.

Compared to traditional applications, smart contracts running on blockchain system architecture have characteristics such as openness and transparency, executability, immutability, and independence from third parties, which can meet the needs of various decentralized application scenarios, including the rapidly developing decentralized finance (DeFi) projects in recent years.

As of January 15, 2021, decentralized finance (DeFi) has become a successful financial model with over $4.5 billion in capital, utilizing blockchain-based smart contracts to ensure its integrity and security.

Decentralized finance is a new area of development for exchanging, lending, or borrowing tokens. Typically, these instructions are regulated by smart contracts (rather than a single centralized entity or individual) and/or controlled by multi-party, decentralized governance mechanisms (such as DAOs) for "yield" or revenue streams. Decentralized finance (DeFi) is gradually emerging on existing blockchain platforms.

The components of this new field include those related to lending, asset trading, and derivatives markets. As decentralized applications, smart contracts manage a large number of digital assets, making them susceptible to various attacks.

This article will elaborate on the security issues of smart contracts from three dimensions: first, the security of smart contracts due to vulnerabilities at each layer of the Ethereum architecture. Second, it will explore various attacks that have recently emerged in DeFi and smart contracts.

Finally, it will discuss existing feasible tools and other effective practices to minimize such attacks.

Vulnerabilities of Smart Contracts at Different Layers of Ethereum Architecture

Overview of Ethereum Architecture

Before discussing the vulnerabilities of smart contracts, let’s briefly outline the architecture of Ethereum smart contracts.

Blockchain networks can deploy and automatically execute programming script tasks. These programs are called smart contracts, which define custom functions and rules invoked during transactions. Blockchain technology based on smart contracts has been applied across various industries, such as finance, supply chain management, healthcare, energy, and government services.

Only specific blockchain platforms support smart contracts: Ethereum was the first to support them. Other blockchain platforms (such as EOS, Lisk, Bitcoin, and Hyperledger Fabric) are compatible with deploying and executing smart contracts.

A scripting language called Solidity is used to develop smart contracts on the Ethereum platform. In this section, we introduce the relevant security vulnerabilities associated with the implementation of smart contracts on the Ethereum platform. Smart contracts can hold and manage corresponding functions Credit (address) {potentially worth thousands of dollars in virtual currency.

Therefore, adversaries continuously attempt to manipulate the execution of smart contracts to support their activities. Essentially, smart contracts run on a distributed and permissionless network that inherits many vulnerabilities. In traditional systems, a small portion of centralized applications can be redeveloped or patched.

In contrast, in a decentralized blockchain network, deployed smart contracts cannot be modified or upgraded in real-time unless extreme measures are taken. The immutability of smart contracts is both an advantage and a disadvantage in terms of security. Due to this immutability, hackers cannot change or modify contracts for their benefit.

However, once deployed, developers cannot modify smart contract applications either. They can cancel or terminate the contract and create a new smart contract, then deploy it again. Therefore, for security reasons, extensive testing of smart contracts should be conducted before deployment. We highlight the basic building blocks of the Ethereum smart contract architecture, as shown in Figure 1, which includes the architecture of Ethereum.

image

Figure 1: The environment for running the Ethereum blockchain interacts with the four layers of Ethereum architecture through a web user interface, the application layer, a database for storing blockchain data, a cryptographic mechanism to support consensus protocols, and the Internet services for the network layer[20].

a. Application Layer: The Ethereum client executes smart contracts in the EVM, where smart contracts are associated with Ethereum accounts. Ethereum supports two types of accounts: externally owned accounts (EOA) and contract accounts. EOA is used to store user funds in Wei, which is the smallest subunit of Ether, worth 10^-18 Ether.

EOA is associated with a public key and resolved by the public key; access to EOA is verified by demonstrating ownership of the corresponding private key. In contrast, contract accounts are associated with executable bytecode (i.e., smart contracts) that define some business logic of interest. Smart contracts are the cornerstone of DApps.

DApps typically use a user interface as their front end and some smart contracts as their back end. Some DApps issue their own cryptocurrency called tokens for initial coin offerings (ICO) and exchanges. Ethereum-based tokens are a special type of smart contract (e.g., ERC-20)[20].

Smart contracts are executed in the EVM, which is a quasi-Turing complete machine using a stack-based architecture. The term "quasi" refers to execution being subject to gas limits provided by transactions. Various vulnerabilities occur in the Ethereum application layer, leading to many attacks, as illustrated in the application layer diagram.

b. Data Layer: Contains the blockchain data structure. Transactions are interactions between an EOA (referred to as the sender) and another EOA or contract account (referred to as the recipient). Transactions are specified by:

(i) nonce, which is a counter used to track the total number of transactions initiated by the sender;

(ii) recipient, which specifies the target EOA or contract account for the transaction;

(iii) value, which is the amount transferred from the sender to the recipient (in Wei) (if applicable);

(iv) input, which is the bytecode or data corresponding to the purpose of the transaction;

(v) gasPrice and gasLimit, which specify the unit price the sender is willing to pay to the winning miner of the block containing the transaction and the maximum amount of gas;

(vi) (v, r, s), which is the sender's Elliptic Curve Digital Signature Algorithm (ECDSA) signature. Executing the transaction updates the state of the involved accounts, thereby updating the blockchain.

c. Consensus Layer: Ensures the consistency of the blockchain state. As of the writing of this article, Ethereum takes about 12-14 seconds to create a block, meaning multiple miners can create valid blocks simultaneously, and there may be many blocks.

Ethereum uses a variant of the GHOST consensus protocol to select the "heaviest" branch as the main chain, where the "heaviest" branch is the subtree rooted in the discussed fork and has the highest cumulative block difficulty, while noting that stale blocks are not on the main chain. However, note that Ethereum is replacing its current proof-of-work (PoW) with proof-of-stake (PoS).

d. Network Layer: Manages the Ethereum peer-to-peer (P2P) network of nodes or clients, ensuring that nodes can always obtain the updated state of the blockchain from certain active nodes.

The Ethereum network is a structured P2P network where each node (i.e., client) stores a copy of the entire blockchain. To facilitate node discovery and routing, each node maintains a dynamic routing table containing 160 buckets, each of which can hold up to 16 other nodes' IDs, IP addresses, and UDP/TCP port entries.

Ethereum uses the RLPx protocol to discover target clients and uses the Ethereum wire protocol to facilitate the exchange of Ethereum blockchain information (e.g., transactions, blocks) between clients.

e. Ethereum Blockchain Environment: Operates in the following four-layer environment: a web interface for users to interact with the Ethereum blockchain; a database of Ethereum clients for storing blockchain data; a cryptographic mechanism for security purposes; and the internet infrastructure supporting blockchain communication between Ethereum nodes.

We distinguish the Ethereum blockchain architecture from the environment because attacks on the Ethereum blockchain may originate from the environment, and these attacks may be better addressed in the environment rather than by Ethereum itself.

1. Vulnerabilities of Ethereum Smart Contracts

The vulnerabilities of smart contracts at each layer of the Ethereum architecture are highlighted, as shown in Figure 2.

image

Figure 2: Classification of vulnerabilities at various layers of Ethereum

Ethereum Application Layer:

Reentrancy: This vulnerability was initially discovered from the DAO attack[1], occurring when an external called contract calls back into the calling contract before the calling contract has completed (i.e., in a sense, a recursive call). This allows attackers to bypass proper validity checks until the caller's contract is drained of Ether or the transaction is exhausted.

Delegatecall Injection: This vulnerability was first discovered from the attack on the Parity wallet[2]. To facilitate code reuse, the EVM provides an opcode delegatecall to insert the bytecode of the called contract into the bytecode of the calling contract.

As a result, a malicious called contract can directly modify (or manipulate) the state variables of the calling contract. This vulnerability arises because the called contract can update the state variables of the calling contract. Declarations intended to share libraries as stateless contracts via delegatecall can completely prevent this vulnerability.

Frozen Ether: This vulnerability was first discovered from the attack on the Parity wallet[3]. The vulnerability arises when users cannot deposit money into their contract accounts and cannot withdraw funds from these accounts, effectively freezing their funds.

Upgradable Contracts: The introduction of the concept of contract upgrades is to mitigate the issue that smart contracts cannot be modified once deployed, even if vulnerabilities are discovered later. To allow contract upgrades, there are two methods: (i) separating the contract into a proxy contract and a logic contract, allowing developers to upgrade the latter instead of the former; (ii) using a registry management contract to store the updated contract. While these methods are effective, they introduce a new vulnerability: when contract developers become malicious, the updated contract may be malicious. This vulnerability (i.e., unsafe contact updates) remains an unresolved issue.

DoS with Unexpected Reverts: This occurs when the calling contract encounters an external call failure, causing the transaction to revert, or the called contract deliberately executes a revert operation to interrupt the execution of the calling contract. This vulnerability is caused by the calling contract reverting due to the execution of the called contract. This vulnerability can be prevented by making the recipient call the transaction to "extract" the funds reserved for the recipient by the sender, effectively preventing the sender's transaction from being reverted.

Integer Overflow and Underflow: This vulnerability was first discovered from attacks on the BEC token[4]. This occurs when the result of an operation exceeds the range of Solidity data types, leading to unauthorized manipulation of the attacker's balance or other state variables. This vulnerability arises because the Solidity source code does not perform proper validation on numerical inputs, and neither the Solidity compiler nor the EVM provides integer overflow/underflow detection. This vulnerability can be prevented by using the SafeMath library to handle these issues.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol

Manipulating Balances: This vulnerability occurs when the control flow decision of the contract relies on this value. By manipulating the balance or resolving balance, attackers can exploit it to become the only one able to access funds. This vulnerability can be prevented by not using the contract balance in any conditional statements[5].

Authentication via tx.origin: tx.origin is a global variable in Solidity that refers to the original EOA that initiated the problematic transaction. This vulnerability occurs when contracts use tx.origin for authorization, which may be susceptible to phishing attacks. This vulnerability can be prevented by using msg.sender instead of tx.origin for authentication, as msg.sender returns the account that caused the message.

Incorrect Visibility: Incorrectly specifying the visibility of functions, allowing unauthorized access.

Unprotected Self-Destruct: The owner of the contract (or an authorized third party) can use the self-destruct or suicide method to destroy the contract. When the contract is canceled, its associated bytecode and storage are deleted. This vulnerability arises from insufficient authentication enforced by the contract. This vulnerability can be mitigated by enforcing measures such as multi-factor authentication, meaning the self-destruct operation must be approved by multiple parties.

Leaking Ether to Arbitrary Addresses: This vulnerability occurs when any caller can extract funds from the contract, where the caller is neither the owner of the contract nor an investor who deposited funds into the contract.

This vulnerability arises when the caller invokes a function that sends Ether to an arbitrary address without checking the caller's identity. This vulnerability can be prevented by implementing proper authentication for the function that sends funds.

Confidentiality Failure: In a blockchain, due to the public nature of the blockchain (i.e., transaction details are widely known), restricting the visibility of variables or functions does not ensure that the variables or functions are confidential. One possible solution to prevent this vulnerability is to use cryptographic techniques, such as time-locked commitments[6].

Insufficient Signature Information: This vulnerability occurs when a digital signature is valid for multiple transactions, which may happen when a sender (e.g., Alice) remits funds to multiple recipients through a proxy contract (instead of initiating multiple transactions). This vulnerability was initially exploited in replay attacks against smart contracts. This vulnerability can be prevented by incorporating appropriate information (e.g., current values and timestamps) into each message.

DoS with Unrestricted Operations: This vulnerability was first observed from the Govern Mental contract[7].

Unchecked Call Return Values: This vulnerability is also known as the exception of handling errors. It has two variants, known as gas-less send and unchecked send. This occurs when the return value of a low-level call is not checked, and execution may continue even if the function call throws an error[8].

Uninitialized Storage Pointers: In Solidity, contract state variables are always placed continuously in storage starting from slot 0. For composite local variables (e.g., structs, arrays, or mappings), assigning a reference to an unoccupied slot in object storage points to the state variable.

Incorrect Constructor Name: This vulnerability was initially observed from the Rubixi contract[9], where the constructor name was incorrect, allowing anyone to become the owner of the contract. Before Solidity version 0.4.22, declaring a function with the same name as the contract was treated as the contract's constructor, which only executes when the contract is created.

Type Conversion: This vulnerability was first discovered in[10]. Contracts written in Solidity can call another contract by directly referencing an instance of the called contract.

Outdated Compiler Version: This vulnerability occurs when contracts use an outdated compiler that contains bugs, making the compiled contract vulnerable. This vulnerability can be prevented by using the latest compiler.

Short Address: This vulnerability was first implemented in[11] and has been widely discussed.

Ether Lost to Isolated Addresses: Ether loss to isolation occurs during remittances when Ethereum only checks that the recipient address length does not exceed 160 bits without checking the validity of the recipient address. If money is sent to a non-existent isolated address, Ethereum automatically registers that address instead of terminating the transaction.

Since the address is not associated with any EOA or contract account, no one can extract the transferred funds, which are effectively lost. This vulnerability arises from the EVM's inability to protect against isolation. As of the writing of this article, this vulnerability can only be prevented by manually ensuring the correctness of the recipient address.

Call Stack Depth Limit: This vulnerability arises from the inadequacies of the EVM's execution model and has been eliminated by the hard fork of EIP-150, which redefined the gas consumption rules for external calls, making it impossible to reach a call stack depth of 1,024.

Underestimated Opcodes: This vulnerability was first discovered from two DoS attacks[12] [13].

Transaction Order Dependence (also known as Front Running): This refers to concurrency issues, where the upcoming state of the blockchain depends on the execution order of transactions, which is determined by miners.

Time Dependency: This vulnerability occurs when a contract uses block.timestamp as part of a trigger condition or as a source of randomness that can be manipulated by malicious miners when executing critical operations (e.g., remittances). This vulnerability arises because Ethereum only requires the timestamp to be greater than its parent block's timestamp and within 900 seconds of the current clock.

Generating Randomness: For example, many gambling and lottery contracts randomly select winners, and the usual practice is to generate pseudo-random numbers based on some initial private seeds (e.g., block.number, block.timestamp, block.difficulty, or blockhash). However, these seeds are entirely controlled by miners, meaning malicious miners can manipulate these variables to make themselves winners. This vulnerability arises from manipulable sources of entropy.

2. Data Layer Vulnerabilities

Indistinguishable Chains: This vulnerability was first observed during the split of Ethereum into ETH and ETC[13], from cross-chain replay attacks. Recall that Ethereum uses ECDSA to sign transactions. Before the EIP-155[7] hard fork, each transaction contained six fields (i.e., nonce, recipient, value, input, gasPrice, and gasLimit).

However, the digital signature was not chain-specific, as chain-specific information was not even known at that time. As a result, transactions created for one chain could be reused on another chain. This vulnerability has been eliminated by incorporating chainID into the fields.

"Empty Accounts" in State Trie: This vulnerability was first reported from DoS attacks referenced in[12] [13].

3. Vulnerabilities in the Consensus Layer

Outsourcable Puzzle: Recall that Ethereum adopted a PoW puzzle called Ethash, designed to resist ASICs and limit the use of parallel computing (since most of the miners' work will be reading the dataset due to limited memory bandwidth). However, cunning miners can still divide the task of searching for puzzle solutions into several smaller tasks and then outsource them. This vulnerability arises from Ethash, which only makes puzzle solutions partially sequential in the original image search, rather than relying on sequential PoW.

Probabilistic Finality: This vulnerability arises from Ethereum's design preference for availability over consistency, as chosen according to the CAP theorem[14].

DoS with Block Filling: This vulnerability was first observed from the Fomo3D contract[15]. This vulnerability only causes the attacker's transaction to be included in newly mined blocks, while other transactions are abandoned by miners for a period. This may occur when the attacker offers a higher gasPrice to incentivize miners to select the attacker's transaction. This vulnerability arises from greedy mining incentive mechanisms. As of the writing of this article, there is no solution to prevent this vulnerability.

Honest Mining Assumption: This vulnerability arises from the consensus protocol, as it is incompatible with incentives; see[16]. As of the writing of this article, this vulnerability remains an unresolved issue.

Block Reward: This refers to the block reward mechanism used to address the increase of stale blocks due to rapid block generation. However, this mechanism has a side effect of allowing selfish miners to turn stale blocks into block rewards, effectively incentivizing selfish mining and double spending.

Validator's Dilemma: This vulnerability was first reported in[17], referring to when validating new transactions requires effortless computation, regardless of whether miners choose to validate the transactions, they will be attacked. If miners validate computationally intensive transactions, they will spend a lot of time and provide an advantage to attackers in the competition for the next block; if miners accept transactions without validation, the blockchain may contain incorrect transactions. This vulnerability arises from the high costs of validating resource-demanding transactions in Ethereum. This vulnerability can be mitigated by limiting the computational requirements for all transactions in the validated block[17]. However, it remains unclear how to eliminate this vulnerability.

4. Vulnerabilities in the Network Layer

Unlimited Node Creation: This vulnerability targets versions of the Geth client before 1.8. In the Ethereum network, each node is identified by a unique ID, which is a 64-byte ECDSA public key. Attackers can create an unlimited number of nodes (i.e., with the same IP address) on one computer and then monopolize the incoming and outgoing connections of certain victim nodes, effectively isolating the victims from other peer nodes in the network.

This vulnerability arises from weak restrictions on the node generation process. This vulnerability can be eliminated by using a combination of IP addresses and public keys as node IDs. Geth developers have not adopted this countermeasure, as they believe it negatively impacts client usability.

Unrestricted Incoming Connections: This vulnerability exists in Geth clients before version 1.8[18]. Each node can have a total number of connections equal to maxpeers at any given time (default is 25) and can initiate up to (\lfloor (1 + maxpeers)/2 \rfloor) outbound TCP connections with other nodes.

However, there is no limit on the number of incoming TCP connections initiated by other nodes. By establishing many incoming connections to victim nodes without outbound connections, attackers have the opportunity to overshadow the victims. In Geth v1.8, this vulnerability has been eliminated by imposing a limit on the number of incoming TCP connections to nodes, with a default of (\lfloor maxpeers/3 \rfloor = 8).

Public Peer Selection: This vulnerability was detected in versions of the Geth client before 1.8[18].

Peer Selection: This vulnerability refers to the Geth client always selecting the head of a randomly chosen bucket when selecting nodes from its routing table to establish outbound connections. Since nodes in each bucket are sorted by activity, attackers can keep their nodes ahead of others by regularly sending messages to the Geth client.

This vulnerability has been eliminated in Geth v1.9 by randomly selecting a unified node from the collection of all nodes in the routing table, rather than randomly selecting nodes only from the head of each bucket.

Independent Block Synchronization: This allows attackers to partition the Ethereum P2P network without monopolizing the connections of victim clients. Recall that each block header contains a difficulty field that records the mining difficulty of that block. The total difficulty of the blockchain is represented by totalDifficulty, which is the sum of the difficulties up to the current block.

RPC API Exposure: This vulnerability was initially discovered through attacks on Geth and Parity clients[19].

image

References:

[1] ++https://www.coindesk.com/under++

++standing-dao-hack-journalists++

[2]++https://www.freecodecamp.org/news/++

++a-hacker-stole-31m-of-ether-how-it-happ++

++ened-and-what-it-means-for-ethereum-9++

++e5dc29e33ce/++

[3] ++https://medium.com/blockcat/on-the++

++-pa++ ++rity-multi-sig-wallet-attack-83fb5e7f++

++4b8c++

[4] ++https://nvd.nist.gov/vuln++

++/detail/CVE-2018-10299++

[5]++https://medium.com/loom-network/++

++how-t++ ++o-secure-your-smart-contracts-++

++6-solidity-vu++ ++lnerabilities-and-how-to-++

++avoid-them-part-2-7++ ++30db0aa4834++

[6] ++https://eprint.iacr.org/2016/1007.pdf++

[7]++https://www.reddit.com/r/ethereum/co++

++mments/4ghzhv/governmentals1100et++

++hjackpotpayoutisstuck/++

[8]++https://github.com/KadenZipfel/smart-c++

++ontract-attack-vectors/blob/master/vulner++

++abilities/unchecked-call-return-value.md++

[9]++https://medium.com/hackernoon/hackp++

++edia-16-solidity-hacks-vulnerabilities-their++

++-fixes-and-real-world-examples-f3210eba5148++

[10]++https://medium.com/golem-project/how++

++-to-find-10m-by-just-reading-blockchain-6a++

++e9d39fcd95++

[11]++https://medium.com/loom-network/how++

++-to-secure-your-smart-contracts-6-solidity-++

++vulnerabilities-and-how-to-avoid-them-part++

++-2-730db0aa4834++

[12] ++https://blog.ethereum.org/2016/09/22/t++

++ransaction-spam-attack-next-steps/++

[13] ++https://blog.comae.io/the-280m++

++-ethereu++ ++ms-bug-f28e5de43513?gi=++

++3b0603be9186++

[14] ++https://dl.acm.org/doi/10.1145/31++

++49.214121++

[15]++https://medium.com/coinmonks/how-the++

++-winner-got-fomo3d-prize-a-detailed-explan++

++ation-b30a69b7813f++

[16] ++https://dl.acm.org/doi/10.1145/3212998++

[17] ++https://dl.acm.org/doi/10.1145/2810103++

++.2813659++

[18]++https://ljk.imag.fr/membres/Jean-Guillau++

++me.Dumas/Enseignements/ProjetsCry++

++pto/Ethereum/236.pdf++

[19] ++https://mp.weixin.qq.com/s/ia9nBhm++

++qVEXiiQdFrjzmyg++

[20] ++https://dl.acm.org/doi/fullHtml/10.114++

++5/3391195++

ChainCatcher reminds readers to view blockchain rationally, enhance risk awareness, and be cautious of various virtual token issuances and speculations. All content on this site is solely market information or related party opinions, and does not constitute any form of investment advice. If you find sensitive information in the content, please click "Report", and we will handle it promptly.
ChainCatcher Building the Web3 world with innovators