EternityProtcol Honeypot
What happened
EternityProtcol (ETP) is a BNB Smart Chain token whose owner holds a switch, setFeeEnabled, that can turn on a sell fee of effectively 100%. While the switch is on, a holder who sells to the PancakeSwap pair has their full amount debited, but the pair is credited with almost nothing, so selling returns next to no value. The owner and the router are exempt from the fee.
De.Fi's REKT database lists the token as an exit scam/honeypot dated 2021-05-05 and says the contract owner could restrict users from selling.
How it happened
- The constructor sets
_owner = msg.sender, mints the whole_totalSupply = 100000000 * 10**9to the owner and creates the pair withcreatePair(address(this), uniswapV2Router.WETH()), where the router is hard-coded as0x10ED43C718714eb63d5aA57B78B54704E256024E. _feeEnabledstarts asfalse, so early transfers and buys behave like a plain token. Only the owner can change it:function setFeeEnabled(bool feeEnabled) external { require(_owner == msg.sender); _feeEnabled = feeEnabled; }. The contract has norenounceOwnershipor ownership-transfer function, so this power stays with the deployer address.- Once the flag is on,
_transfertakes the fee branch for any transfer to the pair that is not from the router, the owner or the token itself:_feeEnabled && to == uniswapV2Pair && from != address(uniswapV2Router) && from != _owner && from != address(this). A normal sell through the router callstransferFromwith the holder asfrom, so it lands in this branch. - The fee is
uint256 fee = mul(div(amount, 100), 100);. This isamountrounded down to a multiple of 100, so it equalsamountfor round amounts and leaves at most 99 base units otherwise. The holder is debited in full (_balances[from] = sub(_balances[from], amount)runs first), the pair receivessub(amount, fee), and_totalSupplyis reduced byfee. - Because the pair is credited with almost none of the tokens that were sent, the swap cannot pay out BNB for them. The owner and router exemption means the owner's own transfers to the pair are untouched. What the code allows is a sell tax the owner can switch on at any time with no cap and no delay; whether and when
setFeeEnabled(true)was called is not shown by any transaction opened for this record.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.