1. Introduction
The smart contract has been applied in many scenarios [
1,
2,
3]. However, the security of a smart contract has always been a major issue. Smart contract vulnerability [
4] has been plagued by security incidents [
5,
6] due to two major issues. First, smart contract vulnerability detection, easily affected by in-built features, such as nested calls and complex data types, is more difficult than ordinary bytecodes, such as reentrancy and integer overflow. Second, deployed smart contracts are not allowed to be patched even if they are vulnerable, leading to the difficulties of anticipating possible states and environments that the code may encounter in the future. This provides an intriguing and practical question of how to present effective smart contract vulnerability detection.
A lot of efforts [
7] are made in order to prevent such vulnerabilities. Durieux et al. [
8] used nine kinds of automation tools to detect 428,337 vulnerable smart contracts and found that only 42% of vulnerabilities were detected. The existing methods can be roughly cast into two categories. One kind of work [
9] utilized classical program analysis to identify vulnerabilities, which can discover vulnerabilities before smart contracts are deployed and address security issues at the root. However, they fundamentally rely on several fixed expert rules, while the manually defined patterns bear the inherent risk of being error-prone and some complex patterns are non-trivial to be covered. Meanwhile, some deep vulnerabilities are hard to be triggered. Therefore, Zhang et al. [
10] proposed another kind of work detecting vulnerabilities in transactions, which solves this problem by detecting real transaction attacks. As shown in
Figure 1, however, this method ignores the data attribute, so it may miss data sensitivity vulnerabilities. Additionally, it needs to traverse the logic repeatedly, leading to detection inefficiency.
In this paper, we propose
TxMirror, an extendable and data-driven framework analyzing smart contract vulnerability by simulating transactions symmetrically. The key idea of our approach is to inspect customized EVM stack data in the process of the transactions in order to detect new smart contract vulnerabilities and attacks; in particular,
TxMirror is able to quickly detect data sensitive vulnerabilities by data index. In addition, because
TxMirror replays the transaction completely, this symmetry guarantees that
TxMirror and EVM have identical transaction results, which means
TxMirror has the potential to be designed as a new EVM. This design is inspired by
TxSpector [
10], which is a logic-driven program analysis tool on Ethereum transactions. The challenges of performing transaction analysis, however, are twofold: First, it is hard for us to accurately describe the dependencies between smart contract instructions through data indexing since the data storage structure is extremely cumbersome. Second, while a smart contract is executed, we can hardly judge to which data type that generated data belongs. Therefore, extracting and analyzing EVM stack data in transactions requires innovative approaches to improve performance.
TxMirror addresses these challenges as follows. On the one hand, our framework can figure out new vulnerabilities and attacks from the stack data of a customized virtual machine. On the other hand, its dependency between the stack data and logic relation can be stored in a new way, where the logic relation between the opcodes can be effectively collected for smart contract vulnerability detection. It is noted that few dynamic analysis tools can detect such data-sensitive vulnerabilities because of integer overflow through the data type of each variable at the bytecode level. Additionally, TxMirror supports the extension of some detection rules defined by users. To the best of our knowledge, TxMirror is the first extendable data-driven framework to perform smart contract vulnerability analysis.
In short, our contribution is as follows:
We propose TxMirror, the first data-driven framework of a customized virtual machine for inspecting stack data in transactions, instead of using classical program analysis techniques to identify vulnerabilities at the bytecode level.
Our framework speeds up smart contract vulnerability detection through a customized design of a virtual machine, which is apt to be applied to new Ethereum development.
TxMirror has the ability to detect some vulnerabilities more precisely, compared with other tools. In our experiments, TxMirror detects five kinds of attacks, including integer overflow, stack overflow, reentrancy attack, suicide attack, and exception disorder, and three vulnerabilities, including timestamp dependency, misuse of origin, and unchecked call.
2. Related Work
Tools for smart contracts. Most of these tools [
11,
12,
13,
14,
15,
16,
17,
18] are oriented to the smart contract itself, and the detection of vulnerabilities caused by smart contract interaction is weak. Symbolic execution [
19,
20,
21,
22,
23] is perhaps the most popular approach. Chang et al. [
24] proposed a method called
Scompile to automatically identify the key program path in the smart contract. Using static analysis technology [
25],
Securify [
17] detects vulnerability automatically, which is based on a decompiler that symbolically encodes the dependency graph, abstract interpretation, and compliance and violation pattern checks.
Vandal [
26] analyzes the smart contract bytecode, which is based on semantic logic relation conversion.
Slither [
27] customized an intermediate language SlitherIR and carried out all static analysis work at this level. Using formal verification [
28],
ZEUS [
29] compiles smart contracts written in high-level languages into a low-level intermediate language LLVM IR [
30], and checks the security by using the symbolic model and constrained Horn clauses [
31]. Bhargavan et al. [
32] proposed a smart contract analysis framework that translates Ethereum instructions into a type-dependent functional programming language. Permenev et al. [
33] developed a formal verification program
VERX that can prove the functional characteristics of an Ethereum smart contract. Fuzzing [
34,
35,
36] is another simple yet effective method. It generates random transaction data that can be called by the contract to expose the vulnerabilities. Additionally, the neural network is also applied to detect smart contract vulnerabilities. Zhang et al. [
37] and Liu et al. [
38] constructed contract graphs to train graph neural networks to detect vulnerabilities. In addition, Liu et al. [
39] also proposed combining deep learning and expert patterns to analyze the source code to detect vulnerabilities.
Tools for transactions. In recent years, new types of transaction-oriented tools have become a new trend in smart contract vulnerability detection.
Sereum [
40] realizes complex reentrancy vulnerability detection by using dynamic taint tracking and data-flow analysis.
ECFChecker [
41] is a dynamic monitor for effectively callback-free (ECF) Ethereum smart contract verification. Both tools focus on only one specific type of vulnerability detection. Zhang et al. proposed
TxSpector [
10], which replays historical transactions and records EVM bytecode-level traces to detect attacks. It mainly realizes the detection of reentrancy, unchecked call, and suicidal vulnerability, which our tool can also detect but uses different methods. They also leverage a datalog approach to detect vulnerabilities and allow users to specify customized rules. However, in order to save storage space and obtain more intuitive results, we do not use datalog. Perez et al. [
42] also performed bytecode-level transaction analysis to detect vulnerabilities; they proposed a datalog-based formulation for performing analysis over EVM execution traces. The comparison between
TxMirror and other tools in terms of detectable vulnerabilities is shown in
Table 1.
3. Design of TxMirror
Smart contracts themselves have the capability to call another account presenting on the Ethereum blockchain. A contract is vulnerable if it has been flagged by a static analysis tool as such, which means that some contracts may be vulnerable because of a false-positive. Similar to computer software, it is so difficult to estimate what fraction of discovered vulnerabilities are exploited in practice. In addition, some hidden vulnerabilities of a smart contract are difficult to be triggered, so code-based methods are unable to solve this question. Therefore, this paper proposes a transaction-based detection method to detect some vulnerabilities through users’ or attackers’ transactions.
TxMirror is a data-driven analysis tool that detects vulnerabilities and attacks. It contains a virtual machine to simulate transaction execution, similar to the execution of computer software, but they are not the same. The design of
TxMirror is shown in
Figure 2.
Input/Output: Transaction information from the blockchain is received by a transaction crawler, which includes transaction debug information, sender information, receiver information, etc. Usually, the crawler connects the Ethereum, and crawls the transaction from the Ethereum, using the remote procedure call (RPC) eth.get transaction and debug.trace transaction to obtain the transaction information.
Virtual Machine: The simulation machine imitates the virtual machine design, so it includes the opcode analyzer, the virtual data stack, the virtual call stack, and the registers. It is a design between the EVM and the computer bottom layer, which supports a new way of executing smart contracts. The simulation machine analyzes the information and executes the transaction with a special data and logic storage structure.
Detection Rules: There are detection rules set up in the analyzer. When the data information changes or some opcodes are executed, the analyzer will analyze the data and index the logic with the corresponding rules.
Analyzer: The analyzer checks all the data from the stack for detection. After the transaction is executed completely, the analyzer will generate a report to show whether any attacks have occurred or vulnerabilities have been detected.
After the transaction information is received, it will be sent to the virtual machine. The virtual machine will analyze the running process and simulate the transaction in a different way. During the simulating process, TxMirror judges the type of each data based on contextual logic. After the data is popped out of the stack, it will not be used anymore. In TxMirror, it contains not only a value but also other information, for instance, the data type and the related logic. This data will not be freed immediately but will be sent to the analyzer. The analyzer matches the data information and defined detection rules to discover attacks and vulnerabilities, which are written into the report.
4. Transaction Simulation
Although transaction-based vulnerability detection can find some attacks or vulnerabilities through the analysis of the transaction process, current works have a low detection efficiency and a high false positive detection rate. In order to simulate the transaction scenario triggered by the attack, and record all the data attributes and transaction changes in the process of the transactions, we designed a new storage structure and transaction simulation.
4.1. New Storage Structure
All opcodes [
43] can create or use data. Data attributes generated by smart contracts include data value size, data type, data dependency, data generation logic, etc. In
TxMirror, the data and code logic of a smart contract have been stored in a special data structure. All of the data values created during the execution are stored in the form of a tuple (
value,
size,
signed,
overflow,
creation,
father,
children,
codelist):
value: the data value.
size: the size of the byte of the data between 1 and 32.
signed: a bool variable representing whether the data is a signed number.
overflow: a bool variable indicating whether the data is out of range.
creation: records the opcode that creates the data.
father: a pointer to the father data that creates it.
children: a list that appends the pointer of the new data that it creates.
codelist:a list that records all the logic indexed by its father.
We initialized the
size as 32 and the
signed as 0 for each data value. When the execution of the smart contract is simulated,
TxMirror will predict the type of each data according to the context logic and judge whether the data overflows. When data is created by other data and its father is not popped out of the stack, the
father will point to the data that creates it and its father’s
children will record it. Obviously, the data will be stored in the form of a two-way-point forest, which is shown in
Figure 3. We have analyzed all the opcodes in smart contracts and found that only the
DUP opcodes can change the
father and
children. When data is created by other data, it will record the creation opcode and all of the opcodes in the
codelist of the data that creates it and stores them in its
codelist. After this, the new data indexes all the logic that occurred in the process of its creation. There is dependence between this logic because it creates data. It is worth noting that we just record the opcodes but ignore their order because the order has no influence on the detection. Additionally, if data inherits other data, their size is the maximum size of these data, and the new data is signed if one of them is signed.
There are several purposes for storing data in this way. Firstly, we can easily judge the type of each data in order to detect integer overflow. Secondly, we can analyze all the logical dependence through just one simulation. Thirdly, this storage structure can make the detection of attacks and vulnerabilities more convenient.
4.2. Transaction Process Simulation
TxMirror can execute a smart contract, and all the data are in the form shown in
Section 4.1. Because we collect the data from external regions and EVM memory, there is no need to simulate the EVM memory or storage slot. However, the data stack and the call stack are necessary. Additionally, when
TxMirror imitated, we set the
esp and
ebp registers to store the pointers pointing to the top and bottom of the data stack, so a new way is proposed by simulating the transaction execution of smart contracts.
4.2.1. Simulation Process
When a smart contract calls another smart contract, a new data stack will be constructed in the EVM, and the address of the called smart contract will be pushed into the call stack. However, in TxMirror, we reserve the call stack, but all the smart contracts use a common data stack. That is, no data stack will be constructed when a smart contract calls another. There are two registers storing pointers. One is named ebp, which stores a pointer pointing to the bottom of the data stack. The other is called esp and points to the top of the data stack. When TxMirror is initialized, −1 will be pushed into the data stack. When TxMirror begins to analyze a transaction, it will push the sender address and the callee address into the call stack. The sender must be an external account. It is worth noting that only the callee address will be pushed into the call stack in the EVM but we push two.
Furthermore, the opcodes in smart contracts are limited. Each opcode pushes data into the stack or pops data out of the stack.
TxMirror strictly meets the operation of all the opcodes in the EVM except call-related opcodes. In
Figure 4, we provide an example of a simulation including the
ADD,
CALL, and
RETURN opcodes. Before executing
ADD, there are n data in the data stack. After executing it, the Data
and Data
are popped out of the data stack and add up to Data
, which is pushed into the data stack. This process is the same as the operation of the
ADD opcode in the EVM except for changing
esp.
The call operation is different from the call-related opcodes in smart contracts but is similar to the call of functions in the computer. In the computer, when a function is called, it will first push the return address into the stack. Then, it will push the value of
ebp. Lastly, the value of
ebp will be changed into the value of
esp. After this operation, the stack will create a new stack space to run the function.
TxMirror is a little different from this process. As shown in
Figure 4, because we have simulated the call stack and we can obtain the next opcode pc after a smart contract returns, there is no need to push any return address into the data stack. Alternatively, because there are many different call-related opcodes and each needs a different amount of arguments, we push the number of arguments into the data stack in order to judge the different call methods. In particular, the
CALL opcode and
CALLCODE opcode need seven arguments. The
DELEGATECALL opcode and
STATICCALL need six arguments. The
CREATE2 opcode needs four arguments and the
CREATE opcode needs three arguments. Then, we push the value of
ebp and change
ebp into
esp. Lastly, the address of the called new smart contract is pushed into the call stack, which is stored in the second cell from the top of the data stack before calling.
The returning process is also shown in
Figure 4. When a smart contract returns, we need to destroy its stack space and pop an address at the top of the call stack. In order to achieve this, we need to change the value of
esp to the value of
ebp and pop all the data generated during the execution of the smart contract. Then, we pop the integer where
esp is pointing to
ebp. Next, we pop the integer at the top of the data stack, which means the number of arguments the call used. Lastly, we pop these arguments and push the returned data into the data stack. For the opcodes creating the smart contract, this is the address of the new smart contract. For the others, it is zero or one, which indicates whether the smart contract executes successfully.
The purpose of simulating the execution is to analyze the attributes of each data point and all of the logical dependence. Redesigning the calling and returning process aims to detect reentry attacks better, which is explained in
Section 5.2.
4.2.2. Data Type Judgment
The data type is an important criterion for judging smart contract vulnerability, such as the size, the sign, and so on. The data pushed into the EVM stack is divided into four types:
An unsigned number less than 32 bytes.
A signed number less than 32 bytes.
An unsigned 32-byte number.
A signed 32-byte number.
Because all the data are stored in the form of a forest, and each data is stored on a two-way-point tree, if we judge the type of one data point, we can ensure the type of all the data on the tree where the data is located. Then, we can change the type of all the data on the tree and ensure the range of the data can represent to check whether integer overflow happens in the data.
There are some opcodes that only aim at signed numbers. Examples are SIGNEXTEND, SDIV, and SMOD. If these opcodes are executed, all of the data on the tree must be signed. However, if a data point is not executed by these opcodes, we cannot confirm it as unsigned data. For example, SIGNEXTEND is used to extend the size of a signed integer to 32 bytes with the sign bit before a signed integer performs the calculations. However, each cell in the data stack is 32 bytes. For a type four integer, although it is signed, it will not be executed by the SIGNEXTEND opcode before it performs any calculations. So, we cannot distinguish type three and type four according to SIGNEXTEND. In this case, we default to data type three. If it is calculated as a negative number, it must be type four. In addition, if type three data is calculated with other signed data, we change them to type four too.
In addition to the data sign, the data size has to be considered, so the data type judgment rules are as follows:
There are 32 PUSH opcodes from PUSH1 to PUSH32 in smart contracts, which can help us confirm the size of the data. For example, if the data is pushed into the data stack by PUSH29, we can ensure that this data occupies 29 bytes.
The SIGNEXTEND opcode can help confirm not only the sign but also the size. There are two arguments for SIGNEXTEND. One is the data extended and the other is N-1, where N is the size of the data. For example, when two-byte data executes SIGNEXTEND, the top data in the data stack is one and the second is the data itself.
For the data coming from external regions, if it is not 32-byte, an AND opcode will be inserted to eliminate the unnecessary bits. One of the operation numbers is the origin data and the other is a constant p, where p is in the form of 16-1. N is the size of the data. For example, if data from the storage slot is 1 byte, the smart contract will insert AND value 0xFF to eliminate the high 31 bytes. Therefore, if the data is operated on by this, we can confirm its size.
When the type of data is confirmed or changed, we will verify whether integer overflow happens. If we find it overflows, the
overflow attribute will be changed into
True. However, the fact that the data’s
overflow attribute is
True does not mean that the transaction happens with integer overflow, which we will explain in
Section 5.1.
5. Detection Rules
In our work, we propose nine rules to detect five kinds of attacks, including integer overflow, reentrancy attack, stack overflow, suicide attack, and exception disorder, and three kinds of vulnerabilities, including timestamp dependence, misuse of origin, and unchecked call. For some of them, we provide the pseudocode.
5.1. Integer Overflow
The type of each data point limits its range. If the value of the data goes beyond the range it can represent, it overflows. Although there are
overflow attributes in each data point, the
True value does not mean the transaction happens with overflowing. It is related to the compilers. For example, in order to push
0xFFFFFF into the stack, some of the compilers use the
PUSH3 0xFFFFFF, but some use the opcodes in
Figure 5. Firstly, the EVM will push
0x3 and
0x100 into the stack. Then, it uses
EXP to perform the power calculation obtaining
0x1000000. Next, it pushes
0x1 and swaps the position of the two data. At last, it uses
SUB to obtain
0xFFFFFF. Although it seems cumbersome, when it pushes larger numbers, the size of the opcodes will be smaller. According to the rules of inheriting, because the size of
0x3 is one and
0x100 is two, the size of
0x1000000 is two, which happens with overflow. These data are compiled into the smart contract bytecode and the overflow is designed deliberately, which should not be judged as an overflow attack. Therefore, we need to exclude the internal data when checking integer overflow. Additionally, some solutions may be considered separately. For some early compilers, when data from external regions needs to be reduced to one, it does not use the
SUB opcode. It pushes zero and uses the
NOT opcode to obtain the biggest number in the smart contracts. Then, the data adds this biggest number to the happening overflow to reduce it to one. However, it is designed deliberately, so we need to exclude this solution too.
Algorithm 1 shows the pseudocode of checking integer overflow. We checked each data point that popped out of the data stack.
s1 represents the set of the opcodes that push external data into the stack. Among them,
SLOAD pushes the data from the storage slot.
CALLDATALOAD pushes the arguments from the user input and
MLOAD pushes the data returned from the other smart contracts.
s2 is the set containing calculating opcodes that may lead to integer overflow.
s is a set containing the indexed logic of the data. If
s ∩
s1 , it means this data is created by data from external regions. If
s ∩
s2 , it means this data is created by the data executing calculating opcodes. If the data is directly or indirectly from external regions and is executed by calculating opcodes, and if the value is beyond the range it can represent, we think the transaction involves integer overflow, which is judged in lines 5 to 9.
Algorithm 1 The rule of checking integer overflow |
- Input:
the data popped out of the data stack - Output:
if happening integer overflow - 1:
function CheckIO() - 2:
- 3:
- 4:
- 5:
if and then - 6:
if then - 7:
return - 8:
end if - 9:
end if - 10:
return - 11:
end function
|
5.2. Reentrancy Attack
Reentrancy attack has very typical characteristics. One of them is that, after calling a smart contract, it will be called again before it returns. Based on this, we propose two detection rules to detect reentrancy attacks. These are shown in Algorithms 2 and 3.
Algorithm 2 Rule 1 of checking reentrancy attack |
- Input:
the opcode and the call stack - Output:
if happening reentrancy attack - 1:
- 2:
function CheckRA1() - 3:
if opcode is calling a contract then - 4:
if called address in the then - 5:
- 6:
end if - 7:
end if - 8:
if and then - 9:
return - 10:
end if - 11:
return - 12:
end function
|
Algorithm 3 Rule 2 of checking reentrancy attack |
- 1:
function CheckRA2() - 2:
if opcode is calling a contract then - 3:
the number of stack space - 4:
each stack space in stack - 5:
- 6:
for to do - 7:
if then - 8:
if corresponding data’s logic in two space are all the same then - 9:
return - 10:
end if - 11:
end if - 12:
end for - 13:
end if - 14:
return - 15:
end function
|
Algorithm 2 shows the first rule for checking for a reentrancy attack. The Sign defined in line one is a global variable. If the opcode is calling a contract, such as CALL, DELEGATECALL, we check whether the new address of the contract is in the call stack. If it is in the call stack, it means the contract has been called and not returned, and we change the Sign to True. Then, if it executes SSTORE, which means the state variables change, we confirm that a reentrancy attack happened and return True.
Algorithm 3 shows the second rule of checking for a reentrancy attack. In this rule, we input the data stack and the opcodes. As we have mentioned, each contract will receive a new stack space, so the data stack in TxMirror is made up of many stack spaces, which can be ensured by esp and ebp. When the reentrancy attack happens, there must be two identical stack spaces. Based on this, the rule is also to monitor all the opcodes that are executing. If the opcode is calling a contract, before creating a new stack space, it divides the data stack into many stack spaces. The last stack space corresponds to the running contract, which is defined in line five. We compare the last stack space with each forward stack space. If the length of the two stack spaces is the same, we need to perform further inspection, as shown in lines 7 to 11. For each data in the last stack space, we compare the logic it indexes with the logic of the corresponding data in the other stack space. Note that we just compare the logic and do not compare the value of the data because the value of some data may not be the same, although they experience the same logic. An example is the data created by GAS. If the logic indexed by these data are all the same, there must be a reentrancy attack happening and the function returns True in line nine. Otherwise, it returns False. In order to check more precisely for a reentrancy attack, we push the number of the arguments and reserve them until returning.
5.3. Stack Overflow
There are only 1024 cells in the data stack for each smart contract. In general, the 1024 cells are enough for a smart contract. However, the attacker may push more than 1024 data points into the data stack to perform an attack. In the virtual hardware in TxMirror, we can obtain the length of the data stack by esp-ebp. Therefore, we can monitor the length of the stack all the time to check stack overflow.
5.4. Suicide Attack
We check whether a smart contract verifies the permission before destroying itself. This is shown in function AllowSuicide in Algorithm 4. The input arguments are the data popped out of the data stack and the opcode being executed. Because of the call of a smart contract, we provide each called contract a sign to mark whether it verifies the permission; this is stored in AllowSuicideList defined in line one. We initialize it with False because there is a smart contract running first. When calling a new smart contract, we initialize a new sign with False. When returning, the last sign in the list will be popped, which is shown in lines 11 to 16. Then, we monitor all the data out of the data stack too. s records the logic of the data. If JUMPI is executed, and the CALLER and EQ opcodes are indexed by the data, it means the permission has been verified. In that case, we change the last sign in AllowSuicideList to True to indicate that this smart contract can commit suicide.
Function CheckSA in Algorithm 4 provides the rule for checking for suicide attacks. It monitors the data and opcodes too. If the opcode is SELFDESTRUCT, we check the sign in the AllowSuicideList. If the last sign marking the contract is False, it means it has not verified the permission and a suicide attack happens. Then, it returns True; otherwise, it returns False.
Algorithm 4 The rule of checking suicide attack |
- Input:
the data popped out of the data stack and opcode - Output:
if happening suicide attack - 1:
- 2:
function CheckSA() - 3:
AllowSuicide() - 4:
if and then - 5:
return - 6:
end if - 7:
return - 8:
end function - 9:
- 10:
function AllowSuicide() - 11:
if opcode is calling a contract then - 12:
- 13:
end if - 14:
if opcode is returning a contract then - 15:
- 16:
end if - 17:
if then - 18:
- 19:
if in s and in s then - 20:
- 21:
end if - 22:
end if - 23:
end function
|
5.5. Exception Disorder
When the programmer designs a smart contract, the exception is easy to be ignored. When handling the exception, there may be some unexpected logic. The attackers may use this vulnerability to steal money. When we crawl the information from the blockchain, we can obtain the error information at the same time. In theory, after an exception happens, it is unallowable to change the state variables because the code has an error. If the attacker wants to steal money through this vulnerability, he must change the state variables after an exception happens. While simulating the transaction, if there are SSTORE opcodes after an exception happens, there must be an exception disorder and may be an attack.
Algorithm 5 provides the rule for checking for an exception disorder. The input is the exception sign in the transaction that we crawl, as well as the opcodes. There is a global variable
Sign to present whether an exception is happening. If an exception happens, the
Sign is changed into
True as shown in lines 3 to 5. When executing
SSTORE, it means the state variable is being changed and that, if an exception has happened, it must be an exception disorder and the function will return
True, which is shown in lines 6 to 8.
Algorithm 5 The rule of checking exception disorder |
- Input:
whether happening exceptions and the opcode - Output:
if happening exception disorder - 1:
- 2:
function CheckED() - 3:
if then - 4:
- 5:
end if - 6:
if and then - 7:
return - 8:
end if - 9:
return - 10:
end function
|
5.6. Timestamp Dependency
Some smart contracts depend on the timestamp. However, the miner could control the time of packing the transactions to control the timestamp. Then, the malicious miners could control some judging conditions depending on the timestamp to achieve some purposes. Therefore, if there are judging conditions that depend on the timestamp, there must be a timestamp dependence vulnerability in the smart contract.
Algorithm 6 shows the rule of checking for timestamp dependence. It inputs the data popped out of the data stack and the opcode, and outputs whether a timestamp dependence vulnerability exists.
s1 is the set of all the comparing opcodes.
s is the set of the logic of the data. When executing the
JUMPI, we monitor the data. If there is a
TIMESTAMP, while also comparing the opcodes in it at the same time, we can say that this transaction may be controlled by miners and that the smart contract demonstrates a timestamp dependence vulnerability.
Algorithm 6 The rule of checking timestamp dependence |
- Input:
the data popped out of the data stack and the opcode - Output:
if existing timestamp dependency - 1:
function CheckTD() - 2:
- 3:
- 4:
if then - 5:
if in s and then - 6:
return - 7:
end if - 8:
end if - 9:
return - 10:
end function
|
5.7. Misuse of Origin
The tx.origin could obtain the beginning account of a transaction, which corresponds to the ORIGIN opcode in the compilation level. In general, this opcode is used to verify the identity. However, due to the vulnerability of the design, some malicious smart contracts may induce a user to run it to obtain and pass the verification. While doing this, there must be more than two contracts in the call stack and happening verifying.
Algorithm 7 shows the rule for checking for the misuse of origin. It inputs the call stack, the data, and the opcode. Similar to Algorithm 6,
s1 is the set of all the comparing opcodes and
s is the set of the data logic. When executing
JUMPI, we verify whether
ORIGIN is in
s and if there are comparing opcodes. At the same time, we have to notice whether it is the first contract running in this transaction. Because we initialize the call stack with two addresses, if the length of the call stack is more than two, there must be a misuse of origin, although maybe it is not being attacked.
Algorithm 7 The rule of checking the misuse of origin |
- Input:
the call stack, the data, and the opcode - Output:
if existing the misuse of origin - 1:
function CheckMO() - 2:
- 3:
- 4:
if then - 5:
if in s and then - 6:
if then - 7:
return - 8:
end if - 9:
end if - 10:
end if - 11:
return - 12:
end function
|
5.8. Unchecked Call
When a smart contract returns, it will return a bool variable about whether the contract is executed successfully. We must verify this data to judge if it is continuing to be executed. However, the programmer may be too lazy to verify it and this causes a significant vulnerability.
Algorithm 8 shows the rule for checking for an unchecked call. There is a global variable
Unchecked defined in line one by zero, which represents the number of unchecked calls. When calling a new smart contract, the
Unchecked adds one. Then, it will check whether a call is checked by
WhetherCheck.
s1 is the set of call-related opcodes. If
JUMPI is executed, and its argument is created by the returned bool data, it means one of the calls is checked so
Unchecked reduces by one, which is shown in lines 18 to 22. After the simulation finishes, if the
Unchecked is not zero, it means there is at least one call not being checked, so it returns
True, which is shown in lines 7 to 11. Otherwise, it returns
False.
Algorithm 8 The rule of checking unchecked call |
- Input:
the data popped out of the data stack and the opcode - Output:
if unchecked call exists - 1:
- 2:
function CheckUC() - 3:
if is calling a contract then - 4:
- 5:
end if - 6:
WhetherCheck() - 7:
if the transaction is finished simulating then - 8:
if then - 9:
return - 10:
end if - 11:
end if - 12:
return - 13:
end function - 14:
- 15:
function WhetherCheck() - 16:
-
- 17:
- 18:
if then - 19:
if then - 20:
- 21:
end if - 22:
end if - 23:
end function
|
6. Experiments
6.1. Experiment Design
We performed our experiments with 4V 8GB CPU running on Ubuntu 20.04. We realized
TxMirror with Python 3.8 and used
Mythril [
21],
Vandal [
26],
TxSpector [
10], and the tool of Perez et al. [
42] to perform experiment comparison.
Mythril and
Vandal were used to check the vulnerabilities from the bytecode.
TxSpector and the tool of Perez are similar to ours and they were used to analyze the transactions to identify attacks and vulnerabilities. In addition to the crawler in
TxMirror, we also used eth.getCode to obtain the bytecode of the smart contract. We randomly crawled the transactions and the bytecodes of related smart contracts between the 2,000,000th and 2,400,000th blocks on Ethereum. We obtained 359,293 items of transaction information and 10,620 smart contract bytecodes. They took up 711 GB and were stored in a mobile hard drive. We did not store them in the database because it needed to modify the source code of Ethereum and other researchers or users may find it difficult to use
TxMirror.
In our experiment, we compared TxMirror with other tools in terms of checking results and efficiency. Firstly, we ran all of the tools again, including checking results and time consumed. While running TxMirror, in addition to collecting the hash of suspicious transactions, we also recorded the related smart contracts performing these transactions. Secondly, we summarized these results and counted the common results between TxMirror and other tools. In particular, we obtained the amount of common suspicious smart contracts flagged by Mythril and Vandal compared with TxMirror. We also counted the total of common suspicious transactions between TxMirror and other tools. Thirdly, we compared the time of these tools and verified the efficiency of TxMirror.
6.2. Result Analysis
There are integer overflow, reentrancy attacks, suicide attacks, timestamp dependence, misuse of origin, and unchecked call. The checked results of these tools are listed in
Table 2. From the table, it is found that it does not mean it suffers attacks if a smart contract contains some vulnerabilities.
6.2.1. Results of Integer Overflow
There were 6356 transactions flagged by
TxMirror, which was more than other tools. Compared with
Mythril, there were 310 smart contracts flagged by
Mythril, 80 of which were flagged by
TxMirror. The Perez tool checked 4828 transactions, of which 3658 were also flagged by
TxMirror, equal to 75.8% of the results using Perez. We next analyzed the transactions flagged by
TxMirror but unflagged by the Perez tool. We found that most of the different results came from extracting data from a storage slot. In order to save space, the data in a storage slot was stored compactly, which meant there may be more than one data point stored in a slot. Therefore, it may have cleared up some bits after extraction, which is when the overflow may have happened. We have excluded the situations mentioned in
Section 5.1, but some may have used
MUL opcode to clear extra bits [
44], where the real overflow may have suffered the same logic. If we excluded this situation,
TxMirror may have missed some real overflow. In order to check all the overflow, we allowed this false positive.
6.2.2. Results of Reentrancy Attack
All of the tools could check reentrancy.
TxMirror flagged 1587 transactions with a reentrancy attack.
Mythril checked 50 smart contracts and 7 were also checked by
TxMirror.
Vandal flagged 1918 smart contracts and 88 were also flagged by
TxMirror.
Mythril combines more checking methods and has more strict checking rules, so its results were far fewer than
Vandal.
TxSpector flagged 614 transactions and 97.9% of them were also flagged by
TxMirror because the rule of
TxSpector is similar to Algorithm 2 mentioned in
Section 5.2. Because there are two rules for reentrancy attack in
TxMirror, its results were far more than
TxSpector. We analyzed the transactions
TxMirror flagged that
TxSpector did not flag and found that most of the different results were from Algorithm 3. Although we did not check whether or not the state variables were changed in Algorithm 3, which indicates whether this kind of reentrancy attack has meanings or not, the smart contract was used to carry out transactions; if there is completely the same logic in a transaction, it is suspicious and needs to be checked artificially. The results of reentrancy attack using Perez’s tool were much greater than
TxMirror. Perez’s tool flagged 2139 transactions but only 918 were also flagged by
TxMirror, which amounted to only 42.9%. We analyzed them and found that the Perez tool had looser checking rules. Some smart contracts are called multiple times before returning but they do not change the state variables or experience the same logic; it also flags them as reentrancy attacks. However, we think Perez’s tool is the most justifiable in terms of security because it can check all of the reentrancy attacks.
6.2.3. Results of Suicide Attack
In
TxMirror, we checked 4 transactions with suicide attacks because they had not verified the identity before destroying the smart contracts.
Mythril checked 19 and 1 of them was flagged by
TxMirror.
Vandal checked 1007 and no smart contract was flagged by
TxMirror.
TxSpector flagged 2, both of which were flagged by
TxMirror. There were still 2 transactions flagged by
TxMirror but ignored by
TxSpector. In these transactions, an external account inputted an argument to compare with some data to verify identity. However, because the compared data was stored in the storage slot or bytecode and everyone could obtain it [
45], we did not think this verification was efficacious.
6.2.4. Results of Timestamp Dependence
We used only Mythril to check timestamp dependence. TxMirror flagged 14,899 transactions and Mythril flagged 53 smart contracts, 32 of which had the transactions flagged by TxMirror. In TxMirror, we did not allow timestamps to be compared with other data. In terms of high-level language, we did not allow timestamp as a judging condition. However, we analyzed the flagged transactions and found that, if a transaction needed a timestamp, it was most likely to compare with other data. Few transactions used timestamps to perform timing. However, because a malicious miner can control the time of packing a transaction, we think our checking results were reasonable.
6.2.5. Results of Misuse of Origin
TxMirror flagged 273 transactions while Mythril flagged 43 and Vandal flagged 110. No smart contract was flagged in common with Mythril and only 1 was flagged in the results of Vandal. The reason there was so large a difference is that it was difficult to trigger the origin vulnerability. However, TxSpector flagged 113 transactions, while no transaction was also flagged by TxMirror. We analyzed both of their results and found that TxSpector allowed the address generated by ORIGIN to be compared with other data but did not allow it to be stored as a state variable. In TxMirror, this address was allowed to be stored in a storage slot but could not be compared with other data. Clearly, TxMirror and TxSpector have completely converse rules to check the misuse of origin because we had a completely different comprehension for this vulnerability.
6.2.6. Results of Unchecked Call
TxMirror flagged 21,328 unchecked calls. This was the most among the tools.
Mythril flagged 171 smart contracts, 56 of which were also flagged by
TxMirror.
Vandal flagged 5801, of which 4026 were also flagged by
TxMirror.
TxSpector checked 17,115 transactions that had unchecked calls, 16,996 of which were also flagged by
TxMirror, which equaled 99.3% of the results of
TxSpector. However, there were 4332 transactions flagged by
TxMirror but ignored by
TxSpector. We analyzed them and found they transformed tokens to external accounts [
46]. Although transforming to external accounts did not execute smart contracts, it also returned a bool variable to represent whether or not this transaction was successful.
TxSpector may think these calls did not need to be checked, but we checked them because they had the risk of failure too.
6.3. Efficiency Analysis
Experiment time is listed in
Table 3.
Mythril and
Vandal analyzed 10,620 smart contracts.
TxSpector,
TxMirror, and Perez’s tool analyzed 357,293 transactions. The number of transactions was more than 30 times the number of smart contracts. However,
Mythril used almost 57 h to analyze the smart contracts, while
Vandal used less than 6 h. For the tools for checking transactions,
TxSpector uses 52 h, which was much more than
TxMirror and Perez’s tool. Perez’s tool used almost 20 h and
TxMirror used only 4.5 h. Because we had stored the data in a mobile hard drive, the tools used a lot of time to read the data into memory. In addition, the monitoring program may have affected efficiency. Therefore, we calculated the average time each tool needed to analyze data. From the table,
TxMirror was 0.48 s less than
TxSpector and 0.15 s less than Perez’s tool for each transaction. It is obvious that
TxMirror has better efficiency than other tools. In order to measure the real speed of
TxMirror, we selected 10,000 transactions randomly from our dataset and stored them locally. We used
TxMirror to analyze them directly, and it only used 21 s. That is,
TxMirror could analyze more than 400 transactions per second.
7. Discussion
Compared with traditional logic analysis methods, there are many advantages of TxMirror. Firstly, TxMirror is more efficient. Logic analysis methods store all of the logic until the analysis finishes. They can inquire about all of the logic at any time. However, they need to waste a lot of time inquiring about the logic to obtain the dependence among the opcodes. TxMirror is designed as a simulator to analyze transactions, which enables the related logic to be indexed by the data. Therefore, we can obtain the dependence among the opcodes easily, which makes TxMirror at least four times faster than other methods. Secondly, TxMirror has more accurate detection for certain attacks and vulnerabilities, for example, suicide attacks because TxMirror can analyze the attributes of all the data. Last but not least, TxMirror has a high application value. Other tools can just be run standalone. However, because TxMirror contains a virtual machine, it can be combined with Ethereum to detect smart contracts while running them with few influences on the transaction speed. When an attack or a vulnerability is detected, it can notify miners not to package this transaction to prevent economic losses, which is something that the other tools cannot achieve.
However, there are also some disadvantages when compared with other tools because TxMirror does not store all the logic dependence permanently. Firstly, we cannot provide separate APIs for each attack or vulnerability. If we provide separate APIs, it means we need to simulate the transactions one time for each attack or vulnerability, which wastes too much time. Secondly, this may lead to missing attacks and vulnerabilities. We proposed a complex algorithm to solve this problem, which makes realizing TxMirror difficult.
There is also a limitation in TxMirror. TxMirror can only detect the attacks and vulnerabilities triggered during the running process. If the attack happens before the smart contract starts to run, it will not be detected, for example, the short address attack. This is a common problem for detecting methods based on transactions.
8. Conclusions
This paper proposed a new data-driven analyzing framework for smart contract security. Through simulating the whole execution of transactions, the tool can dynamically analyze vulnerabilities in a hybrid of smart contract calling and detects attacks and vulnerabilities in terms of transactions. In this paper, our tool detected eight kinds of attacks and vulnerabilities by experimenting with some available smart contracts. Compared with other state-of-the-art tools, our conducted experiment showed that TxMirror detects more kinds of smart contract vulnerabilities, has higher accuracy for certain vulnerabilities, and uses less time. In the future, we will make more contributions to this topic.
Author Contributions
Conceptualization, Y.Z.; methodology, Y.Z.; Software, Y.Z.; validation, Y.Z.; formal analysis, Y.Z. and C.L.; investigation, Y.Z., Y.W. and C.L.; data curation, Y.Z., Y.W. and C.L.; writing—original draft, Y.Z.; writing—review and editing, R.Y. and Y.Z.; visualization, Y.Z. and Y.W.; supervision, R.Y.; project administration, R.Y.; funding acquisition, R.Y. All authors have read and agreed to the published version of the manuscript.
Funding
This research was funded by the National Science Foundation of China (NO. 42071431), the Key National Research and Development of China Plan (NO. 2020YFB1805400), and the Key Research and Development Plan of Hubei Province (No. 2020BAB101).
Data Availability Statement
The data presented in this study are not available, because they are applied in another project.
Conflicts of Interest
The authors declare no conflict of interest.
References
- Aldyaflah, I.M.; Wenbing, Z.; Himanshu, U.; Leonel, L. The Design and Implementation of a Secure Datastore Based on Ethereum Smart Contract. Appl. Sci. 2023, 13, 5282. [Google Scholar] [CrossRef]
- Chinnasamy, P.; Ashwag, A.; Mudassir, K.; Khan, M.; Raja, A.A.; Ajmeera, K.; Jyothi, C.B. Smart Contract-Enabled Secure Sharing of Health Data for a Mobile Cloud-Based E-Health System. Appl. Sci. 2023, 13, 3970. [Google Scholar] [CrossRef]
- Alanzi, H.; Mohammad, A. Towards Improving Privacy and Security of Identity Management Systems Using Blockchain Technology: A Systematic Review. Appl. Sci. 2022, 12, 12415. [Google Scholar] [CrossRef]
- Wood, G. Ethereum: A secure decentralised generalised transaction ledger. Ethereum Proj. Yellow Pap. 2014, 151, 1–32. [Google Scholar]
- Mehar, M.I.; Shier, C.L.; Giambattista, A.; Gong, E.; Fletcher, G.; Sanayhie, R.; Kim, H.M.; Laskowski, M. Understanding a revolutionary and flawed grand experiment in blockchain: The DAO attack. J. Cases Inf. Technol. 2019, 21, 19–32. [Google Scholar] [CrossRef] [Green Version]
- Etherscan: The BEC. 2018. Available online: https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d (accessed on 9 February 2018).
- Atzei, N.; Bartoletti, M.; Cimoli, T. A Survey of Attacks on Ethereum Smart Contracts (sok). In Proceedings of the International Conference on Principles of Security and Trust, Uppsala, Sweden, 22–29 April 2017; Springer: Berlin/Heidelberg, Germany, 2017; pp. 164–186. [Google Scholar]
- Durieux, T.; Ferreira, J.F.; Abreu, R.; Cruz, P. Empirical Review of Automated Analysis Tools on 47,587 Ethereum Smart Contracts. In Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering, Seoul, Republic of Korea, 27 June–19 July 2020; pp. 530–541. [Google Scholar]
- Tsankov, P.; Dan, A.; Drachsler-Cohen, D.; Gervais, A.; Buenzli, F.; Vechev, M. Securify: Practical Security Analysis of Smart Contracts. In Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security, Toronto, ON, Canada, 15–19 October 2018; pp. 67–82. [Google Scholar]
- Zhang, M.; Zhang, X.; Zhang, Y.; Lin, Z. TXSPECTOR Uncovering Attacks in Ethereum from Transactions. In Proceedings of the 29th USENIX Security Symposium (USENIX Security 20), Boston, MA, USA, 12–14 August 2020; pp. 2775–2792. [Google Scholar]
- Krupp, J.; Rossow, C. teEther Gnawing at Ethereum to Automatically Exploit Smart Contracts. In Proceedings of the 27th USENIX Security Symposium (USENIX Security 18), Baltimore, MD, USA, 15–17 August 2018; pp. 1317–1333. [Google Scholar]
- Chen, J.; Xia, X.; Lo, D.; Grundy, J.; Luo, X.; Chen, T. Defectchecker: Automated smart contract defect detection by analyzing evm bytecode. IEEE Trans. Softw. Eng. 2021, 48, 2189–2207. [Google Scholar] [CrossRef]
- So, S.; Lee, M.; Park, J.; Lee, H.; Oh, H. VeriSmart: A Highly Precise Safety Verifier for Ethereum Smart Contracts. In Proceedings of the 2020 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 18–21 May 2020; pp. 1678–1694. [Google Scholar]
- Tikhomirov, S.; Voskresenskaya, E.; Ivanitskiy, I.; Takhaviev, R.; Marchenko, E.; Alexandrov, Y. Smartcheck: Static Analysis of Ethereum Smart Contracts. In Proceedings of the 1st International Workshop on Emerging Trends in Software Engineering for Blockchain, Gothenburg, Sweden, 27 May 2018; pp. 9–16. [Google Scholar]
- Hildenbrandt, E.; Saxena, M.; Rodrigues, N.; Zhu, X.; Daian, P.; Guth, D.; Moore, B.; Park, D.; Zhang, Y.; Stefanescu, A.; et al. Kevm: A Complete Formal Semantics of the Ethereum Virtual Machine. In Proceedings of the 2018 IEEE 31st Computer Security Foundations Symposium (CSF), Oxford, UK, 9–12 July 2018; pp. 204–217. [Google Scholar]
- Schneidewind, C.; Grishchenko, I.; Scherer, M.; Maffei, M. ethor: Practical and Provably Sound Static Analysis of Ethereum Smart Contracts. In Proceedings of the2020 ACM SIGSAC Conference on Computer and Communications Security, Online, 9–13 November 2020; pp. 621–640. [Google Scholar]
- Grieco, G.; Song, W.; Cygan, A.; Feist, J.; Groce, A. Echidna: Effective, Usable, and Fast Fuzzing for Smart Contracts. In Proceedings of the ISSTA 2020—Proceedings of the 29th ACM SIGSOFT International Symposium on Software Testing and Analysis, Online, 18–22 July 2020; pp. 557–560. [Google Scholar]
- Torres, C.F.; Iannillo, A.K.; Gervais, A.; State, R. ConFuzzius: A Data Dependency-Aware Hybrid Fuzzer for Smart Contracts. In Proceedings of the 2021 IEEE European Symposium on Security and Privacy (EuroS&P), Vienna, Austria, 6–10 September 2021; pp. 103–119. [Google Scholar]
- Baldoni, R.; Coppa, E.; D’elia, D.C.; Demetrescu, C.; Finocchi, I. A survey of symbolic execution techniques. ACM Comput. Surv. 2018, 51, 50. [Google Scholar] [CrossRef] [Green Version]
- Luu, L.; Chu, D.H.; Olickel, H.; Saxena, P.; Hobor, A. Making Smart Contracts Smarter. In Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, Vienna, Austria, 24–28 October 2016; pp. 254–269. [Google Scholar]
- Mythril: A Security Analysis Tool for EVM Bytecode. Available online: https://github.com/ConsenSys/mythril (accessed on 1 January 2021).
- Mossberg, M.; Manzano, F.; Hennenfent, E.; Groce, A.; Grieco, G.; Feist, J.; Brunson, T.; Dinaburg, A. Manticore: A User-Friendly Symbolic Execution Framework for Binaries and Smart Contracts. In Proceedings of the 2019 34th IEEE/ACM International Conference on Automated Software Engineering (ASE), San Diego, CA, USA, 11–15 November 2019; pp. 1186–1189. [Google Scholar]
- So, S.; Hong, S.; Oh, H. SmarTest Effectively Hunting Vulnerable Transaction Sequences in Smart Contracts through Language Model—Guided Symbolic Execution. In Proceedings of the 30th USENIX Security Symposium (USENIX Security 21), Vancouver, BC, Canada, 11–13 August 2021; pp. 1361–1378. [Google Scholar]
- Chang, J.; Gao, B.; Xiao, H.; Sun, J.; Cai, Y.; Yang, Z. sCompile: Critical Path Identification and Analysis for Smart Contracts. In International Conference on Formal Engineering Methods; Springer: Berlin/Heidelberg, Germany, 2019; pp. 286–304. [Google Scholar]
- Zhou, E.; Hua, S.; Pi, B.; Sun, J.; Nomura, Y.; Yamashita, K.; Kurihara, H. Security Assurance for Smart Contract. In Proceedings of the 2018 9th IFIP International Conference on New Technologies, Mobility and Security (NTMS), Paris, France, 26–28 February 2018; pp. 1–5. [Google Scholar]
- 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 2018, arXiv:1809.03981. [Google Scholar]
- Feist, J.; Grieco, G.; Groce, A. Slither: A Static Analysis Framework for Smart Contracts. In Proceedings of the 2019 IEEE/ACM 2nd International Workshop on Emerging Trends in Software Engineering for Blockchain (WETSEB), Montreal, QC, Canada, 27 May 2019; pp. 8–15. [Google Scholar]
- Park, D.; Zhang, Y.; Saxena, M.; Daian, P.; Roşu, G. A Formal Verification Tool for Ethereum VM Bytecode. In Proceedings of the 2018 26th ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering, Lake Buena Vista, FL, USA, 4–9 November 2018; pp. 912–915. [Google Scholar]
- Kalra, S.; Goel, S.; Dhawan, M.; Sharma, S. Zeus: Analyzing Safety of Smart Contracts. In Proceedings of the 25th Annual Network and Distributed System Security Symposium (NDSS 2018), San Diego, CA, USA, 18–21 February 2018; pp. 1–12. [Google Scholar]
- Lattner, C.; Adve, V. LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation. In Proceedings of the International Symposium on Code Generation and Optimization, San Jose, CA, USA, 20–24 March 2004; pp. 75–86. [Google Scholar]
- McMillan, K.L. Interpolants and Symbolic Model Checking. In International Workshop on Verification, Model Checking, and Abstract Interpretation; Springer: Berlin/Heidelberg, Germany, 2007; pp. 89–90. [Google Scholar]
- Bhargavan, K.; Delignat-Lavaud, A.; Fournet, C.; Gollamudi, A.; Gonthier, G.; Kobeissi, N.; Kulatova, N.; Rastogi, A.; Sibut-Pinote, T.; Swamy, N.; et al. Formal Verification of Smart Contracts: Short Paper. In Proceedings of the 2016 ACM Workshop on Programming Languages and Analysis for Security, Vienna, Austria, 24 October 2016; pp. 91–96. [Google Scholar]
- Permenev, A.; Dimitrov, D.; Tsankov, P.; Drachsler-Cohen, D.; Vechev, M. Verx: Safety Verification of Smart Contracts. In Proceedings of the 2020 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 18–21 May 2020; pp. 1661–1677. [Google Scholar]
- Jiang, B.; Liu, Y.; Chan, W.K. Contractfuzzer: Fuzzing Smart Contracts for Vulnerability Detection. In Proceedings of the 2018 33rd IEEE/ACM International Conference on Automated Software Engineering (ASE), Montpellier, France, 3–7 September 2018; pp. 259–269. [Google Scholar]
- He, J.; Balunović, M.; Ambroladze, N.; Tsankov, P.; Vechev, M. Learning to Fuzz from Symbolic Execution with Application to Smart Contracts. In Proceedings of the2019 ACM SIGSAC Conference on Computer and Communications Security, London, UK, 11–15 November 2019; pp. 531–548. [Google Scholar]
- Nguyen, T.D.; Pham, L.H.; Sun, J.; Lin, Y.; Minh, Q.T. sfuzz: An Efficient Adaptive Fuzzer for Solidity Smart Contracts. In Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering, Seoul, Reoublic of Korea, 27 June–19 July 2020; pp. 778–788. [Google Scholar]
- Zhuang, Y.; Liu, Z.; Qian, P.; Liu, Q.; Wang, X.; He, Q. Smart Contract Vulnerability Detection Using Graph Neural Network. In Proceedings of the Twenty-Ninth International Joint Conference on Artificial Intelligence, Yokohama, Japan, 11–17 July 2020; pp. 3283–3290. [Google Scholar]
- Liu, Z.; Qian, P.; Wang, X.; Zhuang, Y.; Qiu, L.; Wang, X. Combining Graph Neural Networks With Expert Knowledge for Smart Contract Vulnerability Detection. IEEE Trans. Knowl. Data Eng. 2021, 35, 1296–1310. [Google Scholar] [CrossRef]
- Liu, Z.; Qian, P.; Wang, X.; Zhu, L.; He, Q.; Ji, S. Smart Contract Vulnerability Detection: From Pure Neural Network to Interpretable Graph Feature and Expert Pattern Fusion. arXiv 2021, arXiv:2106.09282. [Google Scholar]
- Rodler, M.; Li, W.; Karame, G.O.; Davi, L. Sereum: Protecting existing smart contracts against reentrancy attacks. arXiv 2018, arXiv:1812.05934. [Google Scholar]
- Grossman, S.; Abraham, I.; Golan-Gueta, G.; Michalevsky, Y.; Rinetzky, N.; Sagiv, M.; Zohar, Y. Online detection of effectively callback free objects with applications to smart contracts. Proc. ACM Program. Lang. 2017, 2, 48. [Google Scholar] [CrossRef] [Green Version]
- Perez, D.; Livshits, B. Smart Contract Vulnerabilities: Vulnerable Does Not Imply Exploited. In Proceedings of the 30th USENIX Security Symposium (USENIX Security 21), Vancouver, BC, Canada, 11–13 August 2021; pp. 1325–1341. [Google Scholar]
- Ethereum Virtual Machine Opcodes. Available online: https://ethervm.io (accessed on 1 May 2023).
- A False Positive Example of Integer Overflow. Available online: https://etherscan.io/tx/0xe2d590c8b82058d8c6c32fbbfadd542fa29544f592287111b3f4dcabd6500f1f (accessed on 16 September 2016).
- An Example of Using Arguments to Verify to Suicide. Available online: https://etherscan.io/tx/0x08164923d4082fd70e4154404ebab0048d18a42460905c539521fba6af655257 (accessed on 14 September 2016).
- An Example of Unchecked Call Transferring ETHs to External Accounts. Available online: https://etherscan.io/tx/0x138586bd5ef4bd5bacad3d09f7f7c72f608a1f77ae99ea8fb238b2ea4facfd50 (accessed on 15 September 2016).
| Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content. |
© 2023 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (https://creativecommons.org/licenses/by/4.0/).