Freela Honeypot
What happened
Freela (FREL) routes every transfer through a burnTokenCheck modifier. A sender who is not the owner, not _safeOwner, not whitelisted and not blacklisted can only send tokens to _unirouter (0x7a250d56…F2488D) while _sellAmount is zero. A sale through the router moves tokens into a pair, not to the router address, so it reverts for such a holder.
The owner can whitelist or blacklist addresses, change _safeOwner, and mint. De.Fi's REKT database lists FREL as an Exit Scam/Honeypot dated 2021-05-27, stating the contract owner could disable the transfer function, which restricted users in selling their tokens. No loss figure is given.
How it happened
- The constructor sets
_owner = owner; _safeOwner = owner;and mints the initial supply to the owner. transferandtransferFromboth call_approveCheck, which carries theburnTokenCheck(sender,recipient,amount)modifier.- The first branch:
if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}. While the two are equal, a transfer by the owner moves_safeOwnerto that transfer's recipient. - Afterwards, senders
_ownerand_safeOwner, and any transfer to_owner, pass (if (sender == _owner || sender == _safeOwner || recipient == _owner)). A whitelisted sender (_whiteAddress[sender] == true) also passes. - Any other sender, including a blacklisted one, reaches
require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");. For a non-listed sender this branch runs whenamount < _sellAmountis false, and_sellAmountstarts at 0 (uint256 private _sellAmount = 0;), so the require applies to every amount until_sellAmountis raised. Selling through the router sends tokens to a pair address, not_unirouter, so it reverts with the misleading balance message. - The owner can alter who is exempt:
increaseAllowance(address[])whitelists,addApprove(address[])blacklists,decreaseAllowance(address safeOwner)replaces_safeOwner, andmultiTransferwhitelists the firstapprovecountreceivers._sellAmountis set when the owner transfers to themselves (if (sender == _owner && sender == recipient){_sellAmount = amount;}); a non-listed sender whoseamount < _sellAmountpasses, but if the recipient is_safeOwnerthat sender is blacklisted. _mintispublicand owner-only, so the owner can increase supply; the code does not show it being used. No opened transaction shows any of these functions being called or any sale failing; the sell restriction is stated by the De.Fi listing.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.