# A Fly in the Ointment: An Empirical Study on the Characteristics of Ethereum
Smart Contracts Code Weaknesses and Vulnerabilities

Majd Soud<EMAIL_ADDRESS>Grischa Liebel<EMAIL_ADDRESS>Mohammad Hamdaqa
<EMAIL_ADDRESS>School of Computer Science, Reykjavik University,
Reykjavik, Iceland  Department of Computer and Software Engineering,
Polytechnique Montreal, Montreal, Canada

###### Abstract

Context: Smart contracts are computer programs that are automatically executed
on the blockchain. Among other issues, vulnerabilities in their implementation
have led to severe loss and theft of cryptocurrency. In contrast to
traditional software, smart contracts become immutable when deployed to the
Ethereum blockchain. Therefore, it is essential to understand the nature of
vulnerabilities in Ethereum smart contracts to prevent these vulnerabilities
in the future. Existing classifications exist, but are limited in several
ways, e.g., focusing on single data sources, mixing dimensions, or providing
categories that are not orthogonal.
Objective: This study aims to characterize vulnerabilities and code weaknesses
in Ethereum smart contracts written in Solidity, and to unify existing
classifications schemes on Ethereum smart contract vulnerabilities by mapping
them to our classification.
Method: We extracted 2143 vulnerabilities from public coding platforms (i.e.,
GitHub and Stack Overflow) and popular vulnerability databases (i.e., National
Vulnerability Database and Smart Contract Weakness Registry) and categorized
them using a card sorting approach. We targeted the Ethereum blockchain in
this paper, as it is the first and most popular blockchain to support the
deployment of smart contracts, and Solidity as the most widely used language
to implement smart contracts. We devised a classification scheme of smart
contract vulnerabilities according to their error source and impact.
Afterwards, we mapped existing classification schemes to our classification.
Results: The resulting classification consists of 11 categories describing the
error source of a vulnerability and 13 categories describing potential
impacts. Our findings show that the language specific coding and the
structural data flow categories are the dominant categories, but that the
frequency of occurrence differs substantially between the data sources.
Conclusions: Our findings enable researchers to better understand smart
contract vulnerabilities by defining various dimensions of the problem and
supporting our classification with mappings with literature-based
classifications and frequency distributions of the defined categories. Also,
they allow researchers to target their research and tool development to better
support the implementation and quality assurance of smart contracts.

###### keywords:

Blockchain, Smart Contracts, Ethereum, Solidity, Software Security,
Vulnerability.

##  1 Introduction

To process autonomous tasks, some blockchains execute digital programs called
_smart contracts_ that become immutable once deployed (Zheng et al., 2020).
Smart contracts are autonomous programs that can (1) customize contracting
rules and functions between contractors and (2) facilitate transferring
irreversible and traceable digital cryptocurrency transactions (Hewa et al.,
2020). Smart contracts were born and continued to grow with noteworthy
achievements in various life fields, including industry, finance, and
economic.

Due to the immaturity of blockchain technology, vulnerabilities in smart
contracts can have severe consequences and result in substantial financial
losses. For instance, the infamous DAO attack in 2016 (Mehar et al., 2019)
resulted in stealing around 50 million dollars because of exploiting a re-
entrancy vulnerability in the Distributed Autonomous Organizations (DAO)
contract111https://www.coindesk.com/understanding-dao-hack-journalists.

Therefore, understanding vulnerabilities in smart contracts is critical to
perceive the threats they represent, e.g., to develop predictive models or
software engineering tools that can predict or detect threats with a high
precision (Seacord and Householder, 2005). Furthermore, classifying smart
contract vulnerabilities enables researchers and practitioners to better
understand their frequency and trends over time

Existing studies attempt to categorize vulnerabilities in Ethereum smart
contracts Atzei et al. (2017); Dingman et al. (2019); Chen et al. (2020b);
Zhang et al. (2020); Rameder (2021). While they provide valuable insights into
existing security issues in smart contracts, they fall short in several ways:

  1. 1.

There is no unified view on smart contract vulnerabilities. For instance,
(Atzei et al., 2017) classify security vulnerabilities according to their
network level, (Chen et al., 2020b) classify defects in smart contracts
according to their impact on quality attributes, and (Zhang et al., 2020)
categorize smart contract defects according to sources of error. While these
dimensions are all relevant, they are orthogonal and cannot easily be
compared.

  2. 2.

Several studies mix different classification dimensions. For instance, (Zhang
et al., 2020) focus primarily on error sources (e.g., data and interface
errors), but also include categories concerned with effects/impact on quality
attributes (e.g., security and performance). This leads to classifications
where categories are not orthogonal and, since these dimensions are not
discussed, often confusing.

  3. 3.

Vulnerabilities are classified into broad categories. Several studies classify
vulnerabilities into broad categories, which results in two main shortcomings.
First, a vulnerability can be assigned into more than one category. Second,
the differences among the categories are too general to be useful to reason
about the vulnerabilities.

  4. 4.

Data sources differ widely. Several existing studies rely only on
vulnerabilities published in academic literature or white literature, e.g.,
(Atzei et al., 2016) and (Alharby and Van Moorsel, 2017), while (Chen et al.,
2020b) used posts on StackExchange, and (Zhang et al., 2020) used a mix of
academic literature and GitHub project data. This makes the comparison
challenging or even impossible.

  5. 5.

Important data sources are omitted in existing classifications. To our
knowledge, no existing study uses established vulnerability and defect
registries such as the Smart Contract Weakness Registry (SWC)
222https://swcregistry.io/ and vulnerabilities in the Common Vulnerability and
Exposure (CVE)333https://cve.mitre.org/.

To address these gaps, the contribution of this study is twofold:

  1. 1.

To unify existing classifications on smart contract vulnerabilities by
providing an overview of the different classification dimensions, and by
mapping existing classifications to a single classification scheme using error
source and impact as dimensions of the vulnerabilities.

  2. 2.

To complement existing studies by classifying smart contract vulnerabilities
extracted from a variety of important data sources according to the different
dimensions presented in existing work.

We extracted and analyzed data related to Ethereum smart contracts written in
Solidity from four data sources, i.e., Stack Overflow, GitHub, CVE and SWC.
Using a card sorting approach, we devised a classification scheme that uses
the error source and impact of a vulnerability as dimensions. Furthermore, we
mapped existing classfications to this scheme and analyzed the frequency
distribution of the defined categories per data source. The resulting
classification scheme consists of 11 categories describing the error source,
and 13 categories describing potential impacts.

Our findings show that language specific coding and structural data flow
categories are the dominant categories of vulnerabilities in Ethereum smart
contracts. However, frequency distribution of the error source categories
differ widely across data sources. With respect to the existing
classifcations, we find that the majority of sources use broad categories that
are applicable to many vulnerabilities, such as “security” or “availability”.

The remainder of this paper is organized as follows. Section 2 presents the
background on Ethereum smart contracts, Solidity and the used data sources.
Section 3 discusses how existing work relates to our study and what gaps
exist. Section 2 describes the methodology that we followed. In Section 5, we
report our findings in terms of the obtained classification and mapping to
existing work. We then discuss our findings in Section 6 and potential threats
to validity in Section 7. The paper is concluded in Section 8.

##  2 Background

In this section, we discuss the background of our work. Specifically, we
discuss definitions used in this paper, the Ethereum environment, and existing
vulnerability and weakness databases.

###  2.1 Definitions

Before we can discuss a classification scheme for smart contracts’
vulnerabilities, it is fundamental that we have a sufficiently specific
definition of what we are classifying. There have been efforts to formally
define concepts such as vulnerability in SE. However, we will use the formal
definition of a vulnerability and weakness that were defined in the Ethereum
Improvement Proposals (EIPs)444https://eips.ethereum.org/ as follows:

  * 1.

Vulnerability: “A weakness or multiple weaknesses which directly or indirectly
lead to an undesirable state in a smart contract system” (EIP  1470). A
vulnerable contract does not necessarily imply exploited (Perez and Livshits,
2019). Moreover, as the contract is a digital agreement between two or more
parties, exploiting the contract is not always done by external malicious
actors. A venerable contract can also be exploited by one of the contracting
parties such as the contract owner who can use vulnerabilities to gain more
profits such as in
CVE-2018-13783555https://nvd.nist.gov/vuln/detail/CVE-2018-13783. Any of the
contractors can also exploit it, the miners or even the developers who
implemented the contract (e.g., CVE-2018-17968
666https://nvd.nist.gov/vuln/detail/CVE-2018-17968).

  * 2.

Weakness: “a software error or mistake in contract code that in the right
conditions can by itself or coupled with other weaknesses lead to a
vulnerability”. (EIP  1470).

What distinguishes smart contract code weaknesses from other software
applications is that any smart contract code instruction costs a specific
amount of gas (see Section-2.4). This means even if the weakness was not
exploited, it would result in losing Ether 777Ethereum corresponding
cryptocurrency when it is triggered by the contract itself and executed, which
makes the contract vulnerable even if it is not exploited. Thus, it is of high
importance to study smart contracts’ weaknesses along with smart contracts’
vulnerabilities.

###  2.2 Ethereum Virtual Machine (EVM)

Ethereum888https://ethereum.org/en/ is a globally open decentralized
blockchain framework that supports smart contracts, referred to as Ethereum
Virtual Machine (EVM). Because EVM hosts and executes smart contracts, it is
often referred to as the programmable blockchain. EVM contracts reside on the
blockchain in a Turing complete bytecode language; however, they are
implemented by developers using high-level languages such as Solidity or Vyper
and then compiled to bytecode to be uploaded to the EVM. Users on the EVM can
create new contracts, invoke methods in a contract, and transfer Ether. All of
the transactions on EVM are recorded publicly and their sequence determines
the state of each contract and the balance of each user. In order to ensure
the correct execution of smart contracts, EVM relies on a large network of
mutually untrusted peers (miners) to process the transactions. EVM also uses
the Proof-of-Work (PoW) consensus protocol to ensure that a trustworthy third
party (e.g., banks) is not needed to validate transactions, fostering trust
among users to build a dependable transaction ledger. EVM gained remarkable
popularity among blockchain users as EVM is the first framework that supports
smart contracts to manage digital assets and build decentralized applications
(DApps) (Khan and Namin, 2020a).

###  2.3 Ethereum Smart Contracts

A smart contract is a general-purpose digital program that can be deployed and
executed on the blockchain. Ethereum smart contract is identified by a unique
160-bit hexadecimal string which is the contract address. It is written in a
high-level language, either Solidity or Vyper. In this paper, we focus on
Ethereum smart contracts written in Solidity because it is the most popular
language in the EVM community and most of the deployed contracts on EVM are
written using Solidity (Bhat and Vijayal, 2017; Badawi and Jourdan, 2020). A
smart contract can call other accounts, as well as other contracts on the EVM.
For example, it can call a function in another contract and send Ether to a
user account. In EVM, internal transactions (i.e., calls from within a smart
contract) do not create new transactions and are therefore not directly
recorded on-chain.

###  2.4 Ethereum Gas System

In order to execute a smart contract, a user has to send a transaction (i.e.,
make a function call) to the target contract and pay a transaction fee that is
measured in units of gas, referred to as the gas usage of a transaction. The
transaction fee is derived from the contract’s computational cost, i.e., the
type and the number of executed instructions during runtime. Each executed
instruction in the contract consumes an agreed-upon amount of gas.
Instructions that need more computational resources cost more gas than
instructions that need less computational resources. This helps secure the
system against denial-of-service attacks and prevents flooding the network.
Hence, the gas system in EVM has two main benefits: (1) it motivates
developers to implement efficient applications and smart contracts and (2) it
compensates miners who are validating transactions and executing the needed
operations for their contributed computing resources. To pay for gas, the
transaction fee equals the $gasprice*gascost$. The minimum unit of gas price
is Wei (1 Ether = $10^{18}$ Wei). Therefore, Ether can be thought of as the
fuel for operating Ethereum.

###  2.5 Solidity

Solidity999https://docs.soliditylang.org/ is a domain-specific language (DSL)
that is used to implement smart contracts on the Ethereum blockchain. It is
the most widely used open-source programming language in implementing
blockchain and smart contracts. Also, although it was originally designed to
be used on Ethereum, it can be used in other blockchain platforms such as
Hyperledger and Monax101010https://monax.io/. Solidity is statically typed,
which requires specifying the type of all variables in the contract. It does
not support any “undefined” or “null” values, and any newly defined variable
has a default value based on its type. Smart contracts written in Solidity are
organized in terms of subcontracts, interfaces, and libraries. They may
contain state variables, functions, function modifiers, events, struct types,
and enum types. Also, Solidity contracts can inherit from other contracts, and
can call other contracts.

In Solidity there are two kinds of function calls. Internal function calls,
which do not create an actual EVM call, and External function calls, which do.
Due to this distinction, Solidity supports four types of visibility for
functions and state variables:

  * 1.

External functions can be called from other contracts using transactions as
they are part of the contract interface. They can not be called internally
(e.g., _externalFunction()_ does not work, while _this.externalFunction()_
works). State variables can not be external.

  * 2.

Public functions can be called internally or using messages and they are part
of the contract interface. For public state variables, an automatic getter
function is generated by the Solidity compiler to avoid high gas cost when
returning an entire array.

  * 3.

Internal functions and state variables can only be accessed internally (i.e.,
from within the current contract or contracts deriving from it).

  * 4.

Private functions and state variables are only visible for the contract they
are defined in and not in derived contracts.

State variables can be declared using the keywords constant or immutable.
Immutable variables can be assigned at construction time, while constant
variables must be fixed at compile time. For the functions declaration, they
can be declared as follows.

  * 1.

Pure Functions promise not to read or modify the state. They can use the
revert() and require() functions to revert potential state changes when an
error occurs.

  * 2.

View Functions promise not to modify the state such as writing to state
variables.

  * 3.

Receive Ether Functions can exist at most once in a contract. They cannot have
any arguments and cannot return any value, and must be declared with external
visibility and payable state mutability as in receive() external payable{ …}.
These functions are executed on plain Ether transfers (e.g., using .send() or
.transfer()) and based on a call to the contract with empty calldata.

  * 4.

Fallback Functions are similar to Receive Ether functions, as any contract can
have at most one such function. It must have external visibility, and is
executed on a call to the contract if none of the other functions match the
given function signature or if no data was supplied at all and there is no
receive function. The fallback function always receives data, but in order to
also receive Ether it must be marked as payable.

Finally, if any function promises to receive Ether, it has to be declared as
payable. An example of a Solidity contract is shown in Figure 1. It shows a
voting contract as explained in Solidity’s official documentation (Ethereum,
2021).

Figure 1: Voting Contract Example Written in Solidity (Ethereum, 2021)

###  2.6 Common Vulnerability and Exposure (CVE) and National Vulnerability
Database (NVD)

CVE is a list of publicly disclosed vulnerabilities and exposures that is
maintained by MITRE111111https://cve.mitre.org/cve/. It feeds into the
NVD121212http://nvd.nist.gov/, so both are synchronized at all times. NVD is a
comprehensive repository with information about all publicly known software
vulnerabilities and includes all public sources of vulnerabilities (e.g.,
alerts from security focus131313https://www.securityfocus.com/). NVD also
provides more information about the CVE lists’ vulnerabilities, such as
severity scores and patch availability. It also provides an easy mechanism to
search for vulnerabilities using various variables. Both CVE and NVD are
maintained by the US Federal Government. An example of a reported smart
contract vulnerability in NVD is shown in Table 1. It also shows the impact
metrics (Common Vulnerability Scoring System - CVSS), vulnerability types
(Common Weakness Enumeration - CWE), applicability statements (Common Platform
Enumeration - CPE), and other relevant meta-data. Each CVE in the list also
has a unique identifier that shows the affected software product, sub-
products, and various versions.

Table 1: An example of a vulnerability in NVD CVE ID |  CVE-2021-3006
---|---
NVD Published Date: |  01/03/2021
Source: |  CVE MITRE
Description |  The breed function in the smart contract implementation for Farm in Seal Finance (Seal), an Ethereum token, lacks access control and thus allows price manipulation, as exploited in the wild in December 2020 and January 2021.
CVSS |  7.5
Weakness Enumeration |  CWE-863
CWE Name |  Incorrect Authorization
Hyperlink |  Link141414https://etherscan.io/address/0x33c2da7fd5b125e629b3950f3c38d7f721d7b30d
Integrity |  High
Impact score |  3.6

###  2.7 Common Weakness Enumeration (CWE)

CWE 151515http://cwe.mitre.org is a community-developed list of common
software security weaknesses. It is considered as a comprehensive online
dictionary of weaknesses that have been found in computer software. It also
serves as a baseline for weakness identification, mitigation, and prevention
efforts. Its primary purpose is to promote the effective use of tools to
identify, find, and repair vulnerabilities and exposures in computer software
before the programs are distributed to the public.

###  2.8 Smart Contract Weakness Classification Registry (SWC)

SWC is an implementation of the weakness classification scheme that is
proposed in Ethereum Improvement Proposals161616https://eips.ethereum.org/. It
is also aligned with the terms and structures described in the CWE. Each SWC
has an identifier (ID), weakness title, CWE parent, and related code samples
list.

##  3 Related Work

Multiple studies that classify smart contract vulnerabilities have been
published since the first attack on Ethereum smart contracts in 2016 (Daian,
2016), e.g., Atzei et al. (2016), Alharby et al. (2018), Dingman et al.
(2019), and Zhang et al. (2020). This section summarizes these studies in
relation to our work.

###  3.1 Literature-Based Vulnerability Classification

Several studies on Ethereum smart contract vulnerabilities classify
vulnerabilities reported in blogs, academic literature, and white papers,
i.e., Atzei et al. (2016); Alharby and Van Moorsel (2017); Huang et al.
(2019); Sánchez (2018); Chen et al. (2020a); Praitheeshan et al. (2019);
Dingman et al. (2019).

Atzei et al. (2016) propose a classification scheme comprised of three
categories to classify security vulnerabilities in Ethereum smart contracts.
In addition to blogs and academic literature, the authors also employ their
own practical experience as a resource for their classification.
Vulnerabilities are classified into language-related issues, blockchain
issues, and EVM bytecode issues. The classification is followed by a brief
discussion on potential attacks that result in stealing money or causing other
damage.

Alharby and Van Moorsel (2017) also use academic literature as the main source
of data, classifying them into four main classes: codifying, security,
privacy, and performance issues. Additionally, they discuss proposed solutions
based on suggestions provided by smart contract analysis tools. The proposed
classification suffers from a significant overlap between categories. For
example, codifying issues can lead to security and privacy issues, as in the
case of the popular re-entrancy vulnerability (classified as a security issue
in the paper).

Huang et al. (2019) report a literature review of smart contract security from
a software lifecycle perspective. The authors analyze blockchain features that
may result in security issues in smart contracts and summarize popular smart
contracts’ vulnerabilities based on four development phases, i.e., design,
implementation, testing before deployment, and monitoring and analysis.
Finally, they classified 10 vulnerabilities into three broad categories (i.e.,
Solidity, blockchain and misunderstanding of common practices). Unfortunately,
there is no explanation of how or on what basis these categories were
designed.

Dingman et al. (2019) study well-known vulnerabilities reported in white and
gray literature and classify them according to National Institute of Standards
and Technologies Bugs framework (NIST-BF)171717https://samate.nist.gov/BF/
into security, functional, developmental, and operational vulnerabilities. The
results show that the majority of vulnerabilities fall outside the scope of
any category. However, the categories and the classification process are not
defined or described in the paper.

Similar to Dingman et al. (2019), Samreen and Alalfi (2021) survey and map
eight popular smart contracts’ vulnerabilities in the literature to the NIST-
BF. Their results show that only three of the studied eight vulnerabilities
could be matched with two NIST-BF classes. They also suggest a preventive
technique per classified vulnerability. Finally, a map between existing
analysis tools and the eight vulnerabilities are provided in the paper.

Praitheeshan et al. (2019) classify 16 smart contracts’ vulnerabilities
reported in literature based on their internal mechanisms. The authors use
three categories, i.e., blockchain, software security issues, and Ethereum and
Solidity vulnerabilities.

Finally, Chen et al. (2020a) survey Ethereum System Vulnerabilities including
smart contract vulnerabilities reported in literature, classifying them
according to two dimensions. First, they group vulnerabilities into four-layer
groups according to the location, i.e., on the application, data, consensus or
network layer. Secondly, they group vulnerabilities according to their cause
into Ethereum design and implementation, smart contract programming, Solidity
language and tool-chain, and human factors. This classification focuses on few
locations that a vulnerability might occur at, while omitting others. For
instance, the vulnerability could be located in the source code of the smart
contract itself or in its dependencies. Furthermore, there is no clear
indication of how these categories were defined or if a systematic way to
classify them was followed.

###  3.2 Repository-Based Vulnerability Classification

In addition to classifications that are based on published vulnerabilities,
two papers attempt classifications based on data extracted from public
repositories such as StackExchange, i.e., Chen et al. (2020b); Zhang et al.
(2020).

Chen et al. (2020b) collect smart contract vulnerabilities from discussions
available on Ethereum StackExchange, classifying them based on five high-level
aspects according to their consequences, i.e., security, availability,
performance, maintainability, and reusability. To evaluate if the selected
vulnerabilities are harmful, the authors conduct an online survey to collect
feedback from practitioners. The proposed categories have the drawback that
not all vulnerabilities can be clearly placed in a single category, i.e., one
vulnerability could have various consequences.

Zhang et al. (2020) classify smart contracts vulnerabilities from both
literature and open projects on GitHub. The authors classify extracted
vulnerabilities into 9 categories based on an extension of IEEE Standard
Classification for Software
Anomalies181818https://standards.ieee.org/standard/1044-2009.html. Finally,
they propose a four-category classification scheme for the impact of a
vulnerability, i.e., unwanted function executed, performance, security, and
serviceability. This classification is based on vulnerability GitHub reports,
and some categories are too general to be useful in any detailed engineering
analysis (e.g., the security category).

###  3.3 Tool-Based Vulnerability Detection

As a last category of related work, several publications study existing tools
to detect vulnerabilities in smart contracts, and propose classifications
based on the tools’ capabilities, i.e., Khan and Namin (2020b); Rameder
(2021).

Khan and Namin (2020b) provide an overview of current smart contracts
vulnerabilities and testing tools in their work. In addition, they propose a
vulnerability taxonomy for smart contracts’ vulnerabilities. The proposed
taxonomy consists of seven categories, i.e., inter-contractual
vulnerabilities, contractual vulnerabilities, integer bugs, gas-related
issues, transnational vulnerabilities, deprecated vulnerabilities, and
randomization vulnerabilities. The authors then provide a mapping between the
surveyed vulnerabilities and the available detection tools. Unfortunately,
this categorization is not actually a classification scheme, in the sense that
it fails to identify a category unique to each vulnerability and no structured
method was provided to show how the classification was performed.

In a Master Thesis, Rameder (2021) provides a comprehensive overview of state-
of-the-art tools that analyze Ethereum smart contracts with an overview of
known security vulnerabilities and the available classification schemes in the
literature. The studied vulnerabilities are classified into 10 novel
categories, i.e., malicious environment, environment dependency/blockchain,
exception & error handling disorders, denial of service, gas related issues,
authentication, arithmetic bugs, bad coding quality, environment
configuration, and deprecated vulnerabilities. However, the proposed
categories cover different dimensions, e.g., vulnerability consequences as
well as programming errors. Finally, some categories are not defined in the
work.

###  3.4 Summary and Research Gap

In summary, various attempts to classify smart contract vulnerabilities have
been published, both on reported vulnerabilities and by mining software
repositories. A third line of research focuses on studying smart contract
vulnerability detection tools, classifying what vulnerabilities they are able
to detect. These papers suffer from three flaws. First, they rely exclusively
on vulnerabilities reported in literature and might, therefore, provide a
skewed image, e.g., Atzei et al. (2016). Secondly, they propose
classifications that mix different concerns or dimensions, such as
consequences of exploiting a vulnerability and the source of error in Rameder
(2021). Third, they use categories with too broad distinctions that do not
allow for detailed reasoning, such as the privacy and security categories in
Alharby and Van Moorsel (2017) and Zhang et al. (2020). Finally, they provide
only a limited view on smart contract vulnerabilities due to focusing on a
single dimension, such as the consequences in Chen et al. (2020a). Therefore,
there is a need to unify existing taxonomies and classification schemes and
provide a reference taxonomy that includes several dimensions such as root
cause, impact, or scope Vacca et al. (2021). The aim of this paper is to
arrive at such a classification by integrating existing work and complementing
it with additional data from software repositories and well-known sources such
as the CVE and SWC registries.

##  4 Research Method

This section presents the method we followed in this paper, as shown in Figure
2. It includes the study setup, data sources, data cleaning, and data
analysis.

Figure 2: Empirical Study Method

###  4.1 Study setup

In this study, we aim to answer the following research questions (RQs):

  * 1.

_RQ1. What categories of vulnerabilities appear in smart contracts?_

Goal: To comprehensively categorize the vulnerabilities that appear in
Ethereum smart contracts. To study different dimensions of the problem and to
map literature-based classifications on Ethereum smart contract
vulnerabilities and unify them in one thorough classification. A thorough
classification scheme will make it possible to collect statistics on
frequency, trends, and vulnerabilities, as well as evaluate countermeasures.

  * 2.

_RQ2. Are the frequency distributions of smart contract vulnerability
categories similar across all studied data sources?_

Goal: To investigate if all data sources have the same frequency distributions
of vulnerabilities. If so, then we can rank vulnerability categories from the
most common to the least common. If not, we can reason about the skew or bias
when different sources are used. Further research can find solutions for the
most common vulnerabilities. More effort could be put to address the prevalent
category before deploying the contract to the blockchain.

  * 3.

_RQ3. What impact do the different categories of smart contract
vulnerabilities and weaknesses have?_

Goal: To investigate the impacts of smart contract vulnerability and code
weaknesses. To define various dimensions of impacts classifications and to map
literature-based impact classifications and propose a thorough impact
classification of smart contracts vulnerabilities and code weaknesses. More
effort can be put to vulnerabilities and code weaknesses with critical
impacts.

####  4.1.1 Data Sources

To answer the proposed research questions, we analyzed and studied smart
contract code vulnerabilities and weaknesses from four primary sources. Two of
these sources are widely used by developers (i.e., Github and StackOverflow),
and two are very well-known publicly accessible sources (i.e., SWC and NVD)
for reporting vulnerabilities and weakness in Ethereum smart contracts and
other software systems. Table 2 shows the final number of data records during
and after data pre-processing.

Table 2: Summary of the sampled vulnerabilities in the selected data sources Data Source |  Stack Overflow |  GitHub |  CVE |  SWC
---|---|---|---|---
# of collected data |  2065 |  3160 |  523 |  37
# of data records after preprocessing steps |  1490 |  1160 |  523 |  37
Final # of Vulnerabilities |  765 |  818 |  523 |  37

Data-source 1: We opted for extracting data from Stack Overflow, as it has
successfully been leveraged in existing work on smart contracts (Ayman et al.,
2019, 2020; Chen et al., 2020b), and in general Software Engineering research
(Bajaj et al., 2014; Ponzanelli et al., 2014; Calefato et al., 2015; Chen and
Xing, 2016; Ahasanuzzaman et al., 2016).

We used Stack Overflow posts to study weaknesses and vulnerabilities in smart
contracts. To do so, we extracted Q&A posts tagged with “smart contract”,
“Solidity”, and “Ethereum”, posted between January 2015 and April 2021. We
discarded posts with the “Ethereum” tag, but without the “Solidity” or “smart
contract” tags. To retrieve the related information for each post, we used
Scrapy Scr , an open source Python library that facilitates Web crawling. For
each of the 2065 extracted posts, we extracted the post title, URL, related
tags, post time and accepted answer time.

Figure 3: Vulnerability Example from GitHub

Data-source 2: We used GitHub as the second data source for our study, as it
is the most popular social coding platform (Cosentino et al., 2017). Moreover,
many studies on Ethereum smart contracts and smart contract analysis tools
have been published reporting findings based on data published in GitHub open-
source projects (e.g., Durieux et al. (2020)). We studied vulnerabilities and
code weaknesses reported in open source projects that have Ethereum smart
contracts written in Solidity. We used the keywords “smart contract”,
“Solidity”, and “Ethereum” to search for these projects. Then we searched for
the vulnerabilities and weaknesses based on the fixes in each project and
based on the keywords “Vulnerability”, “bug”, “defect”, “issue”, “problem”,
and “weakness”.

We also studied Ethereum official GitHub repository. Figure 3 shows an example
of a reported smart contract vulnerability in GitHub.

Data-source 3: We used the NVD search interface to collect and extract all
reported CVEs on smart contracts and their CVSS until April 2021. We searched
with “smart contracts”, “Solidity”, and “Ethereum”. Then, we manually
extracted the reported CVEs that are related to smart contracts.

Data-source 4: We extracted all the reported code weaknesses in SWC until
April 2021. For each code weakness, we extracted the ID, title, relationships,
and test cases.

####  4.1.2 Data Cleaning and Pre-Processing

After the initial extraction, we applied several filtering steps to obtain a
clean dataset. First, we removed posts with duplicate titles or marked as
[duplicate] in StackOverflow. Secondly, we manually inspected the title and
the body of the question and decided if the post actually discussed smart
contracts in Ethereum/Solidity. Finally, we removed vague, ambiguous,
incomplete, and overly broad posts. As an indication for such posts, we
considered the amount of negative votes and/or negative feedback. Finally, we
extracted the code of the smart contract in each post for further analysis.

In order to pre-process the collected GitHub data, we removed the duplicates
based on the description of the vulnerability. For further analysis, we also
extracted the code of the smart contract that contained the vulnerability.

We also double-checked data collected from both the NVD database and SWC
registry for duplicates. After this stage, we had a clean dataset with records
from the four data sources.

Table 2 shows a summary of the collected dataset after applying the
aforementioned cleaning and pre-processing steps.

###  4.2 Data Analysis and Classification Categories

To analyze and label the cleaned dataset, we manually inspected each record
and read the description of each vulnerability and weakness. Then, to define
the categories of vulnerabilities and weaknesses in smart contracts, two
experts (i.e., a software engineering expert and a cybersecurity expert)
together used card sorting to propose a classification scheme based on the
cleaned data. After that, we discussed each category and gave it a name based
on the categories that were defined by Beizer (Beizer, 1984). To find out root
causes of the categories, we analyzed the question and/or the answer
information. Finally, we followed the same categorization approach to propose
a classification scheme for the impact of the recorded vulnerabilities and
weaknesses.

For each record in the cleaned dataset, we created a card containing the
information of the vulnerability as collected from the original data source.
Then, the two experts determined the category of the vulnerability (RQ1)
independently based on its root cause. As well as the impact category (RQ3)
was decided based on its consequence on the software product (i.e., smart
contracts). When cards did not fit into any of the existing categories, we
extended the schemes accordingly. We started with a random 10% of the data,
and measured inter-rater agreement after independent labeling using Cohen’s
Kappa coefficient. The Kappa value between the two experts was 0.60, showing
moderate agreement (Viera et al., 2005). We then clarified major disagreements
to reach a common decision, and continued with the remaining 90% of the data.
We repeated the clarification discussions again after 20% and 40% of the posts
were labeled (with Kappa values of 0.75 and 0.82 respectively). Finally,
calculations of the Kappa coefficient at 60%, 80%, and 100% resulted in values
of $>0.90$, indicating perfect agreement.

The same approach was followed to label the impact of each vulnerability in
the cleaned dataset. The Kappa value was also $>0.90$ in the final discussion
of the impact labeling.

####  4.2.1 Classification Scheme Attribute-value Design

To design a thorough classification scheme for smart contracts’
vulnerabilities, we also followed the structured approach and recommendations
of Seacord and Householder (2005).

To eliminate the problem of having vulnerabilities that fit into multiple
classifications and therefore invalidate frequency data, we added attribute-
value pairs in our classification for each vulnerability. This also helped us
to provide an overall picture of the vulnerability.

A smart contract has many attributes such as size, complexity, performance,
and other quality attributes. In this paper, we are only interested in
attributes that characterize the overall vulnerability of a smart contract.
Therefore, these attributes can also represent code weaknesses (that may or
may not lead to vulnerabilities). All attributes and values that we list in
this paper are selected based on engineering differences of the vulnerability
sources of error that were concluded from expert discussions while analyzing
the data (see Section 4.2). An example of the proposed attributes-value pairs
is shown in Figure 4.

We present a sample contract (i.e., not a real contract) demonstrating
solidity functions with a set of weaknesses and vulnerabilities. In
particular, the contract has multiple vulnerabilities, some of which are
popular vulnerabilities, such as authorization with tx.origin and reentrancy.
In addition, the contract contains another attribute that is an insufficient/
outdated compiler version, which uses insufficient pragma version 0.x.x.
Another attribute is the use of wrong visibility initialization that uses
wrong state variable initialization.

Figure 4: Sample Solidity contract annotated with vulnerability attribute-
value pairs

The attribute-value pairs eliminate the possibility of vulnerabilities fitting
into multiple classifications and therefore invalidating frequency data
Seacord and Householder (2005).

###  4.3 Unifying Classification Schemes

To unify existing vulnerability classification schemes in the literature, we
gathered all the categories proposed in the literature into an Excel sheet.
The first and the second authors then discussed each category in relation to
the categories proposed by us. We subsequently defined three dimensions of the
problem (i.e., the vulnerability’s source of error; the location of the
vulnerability in the network level; the behavior and consequences arising from
an exploit of the vulnerability). Afterwards, we mapped existing
classifications to the defined dimensions, as illustrated in Figure 5. We name
these vulnerability dimensions _V-D_. The error source dimension (V-D1)
describes the main cause that, when triggered, can result in executing the
vulnerability, such as the logic of the contract and the data initialization.
V-D2 is the network dimension, which indicates at which layer on the network
the vulnerability occurs. Finally, V-D3 describes the resulting behavior and
consequences of the vulnerability, which means the result of executing the
vulnerability.

Figure 5: Dimensions of Smart Contract Vulnerabilities (_V-D_)

We followed the same approach to devise a thorough classification scheme for
the impacts of smart contract vulnerabilities. We defined two dimensions
(i.e., impact on the software product, and impact on business factors) as
shown in Figure 6. We name these impact dimensions _I-D_. I-D1 is the impact
of the vulnerability on the software product itself and its resulting
behavior, whereas I-D2 describes the impact of the vulnerability on the
business level, e.g., losing money or important information.

Figure 6: Dimensions of Smart Contract Vulnerability Impacts (_I-D_)

##  5 Results

In this section, we present the results of our study, and answer the proposed
RQs. Our objective is to unify the existing classification schemes and define
the causes, impacts, and recurrences of smart contract vulnerabilities and
code weaknesses. Moreover, we propose thorough classification schemes for both
the impacts and categories of smart contracts’ weaknesses and vulnerabilities.

Smart contracts’ code weaknesses and vulnerabilities are found in more than
half (i.e., 66.7%) of the cleaned data from all the four data sources (Stack
Overflow, GitHub, CVE and SWC).

###  5.1 What categories of vulnerabilities appear in smart contracts? (RQ1)

To answer RQ1, we followed the analysis approach in Section 4.2, then mapped
the result of our classification to other classification schemes as explained
in Section 4.3. We classified the 2143 extracted vulnerabilities and
weaknesses into 47 unique smart contract weaknesses and vulnerabilities,
grouped into 11 categories. Within our classification scheme, we mapped the
existing literature classification schemes.

Table 3 shows a mapping between our categories and Beizer’s categories
(Beizer, 1984). We define each category in our proposed classification scheme
and show its relation to Beizer’s categories. The categories _Interface_ ,
_Dependency and upgradability_ , _Authentication & authorization_, and
_Deployment and configurations_ were added to the classification based on
discussions throughout the card sorting process, and do not correspond to any
category in Beizer’s classification.

Table 4 maps literature-based classification schemes of smart contracts
vulnerabilities with our own. The categories proposed in the literature are
listed in the rows, while our categories are listed in the columns of the
table. The table covers all the three dimensions of _V-D_ discussed in Section
4.3. As can be seen, some broad categories listed in literature essentially
cover all of our classification categories.

Most literature-based classification schemes for smart contract
vulnerabilities include broad categories, such as security and availability.

Table 3: Classification Scheme of Vulnerabilities in Smart Contracts Category Name |  Description |  Short
---|---|---
Language Specific Coding |  Syntax mistakes in implementing Solidity contracts that are not captured by the Solidity compiler can introduce unexpected behavior or damage the contract. Similar to _Implementation_ in Beizer (1984), but specific to Solidity. |  CV
Data Initialization and Validation |  The input data type to the contract or the fields’ data type in the contract are not initialized correctly. Also includes the data passed from/sent to other contracts. Corresponding to _Data definition_ and _Data access_ in Beizer (1984). |  DV
|  Predictable resources is a subcategory of data initialization and validation. Weaknesses and vulnerabilities resulting from using expected values in state variables or functions. These vulnerabilities can allow malicious minors to take advantage of the vulnerabilities and control the contract. |  DV-PR
Structural Sequence & Control |  Problem with the structure of the contract control flow. Specifically, a result of incorrect control flow structure such as require, if-else conditions, assert, and loop structures. Corresponding to _Flow control and sequence_ in Beizer (1984). |  SV-SC
Structural Data Flow |  Problems with the structure of the contract data flow. The main difference to _Data_ is that _Data_ originates in the data fields and input parameters to the subcontracts or the contract methods. Instead, in this category, changing data fields in a wrong way during and after the execution of the contract leads to issues. Corresponds to _Data-flow anomaly_ in Beizer (1984). |  SV-DF
Logic |  Inconsistency between the intention of the programmer and the coded contract, and not one of the other categories. Corresponds to _Logic_ in Beizer (1984). |  LV
Timing & Optimization |  Performance and timing issues that can affect execution time and results in abnormal responsiveness under a normal workload. Corresponds to _Performance and timing_ in Beizer (1984), considering the existence of the Ether/gas concept. |  TV
Compatibility |  Required software and packages are not compatible with the available resources (e.g., operating system, CPU architecture). Corresponds to _Configuration sensitivity_ in Beizer (1984) |  CoV
Deployment & Configurations |  Weaknesses during deployment of implemented contracts on the Ethereum blockchain. |  DL
Authentication & Authorization |  Vulnerabilities allow malicious actors to take control over the contract. |  SV
Dependency & Upgradability |  Upgrades in a smart contract breaking the dependencies in the new contract. |  UV
Interface |  Vulnerabilities and weaknesses in the interface of smart contracts, e.g., when the contract is functioning correctly, but the interface is showing a wrong output that contradicts the contract’s execution logs and transaction logs. |  IB
Table 4: Mapping Literature-based Classifications to V-D. The rows marked
_V-D1_ refer to the source of error dimension, rows marked _V-D2_ refer to the
network view dimension, and rows marked _V-D3_ refer to the resulting behavior
and consequences dimension. $\subset$* indicates that the category in the V-D
classification is a subset of the corresponding category in the literature
marked by *. *$\subset$ means the category in the literature is a subset of a
proposed category in V-D. Finally, = means the categories are identical.

Literature Ours | CV | DV | SV | LV | TV | CoV | DL | SV | UV | IB
---|---|---|---|---|---|---|---|---|---|---
Codifying (Alharby and Van Moorsel, 2017) |  $\subset$* |  |  |  $\subset$* |  |  |  |  |  |
Data* (Zhang et al., 2020) | *$\subset$ | *$\subset$ |  |  |  |  |  |  |  |
Description* (Zhang et al., 2020) | *$\subset$ |  |  |  |  |  |  |  |  |
Interaction* (Zhang et al., 2020) | *$\subset$ | *$\subset$ |  | *$\subset$ |  |  |  |  |  |
Interface* (Zhang et al., 2020) |  |  |  |  |  |  |  |  |  | =
Logic* (Zhang et al., 2020) |  |  |  | = |  |  |  |  |  |
Standard* (Zhang et al., 2020) | *$\subset$ |  |  |  |  |  |  |  |  |
Authentication* (Rameder, 2021) |  |  |  |  |  |  |  | = |  |
Arithmetic* (Rameder, 2021) |  |  |  | = |  |  |  |  |  |
Bad Coding Quality* (Rameder, 2021) | = |  |  |  |  |  |  |  |  |
Environment Configuration* (Rameder, 2021) |  |  |  |  |  |  | = |  |  |
Deprecated* (Rameder, 2021) | *$\subset$ |  |  |  |  |  |  |  |  |
Solidity* (Atzei et al., 2016) | *$\subset$ |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  |  $\subset$* |  $\subset$* |  $\subset$* |
EVM* (Atzei et al., 2016) |  |  |  |  |  |  $\subset$* |  |  |  |
Blockchain* (Atzei et al., 2016) |  |  |  |  |  |  |  $\subset$* |  |  |
Security* (Alharby and Van Moorsel, 2017) |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$*
Privacy* (Alharby and Van Moorsel, 2017) |  $\subset$* |  $\subset$* |  |  $\subset$* |  |  |  |  |  |
Performance* (Alharby and Van Moorsel, 2017) |  |  |  |  | = |  |  |  |  |
Availability* (Chen et al., 2020b) |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$*
Maintainability* (Chen et al., 2020b) |  $\subset$* |  |  $\subset$* |  $\subset$* |  |  $\subset$* |  |  |  $\subset$* |
Reusability* (Chen et al., 2020b) |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  |  |  $\subset$* |  $\subset$* |  |  $\subset$*

V-D2

V-D3

V-D1

The following subsections present the key findings related to the defined
categories. For each category, we define and explain the most critical
vulnerabilities and weaknesses as agreed by the two raters. We give examples
for some vulnerabilities and weaknesses, which are directly taken from our
dataset. For the full list of vulnerability and code weakness definitions, we
refer to our published dataset (Majd Soud, 2021).

####  5.1.1 Language Specific Coding Vulnerabilities and Weaknesses

Table 5: Language Specific Coding Attribute Attribute |  Values
---|---
Language specific coding |  pragma version, fallback function, pre-defined functions in the language, language standards, language defined libraries, syntax issues (not detectable by the compiler), style guide and recommended language patterns, experimental language features, deprecated code, unsafe language features.

In this category, smart contracts’ vulnerabilities and weaknesses result from
language-based errors not captured by the compiler. The source of error of
this category can be in the language pre-defined functions, events, libraries,
and/or language standards. Table 5 shows the attribute-value pair for this
category.

We define 14 Language Specific Coding vulnerabilities and weaknesses that can
result in undesirable state in a smart contract or can be used by attackers in
their favor. Next, we show a sample of these vulnerabilities and weaknesses.

Insufficient compiler version or pragma version — CV#1. A so-called version
_pragma_ should be included in the source code of smart contract to reject
compiling the contract using incompatible compiler versions. When using a
version _pragma_ in the contract which is later than the selected compiler,
this may introduce incompatible changes and lead to vulnerabilities in
compiled smart contract code. Moreover, future compiler versions may handle
language constructs in a way that introduces unclear changes affecting the
behavior of the contract as shown in Listing 1.

⬇

1pragma solidity ^0.6.3; // weakness/ vulnerability

2pragma solidity 0.6.3;

Listing 1: Version pragma

Fallback function not payable — CV#2. Smart contracts written in Solidity
versions 0.6.0+ should have the fallback function split up into a _receive()_
and a _fallback()_ function (i.e., a new fallback function that is defined
using the _fallback_ keyword and a _receive_ ether function defined using the
_receive_ keyword). If present, the _receive_ function is called whenever no
parameters are provided in the call. The _receive_ function is implicitly
payable. The new _fallback_ function is called when no other function matches.
However, if _fallback()_ is not payable and _receive()_ does not exist,
transactions not matching any other function which send ether will revert and
result in an undesirable state in the contract.

Fallback function does not exist — CV#3. In addition to CV#2, when sending
Ether from a contract to another contract without calling any of the receiving
contract’s functions, sending the Ether will fail if the receiver contract has
no fallback function. Thus, a payable fallback function should be added to the
receiver before deployment. Otherwise, there is no way to receive the Ether
unless the sender has previous knowledge of the exact functions of the
receiving contract, which is not usually the case.

Violating splitting Fallback function — CV#4. Smart contracts written in
Solidity versions 0.6.0+ should have the fallback function split up to
_receive()_ and _fallback()_ (i.e., a new Fallback function that is defined
using the _fallback_ keyword and a _receive_ ether function defined using the
_receive_ keyword). If present, the _receive_ function is called whenever the
call data is empty. The _receive_ function is implicitly payable. The new
_fallback_ function is called when no other function matches. The fallback
function in Listing 2 can be payable or not, however, if it is not payable
then transactions not matching any other function which send value will
revert.

⬇

1contract payment{

2 mapping(address => uint) _balance;

3 fallback() payable external {

4 _balance[msg.sender] += msg.value;

5 }

6}\end{lstlisting}

7

8

9

10 \textbf{Violating modifier definition \--- CV\#5.}

11Solidity provides modifiers that are used to change the behavior of
functions in a declarative way. They can be used to enforce pre/post-
conditions on the execution of a function. The \_ operator should be used in
defining a modifier, and starting from Solidity version 0.4.0+ a semicolon
should be added after the \_ operator. The operator represents the actual code
of the function that is being modified. Thus, the code for the function being
modified is inserted where the \_ is placed in the modifier. Missing the \_
operator might generate unwanted results. For example, in
Listing~\ref{lst:modifierDef}, line 8, every time transferOwnership is
invoked, the onlyOwner modifier will get into play first. If the owner invokes
it, then the control flow will reach the \_ operator, so the transferOwnership
statements will be executed. Otherwise, the execution will just throw, revert,
and exit.

12

13\begin{lstlisting}[language=Python,label={lst:modifierDef},
caption=Violating \emph{modifier} definition]

14contract owned {

15 address public owner;

16 function owned() {

17 owner = msg.sender;}

18 modifier onlyOwner {

19 if (msg.sender != owner) throw;

20 _; }

21 function transferOwnership(address newOwner) onlyOwner {

22 owner = newOwner; }}\end{lstlisting}

23

24\textbf{Manipulated language standard \--- CV\#6}

25Ethereum has adopted many standards to guarantee the composability of smart
contracts and Dapps. Those standards are in Ethereum’s official EIPs and
include token \footnote{An Ethereum token can represent anything, including
lottery tickets, financial assets, a fiat currency like USD, an ounce of gold,
etc.} standards. For example, ERC-20 is a token technical standard that allows
developers to implement tokens of cryptocurrencies. It contains nine unique
functions and two events to guarantee the possibility of exchanging tokens
based on ERC-20 with other ERC-20 tokens. Any modification on the function
name, parameter types, and the return value in the standard might change its
functionality and leave the developer believing it is the same as ERC-20. The
implementation of ERC-20 in any contract shall strictly be the same as in the
standard template.

26

27

28 \textbf{Violating call-stack depth limit \--- CV\\#7.}

29In Ethereum, the call-stack has a hard limit of 1024 frames. Each time the
contract calls an external contract, the call-stack depth of transaction
increases by one. Thus, when the number of calls exceeds the limit of the
call-stack, an exception is thrown and the call is aborted by Solidity.
Moreover, Solidity does not support exceptions in low-level external calls.
Therefore, a malicious actor can recursively call a contract 1023 times, then
call a victim contract to reach the call-stack depth limit. This will fail any
subsequent call made by the victim contract without the victim contract owner
being aware of the attack. Recently, EIP
150\footnote{https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md}
makes it impossible to reach stack depths of 1024, effectively eliminating
call depth attacks

30

31 \textbf{Insufficient Address split \--- CV\\#8.} Starting from Solidity
0.5.0+, the address should be split to address and address payable, where only
address payable provides the transfer function. Otherwise, sending tokens to
‘‘unpayable’’ addresses will be reverted. Moreover, there is no way to convert
an address to address payable.

32

33\textbf{Mixing \emph{pure} and \emph{view} \--- CV\\#9.}

34In Solidity, \emph{pure} and \emph{view} are function modifiers that
describe how the logic in that function will interact with the contract’s
state. Functions that are declared \emph{view} promise not to modify the
state, while functions that are declared \emph{pure} promise not to read or
write the state.By using no specifier, the state can be read as well as
modified. Developers can mix these two modifiers by replacing \emph{view} with
\emph{pure} or missing any of these modifiers, resulting in unexpected state
changes or incorrect reads from the state .

35

36 \textbf{Using of \emph{balance} as attribute to the contract \--- CV\#10}

37One of the features of Solidity is that contracts inherit all members from
\emph{Address}, meaning that the keyword \emph{this} is the pointer to the
current instance of the type derived from Address. In other words, if the
developer wants to access members of the address type (e.g. the balance) of
the current contract instance, then the developer should use \emph{this} and
should use \emph{balance} as an attribute of the address type, not the
contract as shown in Listing~\ref{lst:cv11}. We noticed a confusion in using
balance and other address attributes as if they are attributes of the
contract.

38\begin{lstlisting}[language=Python, caption=Using of \emph{balance} as
attribute to the contract , label={lst:cv11}]

39function getSummary() public view returns(

40 uint, uint, uint, uint, address

41){

42 return (

43 minimumContribution,

44 this.balance, //incorrect

45 address(this).balance,// correct

46 requests.length,

47 approversCount,

48 manager

49 );

50}\end{lstlisting}

51

52

53\textbf{Unsafe delegatecall (code injection)--- CV\#11 }

54A special variant of a message call in Solidity is \emph{delegatecall}. With
this feature, the contract can be executed in the callee’s context, while
msg.sender and msg.value remain unchanged. Consequently, it allows an external
contract to modify the storage of the calling contract. This can be exploited
by a malicious caller to manipulate the caller’s contract state variables and
take full control over the balance.

55

56\textbf{Variable shadowing \--- CV\#12}

57Solidity supports ambiguous naming when inheritance is used. For instance,
contract Alpha with a variable V could inherit contract Beta that also has a
state variable V defined. Consequently, there would be two versions of V, one
accessed from contract Alpha and the other from contract Beta. In complex
contract systems, this condition might go undetected and ultimately cause
security issues. Also, this can also occur at the contract level (e.g., a
contract with more than one definition at the contract and function level).

58

59\textbf{Deprecated Solidity code \--- CV\#13}

60As Solidity evolves, several of its functions and operators are deprecated.
Making use of them leads to poor code quality. It is strongly discouraged to
use deprecated Solidity language code with new major versions of the Solidity
compiler, since it can cause unwanted behavior and vulnerabilities.

61

62\textbf{Experimental Language Features \--- CV\#14}

63Similar to CV \#13, it is strongly discouraged to use experimental Solidity
language features since it can cause undesired behavior and code weaknesses.

64

65

66

67

68

69

70

71

72

73

74

75

76\subsubsection{Data Vulnerabilities and Weaknesses}

77Most of the data vulnerabilities result from the use of wrong or
insufficient data types, or passing wrong data formats to arguments without
knowing the exact required type. Moreover, organizing the memory and storage
in Solidity is the responsibility of programmers, which many developers are
not used to do. Table~\ref{table:dataattribute} shows the attribute-value
pairs for this category.

78\begin{table}[htbp]

79\centering

80\caption{Data vulnerabilities and weaknesses Attribute}

81\label{table:dataattribute}

82\begin{tabular}{||p{2 cm} |p{6 cm}||}

83 \hline

84 Attribute & Values\\\ [0.5ex]

85 \hline

86 Data vulnerabilities and weaknesses & Insufficient/wrong data type, wrong
addresses initialization, writing on arbitrary locations, insufficient memory
and storage management, improper data validation, improper state variable
initialization, data pointer initialization, function pointer initialization.
\\\

87\hline

88\end{tabular}

89\end{table}

90

91\textbf{Violating explicit data location \--- DV\#1.} For Solidity versions
0.5.0+, an explicit data location for all variables of type struct, array, or
mapping is mandatory. This also applies to function parameters and return
variables. For instance, \emph{calldata} is a special data location that
contains the function arguments, which is only available for external function
call parameters. If \emph{calldata} is not included in the initialization, it
results in unexpected values as shown in Listing~\ref{lst:dv1}.

92

93\begin{lstlisting}[language=Python, label={lst:dv1}, caption=Using of
\emph{torage} instead of \emph{memory}]

94contract StructExample {

95

96 struct SomeStruct {

97 int someNumber;

98 string someString;

99 }

100 SomeStruct[] someStructs;

101

102 function addSomeStruct() {

103 SomeStruct storage someStruct = SomeStruct(123, "test");// insufficient
use

104 SomeStruct memory someStruct = SomeStruct(123, "test");// correct

105 someStructs.push(someStruct);

106 }

107}

Listing 2: Fallback function

Using of _storage_ instead of _memory_ — DV#2. In addition to _calldata_ ,
Solidity provides two more reference types to comprise structs, arrays, and
mappings called _storage_ and _memory_. The Solidity contract can use any
amount of memory (based on the amount of Ether that the contract owns and can
pay for) during execution. However, when execution stops, the entire content
of the memory is wiped, and the next execution will start fresh. The _storage_
is persisted into the blockchain itself, so the next time the contract
executes, it has access to all the data it previously stored in its storage
area. Confusing storage and memory can result in data loss.

Violating array indexing — DV#3. Developers are making numerous mistakes when
initializing and accessing arrays in Solidity. Most of the time, discovering
these violations is not easy, especially if there is no syntax error or an
error that can be detected by the compiler. This can result in returning
incorrect values. A clear violation of array indexing is shown in Listing 3,
line 9, where the developer is trying to access a single element in a
3-dimensional array, but only provides two sets of square brackets. Therefore,
the developer is returning an array instead of a single Object.

⬇

1contract Game {

2 struct User{

3 address owner; }

4User[][10][10] public gameBoard;

5User memory mover = gameBoard[_fromX][_fromY][0];

6 function addUser (uint _x, uint _y) public {

7 gameBoard[_x][_y].push(User(msg.sender, 10, 5, 5, 5, 5));}

8 function moveUser (uint _fromX, uint _fromY) public {

9 User memory mover = gameBoard[_fromX][_fromY]; //incorrect access

10 if (mover.owner != msg.sender)return;}}

Listing 3: Violating arrays indexing

Hard-coded address — DV#4 An existing bad practice is the use of hard-coded
addresses in smart contract code, as shown in Listing 4. Any incorrect or
missing digit in the address may result in losing Ether, in case Ether is sent
to that wrong address, or in unexpected outcomes. This vulnerability is also
known as “Transfer to orphan address” Atzei et al. (2016).

⬇

1address recieveraddress ;

2function initializeAddress1 () {

3 recieveraddress = 0x98081c...8e5ace; //hardcoded address}\end{lstlisting}

4\textbf{Improper data validation \--- DV\#5}

5It is necessary to validate input from untrusted sources, such as external
libraries or contracts before integrating it into any contract logic.

6

7\textbf{Unintentional Write to arbitrary storage location \--- DV\#6}

8Because Solidity storage is not dynamically allocated, it can lead to
unpredictable behavior, unauthorized data access, and other vulnerabilities,
especially if the data location of data types like structs, mappings, and
arrays is not clarified and allowed to overwrite entries of other data
structures.

9

10\subsubsection{Predictable Data Values and Resources}

11We encountered several issues in Solidity smart contracts that relate to
values that can be guessed even though they are intended to serve as an
element of randomness.

12

13\textbf{Timestamp dependency \--- DV-PR\# 7}

14To keep contracts safe from malicious actors, developers should avoid using
the block variables as a source of randomness or as part of triggering
conditions for executing significant operations in their contracts, such as
transferring Ether. When submitting blocks, miners determine the value of
block variables such as block.timestamp, block.coinbase, and block.difficulty.
Thus, these values can affect the contract’s outcome and can be used to
benefit the attacker. For example, Listing~\ref{lst:dv-pr7} shows an insecure
lottery contract in which block.timestamp is used as a source of entropy.

15

16\begin{lstlisting}[language=Python,label={lst:dv-pr7}, caption=Insecure
lottery contract using block variables]

17function setWinner() public {

18

19 bytes32 hash = keccak256(abi.encode(block.timestamp));

20 bytes4[2] memory x0 = [bytes4(0), 0];

21 assembly {

22 mstore(x0, hash)

23 mstore(add(x0, 4), hash)

24 } \end{lstlisting}

25

26\textbf{Blockhash dependency \--- DV-PR\\# 8}

27Using blockhash has the same risks as block.timestamp in DV-PR \\#7,
especially when used in critical operations such as Ether transfer. It can
lead to serious attacks as malicious miners can tamper with the blockhash and
take full control over the contract.

28

29\textbf{Bad random number generation--- DV-PR\\# 9}

30Using random numbers is not avoidable in some smart contracts, e.g., games
or lotteries. It is important that the randomness is not based on global
blockchain variables, as that leaves the contract open to manipulation by
malicious miners similar to DV-PR\\#7 and DV-PR\\#8.

31

32

33

34

35\subsubsection{Sequence and Control Vulnerabilities and Weaknesses}

36This category of vulnerabilities is corresponding to incorrect control
structure and loop control statements. These can be exploited and help the
attacker to steal money in the contract. Moreover, they can also result in
losing all the money in the contract without even being attacked, just because
of vulnerabilities in these structures.

37 Table~\ref{table:seqattribute} shows the attribute-value pairs for this
category.

38

39\begin{table}[htbp]

40\centering

41\caption{Sequence and control vulnerabilities and weaknesses}

42\label{table:seqattribute}

43\begin{tabular}{||p{2 cm} |p{6 cm}||}

44 \hline

45 Attribute & Values\\\ [0.5ex]

46 \hline

47 Sequence and control & Wrong use of assert, wrong use of require. \\\

48\hline

49\end{tabular}

50\end{table}

51

52 \textbf{Using assert instead of require \--- SV-SC\\#1.} The \emph{assert}
statement should be only used for conditions that indicate you have an
internal vulnerability in the contract code. The \emph{require} statement
should be used to check valid conditions (e.g., state variables conditions are
met, validate input, and validate return value from external contracts). A
valid code with correct functions should never fail \emph{assert} conditions.
Otherwise, there is a vulnerability in the contract and something unexpected
has happened.

53 In smart contracts, \emph{assert} can consume all the gas in the contract
as shown in Listing~\ref{lst:sv-sc1}. If the example is tested with run(8),
the function runs successfully and 1860 gas will be consumed based on the cost
of the function and the loop iterations\footnote{The actual gas costs are
stated in the Solidity documentation and depend on numerous factors, such as
the executed functions and the used data types.}. If it is tested with
run(15), then the function passes assert, fails at require and the first loop
only will be executed and consume 1049 gas. Finally, testing the same example
with run(25) causes the function to fail the assert statement. The execution
continues and thus iterates 25 times through the loop, resulting in a very
high cost of gas.

54

55 \begin{lstlisting}[language=Python, caption=Using assert instead of
require, label={lst:sv-sc1}]

56contract Test {

57 function run(uint8 i) public pure {

58 uint8 total = 0;

59 for (uint8 j = 0; j < 10; j++)

60 total += j;

61 assert (i < 20);

62 require (i < 10);

63 for (j = 0; j < 10; j++)

64 total += j;

65 }\end{lstlisting}

66

67

68

69\subsubsection{Data Flow Vulnerabilities and Weaknesses}

70These are vulnerabilities and weaknesses in the data flow of smart
contracts, so that data fields are changing unexpectedly or incorrectly. We
defined two vulnerabilities that belong to this category.

71Table~\ref{table:seqdataflowattribute} shows the attribute-value pairs for
this category.

72

73\begin{table}[htbp]

74\centering

75\caption{Data flow vulnerabilities and weaknesses}

76\label{table:seqdataflowattribute}

77\begin{tabular}{||p{2 cm} |p{6 cm}||}

78 \hline

79 Attribute & Values\\\ [0.5ex]

80 \hline

81 Data flow & Unexpected integer overflow/underflow, unexpected conversion in
data values, unexpected arithmetic operation behavior

82 \\\

83\hline

84\end{tabular}

85\end{table}

86

87 \textbf{Updating storage in fallback functions--- SV-DF\\#1.} Upon
receiving Ether without a function being called, either the receive Ether or
the fallback function is executed. If the contract does neither have a receive
nor a fallback function, the Ether will be rejected by throwing an exception.
During the execution of one of these functions, the contract can only rely on
the passed gas (i.e., 2300 gas) being available to it at that time. This
stipend is not enough to modify storage. However, we found that developers
sometimes are updating state variables, trying to write to the storage in the
fallback functions. Updating the variables with such a gas limit will fail.

88 If the data flow of the contract depends on the failed state variables,
this results in an incorrect data flow and in unexpected outcomes.

89

90 \textbf{Arithmetic operation/calculation overflow/ underflow \--- SV-
DF\\#2.} An overflow can happen as a result of an arithmetic operation or
calculation that falls outside the range of a Solidity data type, resulting in
unwanted behavior or unauthorized manipulation of the contract balance.
Underflow happens when an arithmetic operation reaches the minimum size of a
type. This is a data flow vulnerability, as the code of the contract does not
perform correct validation on the numeric inputs and the calculations. In
addition, the Solidity compiler does not enforce detecting integer
overflow/underflow.

91 An example is shown in Listing~\ref{lst:overflow}, where the computation of
\emph{mask} overflows at x $>$= 248.

92\begin{lstlisting}[language=Python,label={lst:overflow}, caption=Arithmetic
Operation/calculation overflow ]

93uint256 public MAXUINT256 = 2*256 - 1;

94for (uint256 x = 0; x < 255; x++) {

95 var mask = MAXUINT256 * (2 ** x);

96 var key = signature & bytes32(mask);}\end{lstlisting}

97

98 \subsubsection{Logic Vulnerabilities and Weaknesses}

99This category reflects inconsistencies with the contract and the
programmer’s intention, which is usually mentioned in the question
information. These issues relate to a number of reasons, e.g., vague developer
intentions, misunderstanding of language components, incorrect usage of Math,
and incorrect gas predictions.

100

101\textbf{Greedy contract--- LV\\#1.}

102This vulnerability occurs when implementing a contract logic that is only
locking Ether balance all the time because of its inability to access the
external library contract to transfer Ether. For instance, the contract logic
may only accept transferring money based on a specific value in the code,
which happens to be unreachable due to incorrect logic. In this case, the
Ether will be locked in the deployed contract forever. In the example of
Listing~\ref{lst:greedy}, the function \emph{refundMoney()}, line 8, does not
decrease the \emph{weiRaised} value, meaning that once starting a refund, the
developer can no longer use \emph{forwardAllRaisedFunds()} to drain the
contract. This code weakness would be triggered even in the regular course of
action and Ether in this contract is stuck. It can receive any funds but the
received funds can never be retrieved.

103

104\begin{lstlisting}[language=Java, label={lst:greedy}, caption=Greedy
Contract]

105contract SwordCrowdsale is Ownable {

106 //amount of raised money in wei

107 uint256 public weiRaised;

108 bool public isSoftCapHit = false;

109 //send ether to the fund collection wallet

110function forwardAllRaisedFunds() internal {

111 wallet.transfer(weiRaised);}

112function refundMoney(address _address) onlyOwner public {

113 uint amount = contributorList[_address].contributionAmount;

114 if (amount > 0 && _address.send(amount)) {

115 //user got money back

116 contributorList[_address].contributionAmount = 0;

117 contributorList[_address].tokensIssued = 0;}

118 }\end{lstlisting}

119\textbf{Transaction order dependency \--- LV\\#2}

120The vulnerability arises when a contract’s logic is dependent on the order
in which transactions are executed and processed in a block. It is a type of
race condition inherent to Blockchains. By manipulating the order of
transaction processing, malicious miners can take advantage of the contract
and benefit from it. Therefore, the logic of the contract should not rely on
the transaction order.

121

122\textbf{Call to the unknown \--- LV\#3}

123This vulnerability arises when a function unexpectedly invokes the fallback
function of the recipient. Consequently, malicious code can be introduced. For
example, the unknown call could trigger the recipient’s fallback function,
allowing malicious code to execute.Also, this can be done via direct call,
delegatcall, send, or only call functions. In the MultiSig Wallet
Attack\footnote{https://blog.openzeppelin.com/on-the-parity-wallet-multisig-
hack-405a8c12e8f7/}, an attacker exploited this vulnerability to steal 30M USD
from the Parity Wallet. Another example is shown in Listing~\ref{lst:Unknown}.
In which, pong function uses a direct call to invoke Alice’s ping. However, if
the interface of contract Alice by mistake was mistyped by declaring the
parameter as \emph{int} instead of \emph{unit} and Alice has no function with
\emph{int} type, then the call to ping results in calling Alice’s fallback
function.

124

125\begin{lstlisting}[language=Python, ,label={lst:Unknown},caption=Call to
the unknown \cite{atzei2016survey}]

126contract Alice {function ping(uint) returns (uint)}

127contract Bob {function pong(Alice c){c.ping(42);}}’

Listing 4: Hardcoded address

DoS by external contract — LV#4 It is possible for external calls to fail and
throw exceptions or revert the transaction. Inefficient management of these
calls in the contract logic can lead to critical vulnerabilities, such as a
Denial of Service (DoS) or loss of funds.

####  5.1.2 Timing and Optimization Vulnerabilities and Weaknesses

Performance and timing vulnerabilities/weaknesses in smart contracts usually
affect the gas amount in the contracts. In the following, we define 2
vulnerabilities belonging to this category.

Unbounded loops — TO#1. In Solidity, iterating through a potentially unbounded
array of items can be costly, as exemplified in _getNotes()_ in Listing 5.
Since the array _notes_ is provided as an input, the smart contract has no
control over the maximum length, allowing a malicious actor to send in large
arrays.

Creating subcontracts cost — TO#2. Contract deployments are very expensive
operations. For instance, deploying a contract for every patient in Listing 5
is very costly. A malicious developer can use this weakness to cost the owner
of the contract more Ether.

⬇

1contract MedicalRecord {

2struct Doctor {

3 bytes32 name;

4 uint id;}

5struct Note {

6 bytes32 title;

7 bytes32 note;}

8function getNotes()

9 view

10 public

11 isCurrentDoctor

12 returns (bytes32[], bytes32[])

13{

14 bytes32[] memory titles = new bytes32[](notes.length);

15 bytes32[] memory noteTexts = new bytes32[](notes.length);

16 for (uint i = 0; i < notes.length; i++) {

17 Note storage snote = notes[i];

18 titles[i] = snote.title;

19 noteTexts[i] = snote.note;

20 }

21 return (titles, noteTexts);}

Listing 5: Unbounded loops and creating subcontracts

Costly state variable data type — TO#3 Because of the padding rules, the
byte[] data type consumes more gas than a byte array. In addition, declaring
variables without constant consumes more gas than one declared with a
constant. This weakness is also reported in Chen et al. (2020b).

Costly function type — TO#4 A function declared public rather than external
and not utilized within the contract consumes more gas on deployment than it
should.This weakness is also reported in Chen et al. (2020b).

####  5.1.3 Compatibility Vulnerabilities and Weaknesses

This category is related to vulnerabilities that prevent Ethereum from running
normally on the developer machine. We find that the main root causes of this
category are: (1) developers are not using the latest binaries/releases and
(2) the hardware that is in use does not meet the minimum requirements. As
this category played only a minor role in the analyzed posts, we did not label
the posts in detail, but decided to keep this for future work.

####  5.1.4 Deployment and Configurations

This category of vulnerabilities and weaknesses is caused by wrong
configurations and weaknesses in deployment.

Improper configuration — DL#1 Wrong or improper configuration of the smart
contract application tool-chain can result in weaknesses, errors, or
vulnerabilities, which applies even if the contract itself is free of
vulnerabilities.

Violating contract size limit — DL#2. In Ethereum, limits are imposed by the
gas consumed for the transaction. While there is no exact size limit there is
a block gas limit and the amount of gas provided has to be within that limit.
When deploying a contract, there are three factors to consider: (1) an
intrinsic gas cost, (2) the cost of the constructor execution, and (3) the
cost of storing the bytecode. The intrinsic gas cost is static, but the other
two are not. The more gas consumed in the constructor, the less is available
for storage. Normally, the vast majority of gas consumed is based on the size
of the contract. If the contract size is large, the consumed gas can get close
to the block gas size limits, preventing the deployment of the contract.

Table 6: Authentication & authorization vulnerabilities and weaknesses Attribute Attribute |  Values
---|---
Authentication & authorization vulnerabilities and weaknesses |  unauthorized function call, wrong permissions, lack of access control, signature issues.

####  5.1.5 Authorization and Authentication

The following vulnerabilities and weaknesses directly affect the security of a
smart contract and could enable attacks/exploits.

Lack of access control management — SV#1. Access control is an essential
element to the security of a smart contract. Based on the privileges of each
client/contractor party, there have to be strict rules implemented in the
contract that enforce access control.

For example, the contract in Listing 6 is trying to provide functionality to
whitelist addresses. The original function in line 10 does not have any access
restrictions, meaning any caller can whitelist addresses. The modified version
in line 15 only allows the contract owner to do so.

⬇

1contract WHITELIST {

2 address owner; //set during the first call

3 modifier isOwner() {

4 require(msg.sender == owner);

5 _;

6 }

7 // insecure

8 function enableWhitelist(address address) {

9 //Whitelist an address

10 }

11 // secure

12 function enableWhitelist(address address) external isOwner {

13 //Whitelist an address

14 }

15}

Listing 6: Lack of access control management

Authorization via tx.origin — SV#2 tx.origin is a global variable in Solidity
which returns the address of the account that sent the transaction. Rather
than returning the immediate caller, tx.origin returns the address of the
original sender (i.e., the first sender who initiated the transaction chain).
It can make the contract vulnerable, if an authorized account calls into a
malicious contract. Therefore, a call could be made to the vulnerable contract
that passes the authorization check as tx.origin returns the original sender
of the transaction, which in this case is the authorized account.

Signature based vulnerabilities — SV#3 These vulnerabilities are introduced as
a result of insufficient signature information or weaknesses in signature
generation and verification. Those include but not limited to:

  * 1.

Lack of proper signature verification: One example can be relying on
_msg.sender_ for authentication and assuming that if a message is signed by
the sender address, then it has also been generated by the sender address.
Particularly in scenarios where proxies can be used to relay transactions,
this can lead to vulnerabilities. For more information, we refer to
SWC-122191919https://swcregistry.io/docs/SWC-122

  * 2.

Missing Protection against Signature Replay Attacks: To protect against
Signature Replay Attacks, a secure implementation should keep track of all
processed message hashes and only allows new message hashes to be processed.
Without such control, it would be possible for a malicious actor to attack a
contract and receive message hashes that were sent by another user multiple
times. For more information, we refer to
SWC-121202020https://swcregistry.io/docs/SWC-121

  * 3.

Signature Malleability: The implementation of a cryptographic signature system
in Ethereum contracts often assumes that the signature is unique, but
signatures can be altered without the possession of the private key and still
be valid. Valid signatures could be created by a malicious user to replay
previously signed messages. For more information, we refer to
SWC-117212121https://swcregistry.io/docs/SWC-117

####  5.1.6 Dependency and Upgradability Vulnerabilities and Weaknesses

Dependencies of and upgrades to smart contracts can lead to a number of issues
in smart contracts. We describe one of these weaknesses/vulnerabilities below.

Insecure contract upgrading — UV#1. There are two ways to upgrade a contract.
First, to use a registry contract that keeps track of the updated contracts,
and second, to split the contract into a logic contract and a proxy contract
so that the logic contract is upgradable while the proxy contract is the same.
Both approaches allow untrusted developers to introduce dependency
vulnerabilities in the updated contract’s logic, allowing attackers to modify
the logic of the upgraded contract using its dependencies, e.g. another
contract. This vulnerability was also reported in Atzei et al. (2017) and Chen
et al. (2020a).

####  5.1.7 Interface Vulnerabilities and Weaknesses

This category describes weaknesses resulting in incorrect display of results.
However, in these cases the smart contracts actually worked and produced the
expected outcomes. The weaknesses were instead found in other applications
that displayed the results. As these applications are not part of the smart
contract, and there was no apparent code weakness in the contracts, we did not
further investigate these kind of weaknesses.

###  5.2 Are the frequency distributions of vulnerabilities similar across all
studied data sources? (RQ2)

To answer RQ2, we analyzed the frequency distributions of the defined eleven
vulnerability categories across the four data sources (i.e., Stack Overflow
GitHub, CVE, and SWC). The frequency distribution of the defined categories is
shown in Figure 7 for each data source.

CoVCVDLDVIBLVSVSV-DFSV-SCTVUV$0$$5$$10$$15$$20$$25$$30$Percentage

(a)

CoVCVDLDVIBLVSVSV-DFSV-SCTVUV$0$$5$$10$$15$$20$Percentage

(b)

CoVCVDLDVIBLVSVSV-DFSV-SCTVUV$0$$20$$40$$60$$80$$100$Percentage

(c)

CoVCVDLDVIBLVSVSV-DFSV-SCTVUV$0$$10$$20$$30$Percentage

(d)

Figure 7: Distribution of SC vulnerability categories for each of the studied
data sources.

The resulting frequency distribution shows that the Language specific coding
category and the Structural data flow category are the most common
vulnerability categories in Ethereum smart contracts

The language specific coding category is dominant on both Stack Overflow and
GitHub. In contrast, structural data flow vulnerabilities are most frequent on
CVE and SWC. Additionally, almost 80% of the reported structural data flow
vulnerabilities in the NVD database (CVEs) are integer overflow/ underflow
vulnerabilities. Interestingly, issues on StackOverflow and GitHub appear to
have similar frequency distributions. However, these are not statistically
significant.

###  5.3 What impact do the different categories of smart contract
vulnerabilities and weaknesses have? (RQ3)

In this section, we present the main impacts of vulnerabilities and bugs in
smart contracts, thus answering RQ3. We unify all the proposed impact
categories in the literature (i.e., (Chen et al., 2020b; Zhang et al., 2020)),
and present a thorough classification scheme of vulnerability impacts on
Ethereum smart contracts. We followed a similar approach to what we did in
RQ1. The definitions of the final impact categories are depicted in Table 7
and Table 8. Furthermore, Table 9 shows how the impact categories in
literature related to our classification. Note that IP5 (in the second-last
row) does not relate to any of our categories, as the category describes smart
contracts that function as intended, something that we did not include in our
classification.

Our mapping shows that the impact of smart contract vulnerabilities and code
weaknesses on certain aspects has not been examined in detail. For instance,
the impact on the development process and the productivity of a software
development team. Additional research in this area can quantify the extent to
which the vulnerabilities impact smart contract development, the developing
team, and the development of decentralized applications based on smart
contracts.

Table 7: Classification Scheme of Impacts (I-D1) Impact |  Description |  App.
---|---|---
Unexpected behavior |  Contract behaves abnormally, e.g., generating incorrect output. |  UB
Unwanted functionality |  Contract executes wrong functionality because of wrong logic. |  UF
Long response time |  Long runtime of a smart contract to any input without providing the desired output. |  LRT
Data Corruption |  Data becomes unreadable, unusable or inaccessible, and unexpected output is generated. |  DC
Memory disclosure |  Problems in the memory storage of the smart contract. |  MF
Poor performance |  Non-optimal resource usage in terms of gas and time. |  PPC
Unexpected stop |  Unexpected exit and execution stop at the point of triggering the vulnerability in the code. |  USP
Table 8: Classification Scheme of Impacts (I-D2) Impact |  Description |  App.
---|---|---
Information disclosure |  When a code weakness or vulnerability is exploited, sensitive information is exposed to an actor not explicitly authorized to see it. |  ID
Lost Ether or assets |  An exploited code weakness can lead to unauthorized actors taking over the Ether of the contract and losing it. |  LEA
Locked Ether |  In the situation of triggering code weaknesses in a contract, one can lose access to the contract and lock the Ether in it without having access to it again. |  LE
Lost control over the contract |  By exploiting code weaknesses or vulnerabilities, an unauthorized actor can take over the contract. |  LC
Table 9: Mapping literature-based Impact classifications to I-D. _D1_ : refers
to the Impact on software product. Note: IP2 belongs to D1 and D2. $\subset$*
indicates the corresponding category in our own classification is a subset of
the corresponding category in the literature marked by *. *$\subset$ means the
category in the literature is a subset of our proposed category.

Literature Ours | UB | UF | LRT | DC | MF | PPC | USP | ID | LEA | LE | LC
---|---|---|---|---|---|---|---|---|---|---|---
Functionality*. (Zhang et al., 2020) |  | = |  |  |  |  |  |  |  |  |
Performance* (Zhang et al., 2020) |  |  |  |  |  | = |  |  |  |  |
Security (Zhang et al., 2020) |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$*
Serviceability *(Chen et al., 2020b) |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  $\subset$* |  |  |  |
IP1 unwanted behaviors* (Chen et al., 2020b) | = |  |  |  |  |  |  |  |  |  |
IP3 non-exploitable UB* (Chen et al., 2020b) | *$\subset$ |  |  |  |  |  |  |  |  |  |
IP4 Errors outside program call (Chen et al., 2020b) |  | * $\subset$ |  |  |  |  |  |  |  |  |
IP5 No errors* (Chen et al., 2020b) |  |  |  |  |  |  |  |  |  |  |
IP2 UB without losses* (Chen et al., 2020b) | *$\subset$ |  |  |  |  |  |  |  |  | *$\subset$ |

I-D1

The analysis of the impacts of vulnerabilities and code weaknesses in smart
contracts shows that unexpected stop is the most prevalent impact category
among all proposed categories. It is caused primarily by vulnerabilities in
the Language Specific Coding category. The second most prevalent impact
category is unexpected functionality. This mostly happens in smart contracts
when the transferred gas amount does not match the expected amount expected
from the logic of the code, or when incorrect amounts of Ether are
transferred.

##  6 Discussion

In the following, we discuss our findings in terms of implications and
relation to existing work.

We find a substantial number of vulnerabilities and weaknesses being discussed
in social coding platforms and existing vulnerability repositories. This
clearly shows that this is an important topic to study and analyze. Because of
the unique characteristics of smart contracts, e.g., immutability and gas
consumption, it is important to make sure that vulnerabilities and code
weaknesses with severe impacts are fixed or even detected before deploying the
contract to the blockchain.

As demonstrated in our findings, existing classifications either focus on a
single dimension of smart contract vulnerabilities, such as the error source,
or mix multiple dimensions in a single classification. Our mapping unifies
these different dimensions to some extent and shows how different
classification schemes relate.

In addition to mixing dimensions, the majority of existing classification
schemes for smart contract vulnerabilities include broad categories, such as
security and availability, to which many vulnerabilities can be assigned. As
such, these categories do not support reasoning about the included
vulnerabilities, which is an important quality criterion for classifications
Ralph (2018). Furthermore, broad categories might prevent orthogonality of the
categories, i.e., that a single vulnerability fits into a single category
only. In the example mentioned above, i.e., security and availability, many
vulnerabilities can lead to negative effects on both, and thus could be
labeled both. Due to the use of attribute-value pairs Seacord and Householder
(2005), we believe that our unified classification avoids this issue.

The frequency distributions discussed in Section 5.2 show notable differences
between the frequencies of found vulnerabilities across different data
sources. This, once again, highlights that focusing on a single source biases
the resulting study. It further demonstrates that established databases such
as CVE and SWC do not reflect well the topics discussed in public coding
platforms such as Stack Overflow or GitHub. On the latter platforms, we
observe specifically that developers seem to have a poor understanding of pre-
defined functions such as _view_ and _pure_ , and that it is hard for them to
cope with continuous changes and updates in Solidity and its documentation. On
the one hand, this finding suggests that tools for verification and analysis
of smart contracts is of high importance, especially focusing on the prevalent
vulnerability categories in our classification. On the other hand, the
observed frequencies might only be a symptom of the technology maturity.
Hence, these issues might become less prevalent once Solidity matures and
updates become less frequent.

Based on our findings, we can provide a number of recommendations to
researchers and practitioners in order to improve smart contract development.

First, available static detection tools must urgently target the defined
categories of vulnerabilities and code weaknesses. Our breakdown of the
frequencies at which the different categories occur can help prioritizing this
development to target the most important categories first. Second, there is a
need to define coding best practices of smart contracts and make them
available to developers. Coding guidelines are available for many programming
languages and technologies, and can help improving quality and reducing code
weaknesses and unexpected gas consumption. Based on the analyzed data from
social coding platforms, we believe that this list can include, e.g., avoiding
multidimensional arrays, or arrays in general, if possible; carefully checking
gas consumption amounts; recomming specific safe libraries such as _SafeMath_
Saf  to avoid common pitfalls such as underflows; and avoiding substantial
sub-contract creation. Finally, we see a need for action from the Solidity
team, in particular when it comes to clearly documenting existing libraries
and code weaknesses they can resolve, as well as clearly defining gas
requirements for patterns, functions, declaration types, creating
subcontracts, upgrading contracts, and other language artifacts and
operations. Such documentation could substantially contribute to a reduction
in smart contract vulnerabilities and weaknesses in Solidity/Ethereum.

##  7 Threats to Validity

In the following, we discuss threats to the validity of our findings according
to internal and external validity, as well as reliability.

###  7.1 Internal Validity

Card sorting was used as the main method to categorize and label the posts in
this work. This method is subjective and open to bias, hence two experts
verified the manual labeling twice independently in order to mitigate this
threat. In case of any disagreement, the two experts would discuss it until
reaching to a consensus.

An additional threat to internal validity lies in the keyword search employed
during data collection. For instance, to collect Q&A posts from Stack-
Overflow, we used the tags “Smart contract”, “Ethereum”, and “Solidity”, while
for GitHub we used “smart contract”, “Solidity”, and “Ethereum”. Also, a part
of the collected data with insufficient information or with information that
is not related to smart contract vulnerabilities and code weaknesses written
in Solidity were excluded from the analysis. This search and filtering process
might have led to exclude relevant data that could have led to further
insights.

As trustworthiness of the collected posts can be a source of noise in the
data, we removed negative voted questions from the dataset. This might have
resulted in a systematic under-representation of certain types of
vulnerabilities/bugs. Given the maturity of Solidity, we deemed this step
warranted to allow for data of sufficiently high quality.

###  7.2 External Validity

A threat to external validity is the continuous updates of Ethereum using the
hard fork. More improvements are being added to Ethereum with each hard fork
such as the EIPs 222222https://github.com/ethereum/EIP that ensures the energy
efficiency of the proof-of-work. Furthermore, many new features are added to
Solidity newer versions. Therefore, new contract vulnerabilities and bugs may
be introduced and some others may be resolved. This means that our
classification might not generalize to newer (or older) versions of Solidity.

Focusing on Solidity and the Ethereum blockchain only limits the external
validity of the results, as there are other blockchains and other smart
contract languages that could have yielded further or different
vulnerabilities/bugs. We focus on Ethereum since it is the second-largest
blockchain, and the largest blockchain that supports smart contracts (written
in Solidity). However, additional studies into other technologies could be a
valuable addition to our findings, and our results might not generalize to
other blockchains or smart contract languages.

###  7.3 Reliability

To ensure reliability of the results, we described in detail the data
collection and analysis process. We systematically calculated inter-rater
reliability coefficients in iterative rounds, to ensure sufficiently clear
categories and agreement among two expert raters. Finally, we published the
full dataset Majd Soud (2021). Overall, these steps should ensure reliability
and enable replication of our study.

##  8 Conclusion

Due to the immaturity of blockchain technology, vulnerabilities in smart
contracts can have severe consequences and result in substantial financial
losses. Hence, it is essential to understand vulnerabilities and code
weaknesses of smart contracts. However, there exist several shortcomings in
existing classifications, i.e., they focus on single dimensions, mix
dimensions, propose too broad categories, or rely on single data source
omitting important sources for vulnerabilities. To address this gap, we
extracted smart contract vulnerabilities written in Solidity from a number of
important data sources, classified them in terms of error source and impact,
and related them to existing classifications in literature. Our findings show
that language-specific coding and structural data flow are the dominant
categories of vulnerabilities in Solidity smart contracts. We also find that
many vulnerabilities and code weaknesses are similar to known issues in
general purpose programming languages, such as integer overflow and erroneous
memory management. However, the immaturity and rapid evolution of the
technology and the Solidity language, and the added concept of gas furthermore
adds vulnerabilities and code weaknesses, and increases the risk of attacks
and financial losses. Interestingly, we find that the frequency at which the
different categories occur differs widely across data sources, indicating that
they should not be viewed in isolation.

Our classification scheme is a further step to standardize and unify
vulnerability analysis in smart contracts. This can support researchers in
building tools and methods to avoid, detect, and fix smart contract
vulnerabilities in the future.

Specifically, we see a number of directions for future research. First, future
studies should investigate whether our classification scheme can be
generalized by investigating other smart contracts in other blockchain
networks, e.g., Hyperledger, Stellar, and Openchain. Potentially, our
classification needs to be modified to fit into other networks or languages.
Similarly, the classification might have to be adapted as Solidity evolves and
as new languages are developed for Ethereum smart contracts. Second, more
dimensions and characteristics of the studied vulnerabilities and code
weaknesses can be explored in the future. For instance, patterns among the
extracted vulnerabilities and code weaknesses could be abstracted, as well as
the evolution over time. For each of the categories, code metrics and
detection tools can be explored. Finally, it should be investigated in which
ways the defined vulnerabilities and code weaknesses can be exploited, as well
as what the impact of these exploits will be. This can be accomplished by
developing automated scripts or manually devising such exploits.

## Acknowledgment

The authors would like to thank Mohammad Alsarhan, a security expert, for
participating in the card sorting and inter-rater agreement discussions. This
work was supported by the Icelandic Research Fund (Rannís) grant number
207156-051.

## References

  * (1) Ethereum improvement proposals (eips).  https://github.com/ethereum/EIPs/issues/1469.  [Online] Accessed: 01-April-2020.
  * (2) Safemath.  https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol. [Online] Accessed: 01-June-2020.
  * (3) A fast and powerful scraping and web crawling framework.  https://scrapy.org. [Online] Accessed: 01-June-2020.
  * Ahasanuzzaman et al. (2016) M. Ahasanuzzaman, M. Asaduzzaman, C. K. Roy, and K. A. Schneider.  Mining duplicate questions of stack overflow.  In _2016 IEEE/ACM 13th Working Conference on Mining Software Repositories (MSR)_ , pages 402–412. IEEE, 2016.
  * Alharby and Van Moorsel (2017) M. Alharby and A. Van Moorsel.  Blockchain-based smart contracts: A systematic mapping study.  _arXiv preprint arXiv:1710.06372_ , 2017.
  * Alharby et al. (2018) M. Alharby, A. Aldweesh, and A. van Moorsel.  Blockchain-based smart contracts: A systematic mapping study of academic research (2018).  In _2018 International Conference on Cloud Computing, Big Data and Blockchain (ICCBB)_ , pages 1–6. IEEE, 2018.
  * Atzei et al. (2016) N. Atzei, M. Bartoletti, and T. Cimoli.  A survey of attacks on ethereum smart contracts.  _IACR Cryptol. ePrint Arch._ , 2016:1007, 2016.
  * Atzei et al. (2017) N. Atzei, M. Bartoletti, and T. Cimoli.  A survey of attacks on ethereum smart contracts (sok).  In _International conference on principles of security and trust_ , pages 164–186. Springer, 2017.
  * Ayman et al. (2019) A. Ayman, A. Aziz, A. Alipour, and A. Laszka.  Smart contract development in practice: Trends, issues, and discussions on stack overflow.  _arXiv preprint arXiv:1905.08833_ , 2019.
  * Ayman et al. (2020) A. Ayman, S. Roy, A. Alipour, and A. Laszka.  Smart contract development from the perspective of developers: Topics and issues discussed on social media.  pages 405–422, 2020.
  * Badawi and Jourdan (2020) E. Badawi and G.-V. Jourdan.  Cryptocurrencies emerging threats and defensive mechanisms: A systematic literature review.  _IEEE Access_ , 2020.
  * Bajaj et al. (2014) K. Bajaj, K. Pattabiraman, and A. Mesbah.  Mining questions asked by web developers.  In _Proceedings of the 11th Working Conference on Mining Software Repositories_ , pages 112–121, 2014.
  * Beizer (1984) B. Beizer.  _Software system testing and quality assurance_.  Van Nostrand Reinhold Co., 1984.
  * Bhat and Vijayal (2017) M. Bhat and S. Vijayal.  A probabilistic analysis on crypto-currencies based on blockchain.  In _2017 International Conference on Next Generation Computing and Information Systems (ICNGCIS)_ , pages 69–74. IEEE, 2017.
  * Calefato et al. (2015) F. Calefato, F. Lanubile, M. C. Marasciulo, and N. Novielli.  Mining successful answers in stack overflow.  In _2015 IEEE/ACM 12th Working Conference on Mining Software Repositories_ , pages 430–433. IEEE, 2015.
  * Chen and Xing (2016) C. Chen and Z. Xing.  Mining technology landscape from stack overflow.  In _Proceedings of the 10th ACM/IEEE International Symposium on Empirical Software Engineering and Measurement_ , pages 1–10, 2016.
  * Chen et al. (2020a) H. Chen, M. Pendleton, L. Njilla, and S. Xu.  A survey on ethereum systems security: Vulnerabilities, attacks, and defenses.  _ACM Computing Surveys (CSUR)_ , 53(3):1–43, 2020a.
  * Chen et al. (2020b) J. Chen, X. Xia, D. Lo, J. Grundy, X. Luo, and T. Chen.  Defining smart contract defects on ethereum.  _IEEE Transactions on Software Engineering_ , 2020b.
  * Cosentino et al. (2017) V. Cosentino, J. L. C. Izquierdo, and J. Cabot.  A systematic mapping study of software development with github.  _IEEE Access_ , 5:7173–7192, 2017.
  * Daian (2016) P. Daian.  Analysis of the dao exploit.  _Hacking, Distributed_ , 6, 2016.
  * Dingman et al. (2019) W. Dingman, A. Cohen, N. Ferrara, A. Lynch, P. Jasinski, P. E. Black, and L. Deng.  Defects and vulnerabilities in smart contracts, a classification using the nist bugs framework.  _International Journal of Networked and Distributed Computing_ , 7(3):121–132, 2019.
  * Durieux et al. (2020) T. Durieux, J. F. Ferreira, R. Abreu, and P. Cruz.  Empirical review of automated analysis tools on 47,587 ethereum smart contracts.  In _Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering_ , pages 530–541, 2020.
  * Ethereum (2021) Ethereum.  Solidity by example, 2021.  URL https://docs.soliditylang.org/en/latest/solidity-by-example.html.
  * Hewa et al. (2020) T. Hewa, M. Ylianttila, and M. Liyanage.  Survey on blockchain based smart contracts: Applications, opportunities and challenges.  _Journal of Network and Computer Applications_ , page 102857, 2020\.
  * Huang et al. (2019) Y. Huang, Y. Bian, R. Li, J. L. Zhao, and P. Shi.  Smart contract security: A software lifecycle perspective.  _IEEE Access_ , 7:150184–150202, 2019.
  * Khan and Namin (2020a) Z. A. Khan and A. S. Namin.  Ethereum smart contracts: Vulnerabilities and their classifications.  In _2020 IEEE International Conference on Big Data (Big Data)_ , pages 1–10. IEEE, 2020a.
  * Khan and Namin (2020b) Z. A. Khan and A. S. Namin.  A survey on vulnerabilities of ethereum smart contracts.  _arXiv preprint arXiv:2012.14481_ , 2020b.
  * Majd Soud (2021) M. H. Majd Soud, Grischa Liebel.  Dataset: A fly in the ointment: An empirical study on the characteristics of ethereum smart contracts code weaknesses and vulnerabilities, Jan. 2021.  URL https://doi.org/10.5281/zenodo.6388179.
  * Mehar et al. (2019) M. I. Mehar, C. L. Shier, A. Giambattista, E. Gong, G. Fletcher, R. Sanayhie, H. M. Kim, and M. Laskowski.  Understanding a revolutionary and flawed grand experiment in blockchain: the dao attack.  _Journal of Cases on Information Technology (JCIT)_ , 21(1):19–32, 2019.
  * Perez and Livshits (2019) D. Perez and B. Livshits.  Smart contract vulnerabilities: Vulnerable does not imply exploited.  _arXiv preprint arXiv:1902.06710_ , 2019.
  * Ponzanelli et al. (2014) L. Ponzanelli, G. Bavota, M. Di Penta, R. Oliveto, and M. Lanza.  Mining stackoverflow to turn the ide into a self-confident programming prompter.  In _Proceedings of the 11th Working Conference on Mining Software Repositories_ , pages 102–111, 2014.
  * Praitheeshan et al. (2019) P. Praitheeshan, L. Pan, J. Yu, J. Liu, and R. Doss.  Security analysis methods on ethereum smart contract vulnerabilities: a survey.  _arXiv preprint arXiv:1908.08605_ , 2019.
  * Ralph (2018) P. Ralph.  Toward methodological guidelines for process theories and taxonomies in software engineering.  _IEEE Transactions on Software Engineering_ , 45(7):712–735, 2018.
  * Rameder (2021) H. Rameder.  _Systematic review of ethereum smart contract security vulnerabilities, analysis methods and tools_.  PhD thesis, Wien, 2021.
  * Samreen and Alalfi (2021) N. F. Samreen and M. H. Alalfi.  A survey of security vulnerabilities in ethereum smart contracts.  _arXiv preprint arXiv:2105.06974_ , 2021.
  * Sánchez (2018) D. C. Sánchez.  Raziel: Private and verifiable smart contracts on blockchains.  _arXiv preprint arXiv:1807.09484_ , 2018.
  * Seacord and Householder (2005) R. C. Seacord and A. D. Householder.  A structured approach to classifying security vulnerabilities.  Technical report, Carnegie-mellon university pittsburgh pa software engineering inst, 2005.
  * Vacca et al. (2021) A. Vacca, A. Di Sorbo, C. A. Visaggio, and G. Canfora.  A systematic literature review of blockchain and smart contract development: Techniques, tools, and open challenges.  _Journal of Systems and Software_ , 174:110891, 2021.
  * Viera et al. (2005) A. J. Viera, J. M. Garrett, et al.  Understanding interobserver agreement: the kappa statistic.  _Fam med_ , 37(5):360–363, 2005.
  * Zhang et al. (2020) P. Zhang, F. Xiao, and X. Luo.  A framework and dataset for bugs in ethereum smart contracts.  In _2020 IEEE International Conference on Software Maintenance and Evolution (ICSME)_ , pages 139–150. IEEE, 2020.
  * Zheng et al. (2020) Z. Zheng, S. Xie, H.-N. Dai, W. Chen, X. Chen, J. Weng, and M. Imran.  An overview on smart contracts: Challenges, advances and platforms.  _Future Generation Computer Systems_ , 105:475–491, 2020\.