-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.tex
694 lines (618 loc) · 40.7 KB
/
main.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
%
% This is a basic LaTeX Template
% for the Informatics Research Review
\documentclass[a4paper,11pt]{article}
% Add local fullpage and head macros
\usepackage{head,fullpage}
% Add graphicx package with pdf flag (must use pdflatex)
\usepackage[pdftex]{graphicx}
% Better support for URLs
\usepackage{url}
% Date formating
\usepackage{datetime}
\usepackage{multirow}
\newdateformat{monthyeardate}{%
\monthname[\THEMONTH] \THEYEAR}
\parindent=0pt % Switch off indent of paragraphs
\parskip=5pt % Put 5pt between each paragraph
\Urlmuskip=0mu plus 1mu % Better line breaks for URLs
% This section generates a title page
% Edit only the following three lines
% providing your exam number,
% the general field of study you are considering
% for your review, and name of IRR tutor
\newcommand{\examnumber}{2187344}
\newcommand{\field}{Detecting Ethereum Smart Contract Security Loopholes}
\newcommand{\supervisor}{Lorenzo Martinico}
\begin{document}
\begin{minipage}[b]{110mm}
{\Huge\bf School of Informatics
\vspace*{17mm}}
\end{minipage}
\hfill
\begin{minipage}[t]{40mm}
\makebox[40mm]{
\includegraphics[width=40mm]{crest.png}}
\end{minipage}
\par\noindent
% Centre Title, and name
\vspace*{2cm}
\begin{center}
\Large\bf Research Methods In Security, Privacy, and Trust \\
\Large\bf \field
\end{center}
\vspace*{1.5cm}
\begin{center}
\bf \examnumber\\
\monthyeardate\today
\end{center}
\vspace*{5mm}
%
% Insert your abstract HERE
%
\begin{abstract}
Smart Contracts enable blockchain systems to run decentralized
applications. Unfortunately, Smart Contract platforms such as Ethereum
face severe security problems leading to permanent funds loss. In recent
years many researchers focused on developing security vulnerability
detection tools for Smart Contracts. The present literature review aims
to analyze relevant studies providing an overview of the current Smart
Contract attack surface and the techniques being used to detect any
vulnerabilities. Analyzing Smart Contracts can be challenging, but we
are indeed on a promising path towards creating reliable and scalable
Smart Contract vulnerability detection tools.
\end{abstract}
\vspace*{1cm}
\vspace*{3cm}
Date: \today
\vfill
{\bf Supervisor:} \supervisor
\newpage
% Through page and setup
% fancy headings
\setcounter{page}{1} % Set page number to 1
\footruleheight{1pt}
\headruleheight{1pt}
\lfoot{\small School of Informatics}
\lhead{Informatics Research Review}
\rhead{- \thepage}
\cfoot{}
\rfoot{Date: \date{\today}}
%
\section{Introduction}
During the predawn of the 21st century, we glimpsed a rapid technological and
economic development that brought us face to face with a new technology called
the blockchain. In recent years, blockchain and foremost cryptocurrencies gained
much attraction due to the high monetary gains. It is a matter of the fact that
this growth has acted as a catalyst for the technological and research eruption
we have been experiencing lately. By the end of 2021, the total cryptocurrency
market capitalization was 2 Trillion US Dollars\cite{coinmarketcap}, featuring
more than 16000 projects\cite{coinmarketcap}. Initially, the blockchain was
proposed to facilitate the transfer of value completely decentralized and
trust-framed over a network of peers. This was Satoshi's Nakamoto
Bitcoin\cite{nakamoto2008bitcoin} that came into existence in 2008. Since then,
the research and technological trends have shifted into second-generation
blockchains. Among them, the most dominant is
Ethereum\cite{buterin2013ethereum}. Ethereum is a general-purpose blockchain,
providing an open platform for individuals to build their applications on top of
it. Their applications, i.e., Smart Contracts, are pieces of code that run
decentralized on the Ethereum network. Ethereum's ecosystem flared into a broad
spectrum of Smart Contract applications, including, but not limited to,
financial apps, games, digital art and music, digital voting, and patent
registration.
Smart Contracts have balance measured in Ether and persistent private storage.
The Smart Contract's code can manipulate changes in the program's variables and
storage. On Ethereum, Smart Contracts code is in EVM\cite{evm} (Ethereum Virtual
Machine), a Turing complete stack-based bytecode language spanning 144
opcodes\cite{opcodes}. Developers can define their code in a high-level
language such as Solidity\cite{solidity}, compiled to EVM bytecode afterward. A new
transaction invocation can cause the execution of the contract's code by
receiving inputs and producing outputs. Typically, when a user wants to trigger
a Smart Contract needs to create a new transaction and pay some fees\cite{gas_fees}.
Transaction fees depend on the code being executed on the Ethereum network.
Beyond any doubt, the Ethereum blockchain is used to manage digital assets
reflecting a considerable value. Hence Smart Contracts gained the interest of
malign entities. Numerous attackers perform attacks on the Ethereum
applications, with the ultimate goal of stealing Ether from them. One of the
most severe attacks was the infamous DAO\cite{dao}. In more detail, in 2016, an
autonomous decentralized organization was founded to direct a venture capital
fund. This organization was formed on the Ethereum blockchain, and over 11000
investors deposited into a Smart Contract over 150 Million US Dollars\cite{dao}
considering the Ether price back then. Then, an unprecedented
attack\cite{reentrancy} was performed on that Smart Contract, resulting in 50
Million US Dollars loss. Another critical incident happened with the Parity
Wallet\cite{parity}, where the attack led to freezing 150 Million US Dollars, in
terms of Ether, impermanently.
Nevertheless, it is typical for any piece of code to have bugs. Likewise, we
expect Smart Contracts to behave in the same way. Potentially, Smart Contracts
are vulnerable due to many reasons. To begin with we might blame developers for
not wholly understanding the blockchain development
stack\cite{tikhomirov2018smartcheck}. Also, Solidity is a relatively new
language with many limitations and challenges. Thus, it is hard for developers
to use it\cite{tikhomirov2018smartcheck}. We consider blockchain immutability as
another non-helping characteristic. Any application deployed on the Ethereum
network can not be modified, so software fixes are not immediately
doable\cite{jiang2018contractfuzzer}. Also, a public blockchain allows
financially motivated attackers to use their online pseudonymity to exploit any
software bug\cite{tikhomirov2018smartcheck}. Finally, we cannot control the
Smart Contract execution environment since the network runs in a decentralized
fashion\cite{tikhomirov2018smartcheck}. For this reason, Smart Contract
developers need to detect possible vulnerabilities in their code before going
live. A Smart Contract Auditing tool would benefit both users and developers. A
developer might use the tool to detect any code issues before deploying the
Smart Contract. At the same time, users can utilize the tool to check if the
Smart Contract they want to interact with is safe and does behave maliciously.
Indeed, such tools came into existence in 2016, with the first one being
OYENTE\cite{luu2016making}. Since then, academic researchers have invested time and effort in
expanding this research field, developing a plethora o tools. Some of them are
general, trying to detect any vulnerability, while some others focus on a few of
them. Also, they employ different analysis techniques, such as Static and
Dynamic Analysis. Furthermore, researchers attempted to document and classify
many of these vulnerabilities according to their behavior or functionality.
The contribution of this work is two-fold. Initially, we document and classify
Smart Contract vulnerabilities reported across the most prominent studies. Next,
we present the research trends of developing a Smart Contract vulnerability
framework throughout the years, giving an overview of the techniques used and
directions taken.
The structure of the following literature review has as follows. The next
section, \emph{Methodology}, describes our strategy for selecting papers to
include in this literature review. Later we separate the review into three
sections. \emph{Smart Contract Attack Surface}, \emph{Static Analysis}, and
\emph{Dynamic Analysis}. Finally, we wrap-up this literature review with a
\emph{Summary anc Conclusion} section, where we disguss our findings, as well
as, future directions in the Smart Contract Vulnerability detection area.
\section{Methodology}
In this literature review, we explore the most prominent research attempts
towards creating an effective vulnerability detection tool for Ethereum Smart
Contracts. The method used to filter relevant studies comprised both bottom-up
and top-down strategies. Their combination significantly accelerated identifying
adequate quality papers to include in this literature review.
During the bottom-up stage, we sought several papers related to frameworks that
identify Smart Contract vulnerabilities. To achieve that, we employed
trustworthy academic search engines such as \emph{Google Scholar} and \emph{IEEE
Explorer}. We noticed that most of the retrieved writings had a joint primary
related work, which guided us to discover this research topic's essence
paper\cite{luu2016making}.
Subsequently, we aimed to find any derivative studies related to the paper
arisen in the previous phase. To do so, we used a graph representation
tool\cite{connectedpapers} that links relevant papers. This mechanism allowed us
to identify remarkable research articles rapidly. Afterward, we manually
inspected the search results and included the most reliable in our under
investigation list.
Namely, we collected forty-seven papers, but we only consider thirteen of them
in this literature review. The selection criteria span the context of the
studies and their research contribution. We measure their contribution according
to their citations and release year. According to their publication year,
studies are assigned a weight ranging from 1 to 4. Papers in the span of
2016-2017, 2018, 2019, 2020 receive 1, 2, 4, 8 points, respectively, for each
citation they hold. Using this metric, we evaluate the studies shown in Table
1.
\begin{table}[t]
\begin{center}
\small
\begin{tabular}{||p{11cm}|c|c|c|c||}
\hline
Study & Year & Cit. & Score & Ref. \\
\hline
\hline
Making Smart Contracts Smarter & 2016 & 1445 & 1445 & \cite{luu2016making} \\
% \hline
% A Survey of Attacks on Ethereum Smart Contracts (SoK) & 2017 & 1176 & 1176 & \cite{atzei2017survey} \\
\hline
Securify: Practical Security Analysis of Smart Contracts & 2018 & 436 & 872 & \cite{tsankov2018securify} \\
% \hline
% VerX: Safety Verification of Smart Contracts & 2020 & 103 & 824 & \cite{permenev2020verx} \\
\hline
ZEUS: Analyzing Safety of Smart Contracts & 2018 & 399 & 798 & \cite{kalra2018zeus} \\
\hline
Finding The Greedy, Prodigal, and Suicidal Contracts at Scale & 2018 & 357 & 714 & \cite{liu2018reguard} \\
\hline
SmartCheck: Static Analysis of Ethereum Smart Contracts & 2018 & 291 & 582 & \cite{tikhomirov2018smartcheck} \\
% \hline
% Formal Verification of Smart Contracts & 2016 & 525 & 525 & \cite{bhargavan2016formal} \\
\hline
ContractFuzzer:Fuzzing Smart Contracts for Vulnerability Detection & 2018 & 233 & 466 & \cite{jiang2018contractfuzzer} \\
\hline
Slither: A Static Analysis Framework For Smart & 2019 & 109 & 436 & \cite{feist2019slither} \\
\hline
MadMax:Surviving Out-of-Gas Conditions in Ethereum Smart Contracts & 2018 & 213 & 426 & \cite{grech2018madmax} \\
\hline
Manticore: A User-Friendly Symbolic Execution Framework for Binaries and Smart Contracts & 2019 & 91 & 364 & \cite{mossberg2019manticore} \\
\hline
teether:Gnawing at Ethereum to Automatically Exploit Smart Contracts & 2018 & 173 & 345 & \cite{krupp2018teether} \\
\hline
Vandal:A Scalable Security Analysis Framework for Smart Contracts & 2018 & 154 & 308 & \cite{brent2018vandal} \\
\hline
ReGuard: Finding Reentrancy Bugs in Smart Contracts & 2018 & 122 & 244 & \cite{liu2018reguard} \\
% \hline
% Ethereum Smart Contracts: Vulnerabilities and their Classifications & 2020 & 12 & 96 & \cite{khan2020ethereum} \\
% \hline
% ETHPLOIT:From Fuzzing to Efficient Exploit Generation against Smart Contracts & 2020 & 10 & 80 & \cite{zhang2020ethploit} \\
\hline
GasFuzzer: Fuzzing Ethereum Smart Contract Binaries to Expose Gas-Oriented Exception Security Vulnerabilities & 2020 & 8 & 64 & \cite{ashraf2020gasfuzzer} \\
\hline
% SoliAudit: Smart Contract Vulnerability Assessment Based on Machine Learning and Fuzz Testing & 2019 & 13 & 52 & \cite{liao2019soliaudit} \\
% \hline
\end{tabular}
\label{table:studies}
\caption{List of papers that are analyzed in this literature review, sorted by their score}
\end{center}
\end{table}
\section{Literature Review}
\subsection{Smart Contract Attack Surface}
One of the most important aspects of Smart Contract vulnerability detection
tools is understanding and realizing models that precisely describe a
vulnerability. Different authors have unique approaches on how to classify
potential faulty code. For example, according to their overall behavior,
Nikolic et al. \cite{nikolic2018finding} categorize Smart Contract into Greedy,
Prodigal, and Suicidal. Namely, each category represents an abstract
representation of a group of more explicit vulnerabilities. On the other hand,
some other authors prefer to distinguish vulnerabilities based on the domain
they affect. For example, a few studies, like GasFuzzer \cite{ashraf2020gasfuzzer}, choose to
examine only gas-oriented vulnerabilities. Subsequently, it is abundantly clear
that there is a broad spectrum of Smart Contract vulnerabilities, and there is
not a single universally accepted classification of them. In 2017 Atzei et al.
\cite{atzei2017survey} published a survey including the most well-known security pitfalls of the
Ethereum Smart Contracts. In more detail, they report twelve points,
taxonomizing them into three categories (Solidity-Level, EVM-Level, and
Blockchain-Level). Four years and over ten million blocks later, new
vulnerabilities arose. Hence, within the context of this literature review, we
have collected reported vulnerabilities across different studies and present a
thorough list of them, trying to categorize them into six groups.
We categorize vulnerabilities according to their domain. We have
classes referring to internal, external, and arithmetic bugs. Also, we
introduce two more categories to enclose transaction and block dependency
exposures. Ultimately, we report eighteen vulnerabilities over these domains
(Note: a vulnerability might be part of multiple domains). Table 2 depicts the
category and vulnerability mappings. The following describe each
vulnerability in more detail.
\begin{table}[t]
\begin{center}
\small
\begin{tabular}{||c|c|l||}
\hline
Class & No. & Vulnerability Name\\
\hline
\hline
% \multirow{8}{*}{Syntax Violations} & 1 & Interface violation \\ \cline{2-3}
% & 2 & Compiler version inconsistency \\ \cline{2-3}
% & 3 & Variable visibility modifiers \\ \cline{2-3}
% & 4 & Function visibility level \\ \cline{2-3}
% & 5 & Argument validation \\ \cline{2-3}
% & 6 & Costly coding scheme \\ \cline{2-3}
% & 7 & Redundant Fallback Function \\ \cline{2-3}
% & 8 & Code format/style violation \\ \cline{1-3}
\multirow{5}{*}{Internal Vulnerabilities} & 1 & Ether Freezing \\ \cline{2-3}
& 2 & Destroybale Contract \\ \cline{2-3}
& 3 & Internal variable access control \\ \cline{2-3}
& 4 & Contract balance access control \\ \cline{2-3}
& 5 & Exposed secret \\ \cline{1-3}
\multirow{6}{*}{External Vulnerabilities} & 6 & Reentrancy \\ \cline{2-3}
& 7 & Denial of Service \\ \cline{2-3}
& 8 & Poor exception handling \\ \cline{2-3}
& 9 & Gasless Send \\ \cline{2-3}
& 10 & Non isolated external calls \\ \cline{2-3}
& 11 & Delegate calls \\ \cline{1-3}
Arithmetic Vulnerabilities & 12 & Integer under/over flow \\ \cline{1-3}
\multirow{3}{*}{Gas related Vulnerabilities} & 13 & Denial of Service\\ \cline{2-3}
& 14 & Integer under/over flow \\ \cline{2-3}
& 15 & Unbounded mass operations \\ \cline{1-3}
\multirow{2}{*}{Transaction related Vulnerabilities} & 16 & Transaction ordering dependency\\ \cline{2-3}
& 17 & Transaction state dependency \\ \cline{1-3}
Block related Vulnerabilities & 18 & Block state dependency \\ \cline{1-3}
\end{tabular}
\label{table:vulnerabilities}
\caption{List of vulnerabilities according to their domain}
\end{center}
\end{table}
% \textbf{Interface Violations:}
% Interface violations refer to implementing particular digital assets on the
% Ethereum blockchain without fully aligning with the defacto community accepted
% requirements. For example, ERC-20 tokens [eth website to erc20] need to expose a
% particular API interface to help third-party services communicate with their
% Smart Contract flawlessly. If a developer decides to implement a non-ERC-20
% compliant token, it might be considered suspicious and thus malicious.
% \textbf{Compiler version inconsistency:}
% Solidity source code files include a header line stating the versions of
% compiler they can be complied with. A similar to Javascript notation can be used
% to indicate the minor compiler version (caret character). This notation can
% produce execution inconsistency in different execution environments. For this
% reason, it is better to declare a stable compiler version precisely.
% Nevertheless, we can argue with this proposal from Tikhomirov et al. since using
% a stable compiler version might make a Smart Contract obsolete and incapable of
% running on newer EVM versions.
% \textbf{Variable visibility modifiers:}
% Many developers migrating from traditional programming languages mistake the
% \emph{private} variable modifier as not visible to others. This is a
% misunderstanding since every Smart Contract state variable is visible to anyone.
% The term \emph{private} means that other Smart Contract instances can not access
% this variable.
% \textbf{Function visibility level:}
% In Solidity, a function can have three visibility levels. These are external,
% internal, and public. Likewise to the previous coding pitfall, many developers
% might misinterpret the meaning of these modifiers and use them wrong.
% \textbf{Argument validation:}
% It is a common practice to adopt for every Smart Contract function. For example,
% when we receive a string of a maximum of eight characters long, we should check
% that its length is valid. However, this practice can require more computational
% complexity and yield more gas fees. It should be used when needed.
% \textbf{Costly coding schemes:}
% In Solidity, different data structures have different gas costs, but they can
% achieve the same result most of the time. For instance, a developer should use
% pure bytes instead of using a byte array because they have lower gas fees.
% Moreover, loops a the most common coding scheme to avoid since a loop of an
% unknown length comes with high execution cost.
% \textbf{Redundant Fallback Function:}
% Solidity supports a fallback/receive function triggered when no function
% signature matches the transaction data. This function deposits the incoming
% value to the contract balance when a transaction has value but no data.
% Similarly, it handles any transaction that has unknown function signatures. A
% fallback/receive function should be implemented only when needed; otherwise, it
% is redundant.
% \textbf{Code format/style violation:}
% Smart Contract developers should use tidy and easy-to-read styling patterns
% throughout the code.
\textbf{Ether Freezing:}
A Smart Contract, as mentioned earlier, has its balance of Ether. Different
types of applications require the user to deposit Ether to participate in a
lucky draw or an online game etc. A Smart Contract will accept deposits, but
under specific conditions, it might lock Ether forever, acting as a black hole.
Something similar happened in 2017 with Parity wallet Smart Contract. The bug
occurred because the Parity wallet transferred funds using an external library.
That library was accidentally removed from the blockchain, and thus all Ether in
Parity wallet became inaccessible. Further, according to Nikolic et al. another
case where funds can be locked in a Smart Contract is when the contract is
removed from the blockchain, and some users continue to send Ether to it. These
Ether will be lost as well.
\textbf{Destroybale Contract:}
Smart Contracts, out of the box, give the ability to their owners or an
authorized entity to destroy them. The funds enclosed in the Smart Contract will
be returned to the owner by default. However, if an arbitrary account can
destroy the Smart Contract, it alarms a vulnerability. This abnormal code
behavior might have been maliciously constructed and helped an attacker harvest
any Ether in the Smart Contract's balance when combined with other attacks.
\textbf{Internal variable access control}
With the term internal variable access control, we refer to insecure Smart
Contract implementation that allows an adversarial entity to alter the internal
state of the Smart Contract. This kind of behavior can be combined with the
earlier mentioned Destruction vulnerability. For instance, an attacker leverages
his ability to alter the Smart Contract owner variable before the Destruction.
Besides that, attackers might straight forward access the contract's private
variables value or logic, revealing an important secret.
\textbf{Contract balance access control}
A Smart Contract that can be invoked to transfer money to an arbitrary account.
We define arbitrary accounts as addresses that have never deposited Ether into a
Smart Contract but can withdraw value from it.
\textbf{Delegate calls}
In Solidity, developers can call third-party Smart Contracts already deployed on
the Ethereum blockchain. This technique is called delegate call and has the
advantage of reducing the initial gas costs required to deploy an application
online. However, if the third-party library is exposed or destructed, it
directly affects the execution of our application. Thus, a delegate call might
lead to security pitfalls.
\textbf{Reentrancy}
We consider the function of a Smart Contract reentrant when it executes an
external call to a contract that maliciously calls back again the caller
function. In other words, there is a recursive entrance to the initial function.
This phenomenon can be problematic, especially in cases where the code being
executed leads to Ether withdrawals. This issue became famous during the DAO\cite{dao}
hack back in 2016.
\textbf{Denial of Service}
Denial of Service is a well-known attack in many systems. Essentially, the
attacker removes the Smart Contract availability for other users. This is
attainable when a condition within the Smart Contract's code relies on the
result of an external call or input. The callee might permanently fail to
respond to that call, preventing the caller from ending its execution.
\textbf{Poor exception handling}
Exception disorder is a common problem in Smart Contracts and depends on poor
exception handling when a contract calls another. The failure to call another
contract function may result in different errors, and various handling is
needed. Instead, most developers do not check for these exceptions, and
subsequently, these transactions fail. This can be problematic in several cases,
primarily when Ether is in transit. Any code executed until the fail point
will revert.
\textbf{Gasless Send}
According to Consesys\cite{consensys_send}, the send() function is not recommened to use since it
only forwards 2300 gas. This can cause problems if the fallback function of
another Smart Contract is costly to execute and fails. Further, gas prices might
change in the future, and 2300 gas units will not be enough to cover any
functionality that can be executed today.
\textbf{Non isolated external calls}
Having several call invocations in a loop is not a good idea. This is because
the failure of one call might lead to canceling all preceding calls in the loop.
Hence we need each call to be isolated. For instance, good practice in
withdrawals is the pull mechanism\cite{consensys_send}, where a user initiates the transaction for
withdrawing Ether to his address. Hence, its transaction will not affect any
other transactions.
\textbf{Integer under/over flow}
In Solidity, integer over/under-flows can happen. For example, a uint8 integer
can take values from 0 to 256. If the current state of a uint8 variable is 0 and
we subtract 1 from it, its value will rotate to 256. Nevertheless, this issue is
being resolved in newer Solidity versions\cite{solidity8}.
\textbf{Unbounded mass operations}
Unbounded mass operations mainly refer to loops. Iterating over a large data
structure, like arrays, might result into out of gas exceptions. Each block
allows only a specific amount of gas, and when exceeded, we get an exception,
and our transaction fails.
\textbf{Transaction ordering dependency}
Transaction ordering dependency is another vulnerability to think about. Some
transactions are essential to execute in a particular order to produce the
desired outcome. For example, a user wants to sell tokens to a smart contract
for Ether using a contract-defined rate. The maligned Smart Contract owner
issues a transaction to reduce that rate and ensures his transaction is executed
first. This results in tricking the user into accepting a different exchange
rate.
\textbf{Block state dependency}
Block state includes information such as block number and timestamp. This
information is insecure to use as input for the Smart Contract functions.
Notably, it is not secure to use them as a source of randomness since they are
predictable, and any adversarial entity might use them for its interest to
simulate the outcome of a tranasction.
\subsection{Static Analysis}
Static analysis is an automated method of analyzing software without executing
its code. This is achieved by only considering the behavior of statements and
declarations throughout the code. Static analysis frameworks achieve that by
employing formal methods such as data flow analysis, model checking, inference
rules, semantic language analysis, and symbolic execution.
Using the data flow analysis, tools can produce a control flow graph. This graph
depicts how a program can be separated into basic blocks\cite{basicBlocks} and how each block
connects, forming different execution paths. In addition, using model checking,
we can observe if a program meets certain conditions and has a finite state.
Inference rules are first-order logic statements representing any code
dependencies and logical actions. Besides that, we use semantic analysis to
reflect how a programming language works. In our case, we are interested in
Solidity bytecode semantic rules formalization. Using these semantics, we can
verify a Smart Contract's correctness. Ultimately, a more practical approach
comes with symbolic execution. Symbolic execution explores possible execution
paths assuming symbolic inputs. The final result of the execution generates a
set of expressions and constraints involving the program variables. We feed
these constraints into a constraint satisfiability solver to generate concrete
inputs for the paths found.
One of the first works on this topic was proposed back in 2016 by Luu et al.\cite{luu2016making},
presenting the first of its kind tool called OYENTE. OYENTE operates using the
Smart Contract's bytecode, and it is mainly based on symbolic execution. The
researchers preferred to use symbolic execution since it is easier to reason
about a program path-by-path. The engine of this framework extracts the CFG out
of the Smart Contract bytecode, distinguishes valid execution paths, and
eventually uses the Z3 Bytevector solver\cite{z3Solver} to generate tangible values
validating any vulnerabilities. We note that OYENTE evaluated using 19366 Smart
Contracts with 350 seconds per contract average analysis time. Also, this tool
yields many false positives. Follow-up work has been proposed with the tool
named Manticore\cite{mossberg2019manticore}. Mossberg et al. take a different approach to path
exploration, defining three states that a Smart Contract can be. They suggest
that a contract can be Ready, Busy, or Terminated. In particular, their
framework tries to explore the different states that a Smart contract can be
during its execution using various heuristics. Afterward, they feed to each
Ready state a symbolic transaction. Manticore is a modular framework that allows
different SMT solvers to be used. Regarding this framework evaluation, the
authors tested it using only 100 Smart Contracts, which is not a representative
amount of contracts to argue about the tool's scalability. Another drawback of
this tool is that it only achieves 66\% code coverage on average, which is
relatively low. MAIAN\cite{nikolic2018finding} is another symbolic execution framework proposed by
Nikolic et al., having good true positive results in detecting the \emph{Contract
balance access control} and \emph{Destroyable contract} vulnerabilities. Furthermore,
Krupp et al. suggested their tool, teEther\cite{krupp2018teether}, based on the same logic.
Nevertheless, their work is inadequate since they analyzed 815 contracts out of
the 33195 they collected. They stated that only 815 contracts exposed critical
paths. According to their assumptions, a critical path leads to Smart Contract
external influence. Hence, their result granularity is very strict.
On the other hand, Securify\cite{tsankov2018securify} utilizes data flow analysis, model checking,
inference rules, and semantic language analysis to detect vulnerabilities. In
more detail, this framework takes as input EVM bytecode and a set of predefined
security patterns. Next uses the semantic facts of the EVM, including some CFG
data, to match any security issues found according to the given patterns. One of
the drawbacks of this tool is that it assumes the bytecode instruction (sstore),
malicious since it can not realize it correctly using semantic analysis. This
fact might lead to false positives. Eventually, Tsankov et al. evaluated
Securify using 24594 Smart Contracts. Comparing this kind of tool with symbolic
execution-only tools, we observe that it is more successful with fewer false
positives.
An alternative school of thought within the static analysis sphere leverages
abstract interpretation to analyze Smart Contracts. Well-known studies following
this method are Zeus\cite{kalra2018zeus}, SmartCheck, Slither, Vandal, and MadMax. Initially, they
take as input Solidity source code or bytecode and translate it into an
intermediate representation. Such representations can be in XML form \cite{tikhomirov2018smartcheck} or LLVM\cite{kalra2018zeus} code. Next, similar to Securify, these tools take a set of
predefined policies as input and translate them into an intermediate
representation. The final step is familiar with the previously described tool
where an SMT solver tries to analyze points in the code where the policy
verification predicates need to be asserted. Zeus, Slither, and Smart check are
evaluated with 22493, 4600, and 1000 Smart Contracts, respectively. The three of
them have significantly better results than Securify, with Zeus reporting only a
2\% false-positive rate. MadMax, which is based on Vandal framework, is a
vulnerability detection tool specifically designed to catch out-of-gas
exceptions. Surprisingly, MadMax can analyze the whore blockchain, snappy, with
an average analysis time of 8 seconds per contract and a reasonably low
false-positive rate.
\subsection{Dynamic Analysis}
In contrast to Static analysis, Dynamic analysis aims to detect any code
vulnerabilities during the runtime of a program. It is a matter of the fact that
Dynamic analysis produces almost zero false positives since every explored path
is being executed. Therefore, we know for sure that it is reachable. There are
two main approaches when using Dynamic analysis, instrumentation, and fuzzing.
In the Smart Contract auditing research domain, most works are fuzzing oriented.
The concept of fuzzing is inspired by random input generation for programs
expecting them crash and reveal potential vulnerabilities. A fuzzing engine
generally comprises the \emph{input generator} and the \emph{monitor} that
detect errors during the program run time. In addition to pure random value
generation, we have \emph{mutation-based fuzzing}, aiming to expose a more
narrow domain of bugs. Fuzzing is a contemporary practice taken when analyzing
Smart Contracts.
ContractFuzzer\cite{jiang2018contractfuzzer} is a state-of-the-art framework transcending the complex and
unsolvable mathematic constraints of Static Analysis. Contract Fuzzer takes a Smart
Contract's application binary interface (ABI), extracts the function signatures,
and uses them to generate possible inputs. Afterward, the code is executed using
the generated inputs, while executions logs are dumped into an external log
pool. Eventually, predefined error detection oracles pass through the recorded
logs to identify potential bugs. It is worth noting that during the execution of
the Smart Contracts, researchers initiated transactions coming from different
types of accounts (owner address, external address, attacker Smart Contract
address). This is something we could not accomplish using Static Analysis.
Building on top of Contract Fuzzer, Ashraf et al. created Gas Fuzzer\cite{ashraf2020gasfuzzer}, a
gas-oriented fuzzing tool. This tool employs two different methods of fuzzing,
gas-greedy, and gas-leveling. The gas-greedy strategy generates random
transactions putting them in a pool. The fuzzing engine takes one, mutates it,
and then executes it. If the mutated transaction gas is more than the
pre-mutated transaction, the first one is placed back to the transaction pool.
In the meantime, the Gas Fuzzer checks the execution fingerprint of the mutated
transaction for potential vulnerabilities. This process runs iteratively until a
predefined runtime timeout reaches. On the other hand, gas leveling introduces
the concept of delivering to the fuzz engine transactions consuming gas of
different levels. This strategy seeks to report the code coverage reached using
different amounts of gas. Once coverage converges to its maximum, the tool
checks for bugs using the execution log.
Some other fuzzing tools extend Static Analysis techniques to achieve their goals.
Namely, Reguard\cite{liu2018reguard}, a reentrancy detection framework, uses Static Analysis to
translate into intermediate representation before generating any random values.
In more detail in this work, researchers attempt to translate Solidity into C++
to use an out-of-the-box fuzzing engine, AFL\cite{afl}. Eventually, they check for bugs
using the execution log, which they feed into automata describing the reentrancy
vulnerability.
\section{Summary \& Conclusion}
With the emergence of blockchain technologies and particular Smart Contracts,
many people and governments decided to get involved in building a decentralized
future. However, this technology is in its very early stages and entails risks.
Namely, Smart Contract vulnerabilities pose a significant threat to future
adoption. This literature review presents the latest developments in detecting
Smart Contract security pitfalls. Ultimately, we refer to prominent studies
describing different vulnerabilities they detect and how they accomplish that.
All studies managed to do that using different techniques to reach relatively
low false positives. It is worth mentioning that the examined vulnerability
detection tools catch different types of errors. Some of them are gas-oriented,
others detect only reentrancy attacks, while most are general.
Initially, researchers focused on conservative bug detection techniques such as
Static Analysis. Remarkable works in this area are OYENTE, Securify, and Zeus.
Nonetheless, technologies evolved, and later studies shifted to Dynamic analysis
in order to achieve more reliable results. Indeed Dynamic analysis presents zero
false positives with some performance tradeoffs. The foremost approach is
Dynamic analysis is fuzzing, which requires a lot of computation effort to
generate random input for Smart Contract and execute them. Sometimes this
procedure can be time-consuming. Notable Dynamic Analysis fuzzing tools are
Contract Fuzzer and Gas Fuzzer.
Throughout the bibliography review, we managed to detect several limitations and
challenges that almost every research has. None of the researchers considered
gas fairness vulnerability detection. Having a fair gas distribution across the
Smart Contract functionality is also essential. Further, all of the studies, but
one \cite{jiang2018contractfuzzer} did not consider the scenarios of Smart Contract
invocation having different roles. It is vital to distinguish vulnerabilities
according to a transaction initiator. A transaction invocation might not be
fatal if its issuer is the Smart Contract owner. Additionally, many tools used
well-predefined vulnerability patterns to detect any abnormal behaviors. The
limitation of this approach is that only known bugs can be identified, which
yields questions about the future direction of these frameworks.
Future directions on this topic include new techniques that we have never used
before. We found several papers using Machine learning combined with fuzzing to
detect vulnerabilities. Such a study was proposed by Liao et al. Zhang et al.
promoted a hybrid solution combining Static and Dynamic Analysis. However, we
did not include them in this literature review since they had no citations, and
their work was not well recognized yet.
Understanding the technological shift towards the blockchain industry, it is
evident that the following years will disrupt the current state, and Smart
Contract auditing will be necessary. Nevertheless, there will always be room for
improvement.
% Now build the reference list
\bibliographystyle{unsrt} % The reference style
% This is plain and unsorted, so in the order
% they appear in the document.
\small
\bibliography{main} % bib file(s).
\end{document}