In-Depth Analysis of Large-Scale Rug Pull Techniques

IntermediateMar 28, 2024
The current situation where the security of tokens depends entirely on the project's self-awareness. To address this, we may need to improve token mechanisms or introduce effective token supply monitoring schemes to ensure transparency in token quantity changes. We need to be vigilant, as while people's awareness of fraud is increasing, attackers' anti-fraud techniques are also constantly evolving. This is an ongoing game, and we need to continue learning and thinking to protect our interests.
 In-Depth Analysis of Large-Scale Rug Pull Techniques

Forward the Original Title’技术详解 | 链上打新局中局,大规模Rug Pull手法解密’

Recently, CertiK security experts have frequently detected multiple instances of the same exit scam method, commonly known as a Rug Pull. Upon further investigation, we discovered that several instances of the same method point to the same group, ultimately linked to over 200 Token exit scams. This suggests that we may have uncovered a large-scale automated hacker group that harvests assets through exit scams. In these exit scams, attackers create a new ERC20 token and use pre-mined tokens along with a certain amount of WETH to create a Uniswap V2 liquidity pool. After bots or users on the chain make a certain number of purchases of the new token from the liquidity pool, the attacker will deplete all the WETH in the pool with tokens generated out of thin air. Since the tokens obtained by the attacker out of thin air are not reflected in the total supply and do not trigger Transfer events, they are not visible on etherscan, making it difficult for outsiders to detect. Attackers not only consider concealment but also design a subterfuge to deceive users with basic technical skills who check etherscan, using a minor issue to conceal their true intentions…

Dive into the scam

In-depth Scam

Using one of the cases as an example, let’s delve into the details of this exit scam. What we detected was a transaction where the attacker used a massive amount of tokens (quietly minted) to deplete the liquidity pool and profit. In this transaction, the project team exchanged approximately 416,483,104,164,831 (about 416 quadrillion) MUMI tokens for about 9.736 WETH, depleting the liquidity of the pool. However, this transaction is just the final part of the entire scam. To understand the whole scam, we need to continue tracing back.

Deploy tokens

On March 6th at 7:52 AM (UTC time, same for the following), the attacker’s address (0x8AF8) deployed an ERC20 token named MUMI (full name MultiMixer AI) at the address 0x4894 and pre-mined 420,690,000 (about 420 million) tokens, all allocated to the contract deployer.

The number of pre-mined tokens corresponds to the contract source code.

Add liquidity

At 8 o’clock sharp (8 minutes after the token was created), the attacker’s address (0x8AF8) started adding liquidity. The attacker’s address (0x8AF8) calls the openTrading function in the token contract, creates a MUMI-WETH liquidity pool through uniswap v2 factory, adds all pre-mined tokens and 3 ETH to the liquidity pool, and finally obtains approximately 1.036 LP token.


It can be seen from the transaction details that of the 420,690,000 (approximately 420 million) tokens originally used to add liquidity, approximately 63,103,500 (approximately 63 million) tokens were sent back to the token contract (address 0x4894). By viewing The contract source code found that the token contract will charge a certain handling fee for each transfer, and the address for collecting the handling fee is the token contract itself (specifically implemented in the “_transfer function”).

What is strange is that the tax address 0x7ffb (the address for collecting transfer fees) has been set in the contract, but the final fee was sent to the token contract itself.

Therefore, the final number of MUMI tokens added to the liquidity pool is 357,586,500 (approximately 350 million) after tax, not 420,690,000 (approximately 430 million).

Lock in liquidity

At 8:01 (1 minute after the liquidity pool was created), the attacker address (0x8AF8) locked all 1.036 LP tokens obtained by adding liquidity.

After the LP is locked, theoretically all MUMI tokens owned by the attacker’s address (0x8AF8) are locked in the liquidity pool (except for the part used as handling fees), so the attacker’s address (0x8AF8) does not have the ability to remove it through Liquidity ability to perform Rug Pull. In order to allow users to buy newly launched tokens with confidence, many project parties lock LP, which means that the project party is saying: “I will not run away, everyone can buy with confidence!”, but is this really the case? ? Obviously not, this is the case, let us continue the analysis.

Rug Pull

At 8:10, a new attacker address ② (0x9DF4) appeared, and he deployed the tax address 0x7ffb declared in the token contract.

There are three points worth mentioning here: 1. The address where the tax address is deployed and the address where tokens are deployed are not the same. This may indicate that the project party is intentionally reducing the correlation between each operation and the address, making it more difficult to trace the behavior. 2. The contract of the tax address is not open source, which means that there may be hidden operations in the tax address that do not want to be exposed. 3. The tax contract is deployed later than the token contract, and the tax address in the token contract has been hard-coded, which means the address of the tax contract can be predicted by the project team in advance. Since the CREATE instruction determines the creator address and nonce, the deployment contract address is determined. Therefore, the project team used the creator address to simulate and calculate the contract address in advance. In fact, many exit scams are conducted through tax addresses, and the deployment mode characteristics of tax addresses comply with points 1 and 2 above. At 11 a.m. (3 hours after the token was created), the attacker’s address ② (0x9DF4) conducted a Rug Pull. By calling the “swapExactETHForTokens” method of the tax contract (0x77fb), he exchanged 416,483,104,164,831 (approximately 416 trillion) MUMI tokens in the tax address for approximately 9.736 ETH, and exhausted the liquidity in the pool.

Since the tax contract (0x77fb) is not open source, we decompiled its bytecode and the decompilation results are as follows:

https://app.dedaub.com/decompile?md5=01e2888c7691219bb7ea8c6b6befe11c

After decompiling the “swapExactETHForTokens” method of the tax collection contract (0x77fb), we discovered that the main functionality implemented by this function is to exchange the specified amount “xt” (specified by the caller) of MUMI tokens owned by the tax collection contract (0x77fb) into ETH using the UniswapV2 router and then send it to the address declared as “_manualSwap” in the tax address.


The storage address of the _manualSwap address is 0x0. After querying with the getStorageAt command of json-rpc, we found that the address corresponding to _manualSwap is exactly the deployer of the tax contract (0x77fb): attacker ② (0x9DF4).

The input parameter xt of this Rug Pull transaction is 420,690,000,000,000,000,000,000, corresponding to 420,690,000,000,000 (approximately 420 trillion) MUMI tokens (the decimal of MUMI tokens is 9).

In other words, in the end, the project used 420,690,000,000,000 (approximately 420 trillion) MUMI to drain the WETH in the liquidity pool and complete the entire exit scam. However, there is a crucial question here: where did the tax collection contract (0x77fb) get so many MUMI tokens? From the previous content, we learned that the total token supply of MUMI tokens at the time of deployment was 420,690,000 (approximately 420 million). However, after the end of the rug pull scheme, when we queried the total token supply in the MUMI token contract, it remained at 420,690,000 (as shown in the figure below, displayed as 420,690,000,000,000,000, which needs to subtract the trailing zeros corresponding to the decimal, where the decimal is 9). The tokens in the tax collection contract (0x77fb), far exceeding the total supply (420,690,000,000,000, approximately 420 trillion), seem to have appeared out of thin air. It is worth noting that, as mentioned earlier, the address 0x77fb, acting as the tax address, has not even been used to receive transaction fees generated during the process of transferring MUMI tokens; the tax was received by the token contract itself.

Reveal the Technique

  • Where did the tax contract come from?

In order to explore the token source of the tax contract (0x7ffb), we looked at its ERC20 transfer event history.

The results revealed that out of all 6 transfer events involving 0x77fb, only events were observed where tokens were transferred out from the tax collection contract (0x7ffb), with no events of MUMI tokens being transferred in. At first glance, it indeed appears that tokens in the tax collection contract (0x7ffb) appeared out of thin air. Therefore, the significant amount of MUMI tokens seemingly appearing out of thin air in the tax collection contract (0x7ffb) has two characteristics: 1. It did not affect the totalSupply of the MUMI contract. 2. The increase in tokens did not trigger a Transfer event. With this in mind, it becomes apparent that there must be a backdoor in the MUMI token contract, directly modifying the balance variable without corresponding changes to the totalSupply or triggering Transfer events. In other words, this is a non-standard or malicious implementation of an ERC20 token, where users cannot perceive the project team’s stealthy minting of tokens from changes in the total supply or events. The next step is to verify this idea by directly searching for the keyword “balance” in the source code of the MUMI token contract.

As a result, we found that there is a private type “swapTokensForEth” function in the contract, and the input parameter is tokenAmount of type uint256. In the 5th line of the function, the project party directly modifies _taxWallet, which is the MUMI balance of the tax contract (0x7ffb) fortokenAmount 10*_decimals, which is 1,000,000,000 (approximately 1 billion) times the tokenAmount, and then convert the tokenAmount amount of MUMI into ETH from the liquidity pool and store it in the token contract (0x4894). Then search for the keyword “swapTokenForEth”.

The “swapTokenForEth” function is called within the “_transfer” function. Upon closer inspection of the calling conditions, it is observed that: 1. When the recipient address (to address) of the transfer is the MUMI-WETH liquidity pool. 2. The “swapTokenForEth” function is called only when the quantity of MUMI tokens purchased by other addresses in the liquidity pool exceeds “_preventSwapBefore” (5 times). 3. The “tokenAmount” parameter passed into the function is the minimum value between the MUMI token balance owned by the token address and “_maxTaxSwap”.



That is to say, when the contract detects that the user has exchanged WETH for MUMI tokens in the pool more than 5 times, it will secretly mint a huge amount of tokens for the tax address, and convert part of the tokens into ETH and store them in the token contract. On the one hand, the project party ostensibly collects taxes and automatically exchanges them for a small amount of ETH regularly and puts them into the token contract. This is shown to users and makes everyone think that this is the source of the project party’s profits. On the other hand, what the project team is really doing is to directly modify the account balance and drain all the liquidity pool after the number of user transactions reaches 5 times.

  • How to make profit

After executing the “swapTokenForEth” function, the “_transfer” function will also execute sendETHToFee to send the ETH obtained from tax collection in the token address to the tax contract (0x77fb).

The ETH in the tax contract (0x77fb) can be taken out by the “rescue” function implemented in its contract.

Now look back at the redemption record of the last profitable transaction in the entire exit scam.

A total of two exchanges were made in the profitable transaction. The first time was 4,164,831 (approximately 4.16 million) MUMI tokens for 0.349 ETH, and the second time was 416,483,100,000,000 (approximately 416 trillion) MUMI tokens for 9.368 ETH. The second exchange is the exchange initiated within the “swapExactETHForTokens” function in the tax contract (0x7ffb). The reason why the number does not match the 420,690,000,000,000 (approximately 420 trillion) tokens represented by the input parameters is that some of the tokens are used as tax sent to the token contract (0x4894), as shown in the figure below:

The first exchange corresponds to the second exchange process. When the token is sent from the tax contract (0x7ffb) to the router contract, the backdoor function trigger condition in the token contract is met, causing “swapTokensForEth” to be triggered. The exchange initiated by the function is not a critical operation.

  • Harvester Behind the Scam

As seen from the previous content, the entire cycle of the MUMI token, from deployment to liquidity pool creation, and then to the Rug Pull, took only about 3 hours. However, it managed to gain over 50% profit with a cost of less than approximately 6.5 ETH (3 ETH for adding liquidity, 3 ETH for swapping MUMI from the liquidity pool as bait, and less than 0.5 ETH for contract deployment and initiating transactions), resulting in 9.7 ETH. The attacker conducted five transactions of exchanging ETH for MUMI, which were not mentioned previously. The transaction details are as follows:

Upon analyzing the EOAs (externally owned accounts) operating within the liquidity, it was discovered that a significant portion of the addresses belonged to on-chain “bot” operations. Considering the rapid in-and-out nature of the entire scam, it is reasonable to assume that the target of this scam was the various active “bots” and scripts on the chain. Therefore, whether it’s the seemingly unnecessary but complex contract design, contract deployment, liquidity locking process, or the suspicious behavior of attackers actively swapping ETH for MUMI tokens midway, it can all be understood as attempts by attackers to deceive various on-chain bots’ anti-fraud mechanisms. By tracking the fund flow, it was found that all profits obtained from the attack were eventually sent by the attacking address ② (0x9dF4) to the address 0xDF1a.

In fact, both the initial funding sources and final destinations of multiple recent exit scams have pointed to this address. Therefore, a rough analysis and statistics of this address’s transactions were conducted. It was found that the address became active approximately 2 months ago and has initiated over 7,000 transactions to date, interacting with over 200 tokens. Among approximately 40 analyzed token transaction records, it was found that almost all tokens, when viewed in their corresponding liquidity pools, would have a single large exchange transaction that depletes all ETH in the liquidity pool, and the entire exit scam cycle is short. Here are the deployment transactions of some tokens (e.g., Chinese cigarette):

https://etherscan.io/tx/0x324d7c133f079a2318c892ee49a2bcf1cbe9b20a2f5a1f36948641a902a83e17

https://etherscan.io/tx/0x0ca861513dc68eaef3017e7118e7538d999f9b4a53e1b477f1f1ce07d982dc3f

Therefore, it can be concluded that this address is, in fact, a large-scale automated “exit scam” harvester, targeting on-chain bot operations. This address is still active.

In conclusion, if a token’s minting process does not correspond to modifying the totalSupply or triggering Transfer events, it is difficult for us to perceive whether the project team is secretly minting tokens. This exacerbates the current situation where the security of tokens depends entirely on the consciousness of the project team. Therefore, it may be necessary to consider improving existing token mechanisms or introducing an effective token total supply monitoring scheme to ensure transparency in token quantity changes. Relying solely on events to capture token state changes is not enough. Moreover, we need to be aware that although people’s awareness of fraud prevention is increasing, attackers’ methods of counter-fraud are also advancing. This is an endless game, and we need to continue learning and thinking in order to protect ourselves.

  • Tools used in this article

View basic transaction information: https://etherscan.io/

Contract decompilation: app.dedaub.com/decompilejson-rpc: https://www.quicknode.com/docs/ethereum/eth_getStorageAt

Disclaimer:

  1. This article is reprinted from [CertiK], Forward the Original Title‘技术详解 | 链上打新局中局,大规模Rug Pull手法解密’.All copyrights belong to the original author [CertiK]. If there are objections to this reprint, please contact the Gate Learn team, and they will handle it promptly.
  2. Liability Disclaimer: The views and opinions expressed in this article are solely those of the author and do not constitute any investment advice.
  3. Translations of the article into other languages are done by the Gate Learn team. Unless mentioned, copying, distributing, or plagiarizing the translated articles is prohibited.
Start Now
Sign up and get a
$100
Voucher!
Create Account