Genswap Rug Pull
What happened
GenSwap (GEN) is an ERC20 token on Ethereum with a Uniswap V2 pool against WETH. On 30 Aug 2023 CertiK Skynet reported an exploit of the token contract 0x65719eda…B631b7, saying the attacker abused an underflow to inflate their balance and then dumped the tokens. The transaction 0x61750911…9567c7, sent by 0xEB4BFb8e…85D144, swapped roughly 4.19 quadrillion GEN (total supply 10,000,000) for 38.36 ETH through Uniswap V2 Router 2. De.Fi's REKT database lists the loss as about 38 ETH (about 62,000 USD) and an exit scam, and lists two bridge deposits to Arbitrum, 0xfc3ddc44…6427be and 0x223e0e6a…d27a85.
The verified source shows where the underflow is: addresses on the fee-exempt list are routed to standardTransfer, which subtracts the amount from the sender's balance inside an unchecked block with no balance check. The sender address 0xEB4BFb8e... is hard-coded in the source as marketing_receiver and is set fee-exempt in the constructor.
How it happened
- The constructor sets
marketing_receiver = 0xEB4BFb8e38f6658eA27d59F95B420C59cC85D144and thenisFeeExempt[marketing_receiver] = true;. The owner can add more exempt addresses withsetisExemptorsetInternalAddresses. _transferhandles an exempt sender first:if (isFeeExempt[sender]) {standardTransfer(sender, recipient, amount); return;}. This line comes beforerequire(amount <= balanceOf(sender),"You are trying to transfer more than your balance");, so the balance check, the trading-allowed check and the max-tx limits are all skipped for exempt senders.standardTransferrunsunchecked {_balances[sender] = _balances[sender] - amount;}and_balances[recipient] = _balances[recipient] + amount;. Because the subtraction is unchecked, an exempt sender with a balance of 0 who sendsamountends up with a balance of 2^256 minusamountand the recipient is credited the fullamount. Sending a very large amount to the Uniswap pair therefore credits the pool with tokens that were never in circulation.transferFromcalls_transfer(sender, recipient, amount)and then.sub(amount, "ERC20: transfer amount exceeds allowance")on the allowance, so the sender only needs anapproveof at least that amount for the router;approveis open to anyone.- What happened: Etherscan shows transaction 0x61750911…9567c7 from 0xEB4BFb8e…85D144 calling
swapExactTokensForETHSupportingFeeOnTransferTokenson Uniswap V2 Router 2, sending about 4,192,296.86 billion GEN to the pool and receiving 38.36 ETH, at 2023-08-30 18:20:47 UTC. CertiK Skynet described the cause as an underflow that inflated the attacker's balance before the tokens were dumped.
Protocol details
Evidence
- report @CertiKAlert incident report twitter.com
- report GenSwap source on Sourcify repo.sourcify.dev
- report CertiKAlert post on GenSwap exploit (via fxtwitter) twitter.com
- transaction Etherscan transaction 0x61750911...67c7 etherscan.io
- transaction etherscan.io transaction 0x223e…7a85 etherscan.io
- transaction etherscan.io transaction 0xfc3d…27be etherscan.io
- address GenSwap (Gen) contract source on Etherscan (verified) etherscan.io
- address etherscan.io address 0xeb4b…d144 etherscan.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.