The rise of Web3 has ushered in a wave of innovation, not all of which is benevolent. A notable manifestation of malicious activity within this space is the emergence of "honeypot contracts." These contracts issue tokens that can be bought but not sold, thereby trapping investors.
One infamous example is the Squid Games token, which emerged in November 2021. In this case, an address tagged as "SQUID Token Rug 2" on BscScan moved a significant amount of BNB, totaling around $6.38 million, into Tornado Cash. Initially, the inability of users to sell or transfer was misrepresented as "innovative anti-dumping technology."
Honeypot contracts employ various mechanisms to restrict selling, including:
• Wallet blacklists • Whitelists permitting only certain wallets to sell • Prohibitive sell taxes • Exorbitant minimum sell amounts • Extended cooldowns between buying and selling
The contract code we scrutinized is detectable by third-party tools due to its transparent use of a blacklist() function. Marked by the presence of a geryAddressList() function, this contract piqued our interest because of its frequent deployment. Over 18 months, similar code has been used hundreds of times, with one likely withdrawal wallet transferring roughly 2,289 BNB (approximately $550,464) to an exchange since February 2022.
Quantifying the exact number of such contracts is challenging due to the sheer volume and time span involved. However, we identified a pattern involving address EOA 0xa676, linked with numerous deployments:
• June: 50 Contracts
• July: 52 Contracts
• August: 41 Contracts
• September: 48 Contracts
Cross-referencing with BscScan's contract similarity tool, we found 208 contracts resembling one that employs _geryAddressList(), with 95 being exact matches.
An additional 264 similar contracts were found when examining a second example, with 31 of those being exact matches.
Our analysis is based on contract 0xa9d6578850d7cc0d505f7d878c5d99c55af58794. This contract's transfer mechanisms initiate with a beforTransfer() function, followed by several conditional checks:
After the beforTransfer() function completes, the transfer functions then check three conditions, shown on line 94 and 120 above:
• ‘ab’ is set to true.
• ‘_to’ address is not on tokenWhitelist, the preceding '!' signifies the opposite of true.
• ‘_to’ is not the LP address, here the '!=' signifies not equal.
Upon meeting these conditions, the _to address is added to a grey list, and the current block number is recorded. Buying tokens triggers the transferFrom() function with the buyer as the _to address, meaning buyers will be added to the tokenGreylist()
if they are not whitelisted.
The beforTransfer() function includes further checks:
Line 141: Check if the transfer from and to addresses are on the whitelist, if they aren’t:
Lines 142,143, 144: Neither the _from, _to or msg.sender
must be on the tokenBlacklist.
Line 145: The _from address must also not be on the grey list OR the block number must be less than the death variable and the blockN variable. blockN is initially set to 1, meaning anyone on the grey list must sell within the same block of the death variable, which records the block number in which an address is added to the tokenGreylist()
, being set or they will be unable to sell.
If any of the above checks fail then the transaction will revert.
To simplify, the first time a user buys tokens they are added to a grey list, unless it is a whitelisted address. Once the address is on the grey list, a user will then be unable to sell their tokens.
Whitelisted wallets, usually controlled by the contract's creator, are often used for wash trading to inflate trading volumes and create a false sense of liquidity. Automated trading across multiple wallets enhances the illusion of activity, thereby attracting more attention to the token.
The following screenshot is a wallet that is set up to automatically trade tokens.
Automated wallets play a crucial role in simulating trading activity. These are orchestrated to perform repeated transactions, creating an illusion of diverse and active trading. Specifically, contract 0x2D1c serves as an unverified facilitator for wash trading. At the initiation of each contract based on our example code, a function from 0x2D1c is invoked, artificially inflating the token's trading volume.
Following this initial surge, the token experiences periodic, smaller-volume transactions, mimicking typical trading behavior. This operational pattern is consistent across multiple automated wallets.
In a span between July 30 and August 1, 2023, a user generated 34 honeypot contracts using code with the geryAddressList() function. We focus here on ZebraSwap, one of these tokens. Relevant addresses involved include:
• Creator of tokens: 0xf01e51504a9f5020f6f46cc0bc76c1d2efb40ec0
• Unverified contract for token creation: 0x2936B8eaEd363015C9E20CfAeb10C84B4deF6BD5
The following example is based on ZebraSwap token, one of 34 tokens created by 0xf01e.
1.0xf01e created token contracts using unverified contract 0x2936B. Although the contract is unverified, we can see the EOA called the function createToken() and passed each token's details.
On August 1, 2023, EOA 0x964d funneled 100 BNB into Tornado Cash, as corroborated by transaction details. This address is linked to multiple tokens that utilize the geryAddressList() honeypot mechanism. Shortly after, 100 BNB was withdrawn to another EOA, aligning with previous patterns of deposits and withdrawals involving Tornado Cash.
The following are some of the examples over the last 18 months showing deposits and withdrawals lining up.
After withdrawing from Tornado Cash, 0x964d routinely sent funds to a Huobi account.
The prevalence of honeypot contracts in the Web3 space is alarming and constitutes a significant risk to investors. These schemes can be spun up rapidly, sometimes within a minute, and can leverage social media hype or automation for mass-scale operations.
While many honeypot contracts are verified to instill a false sense of security, their nefarious functionalities are often either too complex for average users to decipher or are activated at a later stage.
Although third-party tools can identify some honeypot contracts through simulated transactions, they are not foolproof. Scammers continually adapt to evade detection, and contracts can morph into honeypots post-verification. Nevertheless, the utilization of these tools, even with their limitations, can offer a layer of protection for users. A brief scan before purchasing a token could be the decisive factor in preserving one's investment.