The concept of blockchain has been introduced in 2009 with the release of Satoshi Nakamoto’s Bitcoin  and has greatly evolved since then. It is regarded as one of the most disruptive technologies since the invention of the Internet itself. In recent years, companies across the globe have poured value into blockchain research, examining how it can make their existing business more efficient and secure. A blockchain is essentially a verifiable, append-only list of records in which all transactions are recorded in so-called blocks. Every block is linked to its previous block via a cryptographic hash, thus forming a chain of blocks or a so-called “blockchain”. This list is maintained by a distributed peer-to-peer network of untrusted nodes, which follow a consensus protocol that dictates the appending of new blocks. Trust is obtained via the assumption that the majority acts faithfully and going against the protocol is too costly.
A broad range of different blockchain implementations have emerged since the inception of Bitcoin. However, all of these implementations pursue a common goal, namely, the decentralisation of control over a particular asset. Bitcoin’s asset is its cryptocurrency and the trusted centralised entities it attempts to decentralise are traditional banks. Modern blockchains such as Ethereum  aim to decentralise the computer as a whole through so-called smart contracts. Smart contracts are programs that are stored and executed across the Ethereum blockchain via the Ethereum Virtual Machine (EVM). The EVM is a purely stack-based virtual machine that supports a Turing-complete instruction set of opcodes. Smart contracts are deployed, invoked and removed from the blockchain via transactions. Each operation on the EVM costs a specified amount of gas. When the total amount of gas assigned to a transaction is exceeded, program execution is terminated and its effects are reversed. In contrast to traditional programs, smart contracts are immutable. Thus, programming mistakes that were never intended by the developer, become now irreversible. Developers usually write smart contract code in a high-level language which compiles into EVM bytecode. At the time of writing, Solidity  is the most prevalent high-level language for developing smart contracts in Ethereum.
In 2018, Ethereum reached a market capitalisation of over $133 billion . As it becomes more and more valuable, attackers become more and more incentivised to find and exploit vulnerable contracts. In fact, Ethereum already faced several devastating attacks on vulnerable smart contracts. The most prominent ones being the DAO hack in 2016  and the Parity Wallet hack in 2017 , together causing a loss of over $400 million. In response to these attacks, academia proposed a plethora of different tools that allow to scan contracts for vulnerabilities, prior to deploying them on the blockchain (see e.g. [20, 24, 37]). Unfortunately, these tools may also be used by attackers in order to easily find vulnerable contracts and exploit them. This potentially enables attackers to follow a reactive approach by actively scanning the blockchain for vulnerable contracts.
Alternatively, attackers could follow a more proactive approach by luring their victims into traps. In other words: Why should I spend time on looking for victims, if I can just let the victims come to me? This new type of fraud has been introduced by the community as “honeypots” (see e.g. [31, 32]). Honeypots are smart contracts that appear to have an obvious flaw in their design, which allows an arbitrary user to drain Ether (Ethereum’s cryptocurrency) from the contract, given that the user a priori transfers a certain amount of Ether to the contract. However, once the user tries to exploit this apparent vulnerability, a second, yet unknown, trapdoor unfolds which prevents the draining of Ether to succeed. The idea is that the user solely focuses on the apparent vulnerability and does not consider the possibility that a second vulnerability might be hidden in the contract. Similar to other types of fraud, honeypots work because human beings are often easily manipulated. People are not always capable of quantifying risk against their own greed and presumptions.
In this paper, we investigate the prevalence of such honeypot smart contracts in Ethereum. To the best of our knowledge this is the first work to provide an in depth analysis on the inner workings of this new type of fraud. Moreover, we introduce HoneyBadger – a tool that uses a combination of symbolic execution and precise heuristics to automatically detect various types of honeypots. Using HoneyBadger, we are able to provide interesting insights in the plethora, anatomy and popularity of honeypots that are currently deployed on the Ethereum blockchain. Finally, we investigate whether this type of scam is profitable and we discuss the effectiveness of such honeypots. In summary, we present the following main contributions:
We conduct the first systematic analysis of an emerging new type of fraud in Ethereum: honeypots.
We identify common techniques used by honeypots and organise them in a taxonomy.
We present HoneyBadger, a tool that automatically detects honeypots in Ethereum smart contracts.
We run HoneyBadger on 151,935 unique smart contracts and confirm the prevalence of at least 282 unique honeypots.
In this section, we provide the required background for understanding the setting of our work, including a description of smart contracts, the Ethereum virtual machine, and the Etherscan blockchain explorer.
2.1 Smart Contracts
2.2 Ethereum Virtual Machine
The Ethereum blockchain consists of a network of mutually distrusting nodes that together form a decentralised public ledger. This ledger allows users to create and invoke smart contracts by submitting transactions to the network. These transactions are processed by so-called miners. Miners execute smart contracts during the verification of blocks, using a dedicated virtual machine denoted as the Ethereum Virtual Machine (EVM) . The EVM is a stack-based, register-less virtual machine, running low-level bytecode, that is represented by an instruction set of opcodes. To guarantee termination of a contract and thus prevent miners to be stuck in endless loops of execution, the concept of gas has been introduced. It associates costs to the execution of every single instruction. When issuing a transaction, the sender has to specify the amount of gas that he or she is willing to pay to the miner for the execution of the smart contract. The execution of a smart contract results in a modification of the world state , a data structure stored on the blockchain mapping an address to an account state . The account state of a smart contract consists of two main parts: a balance, , that holds the amount of Ether owned by the contract, and a storage, , that holds the persistent data of the contract. Storage is organised as a key-value store and is the only way for a smart contract to retain state across executions. Besides the world state , the EVM also holds a transaction execution environment , which contains the address of the smart contract that is being executed , the transaction input data , the transaction sender and the transaction value . The EVM can essentially be seen as a transaction-based state machine, that takes as input and , and outputs a modified world state .
2.3 Etherscan Blockchain Explorer
Etherscan111https://etherscan.io/ is an online platform that collects and displays blockchain specific information. It acts as a blockchain navigator allowing users to easily lookup the contents of individual blocks, transactions and smart contracts on Ethereum. It offers multiple services on top of its exploring capabilities. One of these services is the possibility for smart contract creators to publish their source code and confirm that the bytecode stored under a specific address is the result of compilation of the specified source code. It also offers users the possibility to leave comments on smart contracts.
3 Ethereum Honeypots
In this section, we provide a general definition of a honeypot and introduce our taxonomy of honeypots.
Definition 1 (Honeypot)
A honeypot is a smart contract that pretends to leak its funds to an arbitrary user (victim), provided that the user sends additional funds to it. However, the funds provided by the user will be trapped and solely the honeypot creator (attacker) will be able to retrieve them.
Figure 1 depicts the different actors and phases of a honeypot. A honeypot generally operates in three phases:
The attacker deploys a vulnerable-looking contract and places a bait in the form of funds;
The victim attempts to exploit the contract by transferring at least the required amount of funds and fails;
The attacker withdraws the bait together with the funds that the victim lost in the attempt of exploitation.
An attacker does not require special capabilities to set up a honeypot. In fact, an attacker has the same capabilities as a regular Ethereum user. He or she solely requires the necessary funds to deploy the smart contract and place a bait.
3.2 Taxonomy of Honeypots
|Ethereum Virtual Machine||Balance Disorder|
|Solidity Compiler||Inheritance Disorder|
|Skip Empty String Literal|
|Type Deduction Overflow|
|Etherscan Blockchain Explorer||Hidden State Update|
|Straw Man Contract|
We grasped public sources available on the Internet, in order to have a first glimpse at the inner workings of honeypots [43, 21, 31, 30, 32]. We were able to collect a total of 24 honeypots (see Table 5 in Appendix A) and distill 8 different honeypot techniques. We organise the different techniques in a taxonomy (see Table 1), whose purpose is twofold: (i) as a reference for users in order to avoid common honeypots in Ethereum; (ii) as a guide for researchers to foster the development of methods for the detection of fraudulent smart contracts. We group the different techniques into three different classes, according to the level on which they operate:
Ethereum Virtual Machine
Etherscan Blockchain Explorer
The first class tricks users by making use of the unusual behaviour of the EVM. Although the EVM follows a strict and publicly known set of rules, users can still be misled or confused by devious smart contract implementations that suggest a non-conforming behaviour. The second class relates to honeypots that benefit from issues that are introduced by the Solidity compiler. While some compiler issues are well known, others still remain undocumented and might go unnoticed if a user does not analyse the smart contract in great detail or tests it under real-world conditions. The final and third class takes advantage of issues that are related to the limited information displayed on Etherscan’s website. Etherscan is perhaps the most prominent Ethereum blockchain explorer and many users fully trust the data displayed therein. In the following, we explain each honeypot technique through a simplified example. We also assume that: 1) the attacker has placed a bait in form of Ether into the smart contract, as an incentive for users to try to exploit the contract; 2) the attacker has a way of retrieving the amount of Ether contained in the honeypot.
3.2.1 Ethereum Virtual Machine
Every smart contract in Ethereum possesses a balance. The contract in Figure 2 depicts an example of a honeypot that makes use of a technique that we denote as balance disorder. The function multiplicate suggests that the balance of the contract (this.balance) and the value included in the transaction to this function call (msg.value) are transferred to an arbitrary address, if the caller of this function includes a value that is higher than or equal to the current balance of the smart contract. Hence, a naive user will believe that all that needs to be done, is to call this function with a value that is higher or equal to the current balance, and that in return he or she will obtain the “invested” value plus the balance contained in the contract. However, if a user tries to do so, he or she will quickly realise that line 5 did not get executed because the condition at line 4 did not hold. The reason for this is that the balance is already incremented with the transaction value, before the actual execution of the smart contract took place. It is worth noting that: 1) the condition at line 4 can be satisfied if the current balance of the contract is zero, but then the user would not have an incentive to loot the contract; 2) the addition this.balance+msg.value at line 5, solely serves the purpose of making the user believe that the balance is updated only after execution.
3.2.2 Solidity Compiler
Solidity supports inheritance via the is keyword. When a contract inherits from multiple contracts, only a single contract is created on the blockchain, and the code from all the base contracts is copied into the created contract. Figure 3 shows an example of a honeypot that makes use of a technique that we denote as inheritance disorder. At first glance, there seems nothing special about this code, we have a contract KingOfTheHill that inherits from the contract Ownable. We notice two things though: 1) the function takeAll solely allows the address stored in variable owner to withdraw the contract’s balance; 2) the owner variable can be modified by calling the fallback function with a message value that is greater than the current jackpot (line 12). Now, if a user tries to call the function in order to set themself as the owner, the transaction succeeds. However, if he or she afterwards tries to withdraw the balance, the transaction fails. The reason for this is that the variable owner, declared at line 9, is not the same as the variable that is declared at line 2. We would assume that the owner at line 9 would be overwritten by the one at line 2, but this is not the case. The Solidity compiler will treat the two variables as distinct variables and thus writing to owner in line 9 will not result in modifying the owner defined in the contract Ownable.
Skip Empty String Literal.
The contract illustrated in Figure 4 allows a user to place an investment by sending a minimum amount of ether to the contract’s function invest. Investors can withdraw their investment by calling the function divest. Now, if we have a closer look at the code, we realise that there is nothing that prohibits the investor from divesting an amount that is greater than the originally invested amount. Thus a naive user is led to believe that the function divest can be exploited. However, this contract contains a bug known as skip empty string literal222https://github.com/ethereum/solidity/blob/develop/docs/bugs.json. The empty string literal that is given as an argument to the function loggedTransfer (line 14), is skipped by the encoder of the Solidity compiler. This has the effect that the encoding of all arguments following this argument are shifted to the left by 32 bytes and thus the function call argument msg receives the value of target, whereas target receives the value of currentOwner, and finally currentOwner receives the default value zero. Thus, in the end the function loggedTransfer performs a transfer to currentOwner instead of target, essentially diverting all attempts to divest from the contract to transfers to the owner. A user trying to use the smart contract’s apparent vulnerability thereby effectively just transfers the investment to the contract owner.
Type Deduction Overflow.
In Solidity, when declaring a variable as type var, the compiler uses type deduction to automatically infer the smallest possible type from the first expression that is assigned to the variable. The contract in Figure 5 depicts an example of a honeypot that makes use of a technique that we denote as type deduction overflow. At first, the contract suggests that a user will be able to double the investment. However, since the type is only deduced from the first assignment, the loop at line 7 will be infinite. Variable i will have the type uint8 and the highest value of this type is 255, which is smaller than 2 * msg.value3332 * 0.1 Ether = 200000000000000000 Wei, and therefore never reaching the halting condition of the loop. Nevertheless, the loop can still be stopped, if the variable multi is smaller than amountToTransfer. This is possible, since amountToTransfer is assigned the value of multi, which eventually will be smaller than amountToTransfer due to an integer overflow happening at line 8, where i is multiplied by 2. Once the loop exits, the contract performs a value transfer back to the caller, although with an amount that will be at most 255 Wei (smallest sub-denomination of Ether, where 1 Ether Wei) and therefore far less than the value the user originally invested.
Solidity provides means to define new data types in the form of structs. They combine several named variables under one variable and are the basic foundation for more complex data structures in Solidity. An example of an uninitialised struct honeypot is given in Figure 6. In order to withdraw the contract’s balance, the contract requires a user to place a minimum bet and guess a random number that is stored in the contract. However, any user can easily obtain the value of the random number, since every data stored on the blockchain is publicly available. The first thought suggests that the contract creator simply made a common mistake by assuming that variables declared as private are secret. An innocent user simply reads the random number from the blockchain and calls the function guessNumber by placing a bet and providing the correct number. Afterwards, the contract creates a struct that seems to track the participation of the user. However, the struct is not properly initialised via the new keyword. As a result, the Solidity compiler maps the storage location of the first variable contained in the struct (player) to the storage location of the first variable contained in the contract (randomNumber), thereby overwriting the random number with the address of the caller and thus making the condition at line 14 fail. It is worth noting that the honeypot creator is aware that a user might try to guess the overwritten value. The creator therefore limits the number to be between 1 and 10 (line 10), which drastically reduces the chances of the user generating an address that fulfils this condition.
3.2.3 Etherscan Blockchain Explorer
Hidden State Update.
In addition to normal transactions, Etherscan also displays so-called internal messages, which are transactions that originate from other contracts and not from user accounts. However, for usability purposes, Etherscan does not display internal messages that include an empty transaction value. The contract in Figure 7 is an example of a honeypot technique that we denote as hidden state update. In this example, the balance is transferred to whoever can guess the correct value that has been used to compute the stored hash. A naive user tries to call the unprotected SetPass function, which is believed to allow the rewriting the hash with a known value, given that least 1 ether is transferred to the contract and assuming that passHasBeenSet is set to false. When analysing the internal messages on Etherscan, the user will not find any evidence of a call to the PassHasBeenSet function and therefore assume that passHasBeenSet is set to false. However, the filtering performed by Etherscan can be misused by the honeypot creator in order to silently update the state of the variable passHasBeenSet, by calling the function PassHasBeenSet from another contract and using an empty transaction value. Thus, by just looking at the internal messages displayed on Etherscan, unaware users will believe that the variable is set to false and confidently transfer ether to the SetPass function.
Etherscan provides a web interface that displays the source code of a validated smart contract. Validated means that the provided source code has successfully been compiled to the associated bytecode. For quite a while, Etherscan presented the source code within an HTML textarea element, where larger lines of code would only be displayed up to a certain width. Thus, the rest of the line of code would be hidden and solely visible by scrolling horizontally. The contract in Figure 8 takes advantage of this “feature” by introducing, at line 4 in function withdrawAll, a long sequence of white spaces, effectively hiding the code that would follow. The hidden code throws, if the caller of the function is not the owner and thereby prevents the subsequent balance transfer to any caller of the function. Also note the check at line 4, where the block number must be greater than 5,040,270. This ensures that the honeypot solely steals funds when deployed on the main network. Since the block numbers on the test networks are smaller, testing this contract on a such a network would transfer all the funds to the victim, making him or her believe that the contract is not a honeypot. We label this type of honeypot as hidden transfer.
Straw Man Contract.
In Figure 9 we provide an example of a honeypot technique that we denote as straw man contract. At first sight, it seems that the contract’s CashOut function is vulnerable to a reentrancy attack  (line 14). In order to be able to mount the reentrancy attack, the user is required to first call the Deposit function and transfer a minimum amount of ether. Eventually, the user calls the CashOut function, which performs a call to the contract address stored in TransferLog. As shown in the Figure 9, the contract called Log is supposed to act as a logger. However, the honeypot creator did not initialise the contract with an address containing the bytecode of the shown logger contract. Instead it has been initialised with another address pointing to a contract that implements the same interface, but throws an exception if the caller is not the honeypot creator. Thus, the reentrancy attack performed by the user will always fail. Another alternative is the use of delegatecall right before the transfer of the balance. Delegatecall allows a called contract to modify the stack of the contract who called. Thus, the attacker would swap the address of the user on the stack with his or her own address and when returning from the delegatecall, the balance would be transferred to the attacker instead of the user.
In this section, we provide an overview on the design and implementation of HoneyBadger444The source code will be released under an open source license..
4.1 Design Overview
Figure 10 depicts the overall architecture and analysis pipeline of HoneyBadger. HoneyBadger takes as input EVM bytecode and returns as output a detailed report regarding the different honeypot techniques it detected. HoneyBadger consists of three main components: symbolic analysis, cash flow analysis and honeypot analysis. The symbolic analysis component constructs the control flow graph (CFG) and symbolically executes its different paths. The result of the symbolic analysis is propagated to the cash flow analysis component as well as the honeypot analysis component. The cash flow analysis component uses the result of the symbolic analysis to detect whether the contract can receive as well as transfer funds. Finally, the honeypot analysis component detects the different types of honeypots studied in this paper using a combination of heuristics and the results of the symbolic analysis. Each of the three components uses the Z3 SMT solver  to check for the satisfiability of constraints.
HoneyBadger is implemented in Python, with roughly 4,000 lines of code. We briefly describe the implementation details of each main component below.
4.2.1 Symbolic Analysis
The symbolic analysis component starts by constructing a CFG from the bytecode, where every node in the CFG corresponds to a basic block and every edge corresponds to a jump between individual basic blocks. A basic block is a sequence of instructions with no jumps going in or out of the middle of the block. The CFG captures all possible program paths that are required for symbolic execution. Symbolic execution represents the values of program variables as symbolic expressions. Each program path consists of a list of path conditions (a formula of symbolic expressions), that must be satisfied for execution to follow that path.
We reused and modified the symbolic execution engine proposed by Luu et al. . The engine consists of an interpreter loop that receives a basic block and symbolically executes every single instruction within that block. The loop continues until all basic blocks of the CFG have been executed or a timeout is reached. Loops are terminated once they exceed a globally defined loop limit. The engine follows a depth first search approach when exploring branches and queries Z3 to determine their feasibility. A path is denoted as feasible if its path conditions are satisfiable. Otherwise, it is denoted as infeasible. Usually, symbolic execution tries to detect and ignore infeasible paths in order to improve their execution performance. However, our symbolic execution does not ignore infeasible paths, but rather executes them, as they can be useful for detecting honeypots (see Section 4.2.3).
The purpose of the symbolic analysis is to collect all kinds of information that might be useful for later analysis. This information includes a list of storage writes, a list of execution paths , a list of infeasible as well as feasible basic blocks, a list of performed multiplications and additions, and a list of calls . Calls are extracted through the opcode CALL, and either represent a function call, a contract call or a transfer of Ether. A call consists of the tuple , where is the recipient, is the call value, is the called contract function, is the list of function arguments, is the type of call (i.e. CALL or DELEGATECALL) and is the available gas for the call.
4.2.2 Cash Flow Analysis
Given our definition in Section 3.1, a honeypot must be able to receive funds (e.g. the investment of a victim) and transfer funds (e.g. the loot of the attacker). The purpose of our cash flow analysis is to improve the performance of our tool, by safely discarding contracts that do not allow for the receiving and transferring of funds.
There are multiple ways to receive funds besides direct transfers: as a recipient of a block reward, as a destination of a selfdestruct or through the call of a payable function. Receiving funds through a block reward or a selfdestruct makes little sense for a honeypot as this does not execute code. The compiler adds a check during compilation time, that reverts a transaction if a non-payable function receives a transaction value that is larger than zero. Based on this observation, we verify that a contract is able to receive funds, by first iterating over all possible execution paths contained in and checking whether there exists an execution path , that does not terminate in a REVERT. Afterwards, we use Z3 to verify if the constraint can be satisfied under the path conditions of the execution path . If satisfies the constraint, we know that funds can flow into the contract.
There are two different ways to transfer funds: either explicit via a transfer or implicit via a selfdestruct. We verify the former by iterating over all calls contained in and checking whether there exists a call , where is either symbolic or . We verify the latter by iterating over all execution paths contained in and checking whether there exists an execution path that terminates in a SELFDESTRUCT. We know that funds can flow out of the contract, if we find at least one call or execution path , that satisfies the aforementioned conditions.
4.2.3 Honeypot Analysis
Our honeypot analysis consists of several sub-components. Each sub-component is responsible for the detection of a particular honeypot technique. Every honeypot technique is identified via heuristics. We describe the implementation of each sub-component below.
Balance Disorder. Detecting a balance disorder is straightforward. We iterate over all calls contained in and report a balance disorder, if we find a call within an infeasible basic block, where .
Inheritance Disorder. Detecting an inheritance disorder at the bytecode level is rather difficult. We report an inheritance disorder if we find 1) an that is written to a storage location, but that storage location is never used inside a path condition, call or suicide; and 2) there exists a call , whose path conditions contain a comparison between and a storage variable, where the variable’s storage location is different than the storage location identified in 1).
Skip Empty String Literal. We start by iterating over all calls contained in and checking wether there exists a call , where the number of arguments in is smaller than the number of arguments expected by . We report a skip empty string literal, if we can find another call , that is called within function and where originates from an argument in .
Type Deduction Overflow. We detect a type deduction overflow by iterating over all calls contained in and checking whether there exists a call , where contains the result of a multiplication or an addition that has been truncated via an AND mask with the value 0xff, which represents the maximum value of an 8-bit integer.
Uninitialised Struct. We use a regular expression to extract the storage location of structs, whose first element is pointing at storage location zero within a basic block. Eventually, we report an uninitialised struct, if there exists a call , where either contains a value from a storage location of a struct or the path condition of depends on a storage location of a struct.
Hidden State Update. We detect a hidden state update by iterating over all calls contained in and checking whether there exists a call , whose path conditions depend on a storage value that can be modified via another function, without the transfer of funds.
Hidden Transfer. We report a hidden transfer, if two consecutive calls and exist along the same execution path , where and .
Straw Man Contract. First, we verify if two consecutive calls and exist along the same execution path , where . Finally, we report a straw man contract if one of the two cases is satisfied: 1) is executed after , where , and ; 2) is executed before , where and .
In this section, we assess the correctness and effectiveness of HoneyBadger. We aim to determine the reliability of our tool and measure the overall prevalence of honeypots currently deployed on the Ethereum blockchain.
We downloaded the bytecode of 2,019,434 smart contracts, by scanning the first 6,500,000 blocks of the Ethereum blockchain. The timestamps of the collected contracts range from August 7, 2015 to October 12, 2018. Figure 11 depicts the number of smart contracts deployed on Ethereum per month. We state a sudden increase in the number of smart contracts deployed between December 2017 and February 2018. We suspect that this inflation is related to the increase of the price of Ether and other cryptocurrencies such as Bitcoin . In 2016, 50,980 contracts were deployed on average per month, whereas in 2017 this number increased almost tenfold, with 447,306 contracts on average per month. Interestingly, a lot of contracts share the same bytecode. Out of the 2,019,434 contracts, solely 151,935 are unique in terms of exact bytecode match. In other words, 92.48% of the contracts deployed on the Ethereum blockchain are duplicates.
All experiments were conducted on our high-performance computing cluster using 10 nodes with 960 GB of memory, where every node has 2 Intel Xeon L5640 CPUs with 12 cores each and clocked at 2,26 GHz, running 64-bit Debian Jessie 8.10. We used version 1.8.16 of Geth’s EVM as our disassembler and Solidity version 0.4.25 as our source-code-to-bytecode compiler. As our constraint solver we used Z3 version 4.7.1. We set a timeout of 1 second per Z3 request for the symbolic execution. The symbolic execution’s global timeout was set to 30 minutes per contract. The loop limit, depth limit (for DFS) and gas limit for the symbolic execution were set to 10, 50 and 4 million, respectively.
We run HoneyBadger on our set of 151,935 unique smart contracts. Our tool took an average of 142 seconds to analyse a contract, with a median of 31 seconds and a mode of less than 1 second. Moreover, for 98.47% of the cases (149,603 contracts) our tool was able to finish its analysis within the given time limit of 30 minutes. The number of explored paths ranges from 1 to 8,037, with an average of 179 paths per contract and a median of 105 paths. Finally, during our experiments, HoneyBadger achieved a code coverage of about 91.32% on average.
Out of the 151,935 analysed contracts, 48,487 had been flagged as cash flow contracts. In other words, only 32% of the analysed contracts are capable of receiving as well as sending funds. Figure 12 depicts for each honeypot technique the number of contracts that have been flagged by HoneyBadger. Our tool detected a total of 460 unique honeypots. However, as mentioned earlier, many contracts share the same bytecode. Therefore, after correlating the results with the bytecode of the 2 million contracts currently deployed on the blockchain, a total of 690 contracts are detected as honeypots. Our tool discovered 22 balance disorders (BD), 75 inheritance disorders (ID), 11 skip empty string literal (SESL), 5 type deduction overflows (TDO), 80 uninitialised structs (US), 382 hidden state updates (HSU), 14 hidden transfers (TS) and finally 101 straw man contracts (SMC). While many contracts were found to be HSU, SMC and US honeypots, only a small number were found to be TDO honeypots.
In order to confirm the correctness of HoneyBadger, we performed a manual inspection of the source code of the contracts that have been flagged as honeypots. We were able to collect through Etherscan the source code for 323 (70.22%) flagged contracts. We verified the flagged contracts by manually scanning the source code for characteristics of a detected honeypot technique. For example, in case a contract has been flagged as a balance disorder, we checked whether the source code contains a function that transfers the contract’s balance to the caller if and only if the value sent to the function is greater than or equal to the contract’s balance.
Table 2 summarises our manual verification in terms of true positives (TP), false positives (FP) and precision , where is computed as . A true positive means that the contract is indeed a honeypot with respect to the reported technique and a false positive means that the contract is not a honeypot with respect to the reported technique. Overall our tool shows a very high precision and a very low false positive rate. Our tool achieves a false positive rate of 0% for 5 out of the 8 analysed honeypot techniques. For the remaining 3 techniques, our tool achieves a decent false positive rate, where the highest false positive rate is roughly 18.29% for the detection of hidden state updates, followed by 14.58% false positive rate for the detection of inheritance disorder and finally 11.76% false positive rate for the detection of straw man contracts.
Skip Empty String Literal
Type Deduction Overflow
Hidden State Update
Straw Man Contract
In this section, we analyse the true positives obtained in Section 5, in order to acquire some insights on the effectiveness, liveness, behaviour, diversity and profitability of honeypots.
We crawled all the transactions of the 282 true positives using Etherchain’s555https ://www.etherchain.org/ API, in order to collect various information about the honeypots, such as the amount of spent and received Ether per address, the deployment date, the balance, etc. Afterwards, we used simple heuristics to label every address as either an attacker or a victim. An address is labeled as an attacker if it either: 1) created the honeypot; 2) was the first address to send Ether to the honeypot; or 3) received more Ether than it actually spent on the honeypot. An address is labeled as a victim if it has not been labeled as an attacker and if it received less Ether than it actually spent on the honeypot. Finally, using this information we were able to tell if a honeypot, was either successful, aborted or still active. A honeypot is marked as successful if a victim has been detected, as aborted if no victim has been detected and the balance is zero or as active if no victim has been detected and the balance is larger than zero.
Figure 13 shows the number of successful, aborted and active honeypots per honeypot technique. Our results show that skip empty string literal is the most effective honeypot technique with roughly 78% success rate, whereas hidden transfer is the least effective technique with solely 33% success rate. The overall success rate of honeypots seems rather low with roughly 37%, whereas the overall abortion rate seems quite high with about 54%. At the time of writing, solely 9.93% of the analysed honeypots are still active. Figure 15 illustrates the number of monthly deployed honeypots per honeypot technique. The very first honeypot technique that has been deployed was a hidden state update in January 2017. February 2018 has been the peak in terms of honeypots being deployed, with a total of 66. The highest number of monthly honeypots that have been deployed per technique are hidden state updates with a number of 36 in June 2018. 7 honeypots have been deployed on average per month. In our analysis, the quickest first attempt of exploitation happened just 7 minutes and 37 seconds after a honeypot had been deployed, whereas the longest happened not until 142 days after deployment. A honeypot takes an average of 9 days and a median of 16 hours before it gets exploited. Interestingly, most honeypots (roughly 55%) are exploited during the first 24 hours after being deployed.
We define the lifespan of a honeypot as the period of time between the deployment of a honeypot and the moment when a honeypot aborted. We found that the shortest lifespan of a honeypot was 5 minutes and 25 seconds and the longest lifespan was about 322 days. Moreover, the average lifespan of a honeypot is roughly 28 days, whereas the median is roughly 3 days. However, in around 32% of the cases the lifespan of a honeypot is solely 1 day. We also analysed how long an attacker keeps the funds inside a honeypot, by measuring the period of time between the first attempt of exploitation by a victim and the withdrawal of all the funds by the attacker. The shortest period was just 4 minutes and 28 seconds after a victim fell for the honeypot. The longest period was roughly 100 days. On average attackers withdraw all their funds within 7 days after a victim fell for the honeypot. However, in most cases the attackers keep the funds in the honeypot for a maximum of 1 day. Interestingly, only 37 out of 282 honeypots got destroyed, where destroyed means that the attacker called a function within the honeypot that would call theSELFDESTRUCT opcode. In other words, 171 honeypots are in some kind of “zombie” state, where they are still alive (i.e. not destroyed), but not active (i.e. their balance is zero). Analysing the 37 destroyed honeypots, we found that 19 got destroyed after being successful and 18 after never been successful.
Our methodology classified a total of 240 addresses as victims. In 71% of the cases a honeypot managed to trap solely one victim. In one case though, 97 victims have been trapped by just a single honeypot. Interestingly, 8 out of the 240 addresses fell for more than one honeypot, where one address even became a victim to four different honeypots. We also found that 53 attackers deployed at least two honeypots, whereas a sole attacker deployed eight different honeypots. 87 out of the 282 honeypots (about 31%) contained comments on Etherscan. We manually analysed these comments and found that the majority of the comments were indeed warnings stating that the contract might be a honeypot (see Figure14). Out of the 87 commented honeypots, solely 20 were successful. 16 were successful before a comment had been placed and 4 have been successful only after a comment had been placed. Interestingly, 21 honeypots aborted after a comment was placed. The quickest abort was performed just 33 minutes and 57 seconds after the comment, whereas the longest abort was performed 37 days after the comment. Finally, attackers took an average of 6 days and a median of 22 hours to abort their honeypot after a user had placed a comment.
We used the normalised Levenshtein distance  to measure the similarity of the bytecode between the individual instances of a particular honeypot technique. Table 3 outlines the similarity in terms of minimum, maximum, mean and mode per honeypot technique. We observe that for almost every technique, except TDO, the bytecode similarity varies tremendously. For example, in case of hidden state update honeypots, we measure a minimum similarity of 11% and a maximum similarity of 98%. This indicates that even though two honeypots share the same technique, their bytecode might be still very diverse.
Table 4 lists the profitability per honeypot technique. The profitability is computed as - + . No values are provided for TDO, because for the single true positive that we analysed, the transaction fees spent by the attacker were higher than the amount that the attacker received from the victim. The smallest and largest profit were made using a hidden state update honeypot, with 0.00002 Ether being the smallest and 11.96 Ether being the largest. The most profitable honeypots are straw man contract honeypots, with an average value of 1.76 Ether, whereas the least profitable honeypots are uninitialised struct honeypots, with an average value of 0.46 Ether. A total profit of 257.25 Ether has been made through honeypots, of which 171.22 Ether were solely made through hidden state update honeypots. However, the exchange rate of cryptocurrencies is very volatile and thus their value in USD may vary greatly on a day-to-day basis. For example, although 11.96 Ether is the largest profit made in Ether, its actual value in USD was solely 500 at the point of withdrawal. Thus, we found that the largest profit in terms of USD, was actually a honeypot with 3.10987 Ether, since it was worth 2,609 USD at the time of withdrawal. Applying this method across the 282 honeypots, results in a total profit of 90,118 USD.
In this section we summarise the key insights gained through our analysis and we discuss the ethical considerations as well as the challenges and limitations of our work.
7.1 Honeypot Insights
Although honeypots are capable of trapping multiple users, we have found that most honeypots managed to take the funds of only one victim. This indicates that users potentially look at the transactions of other users before they effectively submit theirs. Moreover, the low success rate of honeypots with comments, suggests that users also check the comments on Etherscan before submitting any funds. We also found that the bytecode of honeypots can be vastly different across the same honeypot technique. This suggests that the usage of signature-based detection methods would be rather ineffective. HoneyBadger is capable of recognising a variety of implementations, as it specifically targets the functional characteristics of each honeypot technique. Among the honeypots that have trapped the funds of users, more than half did so within one day. This suggests that honeypots become less effective the older they become. This is interesting, as it means that users seem to target rather recently deployed honeypots than older ones. We also note that most honeypot creators withdraw their loot within 24 hours or abort their honeypots if they are not successful within the first 24 hours. We therefore conclude that honeypots have in general a short live and only a small fraction remain active for a longer period than one day.
7.2 Challenges and Limitations
The amount of smart contracts with available source code is rather small. At the time of writing, there are only 50,000 contracts with source code available on Etherscan. This highlights the necessity of being able to detect honeypots at the bytecode level. Unfortunately, this turns out to be extremely challenging for certain honeypot techniques. For example, while detecting inheritance disorder at source code level is rather trivial, detecting it at the bytecode level is rather difficult as information about the inheritance is lost during compilation and therefore not available anymore at the bytecode level. The fact that some information is not available at the bytecode level, forces to make use of other information available in the bytecode in order to detect honeypot techniques such as inheritance disorder. However, as Section 5 shows, this approach allows in some cases for false positives. Moreover, besides these challenges, one major limitation of our tool is that it is currently limited to the detection of the honeypot techniques described in this paper. Thus other honeypot techniques are not detected, unless new heuristics are introduced to detect them.
7.3 Ethical Considerations
In general, honeypots have two participants, the creator of the honeypot, and the user whose funds are trapped by the honeypot. However, the ethical intentions of both participants are not always clear. For instance, a honeypot creator might deploy a honeypot with the intention to scam users and make profit. In this case we clearly have a malicious intention. However, one could also argue that a honeypot creator is just attempting to punish users that behave maliciously. Similarly, the intentions of a honeypot user can either be malicious or benign. For example, if a user tries to intentionally exploit a reentrancy vulnerability, then he or she needs to be knowledgable and mischievous enough to prepare and attempt the attack, and thus clearly showing malicious behaviour. However, if we take the example of an uninitialised struct honeypot that is disguised as a simple lottery, then we might have the case of a benign user who loses his funds in assuming that he or she is participating in a fair lottery. Thus, both honeypot creators and users cannot always be clearly classified as either malicious or benign, this depends on the case at hand. Nevertheless, we are aware that our methodology may serve malicious attackers to protect themselves from other malicious attackers. However, with HoneyBadger, we hope to raise the awareness of honeypots and save benign users from potential financial losses.
8 Related Work
Honeypots are a new type of fraud that combine security issues with scams. They either rely on the blockchain itself or on related services such as Etherscan. With growing interest within the blockchain community, they have been discussed online [30, 31, 32] and collected within public user repositories [21, 43]. Frauds and security issues are nothing new within the blockchain ecosystem. Blockchains have been used for money laundering  and been the target of several scams , including mining scams, wallet scams and Ponzi schemes, which are further discussed in [4, 41]. In particular, smart contracts have been shown to contain security issues . Although not performed directly on the blockchain, exchanges have also been the target of fraud .
Several different methods have been proposed to discover fraud as well as security issues. Manual analysis is performed on publicly available source code to detect Ponzi schemes .  introduces Erays
, a tool that aims at producing easy to analyse pseudocode from bytecode where the source code is not available. However, manual analysis is particularly laborious, especially considering the number of contracts on the blockchain. Machine learning has been used to detect Ponzi schemes and to find vulnerabilities . The latter relies on  to obtain a ground truth of vulnerable smart contracts for training their model. Fuzzing techniques have been employed to detect security vulnerabilities in smart contracts  and in combination with symbolic execution to to discover issues tied to the ordering of events or function calls . However, fuzzing often fails to create inputs to enter specific execution paths and therefore might ignore them . Static analysis has been used to find security [7, 38, 36] and gas-focused  vulnerabilities in smart contracts.  requires manual interaction, while  requires both the definition of violation and compliance patterns.  requires Solidity code and therefore cannot be used to analyse the large majority of the smart contracts deployed on the Ethereum blockchain.  considers gas-related issues which is not necessary for the purpose of this work. In order to use formal verification, smart contracts can, to some extent, be translated from source code or bytecode into F* [5, 12] where the verification can more easily be performed. Other work operates on high-level source code available for Ethereum or Hyperledger . [13, 14] propose a formal definition of the EVM, that is extended in  towards more automated smart contract verification and adds consideration of gas. Formal verification often requires (incomplete) translations into other languages or manual user interaction (e.g.: ). Both of these reasons make formal verification not suitable to be used on a large number of contracts, as it is required in this work.
Symbolic execution has been used on smart contracts to detect common [27, 24, 20, 37] vulnerabilities. This technique also allows to find specific kinds of misbehaving contracts . It can further provide values that can serve to generate automated exploits that trigger vulnerabilities . The same technique is used in this paper. Symbolic execution has the advantage of being capable to reason about all possible execution paths and states in a smart contract. This allows for the implementation of precise heuristics while achieving a low false positive rate. Another advantage is that symbolic execution can be applied directly to bytecode, thus making it well suited for our purpose of analysing more than 2 million smart contracts for which source code is largely not available. The disadvantage is the large number of possible paths that need to be analysed. However, in the case of smart contracts this is not an issue, as most are not very complex and are very short. Moreover, smart contract bytecode cannot grow arbitrarily large due to system limits required for the correct operation of the Ethereum blockchain.
To the best of the authors’ knowledge, this paper is the first to consider and discuss Honeypots, a new type of fraud, and to propose a taxonomy as well as an automated tool using symbolic execution for their detection.
In this work, we investigated an emerging new type of fraud in Ethereum: honeypots. We presented a taxonomy of honeypot techniques and introduced a methodology that uses symbolic execution and heuristics for the automated detection of honeypots. We showed that HoneyBadger can effectively detect honeypots in the wild with a very low false positive rate. In a large-scale analysis of 151,935 unique Ethereum smart contracts, HoneyBadger identified 460 contracts to be honeypots. Moreover, an analysis on the transactions, revealed that 240 users already became victims of honeypots and that attackers already made more than 90,000 USD profit with honeypots. In future work, we plan to further generalise our detection mechanism through the use of machine learning techniques. However, tools such as HoneyBadger may already help users in detecting honeypots before they can cause any harm.
-  Sidney Amani, Myriam Bégel, Maksym Bortin, and Mark Staples. Towards verifying ethereum smart contract bytecode in isabelle/hol. CPP. ACM. To appear, 2018.
-  Nicola Atzei, Massimo Bartoletti, and Tiziana Cimoli. A Survey of Attacks on Ethereum Smart Contracts (SoK). In Proceedings of the 6th International Conference on Principles of Security and Trust - Volume 10204, pages 164–186. Springer-Verlag New York, Inc., 2017.
-  Massimo Bartoletti, Salvatore Carta, Tiziana Cimoli, and Roberto Saia. Dissecting ponzi schemes on ethereum: identification, analysis, and impact. arXiv preprint arXiv:1703.03779, 2017.
-  Massimo Bartoletti, Barbara Pes, and Sergio Serusi. Data mining for detecting bitcoin ponzi schemes. arXiv preprint arXiv:1803.00646, 2018.
-  Karthikeyan Bhargavan, Nikhil Swamy, Santiago Zanella-Béguelin, Antoine Delignat-Lavaud, Cédric Fournet, Anitha Gollamudi, Georges Gonthier, Nadim Kobeissi, Natalia Kulatova, Aseem Rastogi, and Thomas Sibut-Pinote. Formal Verification of Smart Contracts. In Proceedings of the 2016 ACM Workshop on Programming Languages and Analysis for Security - PLAS’16, pages 91–96, New York, New York, USA, 2016. ACM Press.
-  Cornell Blockchain. Bamboo: a language for morphing smart contracts, May 2018. https://github.com/CornellBlockchain/bamboo.
-  Lexi Brent, Anton Jurisevic, Michael Kong, Eric Liu, Francois Gauthier, Vincent Gramoli, Ralph Holz, and Bernhard Scholz. Vandal: A scalable security analysis framework for smart contracts. arXiv preprint arXiv:1809.03981, 2018.
-  Weili Chen, Zibin Zheng, Jiahui Cui, Edith Ngai, Peilin Zheng, and Yuren Zhou. Detecting ponzi schemes on ethereum: Towards healthier blockchain technology. In Proceedings of the 2018 World Wide Web Conference on World Wide Web, pages 1409–1418. International World Wide Web Conferences Steering Committee, 2018.
-  CoinMarketCap. Ethereum (ETH) price, charts, market cap, and other metrics — CoinMarketCap, January 2018. https://coinmarketcap.com/currencies/ethereum/.
-  Leonardo De Moura and Nikolaj Bjørner. Z3: An efficient smt solver. In International conference on Tools and Algorithms for the Construction and Analysis of Systems, pages 337–340. Springer, 2008.
-  Neville Grech, Michael Kong, Anton Jurisevic, Lexi Brent, Bernhard Scholz, and Yannis Smaragdakis. Madmax: surviving out-of-gas conditions in ethereum smart contracts. Proceedings of the ACM on Programming Languages, 2(OOPSLA):116, 2018.
-  Ilya Grishchenko, Matteo Maffei, and Clara Schneidewind. A semantic framework for the security analysis of ethereum smart contracts. In International Conference on Principles of Security and Trust, pages 243–269. Springer, 2018.
-  Yoichi Hirai. Defining the ethereum virtual machine for interactive theorem provers. In International Conference on Financial Cryptography and Data Security, pages 520–535. Springer, 2017.
-  Yoichi Hirai. Ethereum virtual machine for coq (v0.0.2), June 2017. https://medium.com/@pirapira/ethereum-virtual-machine-for-coq-v0-0-2-d2568e068b18.
-  Bo Jiang, Ye Liu, and W. K. Chan. Contractfuzzer: Fuzzing smart contracts for vulnerability detection. In Proceedings of the 33rd ACM/IEEE International Conference on Automated Software Engineering, ASE 2018, pages 259–269, New York, NY, USA, 2018. ACM.
-  Sukrit Kalra, Seep Goel, Mohan Dhawan, and Subodh Sharma. Zeus: Analyzing safety of smart contracts. In NDSS, 2018.
-  Aashish Kolluri, Ivica Nikolic, Ilya Sergey, Aquinas Hobor, and Prateek Saxena. Exploiting the laws of order in smart contracts. arXiv preprint arXiv:1810.11605, 2018.
-  Johannes Krupp and Christian Rossow. teether: Gnawing at ethereum to automatically exploit smart contracts. In 27th USENIX Security Symposium (USENIX Security 18), pages 1317–1333, 2018.
-  LLL. Ethereum low-level lisp-like language, January 2019. https://lll-docs.readthedocs.io/en/latest/lll_introduction.html.
-  Loi Luu, Duc-Hiep Chu, Hrishi Olickel, Prateek Saxena, and Aquinas Hobor. Making smart contracts smarter. In Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, CCS ’16, pages 254–269, New York, NY, USA, 2016. ACM.
-  misterch0c. Solidity vulnerable honeypots, April 2018. https://github.com/misterch0c/Solidlity-Vulnerable/tree/master/honeypots.
-  Tyler Moore and Nicolas Christin. Beware the middleman: Empirical analysis of bitcoin-exchange risk. In International Conference on Financial Cryptography and Data Security, pages 25–33. Springer, 2013.
-  Malte Moser, Rainer Bohme, and Dominic Breuker. An inquiry into money laundering tools in the bitcoin ecosystem. In eCrime Researchers Summit (eCRS), 2013, pages 1–14. IEEE, 2013.
-  Bernhard Mueller. Smashing ethereum smart contracts for fun and real profit. In 9th annual HITB Security Conference, 2018.
-  Satoshi Nakamoto. Bitcoin: A peer-to-peer electronic cash system. Cryptography Mailing list at https://metzdowd.com, 03 2009.
-  Ivica Nikolic, Aashish Kolluri, Ilya Sergey, Prateek Saxena, and Aquinas Hobor. Finding the greedy, prodigal, and suicidal contracts at scale. arXiv preprint arXiv:1802.06038, 2018.
-  Trail of Bits. Manticore - symbolic execution tool, jun 2018. https://github.com/trailofbits/manticore.
-  Sergey Petrov. Another parity wallet hack explained, nov 2017. https://medium.com/@Pr0Ger/another-parity-wallet-hack-explained-847ca46a2e1c.
-  Christian Reitwiessner. Formal verification for solidity contracts, June 2018. https://forum.ethereum.org/discussion/3779/formal-verification-for-solidity-contracts.
-  Josep Sanjuas. An analysis of a couple ethereum honeypot contracts, December 2018. https://medium.com/coinmonks/an-analysis-of-a-couple-ethereum-honeypot-contracts-5c07c95b0a8d.
-  Alex Sherbachev. Hacking the hackers: Honeypots on ethereum network, December 2018. https://hackernoon.com/hacking-the-hackers-honeypots-on-ethereum-network-5baa35a13577.
-  Alex Sherbuck. Dissecting an ethereum honey pot, December 2018. https://medium.com/coinmonks/dissecting-an-ethereum-honey-pot-7102d7def5e0.
-  David Siegel. Understanding the dao attack, jun 2016. https://www.coindesk.com/understanding-dao-hack-journalists/.
-  Nick Szabo. Formalizing and securing relationships on public networks. First Monday, 2(9), 1997.
-  A Tann, Xing Jie Han, Sourav Sen Gupta, and Yew-Soon Ong. Towards safer smart contracts: A sequence learning approach to detecting vulnerabilities. arXiv preprint arXiv:1811.06632, 2018.
-  S. Tikhomirov, E. Voskresenskaya, I. Ivanitskiy, R. Takhaviev, E. Marchenko, and Y. Alexandrov. Smartcheck: Static analysis of ethereum smart contracts. In 2018 IEEE/ACM 1st International Workshop on Emerging Trends in Software Engineering for Blockchain (WETSEB), pages 9–16, May 2018.
-  Christof Ferreira Torres, Julian Schütte, and Radu State. Osiris: Hunting for integer bugs in ethereum smart contracts. In Proceedings of the 34th Annual Computer Security Applications Conference, ACSAC ’18, pages 664–676, New York, NY, USA, 2018. ACM.
-  Petar Tsankov, Andrei Dan, Dana Drachsler Cohen, Arthur Gervais, Florian Buenzli, and Martin Vechev. Securify: Practical security analysis of smart contracts. arXiv preprint arXiv:1806.01143, 2018.
-  Mathy Vanhoef and Frank Piessens. Symbolic execution of security protocol implementations: Handling cryptographic primitives. In 12th USENIX Workshop on Offensive Technologies (WOOT 18), Baltimore, MD, 2018. USENIX Association.
-  Marie Vasek and Tyler Moore. There’s no free lunch, even using bitcoin: Tracking the popularity and profits of virtual currency scams. In International conference on financial cryptography and data security, pages 44–61. Springer, 2015.
-  Marie Vasek and Tyler Moore. Analyzing the bitcoin ponzi scheme ecosystem. In Bitcoin Workshop, 2018.
-  Vyper. Pythonic smart contract language for the evm, January 2019. https://github.com/ethereum/vyper.
-  Gerhard Wagner. Smart contract honeypots, April 2018. https://github.com/thec00n/smart-contract-honeypots.
-  Gavin Wood. Ethereum: A secure decentralised generalised transaction ledger. Ethereum Project Yellow Paper, 151:1–32, 2014.
-  Gavin Wood. Solidity 0.5.1 documentation, December 2018. https://solidity.readthedocs.io/en/v0.5.1/.
-  Li Yujian and Liu Bo. A normalized levenshtein distance metric. IEEE transactions on pattern analysis and machine intelligence, 29(6):1091–1095, 2007.
-  Yi Zhou, Deepak Kumar, Surya Bakshi, Joshua Mason, Andrew Miller, and Michael Bailey. Erays: Reverse engineering ethereum’s opaque smart contracts. In 27th USENIX Security Symposium (USENIX Security 18), pages 1371–1385, 2018.
Appendix A List of Honeypots
Table 5 presents the list of 24 honeypots that have been collected from public sources available on the Internet.