DoucheCoin Honeypot
What happened
DoucheCoin (DOUCHE) is a BNB Smart Chain token whose transfers pass through a burnTokenCheck modifier that lets the owner, a _safeOwner address, and a whitelist move tokens freely while an ordinary holder can only send to the hard-coded _unirouter address, to the owner, or in amounts below an owner-set _sellAmount (zero by default). The owner controls the whitelist, the blacklist, _safeOwner and _sellAmount, and can also call a public _mint. De.Fi's REKT database lists DoucheCoin as an Exit Scam/Honeypot in which the contract owner could disable transfers and so restrict holders from selling.
How it happened
- The constructor sets
_owner = ownerand_safeOwner = owner, then calls_mint, which itself requiresmsg.sender == _owner, so the deploying address is the owner. The only assignment to_ownerin the file is in the constructor, and the contract has no function that changes it. - All transfers run
_approveCheck(...)guarded byburnTokenCheck. While_owner == _safeOwner, the first transfer sent by the owner takes the first branch,if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}, and records that recipient as_safeOwner. The code does not show which address that was. - For every later transfer, the owner,
_safeOwner, or anyone sending to the owner passes. An owner self-transfer also sets_sellAmount = amount. - Any other sender who is on
_whiteAddresspasses. A non-whitelisted holder reachesrequire((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"), so the transfer reverts unless the recipient is_unirouteror the amount is below_sellAmount._sellAmountstarts at 0, soamount < _sellAmountis never true until the owner raises it. A transfer to any other address, including a liquidity pair that is neither the owner nor_unirouter, therefore reverts for a non-whitelisted holder. - When
amount < _sellAmountand the recipient is_safeOwner, the sender is added to_blackAddressand removed from_whiteAddressafter the transfer. A blacklisted sender can then only send to_unirouter. - The owner manages the lists.
increaseAllowance(address[])whitelists addresses (despite its name),addApprove(address[])blacklists them,decreaseAllowance(address)overwrites_safeOwner, andmultiTransferwhitelists the firstapprovecountrecipients and gives them a maximum allowance to_unirouter. _mint(address account, uint256 amount)ispublicand owner-only, and it credits_balances[_owner]regardless ofaccount, so the owner can increase supply.- Everything above is what the code allows. The code alone does not show which addresses were whitelisted or blacklisted, who
_safeOwnerbecame, or whether_mintwas called.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.