Symbiogenesis Rug Pull
What happened
SYSIS (Symbiogenesis) is an ERC-20 token on Ethereum that traded on Uniswap. PeckShield's alert on 2023-11-28 says address 0x8B54...8cca swapped 99,999,999,999,999 SYSIS for 26.67 WETH (about 53.7K USD) and that the token fell 100 percent. De.Fi's REKT database lists it as a rug pull exit scam with 53,639 USD of liquidity (26.67 ETH) removed from the Uniswap pool, with the funds then moved to another EOA address through a smart contract.
The verified source looks like a standard OpenZeppelin token but is not. Its _transfer does not check the sender's real balance: it asks an external contract for the number, and that contract's address is derived from the constructor argument. The token has a fixed 50,000,000 supply, yet the swap PeckShield reports is far larger than that supply, which is the kind of amount this check would let an attacker-chosen contract approve. No source opened here shows what that external contract returned.
Deployer address: 0xf5e228B8…EfC483. Scammer address listed by De.Fi: 0x95a6FcB5…79C180. Liquidity removal transaction listed by De.Fi: 0x62d292c0…0ec58c. Malicious contract listed by De.Fi: 0x8B544F47…eF8cca.
How it happened
- The deploy-time
_mint(msg.sender, totalSupply)call uses itsamountargument for something other than the supply:uint160 z = uint160(amount) + u; address p = address(z); x = XOL(p);withu = 834774399394859312355. The deployer's constructor argument therefore chooses the address stored inx, and the code then overwritesamount = 50000000 * 10 ** 18;so the minted supply is fixed at 50M whatever was passed. - Every transfer begins by reading the sender's balance from that external contract instead of from storage:
uint256 senderBalance = balanceoF(sender);, wherebalanceoFreturnsx.squirrel(true, bytes32(0), sender). Only after that does it runrequire(senderBalance >= amount, ...). - The stored balance is then set from the external number, not debited from the real one:
_balances[sender] = senderBalance - amount;inside anuncheckedblock, while the recipient is credited normally with_balances[recipient] += amount;. A contract that returns a large value for one sender lets that sender move more tokens than it holds and have the recipient, including the Uniswap pair, credited for them. A contract that returns 0 for a holder makes that holder's transfers and sells revert. balanceOfstill reads_balances, so wallets and explorers show ordinary-looking balances. The token has no owner, mint function or pause switch; the control sits entirely in the external contract thatxpoints to, whose code is not part of the verified source.- What happened, per PeckShield: on 2023-11-28 address 0x8B54...8cca swapped 99,999,999,999,999 SYSIS for 26.67 WETH, far above the 50,000,000 token supply, and the price fell to zero. De.Fi's REKT database describes the same 26.67 ETH (53,639 USD) as liquidity removed from the Uniswap pool and moved to another EOA through a smart contract. Neither source says what the external contract at
xreturned.
Protocol details
Evidence
- report @PeckShieldAlert incident report twitter.com
- report SYSIS verified source (Sourcify, exact match) repo.sourcify.dev
- report PeckShieldAlert post on Symbiogenesis $SYSIS (via fxtwitter) twitter.com
- transaction etherscan.io transaction 0x62d2…c58c etherscan.io
- address SYSIS verified source (Etherscan) etherscan.io
- address etherscan.io address 0x8B54…8cca etherscan.io
- address etherscan.io address 0x95a6…C180 etherscan.io
- address etherscan.io address 0xf5e2…C483 etherscan.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.