This article delves into the functionalities and benefits of token approval tools, while also contrasting the features of De.Fi Shield with Revoke.cash.
Rug pulls are one of the most treacherous crypto scam techniques that DeFi enthusiasts have to deal with. One moment you think you’ve invested in a potentially lucrative coin, the next you are staring at a value of $0 next to the tokens that you own.
What are the mechanics behind this scam? And why are they so common? In this blog, we’ll explain how crypto rug pulls work and how to use our DeFi dashboard safety tools to ensure that you avoid being taken advantage of.
Are All Rug Pulls the Same?
First, a little terminology lesson. Many terms are used in crypto fairly loosely as the industry is so new. As a collective group exploring the bleeding edge of a new economic system, we are still trying to sort through the best ways to refer to things. This means that you may hear the term “rug pull” used to describe a variety of hack and scam techniques that take place throughout the industry. Many people will even go so far as to call a project that has done nothing wrong but had its token price go down a “rug”.
With this in mind it is important to understand that not every use of “rug pull” you see in the wild is referring to a “DeFi rug pull”. There are specific technical ways for a project to perform a “rug pull” that are explicit to the DeFi space. These are techniques that are only possible via onchain trading. In this blog we are specifically talking about these “DeFi rug pulls” and how they are executed.
What Is a DeFi Rug Pull?
DeFi rug pulls occur when a coin’s price drops significantly due to the removal of trading liquidity or a significant shift in the amount of one (or several) bounded tokens in the pair. Scammers use sophisticated techniques to deploy rug pulls and arbitrarily seize total control of the market.
The resulting carnage looks like this:
These exploits are made possible by the smart contract languages DeFi tokens utilize. Because these smart contracts are “Turing-complete” there is a huge variety of logical rules that can be put in place. When these rules are used maliciously to tilt the free market in favor of the person who controlled the deployment of the token, a rug pull can occur.
What Are Tokens?
To perform a basic explanation of the technical underpinnings of rug pulls, it’s important to understand what tokens are from a technical point of view.
Tokens are smart contract representations of some assets, shares, money, or services that can be interacted with and exchanged through a set of standard functions. These functions are embodied in the ERC-20 standard that was developed by Ethereum developers for security and development ease.
The standard ERC-20 functions include:
- Transferring tokens between accounts
- Checking token balances of an address
- Getting the total token supply currently available on the chain
- Approving tokens to be spent by other addresses other than their holders’ addresses
By following the standard, projects make sure their tokens will be fully compatible with any DeFi infrastructure: from yield farms and lending protocols to GameFi and Metaverse projects.
With libraries like OpenZeppelin contracts, ERC standards can be copied and combined with custom functionality to suit the given nature of a project.
Problems come when standard token functionality is maliciously modified or extended with backdoors. This creates the opportunity for rug pulls.
Smart Contract Modifications Used for Rug Pulls
Minting functionality can be risky when a large number of tokens can be minted to a specific Ethereum address, a multisig with anonymous owners + low confirmation threshold, or an unverified contract with the direct purpose of dumping the token on an exchange. Here are common minting strategies used for rug pulls:
Privileged infinite mint
Malicious minting can be done in a few ways. Creating a privileged mint function without any limitations on the amount and destination of minted tokens is one of them.
This rug pull has a simple technique:
- Token deploy
- Liquidity pair creation
- Token mint
- Token dump
Creating a basic ERC-20 token is not a big deal. You don’t even need deep knowledge of Solidity to do it. There are many token constructors available for free, such as OpenZeppelin Wizard, where you can get your token code in a few minutes after selecting the functionality you will need, including a privileged mint.
In terms of development, nothing else is really necessary to perform a mint rug pull. Most rug-pulled tokens do not have any infrastructure built around them. In practice, promises of a bright future for the token are enough to generate hype.
For users to start buying a newly created token, scammers then create a trading pair or few on DEXs. It’s super easy and fast as it doesn’t require passing any KYC process. The only thing needed is to provide liquidity for the pair to enable swaps, where the pair creator has to add some amount of the scamcoin and an appropriate amount of a valuable token like USDT, USDC, or ETH to provide the start price of the future rug pull token.
As users start buying the rug pull token, its price rises. Here is when minting a large number of tokens comes into play. The scammer mints a huge amount of the rug pull token and swaps it to the valuable tokens that buyers have now provided to the liquidity pool via their swaps. The rug pull token then sells off, leaving all other token holders with a token that has no value, nor can be sold because the scammer has emptied the liquidity pool of the valuable token with their sale.
Another way for scammers to get a large token balance is embedding mint into some unexpected protocol functionality. For example, fraudulent devs can add minting into the transfer() function of the token contract or into a Masterchef’s deposit(). As a result, each time users do simple transfers or deposits, a certain amount of the project’s token is minted to a wallet, controlled by the scammers.
One more trick scammers use to take control of a large portion of the token supply is preminting it to their wallet when deploying the ERC-20 token contract. And the other rug pull steps remain the same: create a liquidity pair and sell the preminted tokens once a sufficient amount of buyers appear to increase the token’s price.
You should keep in mind that projects can also do hidden minting. To understand this concept, ask yourself, what technically is “minting” ERC-20 tokens? The answer: Increasing the balance of an address + corresponding increase of the total supply variable + emitting transfer event with “from” set to the zero address.
So, hidden minting happens without updating the total supply, bypassing some formal limitations if present.
Minting can be hidden in an unexpected custom function. Moreover, this backdoor can be added by modifying some standard libraries like SafeMath (a lib for performing basic math operations with protection from overflows or underflows). This makes it even harder to detect. Especially for users with average to low technical knowledge.
How not to get rekt?
To reveal if there was a large premint of a token:
Go to the Transfers section of the token on a blockchain explorer like Etherscan
Filter transfer transactions with zero address. All transfers coming FROM 0x0000000000000000000000000000000000000000 are mints:
We’ve taken the rugged $SCAT as an example, and here is the result:
Click on the transaction hash to see details. In the example, we see that a premint of 100B $SCAT happened right when the deployment of the token contract occurred and the amount was directed to the deployer address.
To check for the possibility of privileged minting:
- Try to find mint() in the token contract.
- Check if only a defined role can call it. Most frequently, the allowed minters are either Owner, Admin, Minter, or Governance, or it can be a list of minter addresses.
If it’s a standard mint function, it will look like this:
In the example code above, there is a “require” statement that the caller must belong to a list of allowed minters. The key word here is “public” meaning this function can be called from anyone outside of the contract with the applied “require” limitations. Often you’ll see this requirement implemented through the “onlyOwner”/”onlyMinter”/”onlyAdmin”/etc. modifiers.
Let’s see what happens inside the internal _mint() function:
The total supply of the token gets increased by the input amount, and so does the receiver’s balance. And a Transfer event is created.
But you won’t always see such a clear picture. Minting can be implemented in a totally custom way so that its presence is not so obvious to regular users.
Look at how creative it can get:
Yes, what you see is actually a mint! A hidden mint. In this “burn” function, the contract owner can literally set the token balance of any address to any value. As no event of transferring the token from zero address gets emitted and the total supply value is not updated, when the scammer calls it, it’s very unlikely somebody will notice a mint has just happened.
Such hidden mint won’t even appear if you filter transfer transactions in a blockchain explorer by 0x0 address. Neither you will be able to see this mint with other tools for onchain analysis like Bloxy.
By the way, the example of this creative mint function is the rug pulled $K3PV. And this is how the scammer actually used the hidden mint/”burn” backdoor:
The scammer assigned 99.9M tokens to their own balance when calling this “burn”. In the next transaction, by the rug pull classic, the malicious receiver of the minted amount just swapped it on Uniswap for ETH.
But before judging if a found mint is a risk factor, especially if it is a standard, non-custom-written ERC-20 mint, you should check what type of address exactly is set as the minter. Externally owned account (EOA)? Unverified contract? Multisig of anonymous devs? These are red flags if there are no limitations on mint(). What is common for all three named caller types? – They are centralized. Nobody can predict and influence their actions.
Speaking of limits, does the amount that can be input into the mint() function have limits? What are the possible destinations of tokens that are about to be minted? Can the “to” parameter be set to any address? These are all excellent questions to ask.
Another classic way to rug pull is to remove liquidity after a token’s price has soared, leaving users with a token that’s worth nothing and can no longer be sold anywhere.
How not to get rekt
Performing a simple on-chain analysis is what is needed to detect a potential liquidity removal rug pull. You need to make sure:
- Liquidity is locked
- Liquidity is sufficient
Locked liquidity means that its provider cannot remove it from the pool until a certain period of time is over. Some projects opt for locking the liquidity they provide permanently through burning it a.k.a. sending LP tokens to the zero address so that the liquidity is always there for trouble-free token swaps.
The lock guarantees liquidity cannot be pulled out of the token pair anytime soon, meaning you’ll be able to sell the token should you want to.
How exactly can liquidity be checked?
1. Open the LP token contract on Etherscan or another blockchain explorer. Addresses of all trade pairs for the token can be found either on platforms like https://dexscreener.com/ or by looking through token holders on Etherscan.
2. Navigate to the Holders section of the LP token.
3. LP tokens must be held by locking contracts or by zero address. In the example given above, we can see that 97% of the liquidity is locked on a Unicrypt contract.
4. If liquidity is held by a lock contract, check what is the unlock time. To do that, click on the contract holding LPs:
5. Open an LP locking or relocking transaction. Let’s check that Relock we see on the screen.
6. You’ll see the unlock time expressed in Unix timestamp in the transaction input section. Click the “Decode Input Data” button to view the input values.
If it still sounds too complicated, no worries. If you use our DeFi dashboard, you’re protected by the De.Fi security solutions. Just use our smart contract scanner when you do your due diligence regarding purchasing a token. It provides an easy-to-use report on all the token’s security information, including its liquidity state.
When it comes to evaluating if added token liquidity is sufficient, there is no single objective value to take as a reference point, but it’s definitely worth avoiding pools where the project team was able to add liquidity worth only a few thousand USD. The price of a token can be easily manipulated under low liquidity. This makes these sorts of tokens extremely volatile.
Such token pools can attract with their impressive, temporary price surge. But remember, easy come, easy go. If a token’s price can be pumped easily it can just as easily be dumped.
Unfair token distribution
Here you should analyze the major token holders. Navigate to the Holders section of the token on a blockchain explorer or the De.Fi token scanner and analyze what addresses own significant token shares:
When a private wallet or an unverified contract owns a large share of a token’s total supply, there is a risk that this token amount will be dumped on an exchange. What total supply percentage is enough for dumping the token price depends on available liquidity in pools. Owning even 5% of the token supply might be enough to cause significant volatility in the token price if there is only minimal liquidity.
However, it’s important to know that many legitimate projects have wallets that hold a large percentage of supply but have pledged to hold these tokens for set periods of time, use them for specific goals, etc. Context is important for judging all rug pull “red flags” and there are no guarantees that wallet supply percentages will lead to a negative outcome.
Now let’s discuss transfer fees and how you can check if any fee is imposed on the ERC-20 transfer.
There are a few risks associated with this token feature:
- If there is a transfer fee and it can be set to 100% without any limits (or if it is already set to the maximum) users will lose their tokens when they attempt to transfer. In general, we consider the max acceptable transfer fee to be 5%.
- Even if the transfer fee is low (below 5%), it still can break the functionality of a protocol the token is used in or make it vulnerable to exploits. An example is the PolyYeld exploit.
Another way projects can rug pull is by making tokens non-transferable. Unsellable tokens are usually called honeypots.
There are many ways to make a token a honeypot. We’ll consider the most common of them, such as blacklisting addresses, pausing token transfers, and setting transfer amount limits.
Pausing in the transfer() and transferFrom() functions can make the token non-transferrable for all users with one click. The contract admin/owner can set a state under which any function containing a requirement for this state will be blocked from execution.
Let’s look at the following example:
This transfer() function contains a function modifier whenNotPaused. It contains a requirement for the state of the “pause” variable to be not paused:
The pause state can be changed by the Pauser role:
You can easily read who the Paused is in the “read contract” section of a blockchain explorer:
In this case, the Pauser role is given to a regular wallet meaning the latter can call the pause() anytime completely blocking users from selling their tokens.
Let’s see how the De.Fi scanner helps you detect the function exposing users to the honeypot risk while defining the severity of the problem based on the function caller. The contract used is 0xcec4d283aa944fbce8abf6aba8d0f7af37f570f4 (Ethereum):
It’s indicated that 2 wallet addresses can call pausing. So, if they have the intention to disable any token transfers and prevent the token from selling, they can do it without any limitations.
You also should know that if the approve() function can be paused, it is another way to turn the token into a honeypot. Once approve() is paused, it is impossible to swap the token since the way to set a DEX router to be a spender of the token is completely blocked. Every swap function on any DEX router has the transferFrom() call inside it, which requires that the swap contact (the router) has approval from the user to move their balance.
Blacklisting is a way to block users from calling a specific function by writing selected addresses into a list that is not allowed to call this function. When we are talking about making ERC-20 tokens unsellable, blacklisting in the transfer() function must be examined.
Let’s analyze another example of De.Fi scanner results. The analyzed token is 0x419264d79b92b8DE3C710AB0cD3406Cd11990e02 (BSC).
The scanner’s advanced view helps us to see that the possibility of transfer blockage comes from the checkWalletLimit check that contains the isWalletLimitExempt condition.
The risk is estimated as High due to the indicated Governance type. You can see that it is a regular wallet. Technically this means that the wallet can disable token transfers anytime making the token unsellable.
Some tokens can include blacklisting for security reasons, such as USDT. This is clear centralization, but for legit projects, it’s acceptable as we know this functionality will only be called on for explicit purposes and not to rug pull users.
Transfer amount limits
Another way to control user transfers in a centralized way is by setting limits on token transfer amounts. Pay attention to both upper/lower limits. For example, if the maximum amount is set to 0 or the minimum amount is a very large number, transfers are blocked completely. Hence, it becomes impossible to sell the token.
Before buying any token, check if it doesn’t contain any transfer-blocking functionality and is sellable with the De.Fi token scanner. We integrated the checks for transfer pause, blacklisting, transfer limits, and honeypots, where the latter is based on transaction simulation to detect if the token is sellable.
As smart contract code deployed to a blockchain cannot be modified, some dev teams decide to use upgradability patterns called proxies. How do they work? Two contracts are deployed. One acts like a gateway and info storage, another contains the logic that must be executed.
The contract that users interact with is a proxy. When developers want to change logic, they just deploy a new logic contract called implementation, which gets bound to the proxy. The proxy address remains the same so users won’t notice anything.
While this brings flexibility for projects utilizing this pattern, users are exposed to significant risk as the functionality of a contract holding their funds or having access to their wallets through approvals can be changed in a malicious way to perform a rug pull.
Avoid Rug Pulls With De.Fi
Here at De.Fi, we’re proud to offer a variety of free tools to users of our DeFi dashboard to help keep their funds safe from malicious rug pulls, tricky smart contract allowances, and phishing scams.
Our free smart contract auditor and wallet permissions revoke tool are essential products that ensure users can spot vulnerabilities quickly and easily. For projects that are interested in boosting security, we also offer smart contract audit services.
Check out the videos below to learn more or connect your wallet to the DeFi dashboard today to get started with web3’s best antivirus!
Make sure to also follow our De.Fi Security account on Twitter to stay up-to-date on new DeFi exploits.