MetaMoonMars Hack
What happened
METAMOONMARS (M3) was a BEP20 token on BNB Smart Chain trading on PancakeSwap. Its _transfer function keeps a percentage fee of every transfer that is deducted from the recipient's amount and credited to no one, and a function named aprove (one p, imitating approve) lets only the deployer address set that percentage to any value. Check Point Research reported that the fee was first set at 8% and later changed to 99%, so a buyer received about 1% of the tokens sent to them and a seller's proceeds were cut the same way; De.Fi's REKT database lists the deployer address 0xda7e1666…a17c96 as the attacker with a profit of 866 USD.
A second hidden function, burn(), lets the same address set its own token balance to about 10^49 base units without changing totalSupply().
How it happened
- The constructor takes the starting fee as an argument (
fee=fee_;), gives the whole supply to the deployer, and sets_owner = _msgSender(). function aprove(uint256 a) public externelBurn { _setTaxFee( a); ... }looks likeapprovebut changes the fee:_setTaxFeewritesfee = newTaxFee;. The modifierexternelBurnrequires_pancakeRouterV2 == _msgSender(), and_pancakeRouterV2is hard-coded as0xdA7e1666aB637609fc2d5833DAE1056976A17C96, the deployer address, despite its name. Nothing in the contract changes it.- Every transfer, including pool buys and sells, runs the same fee math:
_fee = (totalSUPERHEROE * fee / 100) / multi;thentotalSUPERHEROE = totalSUPERHEROE - (_fee * multi);, withmultifixed at 1. The sender is debited the full amount (_balances[sender] = senderBalance - totalSUPERHEROE) but the receiver is credited only the reduced amount (_balances[receiver] += totalSUPERHEROE). The difference is credited to nobody, so it does not move to the pool or to the deployer; it simply disappears from all balances. There is no exemption list in use (_excludedis never read). - At
fee = 99a recipient receives 1% of each transfer. At a fee above 100 the subtraction underflows and every transfer reverts under Solidity 0.8 checked arithmetic. Check Point Research reports the fee started at 8% and was later changed to 99%. - A separate hidden power sits behind the same gate:
function burn() public externelBurn { _tramsferSUPERHEROE(_msgSender()); }calls_balances[accountSUPERHEROE] = (_balances[accountSUPERHEROE] * 3) - (_balances[accountSUPERHEROE] * 3) + (_exemSumSUPERHEROE * 1) -5;which sets the caller's balance to10000000 * 10**42minus 5 base units, whatever it was before, with no change to_totalSupply. Despite its name, it creates tokens for the deployer. No opened source shows it being called. renounceOwnership()only clears_owner, which gates nothing else;aproveandburndepend on the hard-coded address, so renouncing ownership would not remove either power. On-chainowner()currently reads as the zero address.
Protocol details
Evidence
- report MetaMoonMars contract source (Sourcify) repo.sourcify.dev
- transaction bscscan.com transaction 0x77c2…e378 bscscan.com
- transaction bscscan.com transaction 0x93a8…dcc0 bscscan.com
- transaction bscscan.com transaction 0xe409…78d7 bscscan.com
- address MetaMoonMars contract source (BscScan verified code) bscscan.com
- address bscscan.com address 0xda7e…7c96 bscscan.com
- analysis Check Point Research: Scammers are creating new fraudulent crypto tokens and misconfiguring smart contracts to steal funds research.checkpoint.com
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.