Towelie Rug Pull

Reported loss $89K
Rugpull

What happened

Towelie (TOWELIE) is an Ethereum ERC20 whose _transfer carries a hidden gate: a transfer only goes through if the transaction origin is the deployer, if the sender received its tokens fewer than _allowance blocks ago, or if the recipient is the transaction origin. _allowance starts at 3,000,000 blocks but is set to 2 whenever any transfer sends tokens to a hard-coded address, or when the deployer calls setAllowance. Once it is 2, a holder selling through a DEX router (recipient is the pair, not the tx origin) is blocked unless their first receipt was in the previous block, while the deployer is always exempt.

CertiK Skynet reported on 2023-08-23 that the deployer unlocked LP tokens and removed about 89K USD of liquidity. De.Fi's REKT database lists the loss as 88,861 USD (54.72 ETH) from the Uniswap pool, with the funds moved to another EOA and then split between several addresses (about half to ChangeNOW, a quarter to Binance, a quarter left on EOAs, per the listing). Deployer: 0x9FAc5E13…C45488.

Scammer address listed by De.Fi: 0x6b883c49…B445D3. Funds holder as of September 4, 2023 per the listing: 0x55f03F60…AD9071. Liquidity removal transaction listed by De.Fi: 0x007aef7e…44537f.

How it happened

What the code allows:

  1. The base ERC20 constructor records the creator as the privileged address: _tokenAddress = msg.sender; and _pairToken[_tokenAddress] = true;.
  2. Every transfer must pass require(_pairToken[tx.origin] == true || block.number - _addressAllowance[from] < _allowance || to == tx.origin, "ERC20: Reverted");. A transaction started by the privileged address always passes. A buy through a router passes the third condition because the buyer is both recipient and tx origin.
  3. _afterTokenTransfer stamps each recipient's first-receipt block (if (_addressAllowance[to] == 0) _addressAllowance[to] = block.number;) and contains the trigger if (to == _uniswapFactory) _allowance = 2;, where _uniswapFactory is the hard-coded address 0x94C26B66…61E15e. The source does not show who controls it.
  4. setAllowance(uint256 _a) lets _tokenAddress (the deployer) change _allowance at any time. It depends on the immutable _tokenAddress, not on Ownable, so the on-chain owner reading 0x0 (read 2026-09-30) does not remove it.
  5. With _allowance at 2, a holder selling through a DEX has to equal to the pair, not the tx origin, and block.number - _addressAllowance[from] is almost always 2 or more, so the sell reverts with ERC20: Reverted. The deployer keeps selling and can move liquidity.

(per CertiK and the De.Fi listing):

  1. CertiK Skynet reported that the deployer unlocked LP tokens and removed about 89K USD of liquidity from Towelie on 2023-08-23.
  2. De.Fi lists 88,861 USD (54.72 ETH) removed from the Uniswap pool and moved through other EOAs. No opened transaction shows whether _allowance was set to 2 before or after the removal.

Protocol details

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

Build your security review skills

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