ElonSperm Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

ElonSperm (SPERM) is a BNB Smart Chain token whose verified source gives its owner several levers over whether holders can trade. setTaxFeePercent and setLiquidityFeePercent have no upper bound, and setMaxTxPercent accepts 0, which makes every transfer that does not involve the owner revert. De.Fi's REKT database lists SPERM as an "Exit Scam/Honeypot" dated 2021-09-10 and describes it as the contract owner being able to disable the transfer function, which restricted users in selling their tokens; the listing gives no loss figure or proof link, and no transaction showing the owner using these functions was opened.

How it happened

  1. At deployment the whole supply is credited to the deployer (_rOwned[_msgSender()] = _rTotal;) and the owner is exempted from fees (_isExcludedFromFee[owner()] = true;).
  2. The fee setters carry no cap: function setTaxFeePercent(uint256 taxFee) external onlyOwner() { _taxFee = taxFee; }, and setLiquidityFeePercent has the same shape. Both default to 5.
  3. In _transferStandard the sender is debited the full amount (_rOwned[sender] = _rOwned[sender].sub(rAmount);) while the recipient is credited rTransferAmount, which is the amount minus both fees. If the two percentages sum to 100, a transfer between two addresses that are not fee-exempt credits the recipient nothing; if they sum to more than 100, tAmount.sub(tFee).sub(tLiquidity) reverts.
  4. setMaxTxPercent computes _maxTxAmount = _tTotal.mul(maxTxPercent).div(10**2);, so an input of 0 sets the limit to 0. _transfer then requires amount <= _maxTxAmount whenever if(from != owner() && to != owner()) holds, and separately requires amount > 0. With the limit at 0, every transfer that does not involve the owner reverts, whether it is a sale into a pool, a purchase from it or a wallet-to-wallet send.
  5. Liquidity tokens produced by the contract's own swap-and-liquify routine are sent to the owner: addLiquidityETH{value: ethAmount}(address(this), tokenAmount, 0, 0, owner(), block.timestamp). Ownership is not given up in the code: lock(uint256 time) sets _owner = address(0), but unlock() lets _previousOwner take it back once now > _lockTime, and an eth_call on 2026-09-30 still returned the deployer 0x82661068…8b308d as owner.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract SPERM
Protocol links Website @elonsperm

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.