BabyElon Rug Pull
What happened
BabyElon (BabyElon, 9 decimals, 10 billion fixed supply, BNB Smart Chain) restricts who can trade through its own _internalTransfer: wallets that are not "synced" can only trade with the PancakeSwap pair while the owner has trading switched on, and any synced wallet can flag a holder as _claimed, which makes that holder's sales revert. De.Fi's REKT database lists the incident as a rug pull by the contract creator 0x999fae84…32a7c1 for 183.35 BNB (about $52,852), with the tokens afterwards laundered through Tornado Cash. According to that listing, the token at 0x292e89d5…140b43 was paired with 100M BabyElon and 10 BNB in transaction 0x1d07387a…6acc80, the pool was then increased with 290 BNB and 2.9B BabyElon in transaction 0xfac7fa93…2bc03e (described as an attempt to push the price up), and the liquidity was removed in transaction 0xa3974709…d4feff for 484.35 BNB, of which 183.35 BNB was profit.
The listing adds that tokens were then moved in transaction 0xd25a56ea…9fb821. The token code has no function that holds or withdraws LP tokens, so the liquidity removal itself is a pair and router action that the source does not trace to a holder.
How it happened
What the code allows:
- The constructor gives the whole supply to the deployer and marks the owner as synced:
_tokenBalances[_msgSender()] = _tokenTotalSupply;and_synced[owner()] = true;. There is no mint function and_isTradingOpenstarts as false. - Transfers where neither side is synced are gated:
if (!_synced[sender] && !_synced[recipient]) {followed byrequire(_isTradingOpen);. Only the owner can change that flag withfunction openTrading(bool value) public onlyOwner, so the owner can open or close trading for every unsynced wallet. _isSwapEnabledis set to true in the constructor and has no setter, sorequire(sender == uniswapV2Pair || recipient == uniswapV2Pair);always applies: unsynced wallets can only trade with the pair, never send tokens wallet to wallet.- On a sale (
recipient == uniswapV2Pair) the code runsrequire(!_claimed[sender], "Claimed");andrequire(!_claimed[_msgSender()], "Claimed");. Through a router,senderis the holder and_msgSender()is the router, so a flagged holder cannot sell and a flagged router would block everyone using it. The flags are set byfunction claim(address[] calldata wallet, bool value) external onlySynced, so the owner or any wallet already synced can set them. Balances are debited exactly byamountwith no fee (_tokenBalances[sender] = _tokenBalances[sender].sub(amount);), so a flagged holder keeps a balance that cannot be sold. The source does not show that any wallet was flagged.
, as listed by De.Fi's REKT database: 5. The creator paired 100M BabyElon with 10 BNB, added 290 BNB and 2.9B BabyElon, then removed the liquidity and received 484.35 BNB (listed profit 183.35 BNB) before routing the tokens through Tornado Cash. Liquidity removal is performed on the pair, outside the token code.
Protocol details
Evidence
- transaction bscscan.com transaction 0x1d07…cc80 bscscan.com
- transaction bscscan.com transaction 0xa397…feff bscscan.com
- transaction bscscan.com transaction 0xd25a…b821 bscscan.com
- transaction bscscan.com transaction 0xfac7…c03e bscscan.com
- address BscScan verified source for BabyElon (0x292E89d5D5BDab3aF2f5838C194c1983f0140b43) bscscan.com
- address bscscan.com address 0x292e…0b43 bscscan.com
- address bscscan.com address 0x999f…a7c1 bscscan.com
- analysis Sourcify repository entry for the same contract repo.sourcify.dev
- analysis De.Fi REKT database listing for BabyElon de.fi
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.