Skem.finance Honeypot
What happened
Skem.finance (SKEM) is an Ethereum token deployed on 4 May 2021 at 0x6c6291e6…cfedb7 by 0x164537C6…14D600, which is also its owner. Every transfer passes through a modifier, burnTokenCheck, that lets the owner, a second privileged address _safeOwner and owner-whitelisted wallets move tokens freely, but rejects an ordinary holder's transfer unless it is smaller than an owner-set _sellAmount, which starts at zero. The rejection reuses the message "ERC20: transfer amount exceeds balance", so a failed sale looks like a balance error.
If the owner's first outgoing transfer is the liquidity deposit, the Uniswap pair becomes _safeOwner and buys go through while sales revert. The owner can also whitelist, blacklist and mint to itself through functions named like standard allowance helpers. De.Fi's REKT database lists the token as an exit scam/honeypot.
How it happened
- The constructor sets
_ownerand_safeOwnerto theownerargument and mints the supply to_owner. Because_mintrequiresmsg.sender == _owner, the owner is the deploying address. burnTokenCheckbegins withif (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}: the recipient of the owner's first outgoing transfer becomes_safeOwner. If that transfer is the Uniswap liquidity deposit,_safeOwneris the pair.- Transfers pass unconditionally when
sender == _owner || sender == _safeOwner || recipient == _owner, so with the pair as_safeOwnerevery buy (a transfer from the pair) succeeds. - A sale is a transfer from the holder to the pair. For a holder who is not whitelisted, it passes only if
amount < _sellAmount, and thenif(recipient == _safeOwner){_blackAddress[sender] = true; ...}blacklists the seller. Otherwiserequire((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance")reverts._sellAmountstarts at 0 and changes only when the owner transfers to itself, so by default no ordinary holder can sell or even send tokens to another wallet. - The owner's levers are
increaseAllowance(address[])(whitelist),addApprove(address[])(blacklist),decreaseAllowance(address)(set_safeOwner),multiTransfer(airdrop and whitelist the firstapprovecountreceivers) and a public_mintthat adds any amount to the owner's balance._owneris set only in the constructor and there is no renounce function.
Protocol details
Evidence
- report Token Sniffer post 1374999601485291522 (De.Fi proof link) twitter.com
- transaction Skem.finance contract creation transaction etherscan.io
- address Skem.finance (SKEM) verified contract code on Etherscan etherscan.io
- analysis Sourcify exact match for 0x6c6291e630a541734970a14970d2fc1d90cfedb7 on Ethereum repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.