LayerZero Rug Pull

Reported loss $1.0M
Rugpull

What happened

This record covers a copycat token named LayerZero (ZRO) on BNB Chain (0x2266362f…99ae1c), not the LayerZero protocol. The token's _approve function stores every approval under the contract owner's address instead of the approving holder's. As a result, a holder who approves the PancakeSwap router still has a zero allowance, and any router sale reverts, while buys keep working.

The owner also has a misnamed RenounceOwnership function that can switch off transfers and approvals for everyone outside a whitelist, a burn function that actually mints, and functions that hand ownership to any address. On 20 August 2023, CertiK reported that the deployer, 0x7Ee2fc5e…955aBE, removed 4,827.99 WBNB (about $1 million) of liquidity from the token's pool. De.Fi's REKT database says the token was promoted in a Russian-speaking Telegram group called KryptoAtom and puts the loss at 1,045,094 USD.

It lists the liquidity removal as 0x098ed453…2aed67 and swaps to USDT in 0xefa6247b…1b7352, 0x1b63f44b…cf10d2 and 0x3f49c124…3948ff. It names 0x2ebc576b…b72d5e as the scammer address and says the funds were still at 0xa792a4ad…ad4d84 as of 21 August 2023.

How it happened

  1. The constructor credits all 10,000,000 ZRO to the deployer and sets it as owner.
  2. _approve(address _owner, address spender, uint256 amount) writes _allowances[owner][spender] = amount. Here owner is the contract-owner state variable, not the _owner parameter, so a holder's approve for the router sets the contract owner's allowance and leaves the holder's own allowance at zero.
  3. A router sale calls transferFrom(holder, pair, amount), which requires _allowances[sender][_msgSender()] >= amount. For every holder except the owner that value is zero, so the sale reverts with "ERC20: transfer amount exceeds allowance".
  4. Purchases use the pair's plain transfer to the buyer, which does not read allowances, so buying keeps working.
  5. RenounceOwnership(address _DEAD, bool _boo) does not renounce anything; it sets safeTransfer = _boo. When safeTransfer is false, _transfer and _approve only succeed for addresses the owner has listed with Prize_Fund, and everyone else gets a misleading "transfer to the zero address" error.
  6. The owner can also mint any amount to any address with burn(account, amount), which adds to the balance and total supply, and can move ownership with changeOwner or OwnershipRenounce.
  7. What happened: CertiK reports that the deployer removed 4,827.99 WBNB of liquidity from the pool on 20 August 2023.

Protocol details

Classification Token
Protocol Type Bridge
Affected asset / contract ZRO
Protocol links Website @LayerZero_Labs

Build your security review skills

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