Changpeng Zhao Rug Pull

Reported loss $454K
Rugpull

What happened

CZ (on-chain name Changpeng Zhao) is a BEP20 token traded on PancakeSwap with no connection to the person it is named after. De.Fi's REKT database lists a rug pull on 2023-11-24: the deployer removed liquidity worth 454,168 USD (1,934.17 WBNB) from the PancakeSwap pool across multiple transactions while selling a large number of tokens, and the proceeds were sent to another EOA and then spread across several addresses. PeckShield's alert that day said the token had dropped 100% and that address 0xCC78A249…C2f66C swapped 992,035,763,183.91 CZ for 1,290.55 WBNB (about 303.5K USD).

The verified source shows what the contract allowed. The constructor sets _sellMarketingFee = 1000, and _transfer computes fees = amount.mul(sellTotalFees).div(100), which is ten times the amount being sold, then runs amount -= fees under Solidity 0.8 checked arithmetic. For any wallet that is not fee-excluded, a sale to the PancakeSwap pair therefore reverts. The deployer is fee-excluded by excludeFromFees(owner(), true), so the same sale path was open to that address only. The owner also has a mint function with no cap.

Addresses listed by De.Fi. Deployer: 0xCC78A249…C2f66C. Recipient of the withdrawn funds: 0x638Fbf48…0C7a85. Liquidity removal transactions: 0xd020a4e1…80a18e and 0x01f90355…1110b9.

How it happened

What the code allows:

  1. The constructor mints 1_000_000_000 * 1e18 CZ to the deployer with _mint(msg.sender, totalSupply), and the deployer address is also set as marketingWallet and devWallet.
  2. It sets the sell fee to uint256 _sellMarketingFee = 1000; and the buy fee to 0, so sellTotalFees is 1000.
  3. In _transfer, a transfer into an automatedMarketMakerPairs address by a wallet that is not fee-excluded computes fees = amount.mul(sellTotalFees).div(100);, which equals 10 times amount. The contract then executes super._transfer(from, address(this), fees); followed by amount -= fees;. Because fees exceeds amount, the subtraction underflows and the whole sale reverts (and if the seller's balance is below 10 times amount, the fee transfer reverts first). Ordinary wallet-to-wallet transfers and buys (fee 0) are not affected, so holders can receive CZ but cannot sell it into the pool.
  4. excludeFromFees(owner(), true) in the constructor skips the fee branch for the deployer (if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) { takeFee = false; }), so a sale by the deployer goes through at full amount.
  5. function mint(address to, uint256 amount) external onlyOwner { _mint(to, amount); } lets the owner create further tokens without a cap. updateSellFees can also change the sell fee, but is limited to require(sellTotalFees <= 100, ...), i.e. at most 100%.

, per the listings:

  1. On 2023-11-24, per De.Fi, the deployer removed liquidity from the PancakeSwap pool in multiple transactions and sold a large number of tokens, taking 1,934.17 WBNB (454,168 USD). PeckShield reported that 0xCC78A249…C2f66C swapped 992,035,763,183.91 CZ for 1,290.55 WBNB, which is more than the 1,000,000,000 CZ minted in the constructor. No mint transaction was opened for this review, so the source of the extra tokens is not established.
  2. De.Fi says the funds were sent to another EOA and then distributed among several addresses.

Protocol details

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

Build your security review skills

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