On January 8, 2026, an attacker called getPurchasePrice() on a five-year-old Truebit contract with a carefully chosen input. The function returned zero. Eight transactions later, $26.4 million in ETH was gone.
The contract was deployed in 2021. It was compiled with Solidity 0.6.10 — a version without built-in overflow protection. It had no public audit record. And it had been sitting there, holding millions, for five years.
Welcome to the zombie contract problem.
The Scale Nobody Talks About
There are over 60 million smart contracts deployed on Ethereum mainnet alone. The vast majority are dormant — but "dormant" doesn't mean "empty." Conservative estimates suggest $2-4 billion sits in contracts that:
- Were compiled with Solidity <0.8.0 (no automatic overflow checks)
- Have never been audited by a reputable firm
- Haven't had a code change or upgrade in 2+ years
- Still hold significant token balances or ETH
These are zombie contracts. They're not dead — they're just forgotten. And in 2026, forgetting is getting expensive.
Why Now? The AI Scanning Revolution
Here's what changed: attackers have LLMs.
Before 2026, finding bugs in old contracts required manual review by skilled researchers. The economics didn't always work — spending 40 hours reviewing a contract that might have $500K in exploitable value was a gamble.
Now? An attacker can:
- Scrape every verified contract on Etherscan with a balance >$100K
- Feed each one to a fine-tuned LLM trained on historical exploit patterns
- Get a ranked list of candidates in hours, not weeks
- Generate proof-of-concept exploits for the top hits
The cost? About $1.22 per contract for basic vulnerability scanning with current LLM pricing. That means scanning every contract on Ethereum with a non-trivial balance costs less than a used car.
CryptoRank reported in March 2026 that hackers are already using LLMs to systematically scan older EVM contracts for unguarded bugs and stale token approvals. This isn't theoretical — it's happening right now.
Anatomy of a Zombie Contract Kill
Let's trace the Truebit exploit step by step, because it's the textbook case.
The Setup
Truebit's token purchase contract used a bonding curve mechanism:
// Simplified — Solidity 0.6.10, no SafeMath on this path
function getPurchasePrice(uint256 amount) public view returns (uint256) {
uint256 newSupply = totalSupply + amount;
// This multiplication overflows for large `amount` values
uint256 price = newSupply * newSupply * PRICE_FACTOR;
return price - currentPrice;
}
In Solidity 0.6.x, uint256 multiplication that exceeds 2^256 silently wraps to zero. No revert. No error. Just... zero.
The Kill Chain
- Reconnaissance: Attacker identifies the contract holds ~8,535 ETH (~$26.4M)
-
Overflow Discovery: Finds that
getPurchasePrice()returns 0 for a specific large input -
Mint for Free: Calls
buyTRU()with the overflow-triggering amount — pays nothing, receives billions of TRU -
Dump: Sells TRU back through
sellTRU()at full bonding curve price - Drain Complete: 8,535 ETH extracted in 8 transactions
Total time from first transaction to last: 12 minutes.
Why It Went Undetected for 5 Years
Three factors:
- No overflow guards: Compiled before Solidity 0.8.0's automatic checks
- Closed source: Contract wasn't verified on Etherscan until after deployment, limiting community review
- No monitoring: No real-time transaction monitoring or anomaly detection was in place
- Economic threshold: Before LLMs, the cost of finding this bug exceeded most attackers' risk appetite
The Zombie Contract Taxonomy
Not all zombie contracts are equal. Here's a risk classification:
🔴 Critical: Pre-0.8.0 with ETH/Token Balance
- Compiled with Solidity <0.8.0
- Holds >$100K in value
- No SafeMath usage (or incomplete usage)
- No upgrade mechanism
Examples of vulnerable patterns:
- Bonding curves with unchecked math
- Token vesting contracts with manual balance tracking
- Reward distribution contracts with division-before-multiplication
- AMM contracts with custom math libraries
🟠 High: Stale Approvals on Active Contracts
Even if the contract itself is fine, infinite token approvals granted to old contracts create risk:
// User approved this DEX router 3 years ago for MAX_UINT
// The router contract has a known bug in v1.2
// Attacker exploits the bug to drain approved tokens
Revoke.cash data suggests the average active DeFi wallet has 23 outstanding infinite approvals, many to contracts that are no longer actively maintained.
🟡 Medium: Upgradeable Proxies with Stale Implementations
Contracts using the proxy pattern where:
- The implementation hasn't been updated in 12+ months
- The proxy admin key is an EOA (not a multisig or timelock)
- The implementation contains known vulnerability patterns from its era
A Practical Defense Playbook
For Protocol Teams: The Zombie Audit
Step 1: Inventory your attack surface
# Using cast to enumerate all contracts your protocol ever deployed
cast etherscan-source --chain mainnet <deployer_address> | \
grep -E "pragma solidity [0-6]\." | wc -l
Better yet, use ethereum-etl to extract every contract creation from your deployer addresses and check:
- Solidity version (is it <0.8.0?)
- Current balance (ETH + ERC-20 tokens)
- Last interaction timestamp
- Whether SafeMath is imported and consistently used
Step 2: Triage by risk
Prioritize contracts that are:
- Pre-0.8.0 AND hold value → Immediate action required
- Pre-0.8.0 AND have active approvals from users → High priority
- Any version AND no monitoring → Medium priority
Step 3: Remediate
For high-risk zombie contracts, you have four options:
- Migrate funds out — Low effort, low risk, best for contracts you control
- Deploy monitoring — Low effort, medium risk, buys time
- Emergency pause — Medium effort, if pause mechanism exists
- Upgrade implementation — High effort, for proxy contracts
Step 4: Set up continuous monitoring
At minimum, deploy:
- Balance monitoring: Alert on any outflow >10% of TVL
- Function call monitoring: Alert on rarely-called admin/mint functions
- Approval monitoring: Track new approvals to your old contracts
Tools that work today:
- OpenZeppelin Defender 2.0 for automated monitoring and response
- Forta Network for custom detection bots
- Tenderly for real-time transaction simulation and alerts
For Individual Users: The Approval Cleanup
- Visit revoke.cash and connect your wallet
- Sort approvals by last used — anything >6 months is suspect
- Revoke approvals to any contract you no longer actively use
- Set a calendar reminder to repeat quarterly
Cost: A few dollars in gas. Value: Potentially saving your entire token portfolio.
For Auditors and Security Researchers: The Opportunity
There's a goldmine of bug bounties sitting in zombie contracts. Here's a systematic approach:
# Pseudocode for a zombie contract scanner
contracts = etherscan.get_contracts(
min_balance_eth=50,
compiler_version_lt="0.8.0",
last_tx_days_ago_gt=180
)
for contract in contracts:
source = etherscan.get_source(contract.address)
if not source:
continue # Can't analyze unverified contracts easily
# Check for common zombie patterns
risks = []
if "SafeMath" not in source:
risks.append("NO_SAFEMATH")
if re.search(r"uint256.*\\*.*\\*", source):
risks.append("UNCHECKED_MULTIPLICATION")
if "selfdestruct" in source:
risks.append("HAS_SELFDESTRUCT")
if "delegatecall" in source:
risks.append("HAS_DELEGATECALL")
if risks:
report(contract, risks, contract.balance)
Combine this with LLM-powered analysis for logic bugs that regex can't catch, and you have a repeatable pipeline for finding high-value vulnerabilities.
The Numbers Tell the Story
- Truebit (Jan 2026): 5-year-old contract, Solidity 0.6.10, $26.4M lost, no audit
- SagaEVM (Jan 2026): 3-year-old contract, Solidity 0.6.12, $7M lost, partial audit
- Aperture Finance (Jan 2026): 2-year-old contract, Solidity 0.7.6, $4M lost, v1-only audit
Pattern: Every major "legacy contract" exploit in 2026 targeted code compiled before Solidity 0.8.0's automatic overflow protection.
What Solidity 0.8.0 Actually Fixed
For context, here's why the 0.8.0 boundary matters so much:
// Solidity 0.6.x
uint256 a = type(uint256).max;
uint256 b = a + 1; // b = 0, no error
// Solidity 0.8.0+
uint256 a = type(uint256).max;
uint256 b = a + 1; // REVERTS with "Arithmetic overflow"
This single change eliminated an entire class of vulnerabilities. But it only protects contracts compiled with 0.8.0+. The billions locked in older contracts? Still vulnerable.
The Clock Is Ticking
The combination of:
- Billions in value locked in pre-0.8.0 contracts
- AI-powered scanning making bug discovery trivially cheap
- Historical exploit data training increasingly effective attack models
...means zombie contract exploits will accelerate through 2026. The Truebit exploit wasn't an anomaly — it was a preview.
If you're a protocol team: Audit your legacy contracts this week. Not next quarter. This week.
If you're a user: Clean up your approvals today. It takes 10 minutes.
If you're a researcher: The next $26M bug is probably sitting in a contract deployed in 2021, compiled with Solidity 0.6.x, holding a forgotten treasury. Go find it before the attackers do.
This article is part of the DeFi Security Field Notes series at DreamWork Security. Follow for weekly deep dives into vulnerabilities, audit tools, and security best practices across Solana and EVM ecosystems.
Disclaimer: This article is for educational and defensive security research purposes. Always practice responsible disclosure.
Top comments (0)