Torio Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

Torio (Torio) is a SafeMoon-style reflection token on BNB Smart Chain at 0xe8944507…d87a89, deployed on 9 May 2021 with a 100,000,000,000,000 supply credited to the deployer. Every transfer that does not involve the owner must stay under _maxTxAmount, and the owner can set that limit to zero with setMaxTxPercent(0), which makes every holder's transfer, including sells to the PancakeSwap pair, revert. The owner can also raise the tax and liquidity fees with no cap; if they add up to more than 100%, the fee subtraction underflows and transfers revert as well.

The on-chain owner now reads as the zero address, but the contract's lock function also sets the owner to zero while letting the previous owner reclaim it with unlock after a chosen time, so a zero owner does not by itself prove the powers were given up. De.Fi's REKT database lists Torio as an exit scam/honeypot in which the owner could disable transfers.

How it happened

  1. The constructor credits the full reflected supply to the deployer, creates the WBNB pair on the PancakeSwap v2 router 0x10ED43C7…56024E, and excludes the owner and the contract from fees.
  2. _transfer enforces if (from != owner() && to != owner()) require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount."); on every transfer that does not touch the owner.
  3. setMaxTxPercent(uint256 maxTxPercent) is onlyOwner and sets _maxTxAmount = _tTotal.mul(maxTxPercent).div(10**2) with no lower bound. Calling it with 0 makes every non-owner transfer of more than zero tokens revert, so holders can neither sell nor move tokens, while the owner's own transfers are exempt.
  4. setTaxFeePercent and setLiquidityFeePercent are onlyOwner with no cap. The fees are taken out of each transfer through tAmount.sub(tFee).sub(tLiquidity), so values close to 100% take almost the whole amount and values above 100% in total make the subtraction revert.
  5. excludeFromFee and includeInFee let the owner choose which addresses skip these fees.
  6. lock(uint256 time) stores the owner in _previousOwner and sets _owner = address(0); unlock() restores it once block.timestamp > _lockTime. renounceOwnership clears the owner permanently. Either leaves owner() reading zero, which is what it reads today.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract Torio

Build your security review skills

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