Mars Farm Rug Pull
What happened
The verified MARS Farm source is a minimal token whose transfer function reverts for every holder except the owner, one owner-chosen trading address and wallets the owner whitelists, because the sale-limit variables that would allow ordinary transfers are never assigned anywhere in the code. Buyers can receive tokens only if the pool is exempt, but cannot move or sell them. The constructor puts the whole supply on the deployer 0xDa53cC63…A05BA9, which is the transaction De.Fi's REKT database lists as the deployer minting tokens to its wallet (0x152671f8…9b1c7b).
De.Fi's REKT database lists the incident as a rug pull of 37,645 USD on BNB Chain, with the deployer adding initial liquidity in 0x52037a40…d4b475 and removing it in 0xb74338b1…4ad986.
How it happened
- The constructor gives the entire supply to the deployer:
balanceOf[msg.sender] = totalSupply;withowner = msg.sender;. The source comments claimZERO developer premineand anINACCESSIBLEmint function, but the code assigns all tokens to the deployer. - Every transfer calls
ensure:if(_from == owner || _to == owner || _from == tradeAddress||canSale[_from]){ return true; } require(condition(_from, _value));. Only the owner, the singletradeAddressand wallets incanSaleget a free pass. - For everyone else
conditiondecides, and it is a dead end:if(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;. Those three variables are declaredprivatewith default value 0, and no function in the source writes to_saleNum,_minSaleor_maxSale, so the earlyreturn falsealways runs andrequire(condition(_from, _value))reverts. A holder's sell is a transfer from the holder to the pool, so it reverts. - Buys still work only when the pool is exempt: a purchase is a transfer with the pool as
_from, which needs_from == tradeAddressorcanSale[_from]. The owner sets those withfunction transferownership(address addr)(setstradeAddress = addr;) andfunction approveAndCall(address spender, uint256 addedValue)(setscanSale[spender]=true;). Both are restricted byrequire(msg.sender == owner);, and the source has no function to change the owner or give these powers up. approveAndCallalso overwrites a balance without touching supply:if(addedValue > 0) {balanceOf[spender] = addedValue*(10**uint256(decimals));}, so the owner can set any address's balance to an arbitrary amount whiletotalSupplystays unchanged.- What happened, per De.Fi's REKT database: the deployer added initial liquidity and later removed it, with 37,645 USD listed as lost. The liquidity transactions could not be opened here, so amounts, timing and who held the LP tokens are not independently confirmed, and no transaction was opened showing the owner calling
transferownershiporapproveAndCall.
Protocol details
Evidence
- report Report marsfarm.org
- transaction bscscan.com transaction 0x1526…1c7b bscscan.com
- transaction bscscan.com transaction 0x5203…b475 bscscan.com
- transaction bscscan.com transaction 0xb743…d986 bscscan.com
- address Mars Farm (MARS) verified source code on BscScan bscscan.com
- analysis Web Archive web.archive.org
- analysis Sourcify match for Mars Farm on BNB Chain repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.