Skip to content

Rug Pulls and Fake Projects

💡
Before you start

Python 3 and a terminal — nothing else, and no cryptocurrency. On Windows install Python from python.org with “Add python.exe to PATH” ticked; macOS and Linux already have it. Check with python3 --version.

You do not need to read Solidity to do this. You will be handed a token contract, and the skill you are building is not “understand the code” but “find the handful of powers the owner kept” — which is a search, not a reading comprehension test. The two contracts used here are written out on this page; nothing is downloaded and no blockchain is contacted.

What is a Rug Pull?

A rug pull is a type of scam where developers create a cryptocurrency token, attract investors, build up liquidity, and then suddenly withdraw all funds — "pulling the rug out" from under investors. The token becomes worthless and investors cannot sell.

Rug pulls are among the most common DeFi scams because anyone can create a token on Ethereum or similar blockchains in minutes, with minimal cost and no identity verification.

How Rug Pulls Work

  • Step 1: Create a token — the scammer deploys a smart contract creating a new token with a catchy name and marketing
  • Step 2: Add liquidity — they pair their token with a real cryptocurrency (like ETH) on a decentralized exchange, making it tradable
  • Step 3: Generate hype — social media marketing, influencer promotions, fake partnerships, and manufactured FOMO drive people to buy
  • Step 4: Price rises — as people buy, the token price increases, attracting more buyers
  • Step 5: Pull the rug — the developers withdraw all the real cryptocurrency (ETH) from the liquidity pool, leaving investors holding worthless tokens

Types of Rug Pulls

Liquidity theft The developer removes all liquidity from the trading pool. Investors can no longer sell because there is nothing to sell against. This is the classic rug pull.
Hidden mint functions The smart contract contains a hidden function that allows the developer to create unlimited new tokens. They mint millions of tokens and sell them, crashing the price.
Sell restrictions The contract allows anyone to buy but only the developer to sell. Investors discover they are unable to sell at any price. Also known as a "honeypot" — and it can be detected before you buy, by simulating the sale first.
Slow rug Instead of pulling everything at once, the developers gradually sell their holdings over time while maintaining appearances. By the time investors notice, most value has been extracted.

Red Flags of a Rug Pull

⚠️
Any single red flag should make you extremely cautious. Multiple red flags should make you walk away.
  • Anonymous team — no verifiable identities, just pseudonyms and anime profile pictures
  • No smart contract audit — or an "audit" from an unknown or fake auditing firm
  • Unlocked liquidity — the developer can withdraw the liquidity pool at any time
  • Concentrated token supply — a few wallets hold a very large percentage of all tokens
  • Unrealistic promises — "1000x guaranteed," partnerships with major companies that cannot be verified
  • Aggressive marketing over substance — more effort on hype than on actual product development
  • No working product — just a website, a whitepaper full of buzzwords, and a token
  • Copied code — the smart contract is a direct copy of another project with minimal changes

How to Protect Yourself

  • Check if liquidity is locked — locked liquidity means the developer cannot withdraw it for a set period. Tools like token scanners on block explorers can verify this.
  • Read the smart contract — or use automated analysis tools to check for mint functions, sell restrictions, or owner-only functions
  • Verify the audit — check the auditing firm's website directly to confirm the audit is real and applies to the current contract version
  • Check token distribution — block explorers show how tokens are distributed across wallets. High concentration is a risk.
  • Research the team — verifiable identities with professional track records are a positive sign (though not a guarantee)
  • Never invest more than you can afford to lose entirely — especially in new or unproven tokens
💡
DYOR: Do Your Own Research

This is not just a crypto catchphrase. It means independently verifying every claim a project makes before investing. Do not rely on social media hype, influencer recommendations, or community sentiment alone.

Many of these schemes depend on a counterfeit token that simply looks like a well-known asset inside a wallet. Confirming what you are actually holding is a separate and much quicker check — see How to Verify a Token Contract Address.

Now Inspect a Token Before You Buy It, in Five Steps

A rug pull is not a hack. It is a power the developer wrote into the contract, in public, before anyone bought — and it is usually visible in about ninety seconds if you know the five words to search for. In the next twenty minutes you will scan a token that keeps every dangerous power, scan one that keeps none, and then put numbers on the two ways the money actually leaves: dilution and a drained pool. Every figure below came from running these files.

1
Save the contract you are about to buy into

Go: open a terminal in a folder you can write to, e.g. cd ~/Desktop (Windows: cd %USERPROFILE%\Desktop).

Do: save this as token.sol. On a real token you would get this by opening the contract address on the chain’s block explorer and using its Contract → Code tab; if that tab shows only machine code, the source was never published, and that alone is a reason to walk away.

contract MoonRocket {
    address public owner;
    mapping(address => uint256) public balanceOf;
    mapping(address => bool) public blacklist;
    uint256 public sellTax = 5;

    modifier onlyOwner() { require(msg.sender == owner); _; }

    function mint(address to, uint256 amount) public onlyOwner {
        balanceOf[to] += amount;
    }

    function setBlacklist(address who, bool banned) public onlyOwner {
        blacklist[who] = banned;
    }

    function setSellTax(uint256 newTax) public onlyOwner {
        sellTax = newTax;
    }

    function transfer(address to, uint256 amount) public {
        require(!blacklist[msg.sender], "blocked");
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
    }
}

You should see: nothing — this is a file to save, not a program to run. Confirm it landed with ls token.sol (Windows: dir token.sol), which should print the filename back.

If not: if your editor added a .txt extension, the next step will report FileNotFoundError. In Notepad’s Save dialog set Save as type to All Files before saving.

2
Write the scanner and point it at the contract

Go: same folder.

Do: save this as scan.py, then run python3 scan.py token.sol.

import re, sys

DANGERS = {
    "mint":         "the owner can create new tokens out of nothing",
    "blacklist":    "the owner can stop chosen wallets from selling",
    "setSellTax":   "the owner can change the sell tax after you buy",
    "pause":        "the owner can freeze all transfers",
    "selfdestruct": "the contract can be destroyed",
}

source = open(sys.argv[1]).read()
defined = 1 if re.search(r"modifier\s+onlyOwner", source) else 0
owner_only = len(re.findall(r"\bonlyOwner\b", source)) - defined

print(f"scanning {sys.argv[1]}")
print(f"functions only the owner may call: {owner_only}")
found = 0
for name, why in DANGERS.items():
    if re.search(r"\b%s\b" % name, source, re.I):
        print(f"  FOUND {name:14s} -> {why}")
        found += 1
print("no owner-controlled danger found" if not found else f"{found} danger(s) found")

You should see: three powers the developer kept for themselves:

scanning token.sol
functions only the owner may call: 3
  FOUND mint           -> the owner can create new tokens out of nothing
  FOUND blacklist      -> the owner can stop chosen wallets from selling
  FOUND setSellTax     -> the owner can change the sell tax after you buy
3 danger(s) found

Nothing here is hidden or clever. These functions are declared in public, and anyone who looked before buying would have seen them. That is what makes rug pulls preventable in a way most crypto losses are not.

If not: IndexError: list index out of range means you ran python3 scan.py without naming a file — the filename is the argument. FileNotFoundError means token.sol is not in this folder.

3
Scan something honest, so you know what a clean result looks like

Go: same folder. A detector you have only ever seen say “danger” is a detector you cannot trust.

Do: save this as clean.sol and run python3 scan.py clean.sol.

contract PlainToken {
    mapping(address => uint256) public balanceOf;
    uint256 public totalSupply = 1000000;

    constructor() {
        balanceOf[msg.sender] = totalSupply;
    }

    function transfer(address to, uint256 amount) public {
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
    }
}

You should see: a clean report — and the same scanner producing it:

scanning clean.sol
functions only the owner may call: 0
no owner-controlled danger found

The whole supply is handed out once, at creation, and after that the contract can do exactly one thing: move tokens between holders. There is no owner, so there is nobody who can change the rules later. “Nobody can change this” is the property you are shopping for.

If not: if this file also reports dangers, you passed token.sol again — check the filename on the command line.

4
Put a number on what mint does to you

Go: same folder. “The owner can mint” sounds abstract until it is arithmetic.

Do: save this as dilute.py and run it.

supply = 1_000_000
mine = 10_000
print(f"you own {mine:,} of {supply:,} = {mine / supply:.2%} of the project")

for minted in (1_000_000, 10_000_000, 1_000_000_000):
    print(f"owner mints {minted:>13,} more -> your share is now "
          f"{mine / (supply + minted):.6%}")

You should see: your stake shrinking towards nothing, without a single token leaving your wallet:

you own 10,000 of 1,000,000 = 1.00% of the project
owner mints     1,000,000 more -> your share is now 0.500000%
owner mints    10,000,000 more -> your share is now 0.090909%
owner mints 1,000,000,000 more -> your share is now 0.000999%

You still hold every token you bought. Your balance never changed, so nothing looks stolen — and you own a thousandth of what you did. The newly minted tokens are then sold into the same pool your money is in, which is where the value goes.

If not: if the percentages print as decimals like 0.005, the % is missing from the format specifier — it must be :.6%.

5
Watch the liquidity leave, and price your exit

Go: same folder. This is the classic rug pull: not a function in the token at all, but the developer withdrawing the pool that lets anyone sell.

Do: save this as pull.py and run it. It models a standard automated pool, where the coin balance times the token balance stays constant.

coins, tokens = 100.0, 1_000_000.0        # the pool: x * y = k
k = coins * tokens
print(f"price before: {coins / tokens * 1_000_000:.2f} coins per million tokens")

spend = 1.0                                # you buy with 1 coin
got = tokens - k / (coins + spend)
coins, tokens = coins + spend, tokens - got
print(f"you bought  : {got:,.0f} tokens for {spend} coin")

coins, tokens = 0.01, tokens              # the owner removes the liquidity
k = coins * tokens
back = coins - k / (tokens + got)
print(f"you sell back {got:,.0f} tokens and receive: {back:.8f} coins")

You should see: a coin going in, and essentially nothing coming back:

price before: 100.00 coins per million tokens
you bought  : 9,901 tokens for 1.0 coin
you sell back 9,901 tokens and receive: 0.00009901 coins

Your tokens were never taken. They are still yours, and they are now worth about one ten-thousandth of what you paid, because the coins you would be paid from are gone. This is why the practical check is not only the contract but the pool: is the liquidity locked, for how long, and who holds the key? A project that cannot answer that has answered it.

If not: ZeroDivisionError means the remaining pool balance was set to exactly 0 instead of 0.01 — a real pool is drained to near-zero, not to zero. If back comes out negative, the last two lines were swapped; the sale must happen after the pool is drained.

🎉
Check yourself before moving on

Without scrolling up: a token’s source is published, the scanner finds no dangerous functions, and the chart is going up. Name the check you have not done, and why it matters more than the contract. Answer: you have not checked the liquidity — who holds the pool tokens and whether they are locked. Step 5 needed no dangerous function at all: the developer simply withdrew the pool, which is an ordinary action any pool provider is entitled to take. A perfectly clean contract with unlocked liquidity held by one anonymous wallet is still a rug pull waiting to happen, and the chart going up is what makes it worth pulling.

Now do it without the page: add two more entries to DANGERSsetMaxTx (the owner can cap how much you may sell in one transaction) and excludeFromFee (the owner can exempt their own wallets from the tax everyone else pays) — then write a third contract that keeps exactly one of them and confirm your scanner finds it. You now have a tool you can point at any published contract in under a minute.

Summary

  • Rug pulls involve developers creating a token, attracting investment, then stealing the funds
  • They exploit liquidity theft, hidden mint functions, sell restrictions, or gradual dumping
  • Anonymous teams, no audits, unlocked liquidity, and unrealistic promises are major red flags
  • Always verify liquidity locks, audit reports, and token distribution before investing
  • If something seems too good to be true, it almost certainly is
🎉
You can now identify rug pull warning signs!

Next, learn how to choose a secure cryptocurrency exchange and protect your funds.