LayerZero Rug Pull
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
- The constructor credits all 10,000,000 ZRO to the deployer and sets it as
owner. _approve(address _owner, address spender, uint256 amount)writes_allowances[owner][spender] = amount. Hereowneris the contract-owner state variable, not the_ownerparameter, so a holder'sapprovefor the router sets the contract owner's allowance and leaves the holder's own allowance at zero.- 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". - Purchases use the pair's plain
transferto the buyer, which does not read allowances, so buying keeps working. RenounceOwnership(address _DEAD, bool _boo)does not renounce anything; it setssafeTransfer = _boo. WhensafeTransferis false,_transferand_approveonly succeed for addresses the owner has listed withPrize_Fund, and everyone else gets a misleading "transfer to the zero address" error.- 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 withchangeOwnerorOwnershipRenounce. - What happened: CertiK reports that the deployer removed 4,827.99 WBNB of liquidity from the pool on 20 August 2023.
Protocol details
Evidence
- report @CertiKAlert incident report twitter.com
- report De.Fi REKT database listing for ZRO (proof link: CertiK Alert post) twitter.com
- transaction bscscan.com transaction 0x098e…ed67 bscscan.com
- transaction bscscan.com transaction 0x1b63…10d2 bscscan.com
- transaction bscscan.com transaction 0x3f49…48ff bscscan.com
- transaction bscscan.com transaction 0xefa6…7352 bscscan.com
- address LayerZero (ZRO) copycat token verified contract code on BscScan bscscan.com
- address bscscan.com address 0x2ebc…2d5e bscscan.com
- address bscscan.com address 0x7Ee2…5aBE bscscan.com
- address bscscan.com address 0xa792…4d84 bscscan.com
- analysis Sourcify match for 0x2266362f414bf2476c5465dc2ea953fe2a99ae1c on BNB Chain repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.