EspressoBot Rug Pull

Reported loss $53K
Rugpull

What happened

EspressoBot (ESPS) is an ERC-20 token on Ethereum that was marketed as the native token of a Telegram bot for launching tokens, trading on Uniswap. Cyvers posted an alert on 2023-08-31 saying its system had detected multiple rug pull transactions by the deployer, 12 transactions from address 0xee34Cc55…3C0f18 totalling about $91K. De.Fi's REKT database lists the loss as 53,110 USD (33.04 WETH) of Uniswap liquidity drained in 12 transactions, with the proceeds passed through several EOA addresses and part still held in another EOA, and says the deployer was funded on Binance. The two sources give different totals and are kept side by side here.

The verified source gives the deployer wide power over holders: sell and transfer fees that can be set up to 100 percent, and an accounting error that credits whitelisted addresses with a fixed amount of tokens when an ordinary holder sends to them. The code shows what the contract allows. The sources opened here do not show which of these functions were called.

Deployer address: 0x5737083f…a8CdcE. Scammer address listed by De.Fi: 0xee34Cc55…3C0f18. Funds holder address as of Sep 10, 2023 per De.Fi: 0x13ce2410…ef5579. Liquidity drain transactions listed by De.Fi: 0xe49905a4…4482f0 and 0xb20a97e2…c83659.

How it happened

  1. The constructor creates the Uniswap pair, credits the full supply to the deployer (_balances[msg.sender] = _totalSupply;) and whitelists two distinct addresses in isExcludedFromTaxFee: the deployer and the address 0x11d628DD…051B6b, which is set as the development, marketing and liquidity receiver. No function changes that whitelist afterwards.
  2. Ordinary transfers are blocked until the owner calls startTrading(), which only sets tradeActivated = true. Whitelisted addresses skip that check (require(tradeActivated, "tradeActivated") runs only when neither side is whitelisted).
  3. Fees start at 12 percent (sellFee = 1200 with denominator = 10000), but setTransactionRequirements accepts values up to denominator.div(1), which is 10000 or 100 percent, even though the error text says 20 percent. At a 100 percent sell fee, feeAmount equals the sold amount, the seller's balance is debited the full amount (_balances[sender] = _balances[sender].sub(amount);) and the pair receives amountReceived = amount.sub(feeAmount), which is zero.
  4. Fee tokens collect in the contract. On a later sale, swapCATokens sells them for ETH and payable(development_receiver).transfer(contractBalance) sends the whole ETH balance to 0x11d628DD…051B6b.
  5. takeFee contains a line that credits whitelisted recipients with the wrong amount: if (isExcludedFromTaxFee[recipient]) {return _maxTxAmount;}. When a non-whitelisted holder sends any amount to a whitelisted address, the sender is debited amount, but _balances[recipient].add(amountReceived) credits the whitelisted address with _maxTxAmount, initially 2 percent of supply (20,000,000 tokens), and the same transfer skips the trade, wallet and size checks. setTransactionLimits only enforces a minimum of 0.5 percent of supply, so the owner can raise _maxTxAmount without an upper bound. A whitelisted address can then sell those tokens into the pair with no fee and no size limit.
  6. What happened, per Cyvers and De.Fi's REKT database: on 2023-08-31, about four hours after deployment, the deployer-linked address 0xee34Cc55…3C0f18 drained the Uniswap pool in 12 transactions (De.Fi: 53,110 USD, 33.04 WETH; Cyvers: about $91K) and the proceeds moved through several EOA addresses. No opened source says which of the mechanisms above, if any, was used, or whether the drain was liquidity removal or token sales.

Protocol details

Classification Token
Protocol Type Exit Scam/Rugpull
Affected asset / contract ESPS
Protocol links @EspressoBot_ETH

Build your security review skills

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