BitDao Honeypot
What happened
"BitDao" (BDO) is an Ethereum token that borrowed the name of the BitDAO project; it was deployed on 17 June 2021 at 0x1533c795…2415c2 by 0xC6D3cF10…8884C4. A burnTokenCheck modifier on every transfer and transferFrom lets the owner, a second "safe owner" address and whitelisted wallets move tokens, while any other holder's transfer reverts unless it goes to the Uniswap router address or is smaller than a hidden _sellAmount threshold that starts at zero. A sale sends tokens to the pool, not the router, so ordinary holders could buy but not sell, and the revert message "ERC20: transfer amount exceeds balance" hides the cause.
The contract also has a public _mint that only the owner can call and that credits new tokens to the owner. On-chain, the deployer added 99 ETH of liquidity, minted 1 trillion BDO about 12 hours later, and sold into the pool for 188.076 and 200.0003 WETH within three minutes; De.Fi puts the loss at $686,491.
How it happened
- The constructor mints 100 million BDO to the owner. At 04:26:55 UTC on 17 June 2021 the deployer called
addLiquidityETHwith 99 ETH and 100 million BDO, creating the BDO/WETH pool (0x3966fb3f…16a980). burnTokenCheckrunsif (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}, so the owner's first outgoing transfer sets_safeOwnerto its recipient. If that was the liquidity add, the pool became_safeOwner, and transfers out of it (buys) always pass.- For any other sender that is not whitelisted, the modifier requires
amount < _sellAmountorrequire((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance")._sellAmountis zero until the owner sends tokens to itself, and a router sale sends tokens to the pool, so holders' sales revert. A holder who does pass the threshold with a transfer to_safeOwneris added to_blackAddress. - The owner controls the lists through misleadingly named functions:
increaseAllowance(address[])whitelists,addApprove(address[])blacklists, anddecreaseAllowance(address)replaces_safeOwner. _mintispublicwithrequire(msg.sender == _owner, ...)and adds to_balances[_owner]. At 16:09:03 UTC the deployer called it for 1,000,000,000,000 BDO (0x2d704fd0…4ba660).- The deployer then sold 23,678,300 BDO for 188.076 WETH (0x90d7e07e…596c7b) and about 999.98 billion BDO for 200.0003 WETH (0xc0a7f366…f6bff9). De.Fi's write-up says the proceeds went to Tornado Cash (0xa576b767…b45adc).
Protocol details
Evidence
- report Token Sniffer post 1374999601485291522 (seed link) twitter.com
- transaction Etherscan transaction 0x3966fb3f...a980 (addLiquidityETH) etherscan.io
- transaction Etherscan transaction 0x2d704fd0...c660 (_mint) etherscan.io
- transaction Etherscan transaction 0x90d7e07e...6c7b (swapTokensForExactETH) etherscan.io
- transaction Etherscan transaction 0xc0a7f366...6bff9 (swapExactTokensForETH) etherscan.io
- transaction De.Fi REKT database entry for BDO (write-up with transaction list) de.fi
- transaction etherscan.io transaction 0xa576…5adc etherscan.io
- address BitDao (BDO) verified contract code on Etherscan etherscan.io
- analysis Sourcify match for 0x1533c795ea2b33999dd6eff0256640dc3b2415c2 on Ethereum repo.sourcify.dev
- analysis honeypot.is page ethereum.html honeypot.is
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.