Galaxy DeFi Honeypot
What happened
Galaxy DeFi (GLXY) is an Ethereum token whose transfer check blocks almost every sender except the pool, the router and wallets the owner whitelists, so ordinary holders cannot sell or move tokens while buying still works. Etherscan shows the deployer 0x53F823C4…a31408 added 200 ETH and 600,000 GLXY of liquidity on 2021-01-10 (transaction 0x4bb442ad…0eee36) and removed the whole position on 2021-01-12 (transaction 0xac70e946…5c7725), receiving 236.96 ETH and 506,683 GLXY. De.Fi's REKT database lists the incident as a honeypot with 38,798 USD lost and says the owner could disable the transfer function, which stopped users from selling.
How it happened
- At deployment the constructor stores the deployer as both privileged addresses and mints the supply to it:
_address0 = owner; _address1 = owner; _mint(_address0, initialSupply*(10**18));. - Every transfer runs the
safeCheckmodifier:if(recipient != _address0 && sender != _address0 && _address0!=_address1 && amount > _zero){require(sender == _address1 ||sender==_router || _Addressint[sender], "ERC20: transfer from the zero address");}. While_address0differs from_address1, any transfer above_zero(0 by default) must come from_address1, from the router address 0x7a250d56…F2488D, or from a whitelisted wallet. Transfers to or from the owner are exempt. - The modifier arms itself on the owner's first outgoing transfer:
if(sender==_address0 && _address0==_address1){_address1 = recipient;}. If that first transfer was the liquidity deposit (Etherscan shows the deployer sending 600,000 GLXY to the pool 0x53AC7f6f…aDF921 in the add-liquidity transaction),_address1becomes the pool. Buys then pass because the pool is the sender, but a holder's sell is a transfer from the holder to the pool, where the sender is not_address1, not the router and not whitelisted, so it reverts. The sources opened do not show an earlier owner transfer that would have set_address1elsewhere, and no failed sell transaction was opened. - The owner keeps the keys to the block.
upint(addressn,Numb)whitelists any wallet,multiaddress(AllowN, receivers, amounts)airdrops tokens and for the firstAllowNreceivers sets_Addressint[receivers[i]] = true; _approve(receivers[i], _router, _valuehash);,intnum(Numb)sets the_zerothreshold, andints(addressn)replaces_address1. Setting_address1back to the owner's address turns the check off, and a later owner transfer to another address re-arms it. All four are restricted byrequire(msg.sender == _address0, "!_address0"), and the source has no ownership-renounce function. - What happened: Etherscan shows the deployer, who also received the LP tokens, added 200 ETH and 600,000 GLXY of liquidity on 2021-01-10 07:39 UTC, then called
removeLiquidityETHWithPermiton 2021-01-12 07:56 UTC, burning 10,954.45 LP tokens and receiving 506,683.07 GLXY and 236.96 ETH. That is about 36.96 ETH more than the deployer put in. De.Fi's REKT database lists the loss as 38,798 USD.
Protocol details
Evidence
- report Report galaxydefi.io
- transaction Etherscan transaction 0x4bb442addcdf8b0dde549461afc2dc364fdc230b41212d600a3210f8df0eee36 etherscan.io
- transaction Etherscan transaction 0xac70e946c5a2d688ff8e2c66d5033cbe6956b6b9ea3774409343e1aeaa5c7725 etherscan.io
- address Galaxy DeFi (GLXY) verified source code on Etherscan etherscan.io
- analysis Web Archive web.archive.org
- analysis Sourcify match for Galaxy DeFi on Ethereum repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.