zkSync Copycat Rug Pull
What happened
zkSync (TBD) is a copycat BEP-20 token on BNB Chain that reuses the zkSync name; it is not the real zkSync project. The verified source contains an owner-controlled trading switch and an allowance bug that make selling through a router fail for ordinary holders. De.Fi's REKT database lists a rug pull on 2023-07-28 in which the deployer removed liquidity from the PancakeSwap pool in two transactions, with a loss of 201,549 USD (822.65 BNB); the listing says the proceeds were sent to another EOA and then split across several addresses.
CertiK Alert flagged the same day a large liquidity removal on the token by the deployer, put at about 731 WBNB (about 176K USD), and called it a honeypot scam. Deployer: 0x1cd9af6a…ef9a8b. Recipient address in the De.Fi listing: 0xa52f62dc…907594.
Liquidity removal transactions in the listing: 0x65a6f4f5…b23552 and 0xf748b082…4a9606.
How it happened
- The constructor mints the whole 1,000,000,000 supply to the deployer and makes it
owner:_balances[msg.sender] = _totalSupply;andowner = msg.sender;. approveis broken for everyone except the owner._approveignores its_ownerargument and writes to the state variableowner:_allowances[owner][spender] = amount;. A holder who approves a router therefore changes the deployer's allowance, not their own.- A router sell calls
transferFrom(holder, pair, amount), which does_transfer(sender, recipient, amount)and thenrequire(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance")against_allowances[sender][_msgSender()]. That entry is never set for a normal holder, so the sell reverts. Buys, where the pair sends tokens withtransfer, are not affected. The deployer's own allowance is set by every approve call, so the deployer can sell through a router. - The owner also holds a trading switch.
RenounceOwnership(address _DEAD, bool _boo)only setssafeTransfer = _boo(it does not renounce anything), and_transferrequiresrequire(safeTransfer || _balances1[sender], ...). WithsafeTransferfalse, only addresses whitelisted byPrize_Fundcan send tokens, and_approvehas the same check onmsg.sender. - Other owner powers:
burn(address account, uint256 amount) onlyOwneractually mints:_totalSupply += amount; _balances[account] += amount;.changeOwnerandOwnershipRenounceboth just assign a newowner.SetBurnPercentandSetCharityPercenthave no cap, but the burn percentage does not take tokens from the recipient:_transfercomputes the localuint256 _burnAmount = amount * burnPercent / 100 ;yet deducts the never-assigned state variable,amount = amount - charityAmount - burnAmount;, which stays 0, so the recipient is credited the full amount. The local_burnAmountonly shrinks the supply counter,_totalSupply -= _burnAmount;, with no matching balance change, sototalSupply()drifts below the sum of balances, and a large enoughburnPercentwould make that subtraction revert and block transfers. - What was reported: De.Fi's listing says the deployer removed liquidity in two transactions on 2023-07-28 and moved the funds to another address. CertiK Alert called the removal about 731 WBNB (about 176K USD) and the token a honeypot. Which of the code controls above were exercised on-chain was not checked.
Protocol details
Evidence
- report De.Fi REKT database listing for TBD (as imported in meta.json and the live record) twitter.com
- report zkSync (TBD) source, Sourcify repository repo.sourcify.dev
- transaction bscscan.com transaction 0x65a6…3552 bscscan.com
- transaction bscscan.com transaction 0xf748…9606 bscscan.com
- address zkSync (TBD) verified source code, BscScan bscscan.com
- address bscscan.com address 0x1cd9…9a8b bscscan.com
- address bscscan.com address 0xa52f…7594 bscscan.com
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.