PangeaOceanCleaunUp Honeypot
What happened
PangeaOceanCleaunUp (PANGEA) is a BNB Smart Chain reflection token with a hard-coded condition in _transfer: require(tx.origin == to || tx.origin == owner());. A holder selling through a router starts the transaction from their own wallet, but the token's recipient is the pool pair, so the condition fails and the sell reverts. Buying keeps working when the buyer receives the tokens at the same address that sent the transaction.
Because it is hard-coded, the condition is not an owner switch, and renouncing ownership would not remove it. De.Fi's REKT database lists the token as an exit scam/honeypot and says the contract owner could disable the transfer function, which restricted users in selling their tokens. No transaction or holder data was opened for this token, so the code shows how sells fail, not what was done with liquidity.
How it happened
- The constructor gives the whole reflected supply to the deployer, creates the pair with the router at 0x10ED43C7…56024E and exempts the owner from fees:
_rOwned[_msgSender()] = _rTotal;,uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), _uniswapV2Router.WETH());,_isExcludedFromFee[owner()] = true;. The supply is100000 * 10**6 * 10**9, which is 100 billion tokens with 9 decimals. - Every
transferandtransferFromreaches_transfer, which containsrequire(tx.origin == to || tx.origin == owner());with no revert message. - A sell through a router calls
transferFrom(holder, pair, amount).tx.originis the holder,tois the pair andowner()is someone else, so the condition is false and the transaction reverts. The holder's tokens stay in their wallet because the revert happens before_tokenTransfer. The same check stops a holder sending tokens to any address other than their own. - A buy works when the pair pays out to the address that signed the transaction, because
toequalstx.origin. Transactions signed by the owner pass for any recipient throughtx.origin == owner(), so the owner can sell or move tokens. renounceOwnership()exists, but it would only setowner()to the zero address and remove the owner's bypass; thetx.origin == tocondition stays. A latest-block owner read recorded in the evidence metadata (2026-09-30) returns the deployer address 0x1feab2a0…09856d.- The owner also holds uncapped fee setters:
function setTaxFeePercent(uint256 taxFee) external onlyOwner() { _taxFee = taxFee; }andsetliquidityFeePercent, plussetMaxTxPercent, which has no lower bound and takes effect whenswapAndLiquifyEnabledis false (if(from != owner() && to != owner() && !swapAndLiquifyEnabled) require( (amount <= _maxTxAmount) ...). These are additional powers the code allows; no source shows them being used.
Protocol details
Evidence
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.