x20 finance Rug Pull

Reported loss $3K
Ethereum
Rugpull

What happened

x20.finance (X20) was an ERC-20 token on Ethereum (0xd24c65a2…7b13ec) with a sell block hidden in a helper named _ints. The creator, stored as _address0, can call ints(address) to name a second privileged address, _address1. Once that address differs from the creator, any transfer not to or from the creator reverts unless the tokens come from _address1, the Uniswap router or a whitelisted wallet.

On 16 November 2020 the creator added 40,800 X20 and 2 ETH to Uniswap V2 and, 90 seconds later, called ints with the X20/WETH pair as the argument. From then on, buys from the pair went through but holders' sells into it reverted, while the creator could still sell. The creator sold X20 into the pool, and on 17 November removed 282.66 of its 285.66 LP tokens for 5.60 ETH and 14,328 X20.

De.Fi's REKT database lists the case as an exit scam with $2,501 lost.

How it happened

  1. The constructor records the creator as both privileged addresses and mints the whole supply to it: _address0 = owner; _address1 = owner; _mint(_address0, initialSupply*(10**18));. On-chain supply is 50,000 X20.
  2. Every transfer runs _ints(sender, recipient, amount): if(recipient != _address0 && sender != _address0 && _address0!=_address1 && amount > _zero){require(sender == _address1 ||sender==_router || _Addressint[sender], ...)}. While _address1 equals the creator the check is skipped, so the token trades normally.
  3. ints(address addressn) lets only _address0 change _address1. At 11:27:14 UTC on 16 November 2020 the creator added 40,800 X20 and 2 ETH to Uniswap V2. At 11:28:44 UTC it called ints(0xaE8cA64C2A2c2D10D78dB02783081877BBdcBEEF), the X20/WETH pair (transaction 0x1471b466…1f430e).
  4. From then on a buy passes, because the tokens leave from the pair, which is _address1. A holder's sell fails, because the tokens leave from the holder, who is not _address1, the router or whitelisted. The error message reuses the misleading text "ERC20: transfer from the zero address".
  5. The creator is exempt as _address0. It sold X20 into the pool, for example 1,200 X20 for 0.433 ETH at 12:11:44 UTC (transaction 0x7917b57c…0a6682).
  6. On 17 November 2020 at 13:18:57 UTC the creator burned 282.66 LP tokens with removeLiquidityETHWithPermit and received 5.60 ETH and 14,328.11 X20 (transaction 0xe558685b…4c92b6). The payout passes the check because the pair and the router are both allowed senders. The ETH above the creator's 2 ETH deposit had been paid into the pool by buyers.

Protocol details

Classification Token
Protocol Type Exit Scam/Rugpull
Affected asset / contract X20

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.