Available via license: CC BY-NC-SA 4.0
Content may be subject to copyright.
arXiv:2008.04761v1 [cs.CR] 9 Aug 2020
1
Security checklists for Ethereum smart contract
development: patterns and best practices
Lodovica Marchesi∗† , Michele Marchesi∗, Livio Pompianu∗and Roberto Tonelli∗
∗Dept. of Mathematics and Computer Science
University of Cagliari
Cagliari, Italy
Email: { lodovica.marchesi, marchesi, pompianu.livio }@unica.it, roberto.tonelli@dsf.unica.it †corresponding
author
Abstract—In recent years Smart Contracts and DApps are
becoming increasingly important and widespread thanks to the
properties of blockchain technology. In most cases DApps are
business critical, and very strict security requirements should be
assured. Developing safe and reliable Smart Contracts, however,
is not a trivial task. Several researchers have studied the security
issues, however none of these provide a simple and intuitive tool
to overcome these problems. In this paper we collected a list of
security patterns for DApps. Moreover, based on these patterns,
we provide the reader with security assessment checklists that
can be easily used for the development of SCs. We cover the
phases of design, coding, and testing and deployment of the
software lifecycle. In this way, we allow developers to easily verify
if they applied all the relevant security patterns to their smart
contracts. We focus all the analysis on the most popular Ethereum
blockchain, and on the Solidity language.
Index Terms—Blockchain, Smart Contract, Security, Security
Patterns, Software Engineering
I. INT ROD UC TI ON
The concept of Smart Contract (SC), first introduced in
1997 by Nick Szabo [40], has recently gained more and more
attention thanks to the introduction of public blockchains, such
as Bitcoin [32] and Ethereum [7]. These are the ideal environ-
ment to run SCs, due to their transparency and immutability.
A smart contract is a piece of executable code, running on
all the nodes of a blockchain, guaranteed not by a central
authority, but by cryptography and by blockchain technology.
Its execution has the strong constraint that all outputs and
state changes resulting from execution must be the same in all
nodes. In the blockchain scenario, smart contracts (SCs) are
created and executed by specific kinds of transactions, and can
be used to transfer cryptocurrencies, activate new contracts,
record information and also interact to external systems.
Nowadays, Ethereum is the most used blockchain that
supports SCs, with more than 2M deployed SCs and about
1M transactions per day (August 2020) [15]. In Ethereum,
SCs implement a Turing-complete behavior, allowing to per-
form deterministic complex computations. They are written in
highly-specialized programming languages, among which the
most popular is called Solidity [11].
Through SCs it is possible to develop a wide range of
applications in both financial and non-financial sectors, these
are typically called DApps (decentralized applications). Many
DApps deal with direct digital currency or token usage, that
is with entities that have a direct, real monetary value. In
other cases, they may deal with contractual issues, again
with strong economic implications, as in the case of docu-
ment certification, supply chain management, voting systems.
In most cases, DApps are business critical, and very strict
security requirements should be assured. However, due to
the peculiarities of blockchains, DApps development differs
from the development of standard software. For instance, once
deployed, the code of a SC cannot change. Therefore, security
plays a major role in the development process of DApps.
Several failures and attacks occurred in recent years highlight
the need of new specific software development techniques
addressing DApp security.
We strongly believe in the need of code inspection, security
patterns, and tests to get an improved security. While various
research papers discuss smart contract design patterns [4],
[43], [44] or apply them to specific domains [47], [26], our
goal is to provide users with a guide that helps them during
the smart contract development process, allowing developers
to easily verify if they applied all the relevant security patterns
and best practices to their smart contracts.
a) Contributions: Starting from general concepts and
best practices of SC security, this work mainly aims to
provide the reader with security assessment checklists that
can be easily used for the development of SCs, in the realm
of Ethereum and Solidity. Our main contributions are the
following:
1) we discuss the critical issues regarding the safety of
DApps and present 16 main security patterns;
2) we provide a security assurance checklist for the design
phase composed of 8 best practices;
3) we provide a security assurance checklist for the coding
phase including 18 best practices;
4) we provide a security assurance checklist for the testing
phase including 6 best practices.
In order to both keep our checklists updated, and provide them
as a tool that can be easily used by developers, we also release
the checklists in a spreadsheet file available at the following
link: http://tiny.cc/security_checklist. These checklists can be
customised, removing the not relevant parts, on a project-by-
project basis.
b) Structure of the paper: The reminder of this paper is
organized as follows. Section II discusses some related works.
2
Section III discusses general concepts and critical security is-
sues of DApps. Section IV discussed the security patterns and
presents our best practice checklists. Specifically, Section IV-C
presents the main security patterns; Section IV-D focuses on
the design phase and presents our first assurance checklist;
Section IV-E discusses the coding phase and presents our
second assurance checklist. Section IV-F presents the testing
phase and the related checklist. Section IV-G discusses other
design patterns that we found in literature. Finally, Section V
draws some conclusions.
II. RELATED WORK
Various papers describe some security vulnerabilities that
affect SCs [2], [24]. Thereafter, there was a growing literature
on techniques for improving SC security, such as formal
verification [3], [29], [30], [20], static analysis [27], [23], [6],
dynamic analysis [9]. Praitheeshan et al. provides a survey
on such techniques [35]. Our work focuses on software engi-
neering for SCs development and proposes security patterns
checklists to be used in the design, coding and testing phases.
Accordingly, we distinguish two main categories of related
works, which we describe below.
The first category includes the works on software engineer-
ing for SCs development. This area of research is quite recent:
Porru et al. highlighted the need of Blockchain-Oriented
Software Engineering (BOSE) in 2017 [34]. In their overview
of blockchain-based systems for digital coupons, Podda et
al. analyse the source code of SCs and highlight the need
of design patterns to help implementing these systems in a
safe and effective way [33]. Chakraborty et al. confirmed that
standard software engineering methods need to be updated
when developing blockchain software [8], [5]. Various papers
propose methods to facilitate the blockchain development
process [22], [42], [16]. An overview of engineering aspects
of blockchains is introduced in [46] and extended in [45].
The second category includes the works which study design
patterns for smart contracts. Bartoletti et al. inspect the source
code of 811 Solidity SCs and identify nine common design
patterns [4]. In [47] Peng et al. present four design patterns and
describe how they apply to the blockchain-based healthcare
domain. Wohrer et al. elaborate six security patterns which
describe solutions to typical security issues [43]. They also
provide the Solidity source code of each pattern. Xu et al.
show a pattern collection including fifteen patterns and classify
them into four categories: interaction between blockchain and
real world, data management, security, and contract structural
patterns [44]. Liu et al. summarise eight design patterns
and group them into four categories: creational, structural,
inter-behavioral, and intra-behavioral patterns [26]. In [28]
Marchesi et al. provide a pattern collection to help gas saving
in developing Smart Contracts on Ethereum and classify them
into five categories, based on their features.
Compared with the existing surveys [43], [44], our work
classifies design patterns according to the different stages of
the software development process rather than the type of issue
addressed by each pattern. Since we include in our analysis the
patterns relevant to security issues that we found in literature,
several patterns presented in [47], [26], [4], [43], [44] are the
same, or are similar to the patterns we discuss. Furthermore,
we notice that sometimes a pattern is presented by different
authors with a different name. We provide a deep comparison
of our patterns with respect to the patterns discussed in the
existing works in Section IV. Specifically, the Ref. column of
our checklists provides a reference to all the papers in which
we identify each pattern.
III. GEN ER AL C ON CE PT S OF DAPP SECURITY
Assessing and defining patterns of good programming prac-
tice for SCs for granting security in DApps is still in its infancy
and is an ongoing area of research. Nevertheless, based on the
programmers’ experience and on recent exploited weaknesses
–very (in)famous and critical also for the amount of real
money involved–, some major advices for security assessment
in SCs have been identified and discussed among the Solidity
developers community. In fact, Ethereum and Blockchain
ecosystem are highly new and still somewhat experimental.
In addition, SCs are often designed to handle and transfer
significant amount of money (in cryptocurrency, but easily
exchangeable to real money). Therefore, it is necessary that
they correctly achieve their purposes, but it is also crucial that
their execution is secure against attacks.
The critical issues regarding the safety of a DApp can be
divided in three areas:
•Issues related to Blockchain itself : the blockchain it-
self could be attacked. It is known, for instance, that
blockchains using proof-of-work for block generation
are subject, at least theoretically, to the so-called "51%
attack". Those based on proof-of-stake are vulnerable
to other types of attack, for example to "fake stake
attack". Using Ethereum technology, the use of the main
net lowers the probability of a "51% attack", given the
number and the computing power fielded by the min-
ers. Instead, using Ethereum Classic blockchain, a fork
derived from Ethereum in 2016, the probability is higher
because its miners’ computer power is much lower. Using
a permissioned blockchain, for instance Ethereum Parity
"proof-of-authority", the blockchain security depends on
the honesty and reliability of the validating members, and
on their control over their respective IT services. Clearly,
this kind of attacks are more a problem of design choice
of the technology to be used than of proper DApp design,
so their prevention go beyond the scope of this paper.
•Issues related to SCs: the most critical part of a DApp
are the SCs, whose bytecode is publicly available, and ex-
posed to all possible exploits. Moreover, developers often
lack a full knowledge about implementation and usage of
SCs, due to the the fact that this technology is in its early
stage, it is evolving fast and is different from traditional
development. In literature there are several analyses of
possible vulnerabilities related to both Ethereum virtual
machine and Solidity language [35], [21], [25]. These are
a good starting point for providing a checklist of patterns
to verify the SCs under development.
•Issues related to the App System: The App System is
composed of the server and client side of the DApp,
3
interacting with the SCs on one side, and with human
actors, IoT devices and other systems on the other side.
It must be designed and implemented with care, but it
is somewhat less critical, provided that all best practices
related to the security of Web applications are used; a
special emphasis must be made to safeguard the access
to the private keys of the various actors.
In this paper we tackles the issues related to SCs develop-
ment which are the most critical, common and interesting for
blockchain software developers.
The first and foremost concept in security management is
to have a security mindset. The development team(s), and the
whole organization, must be fully aware of the importance of
security and protection from attacks. A good starting point
to focus on security are the Top 10 Proactive Controls of
OWASP organization [1]. Among them we identified those
most relevant for DApp security, often neglected in SCs
development, and report them ordered by importance:
•C1: Define Security Requirements. This looks straight-
forward, but it is often underestimated. You must ex-
plicitly define the security requirements needed for your
system. The requirements can be written as User Stories,
or as non-functional features, and should have acceptance
tests in the form of test cases to confirm these require-
ments have been implemented.
•C2: Leverage Security Frameworks and Libraries.
Don’t write everything from scratch, but reuse software
that is security-hardened, is coming from trusted sources
and is maintained up to date.
•C5: Validate All Inputs. This should be performed for
user inputs on server-side, because client-side validation
can be bypassed. Also, let the SC itself perform validation
of key data sent to it through messages.
•C6: Implement Digital Identity. In a DApp environment,
digital identities are guaranteed by addresses and by the
ownership of the relative private key, so this control is
quite straightforward. Nevertheless specific checks for
address ownership must be implemented to grant SCs
security from unauthorized uses.
•C7: Enforce Access Controls. SC can check access lev-
els of addresses through a mapping, and act accordingly.
•C8: Protect Data Everywhere. In particular, be aware
that data stored in a SC are always accessible to read,
independently of their visibility.
•C10: Handle All Errors and Exceptions. It is known
that even small mistakes in error handling, or forgetting
to handle errors can lead to catastrophic failures in
distributed systems. This is particularly true for SCs.
The general guidelines reported by the Solidity best prac-
tices [10], section "General Philosophy", which complement
OWASP ones, are specifically related to SC security:
1) Prepare for failure. Be able to respond to errors, also
in the context of SCs, which cannot be changed once
deployed.
2) Rollout carefully. Try your best to catch and fix the bugs
before the SC is fully released. Test contracts thoroughly,
and add tests whenever new attack vectors are discovered.
3) Keep SCs simple. Complexity increases the risk of
errors, so ensure that SCs and functions are small and
modular, reuse SCs that are proven, prefer clarity to
performance.
4) Keep up to date. Keep track of new security develop-
ments and upgrade to the latest version of any tool or
library as quickly as possible. It can be hard to enforce
this security pattern once the SC has been deployed, since
the code cannot be directly updated. Thus, special care
must be devoted to this pattern before deploy.
5) Be aware of blockchain properties. While your pre-
vious programming experience is also applicable to SC
programming, there are several pitfalls to be aware of.
An example can be the well known Parity Wallet “Hack”
occurred in November 2017, where the (apparently inci-
dental) use of a self-destruct function by a user who took
ownership of the library frozen all Parity multisig wallets
and all the cryptocurrency kept in there.
Although the literature provides various lists of guidelines
and best practices to improve security, it is not trivial to apply
them to the SC development process. For this reason, our focus
is to provide users with checklists that can be easily adopted
during the development activity. In the following of this paper,
we focus on security assurance practices regarding SC design,
coding, and testing. Indeed, issues related to SCs are the most
critical and less studied among the three categories of issues
cited above. Specifically, performing our analysis, we took
into account both the Proactive Controls of OWASP and the
general guidelines reported above.
IV. SEC UR IT Y ASSESSMENT FOR SMART CONTRACT S
In this section we present the security pattern collection and
the three security checklists to be performed during the differ-
ent phases of the development process. First, Section IV-A
and Section IV-B present our methodology for collecting
patterns. Section IV-C discusses the abstract security patterns.
The remainder of the section presents the three checklists for
the design (Section IV-D), coding (Section IV-E), and test
(Section IV-F) phases. Section IV-G presents other design
patterns discussed in literature.
A. Security: patterns and best practices
Our aim is to provide the reader with an easy way to verify
that all the known security issues are managed. Several related
works provide various practices to mitigate these issues. They
often refer to all these practices as patterns. Indeed, most of
these items are very simple and not structured to be properly
called patterns.
Accordingly, we divide them into two different categories:
abstract security patterns and best practices. The first cate-
gory includes patterns that are not related to a specific step
of the development process. The second category includes
those items related to a specific phase of the smart contract
development process. Moreover, from the best practices, it
is easy to extract checklists to be used to perform security
assurance during each development phase. We provide the
complete checklists online at http://tiny.cc/security_checklist.
4
These checklists can be customized based on the projects
requirements. These practices should complement a broader
software development process for producing DApps, such as
an agile one.
Table I collects the abstract security patterns. For each
pattern, we provide a brief description of both the problem
addressed and its solution, along with a list of references to
the papers discussing it. A short discussion is also presented
in Sec. IV-C. Tables II, III, and IV present the security
assurance practices we propose. They describe the checks
to be performed (column Name), a short description of the
vulnerabilities and how to avoid them, one or more references
to learn more about the problem and a reference to the related
security patterns shown in Table I.
B. Collecting design patterns
Our methodology for collecting design patterns and building
our best practices checklists is described in the following steps:
1) We queried on June 1st, 2020 the Web, searching for
design patterns and best practices for smart contracts.
2) We then manually inspected the results, collecting several
data sources gathering different lists of patterns. Most of
the sources are scientific papers, but we also found some
forum articles.
3) We built a first list of 54 items potentially relevant to our
work, by merging all the lists collected in the previous
step.
4) We filtered out our list, by excluding 6 items that,
although are useful patterns, are not directly related to
security aspects. For the sake of completeness, we decide
to include those items in Table V and discuss them
in Section IV-G.
5) We analysed all the remaining items and splitted them
into two main categories: 16 abstract security patterns
and 32 best practices.
6) We splitted the best practices into three groups according
to the related phase in the development process: design,
coding, testing and deployment.
Summing up, we identified 16 abstract security patterns, and
32 best security practices: 8 for designing, 18 for coding, and
6 for testing and deployment of SCs. The other design patterns
not related to security are 6.
C. Abstract security patterns
Patterns are schemes of a standard solution to a recurring
problem, with a certain structure. However, the security pat-
terns in the DApps scenario, do not always have a structure
and uniformity comparable to traditional design patterns [17].
Some of the patterns we present are variants of well-know
traditional design patterns, applied in the blockchain and smart
contracts scenario, whereas others are specifically designed to
address the peculiarities of Ethereum and Solidity context.
We describe below some of the patterns we deem to be the
most significant. A complete description of all the patterns is
available in Table I.
An example of traditional design pattern which is useful also
in the blockchain context is the Proxy pattern. It introduces
the possibility of upgrading a contract, which is by nature
immutable, without breaking any dependency. The idea is to
divide the contract into modules and to use a Proxy contract
to delegate calls to specific modules. In this way, indeed, it is
possible to modify a contract by implementing a new version
and replacing its address with the previous one in the archive
stored in the Proxy.
An example of pattern specific of the blockchain context is
the Oracle pattern, which is introduced to respond to the need
to acquire information from the outside world. In fact, a smart
contract is by nature isolated, and cannot acquire information
directly. This is due to the fact that network nodes must agree
on the state of transactions. To accomplish this, nodes should
evaluate only static data. On the contrary, the outside world,
for instance a website API, could provide different responses
to the same query performed by different network nodes,
breaking blockchain consensus. An oracle is a smart contract
handled by a trusted authority for uploading outside data to
the blockchain. This allows network nodes to query the static
blockchain data instead of the outside world, overcoming the
limits described above.
Another pattern particularly important in a decentralised
context is the Authorization pattern. Since SCs are publicly
accessible to all blockchain participants, it is critical to re-
strict authorizations to perform specific tasks. Specifically, for
each contract method, developers must specify the subset of
participants who can call it. Contracts usually define at least
one contract owner, which is the only entity authorised to call
critical methods. Table III shows various techniques to handle
authorizations properly during the coding phase.
ATime constraint defines when the related action is allowed
to be performed. Different blockchain nodes could process
transactions at different timestamps, due to network latency
or further causes. Consequently, part of the network could
consider an action as executed beyond the time constraint, and
the corresponding transaction could be rejected by the whole
network. Accordingly, developers must set time constraints
carefully, for instance by ensuring that there is enough time
between two consecutive time constraints.
D. Security in the design phase
In the design phase, developers must be aware of, and use
security patterns, as reported in references [43], [4], [36],
which we refer to. In the remainder of this subsection we
describe some of the design best practices. For the sake of
brevity we describe a few of them, while Table II shows the
full list.
Afail-safe mechanism is a function that allows contract
owners to disable specific SC methods. Developers should
always design mechanisms to either update or terminate con-
tracts because, due to the immutability of blockchains, SCs
can not be removed once published. The fail-safe best practice
can be exploited to accomplish several security patterns. For
instance, it can be used for terminating a contract (Termination
pattern), and optionally for enabling a new version of the
contract (Proxy delegate). Moreover this mechanism could
be used for slowing down sensitive tasks (Speed Bump,Rate
5
Limit). Usually, this mechanism is enabled by the contract
owner (Ownership).
E. Security in the coding phase
Below, we describe some of the most representative coding
best practices. The full checklist for security assessment in the
coding phase is reported in Table III.
During coding, one major class of problems derives from
external calls, namely from functions which recur to others’
SC code for completing their execution. In fact, a SC can
call another SC, exploiting the execution of code contained
in the latter contract. The pattern can be recursive, so the
called SC can in turn perform an external call, and so on.
As a consequence, external calls must be treated like calls to
‘untrusted’ software. They should be avoided or minimized,
because some malicious code could be introduced somewhere
in a SC belonging to this path, and any external call represents
a security risk.
A typical risk of such contract interaction is reentrancy,
namely the called contract can call back the calling function
before the overall function execution has been completed. This
pattern has been performed in the DAO attack. When it is not
possible to avoid external calls, label all the potentially unsafe
variables, functions and contracts interfaces as "untrusted".
In order to prevent these issues, check accurately all precon-
ditions and restrict concurrent accesses to resources, as defined
by the Check-effect-interaction and Mutex patterns.
Another important best practice for SC security and error
handling is to validate inputs by using assert(),require() and
revert() guard functions. They are a very powerful security
tool, and are the subject of security pattern Guard Check
presented in Table I. In general, use assert() to check for
invariants, to validate state after making changes, to prevent
wrong conditions; if an assert() statement fails, something very
wrong happened and you need to fix the code. Use require()
when you want to validate: user inputs, state conditions
preceding an execution, or the response of an external call.
Use revert() to handle the same type of cases as require(), but
with more complex logic [10].
F. Security in the testing and deployment phases
In this subsection we focus on the testing and deployment
steps, and describe some of the best practices shown in Ta-
ble IV.
As in traditional software engineering, also in the smart
contract context develop unit testing is important. Currently,
there are several techniques for testing smart contracts. We do
not prescribe the use of specific testing practices, such as Test
Driven Design, but we highlight the importance of testing. One
way is to use a browser-based real-time compiler and runtime
environment for Solidity, such as Remix.
Another way is to use frameworks for testing. Presently,
among the most popular testing frameworks for Ethereum
DApps there are Truffle [41], Embark [12] and Etherlime
[14]. Moreover, the Ethereum community operates multiple
test networks. These are used by developers to test applications
under different conditions before deploying them on the main
Ethereum network. The most famous ones are Ropsten [38] ,
Rinkeby [37] and Goerli [19]. Finally, it is possible to set up
a local Ethereum blockchain which can be used to run tests,
execute commands, and inspect state while controlling how
the chain operates. An example of such a software is Ganache
[18], from the Truffle suite.
G. Other patterns
As described in our methodology (Section IV-B), 6 more
patterns emerged from the literature. Those patterns are not
strictly related to contract security but are useful for a good
SC design. Therefore, we decided to include them in this work
for completeness and briefly describe some of them in the
followings. Table V shows the full list of those patterns.
The Publisher-Subscriber pattern is a well-known design
pattern studied in traditional (i.e. not blockchain-based) soft-
ware engineering. According to this pattern, when a module
needs to receive some messages from other software modules
(e.g. a smart contract), developers should implement a messag-
ing infrastructure that allows each module to be easily notified
when a new message is generated.
The Tokenisation pattern suggests to use tokens for repre-
senting good and services in the blockchain. The Ethereum
ecosystem provides standards to handle several types of to-
kens, such as the ERC20 and ERC721.
V. CO NC LU SI ON S
In this paper we presented a pattern collection of 48
patterns and best practices for security in blockchain-based
applications. We focused on Ethereum and Solidity, since they
are nowadays the most used blockchain and programming
language to develop DApps. Our collection includes 16 ab-
stract patterns and 32 best practices: 8 for the design, 18 for
the coding, and 6 for the testing phases of smart contract
development process. Some patterns are adaptations of tradi-
tional software patterns modified to account for SCs specificity
in the context of Solidity language, others are specifically
designed for DApps, considering the unique properties of the
blockchain.
To provide a useful guide that allows developers to easily
verify if they applied all the relevant security patterns to their
projects, we collected the patterns into three security assurance
checklists, based on the phase. These checklists can be cus-
tomised on a project-by-project basis. In order to keep them
updated and to provide an easy to use tool, we also released
these checklists in a spreadsheet file available at the following
link: http://tiny.cc/security_checklist. For completeness, since
our collection excluded 6 of the patterns we found in the
literature, we decided to present them.
Combining good software design practice with security
assurance checklists, developers can create DApps that are
more reliable, address security issues and mitigate typical
attacks.
Future works will extend these security checklists in order
to address other blockchains, such as Hyperledger Fabric and
other permissioned blockchains. Indeed, permissioned systems
introduce new challenges that affect the whole development
7
TABLE I: Abstract security patterns
ID Name Description Ref.
CEI Check Effect Interac-
tion
When performing a function in a SC: first, check all the preconditions,
then apply the effects to the contract’s state, and finally interact with
other contracts. Never alter this sequence.
[43]
PD Proxy Delegate /
Decorator
Proxy patterns are a set of SCs working together to facilitate upgrading
of SCs, despite their intrinsic immutability. A Proxy is used to refer to
another SC, whose address can be changed. This approach also ensures
that blockchain resources are used sparingly, thus saving GAS.
[36],
[13],
[47],
[26],
[28]
AU Authorization Restrict the execution of critical methods to specific users. This is
accomplished using mappings of addresses, and is typically checked
using modifiers.
[4]
OW Ownership Specify the contract owner, which is responsible for contract manage-
ment and has special permissions, e.g. it is the only address authorized
to call critical methods. This patter can be seen as a special instance
of the authorization pattern.
[4]
OR Oracle An oracle is a SC providing data from outside the blockchain, which
are in turn fed to the oracle by a trusted source. Here the security risk
lies in how actually the source can be trusted.
[4],
[44]
RO Reverse Oracle A reverse oracle is a SC providing data to be read by off-chain
components for checking specific conditions.
[44]
RL Rate Limit Regulate how often a task can be executed within a period of time, to
limit the number of messages sent to a SC, and thus its computational
load.
[43]
BL Balance Limit Limit the maximum amount of funds held within a SC. [43]
GC Guard Check Ensure that all requirements on a SC state and on function inputs are
met.
[13]
TC Time Constraint A time constraint specifies when an action is permitted, depending on
the time registered in the block holding the transaction. It could be
also used in Speed Bump and Rate Limit patterns.
[4]
TE Termination Used when the life of a SC has come to an end. This can be done
by inserting ad-hoc code in the contract, or calling the selfdestruct
function. Usually, only the contract owner is authorized to terminate
a contract.
[4]
MH Math A logic which computes some critical operations, protecting from over-
flows, underflows or other undesired characteristics of finite arithmetic.
[4]
PR Privacy Encrypt on-chain critical data improving confidentiality and meeting
legal requirements, such as the European GDPR.
[44]
REU Reusability Use contract libraries and templates as a factory for creating multiple
instances.
[44]
MU Mutex A mutex is a mechanism to restrict concurrent access to a resource.
Utilize it to hinder an external call from re-entering its caller function
again.
[43]
SB Speed Bump Slow down contract sensitive tasks, so when malicious actions occur,
the damage is limited and more time to counteract is available. For
instance, limit the amount of money a user can withdraw per day, or
impose a delay before withdrawals.
[43]
8
TABLE II: Security assurance checklist for the design phase
Name Description Ref. Related patterns
Include fail-safe
mechanisms
It is important to have some way to update the contract in the
case some bugs will be discovered. Incorporate an emergency stop
functionality into the SC that can be triggered by an authenticated party
to disable sensitive functions. The fail-safe mechanism, if implemented
using the Proxy Delegate, could be also exploited for forwarding calls
and data to another contract, which is an updated version of the current
one (for instance, a version where the bug has been fixed).
[43] SB, RL, TE, PD,
OW
Never assume
that a contract
has zero balance
Be aware of coding an invariant that strictly checks the balance of a
contract. An attacker can forcibly send ether to any account and this
cannot be prevented.
[10] CEI, MH, GC
State Channel
/Off-chain
Support
In some contexts, transactions either have too high fee compared to
their value, or must have low latency. In these cases, rather than
performing each blockchain transaction, it is possible to firstly perform
the operations outside the blockchain, and then register all the results
batching the requests in a unique blockchain transaction.
[44], [33] RL
Limit the amount
of ether
If the code, the compiler or the platform has a bug, the funds stored in
your smart contract may be lost, so limit the maximum amount. Check
that all money transfers are performed through explicit withdrawals
made by the beneficiary.
[2] RL, BL, AU
Beware of trans-
action ordering
Miners have the power to alter the order of transactions arriving in
short times. Inconsistent transactions’ orders, with respect to the time
of invocations, can cause race conditions.
[35] TC
Be careful
with multiple
inheritance
Solidity uses the "C3 linearization". This means that when a contract is
deployed, the compiler will linearize the inheritance from right to left.
Multiple overrides of a function in complex inheritance hierarchies
could potentially interact in tricky ways.
[10] PD, REU
Use trustworthy
dependencies
Use audited and trustworthy dependencies to existing SCs and ensure
that newly written code is minimized by using libraries.
[10] REU
Withdrawal from
Contracts /Pull
over Push
When you need to send Ethers or tokens to an address, don’t send
them directly. Instead, authorize the address’ owner to withdraw the
funds, and let s/he perform the job.
[39], [13] CEI
9
TABLE III: Security assurance checklist for the coding phase
Name Description Ref. Related patterns
Be careful
with external
calls
If possible, avoid them. When using low-level call functions make
sure to handle the possibility that the call will fail, by checking the
return value. Also, avoid combining multiple ether transfers in a single
transaction. Mark untrusted interactions: name the variables, methods,
and contract interfaces of the functions that call external contracts,
in a way that makes it clear that interacting with them is potentially
unsafe.
[10] CEI,
MU,
GC
Beware of re-
entrancy
Never write functions that could be called recursively, before the
first invocations is finished. This may cause destructive consequences.
Ensure state committed before an external call.
[2],
[10]
CEI,
MU
Embed
addresses
to grant
permissions
Make sure that critical methods can be invoked only by a specific set of
addresses, which belong to privileged users. For instance, each contract
has an owner and only this address can invoke certain methods, like
the method for updating the address of the owner of the contract.
[44] AU,
OW
Use hash se-
crets to grant
permissions
Sometimes you need to provide authorizations to some authorities
whose addresses are not known yet in the developing phase (for
instance, they are unknown authorities). Although the Embed per-
missions pattern can not be applied, hash secrets help providing user
permissions without specifying any address. First, generate a secret
key and, in the contract, provide permissions by requiring its hash.
Then, send (off-chain) the secret key to the authorities you want to
grant permissions.
[26],
[44]
AU
Use multi-
signature
Define a set of entities (or addresses) that can authorize an action and
require that only a subset of them is required to authorize the action.
[26],
[44]
AU,
OW
Avoid using
tx.origin for
authoriza-
tions
tx.origin is a global variable that returns the address of the message
sender. Do not use it as an authorization mechanism.
[31] AU
Encrypt
on-chain data
Encrypt blockchain data for improving confidentiality and privacy.
This is particularly important when actors are in competition.
[44] PR
Hash objects
for tracking
off-chain data
Large objects (such as videos) should not be embedded in the
blockchain, their hashes can be easily uploaded instead. Hashing
objects can be also applied to hide sensitive data in order to meet
specific legal requirements, such as the European GDPR.
[44] PR
Use platform
related stan-
dards
Use platform related standards, like the ERC (Ethereum Request
for Comment) standards, which are application-level blueprints and
conventions in the Ethereum ecosystem.
[44] REU
Prevent over-
flow and un-
derflow
If a balance reaches the maximum uint value it will circle back to
zero; similarly, if a uint is made to be less than zero, it will cause an
underflow and get set to its maximum value. One simple solution to
this issue is to use a library like SafeMath.sol by OpenZeppelin.
[35] MH,
GC,
REU,
BL
Beware of
rounding
errors
All integer divisions round down to the nearest integer. Check that
truncation does not produce unexpected behavior (locked funds, in-
correct results).
[10] MH,
GC,
REU
Validate
inputs to
external
and public
functions
Make sure the requirements are verified and check for arguments. Use
properly assert(),require() and revert() to check user inputs, SC state,
invariants.
[35],
[13]
GC
10
Prevent
unbounded
loops
When executing loops, the gas consumed increases with each iteration
until it hits the block’s gasLimit, stopping the execution. Accordingly,
plan the number of iterations you need to perform and establish a
maximum number. If you still need more iterations, divide computation
among distinct transactions.
[13],
[28]
RL,
BL,
TC,
TE
Provide
fallback
functions
The "fallback function" is called whenever a contract receive a
message which does not match any of the available functions, or
whenever it receives Ethers without any other data associated with the
transaction. Remember to mark it as payable, be sure it does not have
any arguments, has external visibility and does not return anything.
Moreover, keep it simple and if the fallback function is intended to
be used only for the purpose of logging received Ether, check that the
data is empty (i.e. require(msg.data.length == 0) ).
[10],
[35]
CEI,
MU,
GC
Check if
built-in
variables or
functions
were
overridden
It is possible to override built-in globals in Solidity. This allows SCs
to override the functionality of built-ins such as msg and revert().
Although this is intended, it can mislead users of a SC, so the whole
code of every SC called from the SC you are writing must be checked.
[10] GC
Use interface
type instead
of the address
for type safety
When a function takes a contract address as an argument, it is better
to pass an interface or contract type rather than a raw address. If the
function is called elsewhere within the source code, the compiler will
provide additional type safety guarantees.
[10] GC
Be careful
with
randomness
Random number generation in a deterministic system is very difficult.
Do not rely on pseudo-randomness for important mechanisms. Current
best solutions include hash-commit-reveal schemes (ie. one party
generates a number, publishes its hash to "commit" to the value, and
then reveals the value later), querying oracles, and RANDAO.
[4],
[21]
OR,
REU
Be careful
with
Timestamp
Be aware that the timestamp of a block can be manipulated by a
miner; all direct and indirect uses of timestamp should be analyzed
and verified. If the scale of your time-dependent event can vary by
30 seconds and maintain integrity, it is safe to use a timestamp. This
includes thing like ending of auctions, registration periods, etc. Do not
use the block.number property as a timestamp.
[35] TC
11
TABLE IV: Security assurance checklist for the testing and deployment phases
Name Description Ref.
Fix compiler
warnings
Take warnings seriously and fix them. Always use the latest version
of the compiler to be notified about all recently introduced warnings.
[39]
Lock programs to
specific compiler
version
Contracts should be deployed with the same compiler version and flags
that they have been tested with, so locking the version helps avoid the
risk of undiscovered bugs.
[10]
Enforce
invariants with
assert
An assert guard triggers when an assertion fails - for instance an
invariant property changing. You can verify it with a call to assert().
Assert guards should be combined with other techniques, such as
pausing the contract and allowing upgrades. (Otherwise, you may end
up stuck, with an assertion that is always failing.)
[10]
Develop unit test-
ing
Be sure to have a 100% text coverage and cover all critical edge cases
with unit tests. Do not deploy recently written code, especially if it
was written under tight deadline.
[10]
Use frameworks
for testing
When approaching smart contract testing, do not start from scratch
but use existing framework for contract testing.
[10]
Use test networks Before deploying the smart contract in the main network, try it in a
public test network or use a software for configuring a private local
network.
[10]
12
TABLE V: Other design patterns
Name Description Ref.
Publisher-
Subscriber
When a state change must trigger a computation in a different object,
implement a messaging infrastructure where the contracts that produce
messages (called publishers) can generate messages and the other
contracts (called subscribers) receive them. The pattern, also known
as Observer, reduces the overhead of constant information filtering.
[47]
Tokenisation Use tokens for transferring digital or physical services. Use standards,
such as ERC20 and ERC721.
[44]
X-confirmation In order to ensure that a transaction is confirmed (i.e. there is a low
probability that a fork happens), wait for new blocks to be added to the
blockchain. The amount of blocks depends on the adopted blockchain.
[44]
Contract Registry Often a smart contract needs to interact with other contracts which can
be updated over time. A contract registry maps each smart contract to
the address of its latest version. Accordingly, when invoking a smart
contract, the correct address should be retrieved from the registry.
[44]
Eternal storage /
Data Contract
Contract data and logic should be stored into separate contracts. In
this way, when the logic need to be updated (by using a new smart
contract), there is no need to migrate old data.
[44]
Abstract factory Sometimes, systems need to work with groups of related contracts,
for instance with contracts which represent various level user account.
In order to keep the system independent from the different contracts,
define an abstract contract for creating all the related contracts.
[47], [44],
[26]
13
REF ER EN CE S
[1] AN TON , K. , MA NI CO , J. , AND BI RD, J . Owasp proactive controls
for developers. Tech. rep., Open Web Application Security Project
(OWASP), 2018.
[2] ATZEI, N., BARTO LE TT I, M., AND CI MO LI, T. A survey of attacks on
ethereum smart contracts (sok). In Principles of Security and Trust
(2017), M. Maffei and M. Ryan, Eds., Springer Berlin Heidelberg,
pp. 164–186.
[3] ATZEI, N., B ARTO LE TT I, M ., L ANDE, S. , YO SH IDA , N. , AND
ZUNINO, R. Developing secure bitcoin contracts with bitml. In
Proceedings of the 2019 27th ACM Joint Meeting on European Software
Engineering Conference and Symposium on the Foundations of Software
Engineering (2019), pp. 1124–1128.
[4] BART OL ETT I, M ., AND PO MP IA NU , L. An empirical analysis of smart
contracts: platforms, applications, and design patterns. In Financial
Cryptography and Data Security. FC 2017. Lecture Notes in Computer
Science (2017), B. M. et al., Ed., Springer, Cham, pp. 494–509.
[5] BO SU , A., IQ BAL , A. , SH AH RI YAR, R., AND CH AK RA BOR TY, P.
Understanding the motivations, challenges and needs of blockchain
software developers: a survey. Empirical Software Engineering 24
(2019), 2636–2673.
[6] BR ENT, L ., J UR IS EV IC , A. , KONG, M. , LI U, E ., G AUT HI ER , F.,
GRA MO LI, V., H OL Z, R ., AND SC HO LZ , B. Vandal: A scalable
security analysis framework for smart contracts. arXiv preprint
arXiv:1809.03981 (2018).
[7] BUT ER IN , V., ET A L. A next-generation smart contract and decentral-
ized application platform. white paper 3, 37 (2014).
[8] CH AKR AB ORT Y, P., S HA HR IYAR , R. , I QBA L, A ., AND BO SU , A. Un-
derstanding the software development practices of blockchain projects:
A survey. In ESEM 2018, October 11–12, 2018, Oulu, Finland (2018),
ACM.
[9] CH EN, T., ZHU, Y., LI, Z., C HE N, J., LI, X. , LU O, X., L IN , X. , AND
ZHANGE, X. Understanding ethereum via graph analysis. In IEEE
INFOCOM 2018-IEEE conference on computer communications (2018),
IEEE, pp. 1484–1492.
[10] Consensys solidity best practices website, 2019.
url="https://consensys.github.io/smart-contract-best-practices/", last
accessed: November, 2019.
[11] DANNEN, C. Introducing Ethereum and Solidity. Springer, 2017.
[12] Embark website, 2020. url="https://framework.embarklabs.io/", last
accessed: August 7, 2020.
[13] Ethereum smart contract security best practices website,
2019. url="https://ethereum-contract-security-techniques-and-
tips.readthedocs.io/en/latest/", last accessed: November, 2019.
[14] Etherlime website, 2020. url="https://etherlime.gitbook.io/etherlime/",
last accessed: August 7, 2020.
[15] Etherscan. url="https://etherscan.io/", last accessed: July, 2020.
[16] FR ID GEN , G. , L OC KL, J ., RA DS ZUW IL L, S ., R IE GE R, A.,
SCH WE IZE R, A ., AND UR BAC H, N . A solution in search of a
problem: A method for the development of blockchain use cases. In
24th Americas Conference on Information Systems (AMCIS), New
Orleans, USA, August 2018 (2018).
[17] GA MM A, E., H ELM, R. , JOHNSON, R ., AND VL IS SI DE S, J. Design
Patterns: Elements of Reusable Object-Oriented Software. Addison-
Wesley Professional Boston, MA, 1994.
[18] Ganache website, 2020. url="https://www.trufflesuite.com/ganache", last
accessed: August 7, 2020.
[19] Goerli website, 2020. url="https://github.com/goerli/testnet", last ac-
cessed: August 7, 2020.
[20] HA RZ, D ., AND KNOT TEN BE LT, W. Towards safer smart contracts:
A survey of languages and verification methods. arXiv preprint
arXiv:1809.09805 (2018).
[21] HUA NG , Y., BI AN, Y., L I, R. , ZH AO, L ., AND SHI , P. Smart contract
security: A software lifecycle perspective. IEEE Access, 7 (2019).
[22] JU RG ELA IT IS , M. , D RUN GI LA S, V., CE PON IE NE , L. , BU TK IE NE, R .,
AND VAIC IU KY NAS , E. Modelling principles for blockchain-based
implementation of business or scientific processes. In Proceedings of
the International Conference on Information Technologies (2019), IVUS
2019, CEUR Workshop Proceedings, pp. 43–47.
[23] KA LRA , S. , GO EL , S. , DH AWAN, M ., AND SH AR MA , S. Zeus:
Analyzing safety of smart contracts. In NDSS (2018).
[24] LI, X ., J IA NG , P., CHEN , T., L UO , X. , AN D WEN , Q. A survey on the
security of blockchain systems. Future Generation Computer Systems
107 (2020), 841–853.
[25] LI U, J ., AND LI U, Z . A survey on security verification of blockchain
smart contracts. IEEE Access, 7 (2019).
[26] LI U, Y., L U, Q., XU, X. , ZH U, L ., AND YAO, H . Applying design
patterns in smart contracts. In International Conference on Blockchain
(2018), Springer, pp. 92–106.
[27] LU U, L ., C HU , D.-H., OLI CK EL , H. , SAXE NA, P., AND HO BO R, A.
Making smart contracts smarter. In Proceedings of the 2016 ACM
SIGSAC conference on computer and communications security (2016),
pp. 254–269.
[28] MA RCH ES I, L ., MA RCH ES I, M ., DE ST EFA NI S, G. , BA RA BI NO , G.,
AND TIGANO, D. Design patterns for gas optimization in ethereum.
In 2020 IEEE International Workshop on Blockchain Oriented Software
Engineering (IWBOSE) (2020), pp. 9–15.
[29] MAVR ID OU, A ., AND LAS ZK A, A . Designing secure ethereum smart
contracts: A finite state machine based approach. In International Con-
ference on Financial Cryptography and Data Security (2018), Springer,
pp. 523–540.
[30] MAVR ID OU, A ., LA SZ KA , A., STAC HT IA RI , E. , AND DU BEY, A.
Verisolid: Correct-by-design smart contracts for ethereum. In Interna-
tional Conference on Financial Cryptography and Data Security (2019),
Springer, pp. 446–465.
[31] ME NS E, A., AND FL ATSC HE R, M. Security vulnerabilities in ethereum
smart contracts. In Proceedings of the 20th International Conference on
Information Integration and Web-based Applications & Services (New
York, NY, USA, 2018), iiWAS2018, ACM, pp. 375–380.
[32] NAK AM OTO , S. Bitcoin: A peer-to-peer electronic cash system, 2008.
url="https://bitcoin.org/bitcoin.pdf", last accessed: August 15, 2019.
[33] PO DDA , A. S ., AND PO MP IA NU , L. An overview of blockchain-based
systems and smart contracts for digital coupons. In Proceedings - 2020
IEEE/ACM 3rd International Workshop on Emerging Trends in Software
Engineering for Blockchain, WETSEB 2020 (2020).
[34] PO RRU , S. , PIN NA, A ., MA RC HE SI , M. , AND TONE LL I, R . Blockchain-
oriented software engineering: challenges and new directions. In Pro-
ceedings of the 39th International Conference on Software Engineering
Companion (2017), IEEE Press, pp. 169–171.
[35] PR AI THE ES HA N, P., PA N, L., YU, J. , LI U, J ., AND DOSS , R. Security
analysis methods on ethereum smart contract vulnerabilities: A survey.
arXiv preprint arXiv:1908.08605 (2019).
[36] Proxy patterns, 2019. url="https://blog.openzeppelin.com/proxy-
patterns/", last accessed: November, 2019.
[37] Rinkeby website, 2020. url="https://www.rinkeby.io", last accessed:
August 7, 2020.
[38] Ropsten website, 2020. url="https://ropsten.etherscan.io/", last accessed:
August 7, 2020.
[39] Solidity website, 2019. url="https://solidity.readthedocs.io/en/v0.5.13/index.html",
last accessed: November, 2019.
[40] SZ ABO , N. Smart contracts: Formalizing and securing
relationships on public networks. First Monday 2 (1997).
url="https://ojphi.org/ojs/index.php/fm/article/view/548".
[41] Truffle website. url="https://www.trufflesuite.com/", last accessed: Au-
gust 7, 2020.
[42] WE SS LI NG , F., E HM KE , C. , HE SE NI US , M. , AND GRU HN , V. How
much blockchain do you need? towards a concept for building hybrid
dapp architectures. In WETSEB 2018-1st International Workshop on
Emerging Trends in Software Engineering for Blockchain (2018).
[43] WO HRE R, M ., AND ZDUN, U . Smart contracts: Security patterns in
the ethereum ecosystem and solidity. In Blockchain Oriented Software
Engineering (IWBOSE), 2018 International Workshop on (2018), IEEE,
pp. 2–8.
[44] XU, X ., PAU TAS SO , C., ZH U, L., LU, Q ., AND WE BE R, I. A pattern
collection for blockchain-based applications. In Proceedings of the 23rd
European Conference on Pattern Languages of Programs (2018), pp. 1–
20.
[45] XU, X ., W EB ER , I., AND STA PL ES , M. Architecture for Blockchain
Applications. Springer, 2019.
[46] XU, X ., W EB ER , I., STAP LE S, M ., Z HU , L. , BO SC H, J ., BAS S, L.,
PAUTAS S O, C. , AND RI MB A, P. A taxonomy of blockchain-based
systems for architecture design. In Software Architecture (ICSA), 2017
IEEE International Conference on (2017), IEEE, pp. 243–252.
[47] ZHANG, P., W HIT E, J., S CHMI DT, D . C. , AND LEN Z, G. Applying soft-
ware patterns to address interoperability in blockchain-based healthcare
apps. arXiv preprint arXiv:1706.03700 (2017).