Game Swap Exchange Rug Pull
What happened
GAME SWAP (GAME) is an Ethereum token whose source is a hand-written contract, not a standard ERC-20 implementation. Its transferFrom runs an ensure check that only lets the owner, the owner's tradeAddress, and addresses marked in a private canSale mapping move tokens freely. Everyone else falls through to condition, which returns false while three private variables (_saleNum, _minSale, _maxSale) are all zero.
Nothing in the contract ever assigns those variables, so in the verified code an ordinary holder's transfer or sell would revert. The owner-only approveAndCall function is also a hidden mint: it overwrites a chosen address's balance with any amount and whitelists that address, without touching totalSupply or emitting a Transfer event. On 2021-01-24 the deployer 0x8c848BE2…E4897b added 12 ETH and 7,500 GAME to a Uniswap V2 pool (tx 0x67abd476…202758, 13:15 UTC).
About six hours later, at 19:18 UTC, it called approveAndCall for 0x0659f352…4c194d (tx 0x179c0c41…a099c8) with an input value that decodes to 1,000,000,000,000,000. That recipient then sold 10,000 GAME on Uniswap for 28.4033 ETH about 95 seconds later (tx 0x2bc2c0d4…55c56f). De.Fi's REKT database lists the incident as an exit scam / rug pull in which minting and dumping GAME netted about 16 ETH.
How it happened
- The contract's
transferFromcallsensure(_from, _to, _value), which returns true only when_from == owner || _to == owner || _from == tradeAddress||canSale[_from]; every other sender must satisfycondition(_from, _value). conditionstarts withif(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;. The variables_saleNum,_minSaleand_maxSaleare declared private and never assigned, so the code would revert transfers and sells from any holder who is not the owner,tradeAddressor acanSaleaddress when the destination is not the owner.- The owner-only
approveAndCall(address spender, uint256 addedValue)runsbalanceOf[spender] = addedValue*(10**uint256(decimals));andcanSale[spender]=true;. It sets any balance for any address and exempts it from the sell block, whiletotalSupplyand the Transfer event log stay untouched. - The deployer added 12 ETH and 7,500 GAME of liquidity on 2021-01-24 at 13:15 UTC.
- At 19:18:51 UTC the deployer called
approveAndCallwith spender 0x0659f352…4c194d and anaddedValueof 1,000,000,000,000,000 (hex 0x00038d7ea4c68000), which sets that address's balance to 10^15 tokens, against a constructor supply of 10,000 tokens. - At 19:20:26 UTC the whitelisted address swapped 10,000 GAME through the Uniswap V2 router for 28.4033 ETH, taking the ETH out of the pool. The code would revert a sell from any holder who is not the owner,
tradeAddressor acanSaleaddress; no opened transaction shows a failed sell, so whether any other holder tried to sell is not established.
Protocol details
Evidence
- report Report gameswap.exchange
- report GameSwap on Sourcify (full source match, Ethereum) repo.sourcify.dev
- transaction Etherscan: addLiquidityETH transaction 0x67abd476... etherscan.io
- transaction Etherscan: approveAndCall transaction 0x179c0c41... etherscan.io
- transaction Etherscan: swapExactTokensForETH transaction 0x2bc2c0d4... etherscan.io
- address GameSwap (GAME) verified source code (Etherscan) etherscan.io
- address etherscan.io address 0x0659…194d etherscan.io
- address etherscan.io address 0x8c84…897b etherscan.io
- analysis Web Archive web.archive.org
- analysis De.Fi REKT database listing for GAME (Exit Scam/Rugpull) de.fi
- analysis etherscan.io page 0x681b…nces etherscan.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.