On-Chain Password Red Packet: Why Was It "Instantly Snatched" Right After Sending? — A Real MEV Front-Running Attack Experience

A few days ago, I had a sudden idea: to create a pure on-chain password red packet. It sounded romantic and secure.
The design was as follows:
  • Sender: Hash the password off-chain using keccak256 to get the hash
  • Store hash + red packet amount into the smart contract (create red packet)
  • Claimer: Enter password → contract runs keccak256 again
  • If the two hashes match → transfer the corresponding amount
In theory, cracking keccak256 is as difficult as brute-forcing an Ethereum private key, so the security seemed solid.
I tested it N times locally and on testnet — everything worked smoothly. Feeling confident, I deployed the contract to Mainnet.
contract
Then I created the first test red packet:
  • Amount: 0.001 ETH
  • Password: some random string
  • Hit send → transaction Pending
Then I created the claim transaction and stared at Etherscan for about 5-10 seconds...
Page refreshed:
"Error: Red packet already claimed"
??????????
I was stunned for three seconds.
I just created the red packet, I calculated the hash myself, and the private key is on my local machine. How could anyone instantly crack keccak256?
Transaction Details
After calmly reviewing the transaction records, I discovered the truth:
A few milliseconds before my "create red packet" transaction, there was an almost identical claim transaction with the exact same calldata (including the hash I just stored), except the gas price was much higher...
This was done by an MEV searcher's bot.

What Actually Happened? The Principle of MEV Front-Running Attacks

Ethereum (and most public blockchains) process transactions roughly like this:
  1. You sign and send a transaction → enters the public mempool (memory pool)
  2. All nodes across the network can see the transaction contents in the mempool (including calldata, to, value, etc.)
  3. Searchers run bots, monitoring the mempool 24/7
  4. Once they spot a profitable opportunity, the bot immediately copies/constructs a new transaction with higher gas price (or through bundles) to cut in line
  5. Validators (formerly miners, now proposers) prioritize packaging transactions with higher gas bids
In my case:
  • The create red packet transaction exposed the hash in the mempool
  • The bot instantly saw this hash
  • The bot immediately constructed a claim transaction (calling the contract's claim function, passing in the same hash — it didn't even need the password, because it directly used the hash I stored)
  • The bot raised the gas price → got packaged first → red packet was claimed
  • When my claim transaction arrived, the balance was already 0, so it could only revert
This isn't cracking keccak256, but exploiting the "public information + transaction ordering auction" mechanism, directly copying my homework.
This type of attack is classically called Front-running, a common form of MEV (Maximal Extractable Value).
Similar scenarios are more prevalent in DeFi:
  • Sandwich attacks: Buy before your large swap, sell after, profiting from slippage
  • Liquidation front-running: See you're about to be liquidated, liquidate you first to earn the reward
  • ...
As long as transaction content is public in the mempool and execution results can produce quantifiable profit, it may be targeted by bots.

How to Avoid This "Blatant Robbery"? Common Approaches

  1. Commit-Reveal Two-Phase Scheme (more secure but complex)
    • Phase 1: Only submit hash of hash (commit)
    • Phase 2: Attempt to claim based on the submitted hash (reveal)
  2. Sign the Message
    • Off-chain sign the hash value using ERC-712, submit the signature when claiming, contract verifies signature validity. Since the signature is generated by the claimer's private key, bots cannot forge it
The most realistic conclusion: Pure public mempool + pure on-chain password red packet is basically giving it away to bots in the current Ethereum environment.

Conclusion: 0.001 ETH Tuition Fee, Bought Me Clarity

The money lost wasn't much, but the pain was real.
It made me thoroughly understand one thing:
On Ethereum, you're not just interacting with contracts — you're racing with the fastest searchers across the network.
Any design that meets these two conditions will almost certainly be front-run:
  • Critical information (hash, parameters) is public in the mempool
  • Execution results in immediate, quantifiable economic profit
Next time I build something like this, I'll ask myself first:
"If a bot sees this transaction, can it immediately copy it and earn profit by front-running with higher gas?"
If the answer is "Yes", then I need to rethink the approach.
The on-chain world is always a dark forest.

PASS IT ON