VeriSolid: Correct-by-Design Smart Contracts for Ethereum

01/04/2019
by   Anastasia Mavridou, et al.
0

The adoption of blockchain based distributed ledgers is growing fast due to their ability to provide reliability, integrity, and auditability without trusted entities. One of the key capabilities of these emerging platforms is the ability to create self-enforcing smart contracts. However, the development of smart contracts has proven to be error-prone in practice, and as a result, contracts deployed on public platforms are often riddled with security vulnerabilities. This issue is exacerbated by the design of these platforms, which forbids updating contract code and rolling back malicious transactions. In light of this, it is crucial to ensure that a smart contract is secure before deploying it and trusting it with significant amounts of cryptocurrency. To this end, we introduce the VeriSolid framework for the formal verification of contracts that are specified using a transition-system based model with rigorous operational semantics. Our model-based approach allows developers to reason about and verify contract behavior at a high level of abstraction. VeriSolid allows the generation of Solidity code from the verified models, which enables the correct-by-design development of smart contracts.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 1

page 2

page 3

page 4

11/26/2017

Designing Secure Ethereum Smart Contracts: A Finite State Machine Based Approach

The adoption of blockchain-based distributed computation platforms is gr...
01/13/2020

Formal specification of a security framework for smart contracts

As smart contracts are growing in size and complexity, it becomes harder...
05/15/2019

Smart Contract Development in Practice: Trends, Issues, and Discussions on Stack Overflow

Blockchain based platforms are emerging as a transformative technology t...
03/30/2020

SmartCert: Redesigning Digital Certificates with Smart Contracts

The Transport Layer Security (TLS) protocol and its public-key infrastru...
09/26/2018

Towards Safer Smart Contracts: A Survey of Languages and Verification Methods

With a market capitalisation of over USD 205 billion in just under ten y...
07/16/2018

Private Data Objects: an Overview

We present Private Data Objects (PDOs), a technology that enables mutual...
06/26/2019

Cryptocurrency Smart Contracts for Distributed Consensus of Public Randomness

Most modern electronic devices can produce a random number. However, it ...
This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

The adoption of blockchain based platforms is rising rapidly. Their popularity is explained by their ability to maintain a distributed public ledger, providing reliability, integrity, and auditability without a trusted entity. Early blockchain platforms, e.g., Bitcoin, focused solely on creating cryptocurrencies and payment systems. However, more recent platforms, e.g., Ethereum, also act as distributed computing platforms [50, 52] and enable the creation of smart contracts, i.e., software code that runs on the platform and automatically executes and enforces the terms of a contract [12]. Since smart contracts can perform any computation111While the virtual machine executing a contract may be Turing-complete, the amount of computation that it can perform is actually limited in practice., they allow the development of decentralized applications, whose execution is safeguarded by the security properties of the underlying platform. Due to their unique advantages, blockchain based platforms are envisioned to have a wide range of applications, ranging from financial to the Internet-of-Things [11].

However, the trustworthiness of the platform guarantees only that a smart contract is executed correctly, not that the code of the contract is correct. In fact, a large number of contracts deployed in practice suffer from software vulnerabilities, which are often introduced due to the semantic gap between the assumptions that contract writers make about the underlying execution semantics and the actual semantics of smart contracts [29]. A recent automated analysis of 19,336 contracts deployed on the public Ethereum blockchain found that 8,333 contracts suffered from at least one security issue [29]. While not all of these issues lead to security vulnerabilities, many of them enable stealing digital assets, such as cryptocurrencies. Smart-contract vulnerabilities have resulted in serious security incidents, such as the “DAO attack,” in which $50 million worth of cryptocurrency was stolen [16], and the 2017 hack of the multisignature Parity Wallet library [36], which lost $280 million worth of cryptocurrency.

The risk posed by smart-contract vulnerabilities is exacerbated by the typical design of blockchain based platforms, which does not allow the code of a contract to be updated (e.g., to fix a vulnerability) or a malicious transaction to be reverted. Developers may circumvent the immutability of code by separating the “backend” code of a contract into a library contract that is referenced and used by a “frontend” contract, and updating the backend code by deploying a new instance of the library and updating the reference held by the frontend. However, the mutability of contract terms introduces security and trust issues (e.g., there might be no guarantee that a mutable contract will enforce any of its original terms). In extreme circumstances, it is also possible to revert a transaction by performing a hard fork of the blockchain. However, a hard fork requires consensus among the stakeholders of the entire platform, undermines the trustworthiness of the entire platform, and may introduce security issues (e.g., replay attacks between the original and forked chains).

In light of this, it is crucial to ensure that a smart contract is secure before deploying it and trusting it with significant amounts of cryptocurrency. Three main approaches have been considered for securing smart contracts, including secure programming practices and patterns (e.g., Checks–Effects–Interactions pattern [47]), automated vulnerability-discovery tools (e.g., Oyente [29, 49]), and formal verification of correctness (e.g., [23, 19]). Following secure programming practices and using common patterns can decrease the occurrence of vulnerabilities. However, their effectiveness is limited for multiple reasons. First, they rely on a programmer following and implementing them, which is error prone due to human nature. Second, they can prevent a set of typical vulnerabilities, but they are not effective against vulnerabilities that are atypical or belong to types which have not been identified yet. Third, they cannot provide formal security and safety guarantees. Similarly, automated vulnerability-discovery tools consider generic properties that usually do not capture contract-specific requirements and thus, are effective in detecting typical errors but ineffective in detecting atypical vulnerabilities. These tools typically require security properties and patterns to be specified at a low level (usually bytecode) by security experts. Additionally, automated vulnerability-discovery tools are not precise; they often produce false positives.

On the contrary, formal verification tools are based on formal operational semantics and provide strong verification guarantees. They enable the formal specification and verification of properties and can detect both typical and atypical vulnerabilities that could lead to the violation of some security property. However, these tools are harder to automate.

Our approach falls in the category of formal verification tools, but it also provides an end-to-end design framework, which combined with a code generator, allows the correctness-by-design development of Ethereum smart contracts. We focus on providing usable tools for helping developers to eliminate errors early at design time by raising the abstraction level and employing graphical representations. Our approach does not produce false positives for safety properties and deadlock-freedom.

In principle, a contract vulnerability is a programming error that enables an attacker to use a contract in a way that was not intended by the developer. To detect vulnerabilities that do not fall into common types, developers must specify the intended behavior of a contract. Our framework enables developers to specify intended behavior in the form of liveness, deadlock-freedom, and safety properties, which capture important security concerns and vulnerabilities. One of the key advantages of our model-based verification approach is that it allows developers to specify desired properties with respect to high-level models instead of, e.g., bytecode. Our tool can then automatically verify whether the behavior of the contract satisfies these properties. If a contract does not satisfy some of these properties, our tool notifies the developers, explaining the execution sequence that leads to the property violation. The sequence can help the developer to identify and correct the design errors that lead to the erroneous behavior. Since the verification output provides guarantees to the developer regarding the actual execution semantics of the contract, it helps eliminating the semantic gap. Additionally, our verification and code generation approach fits smart contracts well because contract code cannot be updated after deployment. Thus, code generation needs to be performed only once before deployment.

Contributions

We build on the FSolidM [32, 33] framework, which provides a graphical editor for specifying Ethereum smart contracts as transitions systems and a Solidity code generator.222Solidity is the high-level language for developing Ethereum contracts. Solidity code can be compiled into bytecode, which can be executed on the Ethereum platform. We present the VeriSolid framework, which introduces formal verification capabilities, thereby providing an approach for correct-by-design development of smart contracts. Our contributions are:

  • We extend the syntax of FSolidM models (Definition 1), provide formal operational semantics (FSolidM has no formal operational semantics) for our model (Section 3.3) and for supported Solidity statements (Appendix 0.A.3), and extend the Solidity code generator (Appendix 0.E).

  • We design and implement developer-friendly natural-language like templates for specifying safety and liveness properties (Section 3.4). color=yellow!5,linecolor=black!50color=yellow!5,linecolor=black!50todo: color=yellow!5,linecolor=black!50Aron: Maybe state that we refer to the extended versions as VeriSolid to avoid the CCS’18 comment about self-plagarism.

  • The developer input of VeriSolid is a transition system, in which each transition action is specified using Solidity code. We provide an automatic transformation from the initial system into an augmented transition system, which extends the initial system with the control flow of the Solidity action of each transition (Section 4). We prove that the initial and augmented transition systems are observationally equivalent (Section 4.1); thus, the verified properties of the augmented model are also guaranteed in the initial model.

  • We use an overapproximation approach for the meaningful and efficient verification of smart-contract models (Section 5). We integrate verification tools (i.e., nuXmv and BIP) and present verification results.

2 VeriSolid: Design and Verification WorkFlow

VeriSolid is an open-source333https://github.com/anmavrid/smart-contracts and web-based framework that is built on top of WebGME [30] and FSolidM [32, 33]. VeriSolid allows the collaborative development of Ethereum contracts with built-in version control, which enables branching, merging, and history viewing. Figure 1 shows the steps of the VeriSolid design flow. Mandatory steps are represented by solid arrows, while optional steps are represented by dashed arrows. In step

1
, the developer input is given, which consists of:

  • A contract specification containing 1) a graphically specified transition system and 2) variable declarations, actions, and guards specified in Solidity.

  • A list of properties to be verified, which can be expressed using predefined natural-language like templates.

Figure 2 shows the web-based graphical editor of VeriSolid.

Figure 1: Design and verification workflow.
Figure 2: WebGME based graphical editor.

The verification loop starts at the next step. Optionally, step

2
is automatically executed if the verification of the specified properties requires the generation of an augmented contract model444We give the definition of an augmented smart contract in Section 4.. Next, in step

3
, the Behavior-Interaction-Priority (BIP) model of the contract (augmented or not) is automatically generated. Similarly, in step

4
, the specified properties are automatically translated to Computational Tree Logic (CTL). The model can then be verified for deadlock freedom or other properties using tools from the BIP tool-chain [6] or nuXmv [9] (step

5
). If the required properties are not satisfied by the model (depending on the output of the verification tools), the specification can be refined by the developer (step

6
) and analyzed anew. Finally, when the developers are satisfied with the design, i.e., all specified properties are satisfied, the equivalent Solidity code of the contract is automatically generated in step

7
. The following sections describe the steps from Figure 1 in detail. Due to space limitations, we present the Solidity code generation (step

7
) in Appendix 0.E.

3 Developer Input: Transition Systems and Properties

3.1 Smart Contracts as Transition Systems

To illustrate how to represent smart contracts as transition systems, we use the Blind Auction example from prior work [32], which is based on an example from the Solidity documentation [44].

In a blind auction, each bidder first makes a deposit and submits a blinded bid, which is a hash of its actual bid, and then reveals its actual bid after all bidders have committed to their bids. After revealing, each bid is considered valid if it is higher than the accompanying deposit, and the bidder with the highest valid bid is declared winner. A blind auction contract has four main states:

  1. AcceptingBlindedBids: bidders submit blinded bids and make deposits;

  2. RevealingBids: bidders reveal their actual bids by submitting them to the contract, and the contract checks for each bid that its hash is equal to the blinded bid and that it is less than or equal to the deposit made earlier;

  3. Finished: winning bidder (i.e., the bidder with the highest valid bid) withdraws the difference between her deposit and her bid; other bidders withdraw their entire deposits;

  4. Canceled: all bidders withdraw their deposits (without declaring a winner).

Figure 3: Blind auction example as a transition system.

This example illustrates that smart contracts have states (e.g., Finished). Further, contracts provide functions, which allow other entities (e.g., users or contracts) to invoke actions and change the states of the contracts. Hence, we can represent a smart contract naturally as a transition system [45], which comprises a set of states and a set of transitions between those states. Invoking a transition forces the contract to execute the action of the transition if the guard condition of the transition is satisfied. Since such states and transitions have intuitive meanings for developers, representing contracts as transition systems provides an adequate level of abstraction for reasoning about their behavior.

Figure 3 shows the blind auction example in the form of a transition system. For ease of presentation, we abbreviate AcceptingBlindedBids, RevealingBids, Finished, and Canceled to ABB, RB, F, and C, respectively. The initial state of the transition system is ABB. To differentiate between transition names and guards, we use square brackets for the latter. Each transition (e.g., close, withdraw) corresponds to an action that a user may perform during the auction. For example, a bidding user may execute transition reveal in state RB to reveal its blinded bid. As another example, a user may execute transition finish in state RB, which ends the revealing phase and declares the winner, if the guard condition now >= creationTime + 10 days is true. A user can submit a blinded bid using transition bid, close the bidding phase using transition close, and withdraw her deposit (minus her bid if she won) using transitions unbid and withdraw. Finally, the user who created the auction may cancel it using transitions cancelABB and cancelRB. For clarity of presentation, we omitted from Figure 3 the specific actions that the transitions take (e.g., transition bid executes—among others—the following statement: pendingReturns[msg.sender] += msg.value;).

3.2 Formal Definition of a Smart Contract

We formally define a contract as a transition system. To do that, we consider a subset of Solidity statements, which are described in detail in Appendix 0.A.1. We chose this subset of Solidity statements because it includes all the essential control structures: loops, selection, and return statements. Thus, it is a Turing-complete subset, and can be extended in a straightforward manner to capture all other Solidity statements. Our Solidity code notation is summarized in Table 1.

Symbol Meaning
set of Solidity types
set of valid Solidity identifiers
set of Solidity event and custom-type definitions
set of Solidity expressions
set of Solidity expressions without side effects
set of supported Solidity statements
Table 1: Summary of Notation for Solidity Code
Definition 1

A transition-system initial smart contract is a tuple , where

  • is a set of custom event and type definitions;

  • is a finite set of states;

  • is a set of final states;

  • , are the initial state and action;

  • is the fallback action;

  • contract variables (i.e., variable names and types);

  • is a transition relation, where each transition includes:

    • transition name ;

    • source state ;

    • parameter variables (i.e., arguments) ;

    • transition guard ;

    • return type ;

    • action ;

    • destination state .

The initial action represents the constructor of the smart contract. A contract can have at most one constructor. In the case that the initial action is empty (i.e., there is no constructor), may be omitted from the transition system. A constructor is graphically represented in VeriSolid as an incoming arrow to the initial state. The fallback action represents the fallback function of the contract. Similar to the constructor, a contract can have at most one fallback function. Solidity fallback functions are further discussed in Appendix 0.C.1.

3.2.1 Lack of the Re-entrancy Vulnerability

color=yellow!5,linecolor=black!50color=yellow!5,linecolor=black!50todo: color=yellow!5,linecolor=black!50Aron: Too much focus on reentrancy vulnerability considering how simplistic our solution is. Incorporate CCS response!

VeriSolid allows specifying contracts such that the re-entrancy vulnerability is prevented by design. In particular, after a transition begins but before the execution of the transition action, the contract changes its state to a temporary one (see Appendix 0.E). This prevents re-entrancy since none of the contract functions555Our framework implements transitions as functions, see Appendix 0.E. can be called in this state. One might question this design decision since re-entrancy is not always harmful. However, we consider that it can pose significant challenges for providing security. First, supporting re-entrancy substantially increases the complexity of verification. Our framework allows the efficient verification—within seconds—of a broad range of properties, which is essential for iterative development. Second, re-entrancy often leads to vulnerabilities since it significantly complicates contract behavior. We believe that prohibiting re-entrancy is a small price to pay for security.

3.3 Smart-Contract Operational Semantics

We define the operational semantics of our transition-system based smart contracts in the form of Structural Operational Semantics (SOS) rules [41]. We let denote the state of the ledger, which includes account balances, values of state variables in all contracts, number and timestamp of the last block, etc. During the execution of a transition, the execution state also includes the memory and stack state . To handle return statements and exceptions, we also introduce an execution status, which is when an exception has been raised, when a return statement has been executed with value (i.e., return ), and otherwise. Finally, we let signify that the evaluation of a Solidity expression Exp in execution state  yields value and—as a side effect—changes the execution state to  and the execution status to .666Note that the correctness of our transformations does not depend on the exact semantics of Eval.

A transition is triggered by providing a transition (i.e., function) and a list of parameter values . The normal execution of a transition without returning any value, which takes the ledger from state to and the contract from state to , is captured by the TRANSITION rule:

TRANSITION

This rule is applied if there exists a transition whose name is name and whose source state is the current contract state (first line). The execution state is initialized by taking the parameter values and the current ledger state (second line). If the guard condition evaluates in the current state to true (third line), then the action statement of the transition is executed (fourth line), which results in an updated execution state (see statement rules in Appendix 0.A.3). Finally, if the resulting execution status is normal (i.e., no exception was thrown), then the updated ledger state  and updated contract state (fifth line) are made permanent.

We also define SOS rules for all cases of erroneous transition execution (e.g., exception is raised during guard evaluation, transition is reverted, etc.) and for returning values. Due to space limitations, we include these rules in Appendix 0.A.2. We also define SOS rules for supported statements in Appendix 0.A.3.

3.4 Safety, Liveness, and Deadlock Freedom

A VeriSolid model is automatically verified for deadlock freedom. A developer may additionally verify safety and liveness properties. To facilitate the specification of properties, VeriSolid offers a set of predefined natural-language like templates, which correspond to properties in CTL. Alternatively, properties can be specified directly in CTL. Let us go through some of these predefined templates. Due to space limitations, the full template list, as well as the CTL property correspondence is provided in Appendix 0.B.

[boxsep=2pt,left=0pt,right=0pt,top=0pt,bottom=0pt] cannot happen after . The above template expresses a safety property type. Transitions is a subset of the transitions of the model (i.e., ). A statement from Statements is a specific inner statement from the action of a specific transition (i.e., ). For instance, we can specify the following safety properties for the Blind Auction example:

  • bid cannot happen after close.

  • cancelABB; cancelRB cannot happen after finish,

where cancelABB; cancelRB means cancelABB cancelRB.

[boxsep=2pt,left=0pt,right=0pt,top=0pt,bottom=0pt] If happens, can happen only after happens.

The above template expresses a safety property type. A typical vulnerability is that currency withdrawal functions, e.g., transfer, allow an attacker to withdraw currency again before updating her balance (similar to “The DAO” attack). To check this vulnerability type for the Blind Auction example, we can specify the following property. The statements in the action of transition withdraw are shown in Figure 4.

  • if withdraw.msg.sender.transfer(amount); happens,
    withdraw.msg.sender.transfer(amount); can happen only after
    withdraw.pendingReturns[msg.sender]=0; happens.

As shown in the example above, a statement is written in the following form: Transition.Statement to refer to a statement of a specific transition. If there are multiple identical statements in the same transition, then all of them are checked for the same property. color=yellow!5,linecolor=black!50color=yellow!5,linecolor=black!50todo: color=yellow!5,linecolor=black!50Aron: AFAIK this is incorrect, our tools does not do this. Should we talk about how to handle multiple identical statements within a transition? CCS reviewers asked.color=red!10,linecolor=black!50color=red!10,linecolor=black!50todo: color=red!10,linecolor=black!50Natassa

: Yeah, probably thats a good idea.

To verify properties with statements, we need to transform the input model into an augmented model, as presented in Section 4.

uint amount = pendingReturns[msg.sender];
if (amount > 0) {
  if (msg.sender!= highestBidder)
    msg.sender.transfer(amount);
  else
    msg.sender.transfer(amount - highestBid);
  pendingReturns[msg.sender] = 0;
}
Figure 4: Action of transition withdraw in Blind Auction, specified using Solidity.

[boxsep=2pt,left=0pt,right=0pt,top=0pt,bottom=0pt] will eventually happen after .

Finally, the above template expresses a liveness property type. For instance, with this template we can write the following liveness property for the Blind Auction example to check the Denial-of-Service vulnerability (Appendix 0.C.2):

  • withdraw.pendingReturns[msg.sender]=0; will eventually happen after withdraw.msg.sender.transfer(amount);.

4 Augmented Transition System Transformation

To verify a model with Solidity actions, we transform it to a functionally equivalent model that can be input into our verification tools. We perform two transformations: First, we replace the initial action and the fallback action with transitions. Second, we replace transitions that have complex statements as actions with a series of transitions that have only simple statements (i.e., variable declaration and expression statements). After these two transformations, the entire behavior of the contract is captured using only transitions. The transformation algorithms are discussed in detail in Appendices 0.D.1 and 0.D.2. The input of the transformation is a smart contract defined as a transition system (see Definition 1). The output of the transformation is an augmented smart contract:

Definition 2

An augmented contract is a tuple , where

  • is a set of custom event and type definitions;

  • is a finite set of states;

  • is a set of final states;

  • , is the initial state;

  • contract variables (i.e., variable names and types);

  • is a transition relation (i.e., transition name, source state, parameter variables, guard, return type, action, and destination state).

Figure 5: Augmented model of transition withdraw.

Figure 5 shows the augmented withdraw transition of the Blind Auction model. We present the complete augmented model in Appendix 0.F. The action of the original withdraw transition is shown by Figure 4. Notice the added state withdraw, which color=yellow!5,linecolor=black!50color=yellow!5,linecolor=black!50todo: color=yellow!5,linecolor=black!50Aron: ? avoids re-entrancy by design, as explained in Section 3.2.1.

4.1 Observational Equivalence

We study sufficient conditions for augmented models to be behaviorally equivalent to initial models. To do that, we use observational equivalence [34] by considering non-observable transitions. We denote by and the set of states of the smart contract transition system and its augmented derivative, respectively. We show that is a weak bi-simulation by considering as observable transitions , those that affect the ledger state, while the remaining transitions are considered non-observable transitions. According to this definition, the set of transitions in the smart contract system, which represent the execution semantics of a Solidity named function or the fallback, are all observable. On the other hand, the augmented system represents each Solidity function using paths of multiple transitions. We assume that final transition of each such path is an transition, while the rest are transitions. Our weak bi-simulation is based on the fact the effect of each on the ledger state is equal for the states of and . Therefore, if at the initial state of , then at the resulting state.

A weak simulation over and is a relation such that we have:

Property 1

For all and for each , such that , there is such that where

For each observable transition of a state in , it should be proved that (i) a path that consists of and other non-observable transitions exists in all its equivalent states in , and (ii) the resulting states are equivalent.

Property 2

For all and , such that , there is such that where .
For each observable outgoing transition in a state in , it should be proved that (i) there is an outgoing observable transition in all its equivalent states in , and (ii) the resulting states are equivalent.

Property 3

For all and such that ,
For each non observable transition, it should be proved that the the resulting state is equivalent with all the states that are equivalent with the initial state.

Theorem 4.1

For each initial smart contract and its corresponding augmented smart contract , it holds that .

The proof of Theorem 4.1 is presented in the Appendix 0.D.3.

5 Verification Process

Our verification approach checks whether contract behavior satisfies properties that are required by the developer. To check this, we must take into account the effect of data and time. However, smart contracts use environmental input as control data, e.g., in guards. Such input data can be infinite, leading to infinitely many possible contract states. Exploring every such state is highly inefficient [13] and hence, appropriate data and time abstractions must be employed.

We apply data abstraction to ignore variables that depend on (e.g., are updated by) environmental input. Thus, an overapproximation of the contract behavior is caused by the fact that transition guards with such variables are not evaluated; instead, both their values are assumed possible and state space exploration includes execution traces with and without each guarded transition. In essence, we analyze a more abstract model of the contract, with a set of reachable states and traces that is a superset of the set of states (respectively, traces) of the actual contract. As an example, let us consider the function in Figure 6.

void fn(int x) {
   if (x < 0) {
             (1)
   }
   if (x > 0) {
             (2)
   }
}
Figure 6: Code example for overapproximation.

An overapproximation of the function’s execution includes traces where both lines (1) and (2) are visited, even though they cannot both be satisfied by the same values of x. Note that abstraction is not necessary for variables that are independent of environment input (e.g. iteration counters of known range). These are updated in the model as they are calculated by contract statements.

We also apply abstraction to time variables (e.g. the now variable in the Blind Auction) using a slightly different approach. Although we need to know which transitions get invalidated as time increases, we do not represent the time spent in each state, as this time can be arbitrarily high. Therefore, for a time-guarded transition in the model, say from a state , one of the following applies:

  • if the guard is of type , checking that a time variable does not exceed a threshold, a loop transition is added to , with an action that invalidates the guard. A deadlock may be found in traces where this invalidating loop is executed (e.g., if no other transitions are offered in ).

  • if the guard is of type , checking that a time variable exceeds a threshold, an action =+1 is added to the guarded transition. This sets the time to the earliest point that next state can be reached (e.g., useful for checking bounded liveness properties.)

This overapproximation has the following implications.

Safety properties: Safety properties that are fulfilled in the abstract model are also guaranteed in the actual system. Each safety property checks the non-reachability of a set of erroneous states. If these states are unreachable in the abstract model, they will be unreachable in the concrete model, which contains a subset of the abstract model’s states. This property type is useful for checking vulnerabilities in currency withdrawal functions (e.g., the “DAO attack”).

Liveness properties: Liveness properties that are violated in the abstract model are also violated in the actual system. Each liveness property checks that a set of states are reachable. If they are found unreachable (i.e., liveness violation) in the abstract model, they will also be unreachable in the concrete model. This property type is useful for “Denial-of-Service” vulnerabilities (Appendix 0.C.2).

Deadlock freedom: States without enabled outgoing transitions are identified as deadlock states. If no deadlock states are reachable in the abstract model, they will not be reachable in the actual system.

5.1 VeriSolid-to-BIP Mapping

Since both VeriSolid and BIP model contract behavior as transition systems, the transformation is a simple mapping between the transitions, states, guards, and actions of VeriSolid to the transitions, states, guards, and actions of BIP (see Appendix 0.C.3 for background on BIP). Because this is an one-to-one mapping, we do not provide a proof. Our translation algorithm performs a single-pass syntax-directed parsing of the user’s VeriSolid input and collects values that are appended to the attributes list of the templates. Specifically, the following values are collected:

  • variables , where is the data type of and  is the variable name (i.e., identifier);

  • states ;

  • transitions , where is the transition (and corresponding port) name, and are the outgoing and incoming states, and are invocations to functions that implement the associated actions and guards.

end
Figure 7: BIP code generation template.

Figure 7 shows the BIP code template. We use fixed-width font for the generated output, and italic font for elements that are replaced with input.

Case Study Properties Type Result
BlindAuction (initial)
states: 54
(i) bid cannot happen after close:
    
Safety Verified
(ii) cancelABB or cancelRB cannot happen after finish:
   
Safety Verified
(iii) withdraw can happen only after finish:
    
Safety Verified
(iv) finish can happen only after close:
   
Safety Verified
BlindAuction (augmented)
states: 161
(v) 23 cannot happen after 18:
    
Safety Verified
(vi) if 21 happens, 21 can happen only after 24:
    
Safety Verified
DAO attack
states: 9
if call happens, call can happen only after subtract:
    
Safety Verified
King of Ether 1
states: 10
  
7 will eventually happen after 4:
    
Liveness Violated
King of Ether 2
states: 10
  
8 will eventually happen after fallback:
    
Liveness Violated
Table 2: Analyzed properties and verification results for the case study models.

5.2 Verification Results

Table 2 summarizes the properties and verification results. For ease of presentation, when properties include statements, we replace statements with the augmented-transition numbers that we have added to Figures 911, and 12 in Appendices 0.F.1 and 0.G.2. The number of states represents the reachable state space as evaluated by nuXmv.

5.2.1 Blind Auction

We analyzed both the initial and augmented models of the Blind Auction contract. On the initial model, we checked four safety properties (see Properties (i)–(iv) in Table 2). On the augmented model, which allows for more fine-grained analysis, we checked two additional safety properties. All properties were verified to hold. The models were found to be deadlock-free and their state space was evaluated to 54 and 161 states, respectively. The augmented model and generated code can be found in Appendix 0.F.

5.2.2 The DAO Attack

We modeled a simplified version of the DAO contract. Atzei et al. [2] discuss two different vulnerabilities exploited on DAO and present different attack scenarios. Our verified safety property (Table 2) excludes the possibility of both attacks. The augmented model can be found in Appendix 0.G.1.

5.2.3 King of the Ether Throne

For checking Denial-of-Service vulnerabilities, we created models of two versions of the King of the Ether contract [2], which are provided in Appendix 0.G.2. On “King of Ether 1,” we checked a liveness property stating that crowning (transition ) will happen at some time after the compensation calculation (transition ). The property is violated by the following counterexample: . A second liveness property, which states that the crowning will happen at some time after fallback fails in “King of Ether 2.” A counterexample of the property violation is the following: . Note that usually many counterexamples may exist for the same violation.

5.2.4 Resource Allocation

We have additionally verified a larger smart contract that acts as the core of a blockchain-based platform for transactive energy systems. The reachable state space, as evaluated by nuXmv, is . Properties were verified or shown to be violated within seconds. Due to space limitations, we present the verification results in Appendix 0.G.3.

6 Related Work

color=yellow!5,linecolor=black!50color=yellow!5,linecolor=black!50todo: color=yellow!5,linecolor=black!50Aron: Make sure that we do not say anything negative about any PC member’s paper!

Here, we present a brief overview of related work. We provide a more detailed discussion in Appendix 0.H.

Motivated by the large number of smart-contract vulnerabilities in practice, researchers have investigated and established taxonomies for common types of contract vulnerabilities [2, 29]. To find vulnerabilities in existing contracts, both verification and vulnerability discovery are considered in the literature [40]. In comparison, the main advantage of our model-based approach is that it allows developers to specify desired properties with respect to a high-level model instead of, e.g., EVM bytecode, and also provides verification results and counterexamples in a developer-friendly, easy to understand, high-level form. Further, our approach allows verifying whether a contract satisfies all desired security properties instead of detecting certain types of vulnerabilities; hence, it can detect atypical vulnerabilities.

Hirai performs a formal verification of a smart contract used by the Ethereum Name Service [22] and defines the complete instruction set of the Ethereum Virtual Machine (EVM) in Lem, a language that can be compiled for interactive theorem provers, which enables proving certain safety properties for existing contracts [23]. Bhargavan et al. outline a framework for verifying the safety and correctness of Ethereum contracts based on translating Solidity and EVM bytecode contracts into  [8]. Tsankov et al. introduce a security analyzer for Ethereum contracts, called Securify, which symbolically encodes the dependence graph of a contract in stratified Datalog [25] and then uses off-the-shelf solvers to check the satisfaction of properties [49]. Atzei et al. prove the well-formedness properties of the Bitcoin blockchain have also been proven using a formal model [3]. Techniques from runtime verification are used to detect and recover from violations at runtime [15, 14].

Luu et al. provide a tool called Oyente, which can analyze contracts and detect certain typical security vulnerabilities [29]. Building on Oyente, Albert et al. introduce the EthIR framework, which can produce a rule-based representation of bytecode, enabling the application of existing analysis to infer properties of the EVM codee [1]. Nikolic et al. present the MAIAN tool for detecting three types of vulnerable contracts, called prodigal, suicidal and greedy [37]

. Fröwis and Böhme define a heuristic indicator of control flow immutability to quantify the prevalence of contractual loopholes based on modifying the control flow of Ethereum contracts 

[18]. Brent et al. introduce a security analysis framework for Ethereum contracts, called Vandal, which converts EVM bytecode to semantic relations, which are then analyzed to detect vulnerabilities described in the Soufflé language [10]. Mueller presents Mythril, a security analysis tool for Ethereum smart contracts with a symbolic execution backend [35]. Stortz introduces Rattle, a static analysis framework for EVM bytecode [48].

Researchers also focus on providing formal operational semantics for EVM bytecode and Solidity language [21, 19, 20, 53, 26]. Common design patterns in Ethereum smart contracts are also identified and studied by multiple research efforts [5, 51]. Finally, to facilitate development, researchers have also introduced a functional smart-contract language [39], an approach for semi-automated translation of human-readable contract representations into computational equivalents [17], a logic-based smart-contract model [24].

7 Conclusion

We presented an end-to-end framework that allows the generation of correct-by-design contracts by performing a set of equivalent transformations. First, we generate an augmented transition system from an initial transition system, based on the operational semantics of supported Solidity statements (Appendix 0.A.3). We have proven that the two transition systems are observationally equivalent (Section 4.1). Second, we generate the BIP transition system from the augmented transition system through a direct one-to-one mapping. Third, we generate the NuSMV transition system from the BIP system (shown to be observationally equivalent in [38]). Finally, we generate functionally equivalent Solidity code, based on the operational semantics of the transition system (Appendix 0.A.2).

To the best of our knowledge, VeriSolid is the first framework to promote a model-based, correctness-by-design approach for blockchain-based smart contracts. Properties established at any step of the VeriSolid design flow are preserved in the resulting smart contracts, guaranteeing their correctness. VeriSolid fully automates the process of verification and code generation, while enhancing usability by providing easy-to-use graphical editors for the specification of transition systems and natural-like language templates for the specification of formal properties. By performing verification early at design time, we provide a cost-effective approach; fixing bugs later in the development process can be very expensive. Our verification approach can detect typical vulnerabilities, but it may also detect any violation of required properties. Since our tool applies verification at a high-level, it can provide meaningful feedback to the developer when a property is not satisfied, which would be much harder to do at bytecode level. Future work includes extending the approach to model and generate correct-by-design systems of interacting smart contracts.

References

  • [1] Albert, E., Gordillo, P., Livshits, B., Rubio, A., Sergey, I.: EthIR: A framework for high-level analysis of Ethereum bytecode. In: 16th International Symposium on Automated Technology for Verification and Analysis (ATVA) (2018)
  • [2] Atzei, N., Bartoletti, M., Cimoli, T.: A survey of attacks on Ethereum smart contracts (SoK). In: Proceedings of the 6th International Conference on Principles of Security and Trust (POST). pp. 164–186. Springer (April 2017)
  • [3] Atzei, N., Bartoletti, M., Lande, S., Zunino, R.: A formal model of Bitcoin transactions. In: Proceedings of the 22nd International Conference on Financial Cryptography and Data Security (FC) (2018)
  • [4] Baier, C., Katoen, J.P.: Principles of Model Checking (Representation and Mind Series). The MIT Press (2008)
  • [5] Bartoletti, M., Pompianu, L.: An empirical analysis of smart contracts: Platforms, applications, and design patterns. In: Proceedings of the 1st Workshop on Trusted Smart Contracts, in conjunction with the 21st International Conference of Financial Cryptography and Data Security (FC) (April 2017)
  • [6] Basu, A., Bensalem, B., Bozga, M., Combaz, J., Jaber, M., Nguyen, T.H., Sifakis, J.: Rigorous component-based system design using the bip framework. IEEE Software 28(3), 41–48 (2011)
  • [7] Basu, A., Gallien, M., Lesire, C., Nguyen, T.H., Bensalem, S., Ingrand, F., Sifakis, J.: Incremental component-based construction and verification of a robotic system. In: ECAI. vol. 178, pp. 631–635 (2008)
  • [8] Bhargavan, K., Delignat-Lavaud, A., Fournet, C., Gollamudi, A., Gonthier, G., Kobeissi, N., Rastogi, A., Sibut-Pinote, T., Swamy, N., Zanella-Béguelin, S.: Short paper: Formal verification of smart contracts. In: Proceedings of the 11th ACM Workshop on Programming Languages and Analysis for Security (PLAS), in conjunction with ACM CCS 2016. pp. 91–96 (October 2016)
  • [9] Bliudze, S., Cimatti, A., Jaber, M., Mover, S., Roveri, M., Saab, W., Wang, Q.: Formal verification of infinite-state BIP models. In: Proceedings of the 13th International Symposium on Automated Technology for Verification and Analysis (ATVA). pp. 326–343. Springer (2015)
  • [10] Brent, L., Jurisevic, A., Kong, M., Liu, E., Gauthier, F., Gramoli, V., Holz, R., Scholz, B.: Vandal: A scalable security analysis framework for smart contracts. arXiv preprint arXiv:1809.03981 (2018)
  • [11] Christidis, K., Devetsikiotis, M.: Blockchains and smart contracts for the internet of things. IEEE Access 4, 2292–2303 (2016)
  • [12] Clack, C.D., Bakshi, V.A., Braine, L.: Smart contract templates: Foundations, design landscape and research directions. arXiv preprint arXiv:1608.00771 (2016)
  • [13] Clarke, E.M., Grumberg, O., Long, D.E.: Model checking and abstraction. ACM Trans. Program. Lang. Syst. 16(5), 1512–1542 (Sep 1994)
  • [14] Colombo, C., Ellul, J., Pace, G.J.: Contracts over smart contracts: Recovering from violations dynamically. In: 8th International Symposium On Leveraging Applications of Formal Methods, Verification and Validation (ISOLA) (2018)
  • [15] Ellul, J., Pace, G.: Runtime verification of Ethereum smart contracts. In: Workshop on Blockchain Dependability (WBD), in conjunction with 14th European Dependable Computing Conference (EDCC) (2018)
  • [16] Finley, K.: A $50 million hack just showed that the DAO was all too human. Wired https://www.wired.com/2016/06/50-million-hack-just-showed-dao-human/ (June 2016)
  • [17] Frantz, C.K., Nowostawski, M.: From institutions to code: Towards automated generation of smart contracts. In: 1st IEEE International Workshops on Foundations and Applications of Self* Systems (FAS*W). pp. 210–215. IEEE (2016)
  • [18] Fröwis, M., Böhme, R.: In code we trust? In: International Workshop on Cryptocurrencies and Blockchain Technology (CBT). pp. 357–372. Springer (September 2017)
  • [19] Grishchenko, I., Maffei, M., Schneidewind, C.: A semantic framework for the security analysis of Ethereum smart contracts. In: 7th International Conference on Principles of Security and Trust (POST). pp. 243–269. Springer (2018)
  • [20] Grishchenko, I., Maffei, M., Schneidewind, C.: A semantic framework for the security analysis of Ethereum smart contracts – Technical report. Tech. rep., TU Wien (2018)
  • [21] Hildenbrandt, E., Saxena, M., Zhu, X., Rodrigues, N., Daian, P., Guth, D., Rosu, G.: KEVM: A complete semantics of the Ethereum virtual machine. Tech. rep., UIUC (2017)
  • [22] Hirai, Y.: Formal verification of deed contract in Ethereum name service. https://yoichihirai.com/deed.pdf (November 2016)
  • [23] Hirai, Y.: Defining the Ethereum Virtual Machine for interactive theorem provers. In: Proceedings of the 1st Workshop on Trusted Smart Contracts, in conjunction with the 21st International Conference of Financial Cryptography and Data Security (FC) (April 2017)
  • [24] Hu, J., Zhong, Y.: A method of logic-based smart contracts for blockchain system. In: Proceedings of the 4th International Conference on Data Processing and Applications (ICPDA). pp. 58–61. ACM (2018)
  • [25] Jeffrey, D.U.: Principles of database and knowledge-base systems (1989)
  • [26] Jiao, J., Kan, S., Lin, S.W., Sanan, D., Liu, Y., Sun, J.: Executable operational semantics of Solidity. arXiv preprint arXiv:1804.01295 (2018)
  • [27] K Team: K-framework. http://www.kframework.org/index.php/ (2017), accessed on 9/25/2018.
  • [28] Laszka, A., Eisele, S., Dubey, A., Karsai, G.: TRANSAX: A blockchain-based decentralized forward-trading energy exchange for transactive microgrids. In: Proceedings of the 24th IEEE International Conference on Parallel and Distributed Systems (ICPADS) (December 2018)
  • [29] Luu, L., Chu, D.H., Olickel, H., Saxena, P., Hobor, A.: Making smart contracts smarter. In: Proceedings of the 23rd ACM SIGSAC Conference on Computer and Communications Security (CCS). pp. 254–269. ACM (October 2016)
  • [30] Maróti, M., Kecskés, T., Kereskényi, R., Broll, B., Völgyesi, P., Jurácz, L., Levendovszky, T., Lédeczi, Á.: Next generation (meta) modeling: Web-and cloud-based collaborative tool infrastructure. In: Proceedings of the MPM@ MoDELS. pp. 41–60 (2014)
  • [31] Mavridou, A., Emmanouela, S., Bliudze, S., Ivanov, A., Katsaros, P., Sifakis, J.: Architecture-based design: A satellite on-board software case study. In: Proceedings of the 13th International Conference on Formal Aspects of Component Software (FACS). pp. 260–279 (October 2016)
  • [32] Mavridou, A., Laszka, A.: Designing secure Ethereum smart contracts: A finite state machine based approach. In: Proceedings of the 22nd International Conference on Financial Cryptography and Data Security (FC) (February 2018)
  • [33] Mavridou, A., Laszka, A.: Tool demonstration: FSolidM for designing secure Ethereum smart contracts. In: Proceedings of the 7th International Conference on Principles of Security and Trust (POST) (April 2018)
  • [34] Milner, R.: Communication and concurrency, vol. 84. Prentice hall New York etc. (1989)
  • [35] Mueller, B.: Smashing Ethereum smart contracts for fun and real profit. 9th Annual HITB Security Conference (HITBSecConf) (2018)
  • [36] Newman, L.H.: Security news this week: $280m worth of Ethereum is trapped thanks to a dumb bug. WIRED, https://www.wired.com/story/280m-worth-of-ethereum-is-trapped-for-a-pretty-dumb-reason/ (November 2017)
  • [37] Nikolic, I., Kolluri, A., Sergey, I., Saxena, P., Hobor, A.: Finding the greedy, prodigal, and suicidal contracts at scale. In: 34th Annual Computer Security Applications Conference (ACSAC) (2018)
  • [38] Noureddine, M., Jaber, M., Bliudze, S., Zaraket, F.A.: Reduction and abstraction techniques for bip. In: Proceedings of the International Workshop on Formal Aspects of Component Software. pp. 288–305. Springer (2014)
  • [39] O’Connor, R.: Simplicity: A new language for blockchains. In: Proceedings of the 2017 Workshop on Programming Languages and Analysis for Security. pp. 107–120. PLAS ’17, ACM, New York, NY, USA (2017). https://doi.org/10.1145/3139337.3139340, http://doi.acm.org/10.1145/3139337.3139340
  • [40] Parizi, R.M., Dehghantanha, A., Choo, K.K.R., Singh, A.: Empirical vulnerability analysis of automated smart contracts security testing on blockchains. In: 28th Annual International Conference on Computer Science and Software Engineering (CASCON) (2018)
  • [41] Plotkin, G.D.: A structural approach to operational semantics. Computer Science Department, Aarhus University, Denmark (1981)
  • [42] Said, N.B., Abdellatif, T., Bensalem, S., Bozga, M.: Model-driven information flow security for component-based systems. In: From Programs to Systems. The Systems perspective in Computing, pp. 1–20. Springer (2014)
  • [43] Sergey, I., Hobor, A.: A concurrent perspective on smart contracts. In: Proceedings of the International Conference on Financial Cryptography and Data Security (FC). pp. 478–493. Springer (2017)
  • [44] Solidity by Example: Blind auction. https://solidity.readthedocs.io/en/develop/solidity-by-example.html#blind-auction (2018), accessed on 9/25/2018.
  • [45] Solidity Documentation: Common patterns. http://solidity.readthedocs.io/en/develop/common-patterns.html#state-machine (2018), accessed on 9/25/2018.
  • [46] Solidity Documentation: Function calls. http://solidity.readthedocs.io/en/develop/control-structures.html#function-calls (2018), accessed on 9/25/2018.
  • [47] Solidity Documentation: Security considerations – use the Checks-Effects-Interactions pattern. http://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern (2018), accessed on 9/25/2018.
  • [48] Stortz, R.: Rattle – an Ethereum EVM binary analysis framework. REcon Montreal (2018)
  • [49] Tsankov, P., Dan, A., Cohen, D.D., Gervais, A., Buenzli, F., Vechev, M.: Securify: Practical security analysis of smart contracts. In: 25th ACM Conference on Computer and Communications Security (CCS) (2018)
  • [50] Underwood, S.: Blockchain beyond Bitcoin. Communications of the ACM 59(11), 15–17 (2016)
  • [51] Wöhrer, M., Zdun, U.: Design patterns for smart contracts in the ethereum ecosystem. In: Proceedings of the 2018 IEEE Conference on Blockchain. pp. 1513–1520 (2018)
  • [52] Wood, G.: Ethereum: A secure decentralised generalised transaction ledger. Tech. Rep. EIP-150, Ethereum Project – Yellow Paper (April 2014)
  • [53] Yang, Z., Lei, H.: Lolisa: Formal syntax and semantics for a subset of the solidity programming language. arXiv preprint arXiv:1803.09885 (2018)

Appendix 0.A Formalisms

0.a.1 Supported Solidity Subset

Here, we define the subset of Solidity that VeriSolid supports. First, let us introduce the following notation:

  • Let denote the set of Solidity types;

  • let denote the set of valid Solidity identifiers;

  • let denote the set of Solidity event and custom type definitions;

  • let denote the set of Solidity expressions;

  • let denote the set of Solidity expressions without side effects (i.e., expression whose evaluation does not change storage, memory, balances, etc.);

  • let denote the set of supported Solidity statements.

We define the set of supported event () and custom type () definitions as follows:

We let denote the set of Solidity expressions. We let denote the following subset of Solidity expressions, which do not have any side effects:

VeriSolid supports the following types of statements:

  • variable declarations (e.g., int32 value = 0; and address from = msg.sender;),

  • expressions (e.g., amount = balance[msg.sender];
    or msg.sender.transfer(amount);),

  • event statements (e.g., emit Deposit(amount, msg.sender);),

  • return statements (e.g., return; and return amount;),

  • if and ifelse selection statements (including ifelse if … and so on),

  • for and while loop statements,

  • compound statements (i.e., { statement1 statement2 ... }).

We define the formal grammar of the subset of supported Solidity statements as follows:

where is a primary Solidity expression, which may include function calls, transfers, etc., while is a Solidity expression without side effects.

0.a.2 Operational Semantics of the Transition System

We let denote the state of the ledger, which includes account balances, values of state variables in all contracts, number and timestamp of the last block, etc. During the execution of a transition, the execution state also includes the memory and stack state . To handle return statements and exceptions, we also introduce an execution status, which is equal to when an exception has been raised, when a return statement has been executed with value (i.e., return ), and otherwise. Finally, we let signify that the evaluation of a Solidity expression Exp in execution state  yields value and—as a side effect—changes the execution state to  and the execution status to .

A transition is triggered by providing a transition (i.e., function) and a list of parameter values . The normal execution of a transition without returning any value, which takes the ledger from state to and the contract from state to , is captured by the TRANSITION rule:

TRANSITION

This rule is applied if there exists a transition whose name is name and whose source state is the current contract state (first line). The execution state is initialized by taking the parameter values and the current ledger state (second line). If the guard condition evaluates in the current state to true without any exceptions (third line), then the action statement of the transition is executed (fourth line), which results in an updated execution state