PiggyBank Community Token Honeypot
What happened
De.Fi's REKT database lists PiggyBank Community Token (PIGGY) on Ethereum as an exit scam / honeypot, noting that the owner could disable the transfer function and so restrict users from selling their tokens. The verified source shows a narrower control than a general transfer switch: the contract stores an address called newun and reverts any transfer whose recipient is that address with the message "please wait". The first transferFrom call from a non-zero sender while newun is unset records its recipient as newun, which for a token traded through a DEX pair is the address that receives tokens on a sell.
The owner alone can change newun with transfernewun. Whether and when this block was active for PIGGY holders is not shown by the code alone.
How it happened
- The constructor mints the whole supply to the deployer:
_totalSupply = 100000000000000000000; balances[owner] = _totalSupply;. Withdecimals = 8that is 1,000,000,000,000 tokens, matching the header comment. - The contract declares
address public newun;, which starts as the zero address. Nothing in the constructor sets it. transferFrombegins withif(from != address(0) && newun == address(0)) newun = to; else require(to != newun, "please wait");. The firsttransferFromfrom a non-zero sender therefore stores its recipient asnewun. Router-based liquidity adds and swaps move tokens withtransferFrom, so a liquidity deposit made this way would make the pool address thenewun. This is what the code permits; the source does not show which address was captured.- Once
newunis set, both transfer paths refuse it as a destination.transferstarts withrequire(to != newun, "please wait");and every latertransferFromhits theelse require(to != newun, "please wait");branch. A holder's sell, which sends tokens to the pool, reverts. There is no exception for the owner or any other address in these functions. - Buys are not blocked by this check: tokens leaving the pool go to the buyer, who is not
newun, so therequirepasses. - The owner controls the switch:
function transfernewun(address _newun) public onlyOwner { newun = _newun; }. Pointingnewunat an address nobody uses lifts the block; setting it back to the zero address lets the nexttransferFromcapture a new recipient. No transaction showing the owner callingtransfernewunwas opened. - The header comment advertises a 5% liquidity fee, 3% holder reward, 2% burn and a "Token Limitation for trade" of 500,000,000,000, but the contract contains no fee, reward, burn or trade-limit code, and
transferandtransferFrommove the fulltokensamount. Ownership hastransferOwnershipandacceptOwnershipbut no renounce function.clearCNDAOlets the owner send any ETH held by the token contract to themselves.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.