1

The next DeFi drain could come from legacy contracts everyone forgot

The Raydium wake-up call and the graveyard of callable contracts

Think of this as a cautionary ghost story for decentralized finance: an old Raydium program — the AMM V3 that nobody used anymore — was quietly robbed for about $1.34 million. That code had been retired from the main product path, invisible to the current UI and SDK, but still callable on-chain. In plain English: the program lost its job but kept its keys.

The attacker abused a legacy flow that relied on an external order book (it used to talk to Serum). When Serum stopped being a thing, the program lost its purpose but didn’t get properly shut down. Modern Raydium code now checks virtual supply and verifies LP mint addresses, but the old program skipped those safety checks. That allowed someone to forge a new mint, pretend it was the LP token, and bypass the proportion controls. Poof — about 150,177 RAY, 5,603 SOL, and 893,700 USDC were scooped out of pools that had been left in the protocol’s attic.

Raydium’s hit wasn’t an isolated blip. Since March 2025 there have been multiple cases where deprecated or obsolete contracts that were supposed to be retired instead became attack surfaces. Narrowly counted, those incidents total roughly $10.8 million in losses; broaden the definition to include legacy vaults and product migrations and the publicly reported tally pushes toward $22.5 million. In other words: the graveyard is worth watching.

Examples: an outdated resolver in a Fusion v1 implementation cost one protocol roughly $5 million in March 2025. Another protocol lost about $1.8 million when deprecated Cauldron V4 contracts were still callable. A legacy vault holding TUSD was drained for a few hundred thousand dollars while newer vault versions stayed untouched. Other teams lost mid-six-figure sums to retired contracts on chains they’d migrated away from, and a few incidents were partially mitigated by good-faith recoveries.

Why zombie contracts keep getting looted — and what actually helps

Most security reports obsess over the immediate technical mechanism: an oracle got tricked, a reentrancy happened, or a private key was leaked. That lens is useful, but it hides a different root cause: lifecycle negligence. A contract that’s ‘‘deprecated’’ on paper but still callable on-chain is basically an unlocked basement window. Attackers love basements.

Research looking at dozens of high-impact exploits from 2022–2025 shows a pattern: the biggest incidents often chain together human, operational, economic, lifecycle, and governance failures. Lifecycle problems — failing to truly retire or monitor old code — deserve their own category, not to be lumped into generic ‘‘implementation bugs.’p>

So what actually stops these zombie contracts? Treat decommissioning like a security control, not a box on a docs page. Practical steps that help:

– Drain old vaults and remove assets, or pause them on-chain if possible.

– Add strict verification checks on any program that handles token mints or LP tokens (don’t trust presented mints).

– Lock or disable initializers so nobody can reinitialize legacy deployments, and fix migration flows that leave old deployments live.

– Maintain monitoring and alerts for callable retired contracts and for approvals that still grant rights to obsolete code.

– Make decommissioning checklists part of audits and post-deploy governance — count and classify legacy surfaces during risk assessments.

When teams treat retirement as active maintenance, the attack surface shrinks. When they don’t, the treasury often eats the bill anyway — turning what should be an operational cleanup into a security incident with real payouts.

In short: audits are great, tests are great, but if you leave the old stuff plugged in, an attacker will go rummaging through the protocol’s attic. Call it preventive maintenance for Web3 — boring, necessary, and way cheaper than clean-up after a heist.