Burn Notice #5
Aztec Connect’s $2.19M Unpausable Drain, Verus’s $11.6M Replay of a 2022 Bridge Bug, and Two Bounty Programs Going Dark
Three of this week’s incidents share a pattern. Each one hit infrastructure that the owning team had already deprecated and stopped maintaining. A wound-down Aztec Connect bridge contract was drained, a set of Raydium pools retired in 2021 was emptied, and two teams closed their bug bounty programs in the same period.
In today’s issue.
How a deprecated Aztec Connect contract lost $2.19M with no admin key left to pause it.
How the Verus bridge lost $11.6M to a value-binding flaw, in a bridge failure class first seen in 2022.
Two vulnerability bounty programs shut their doors as AI-generated reports overwhelmed triage.
Need to Know
Most of this week's losses came out of the past, from contracts their teams had already deprecated to a bridge that fell to a value-binding flaw in a class the industry first paid for in 2022. Code that has been deprecated, frozen, or left unverified keeps holding funds and attracting attackers, and the bug classes draining bridges are old enough to carry name-brand precedents and known fixes nobody applied. Meanwhile the disclosure programs that would route a researcher's write-up to a team before an attacker's exploit are the thing closing, with two of them shutting this fortnight over a flood of low-signal AI-generated reports. If your treasury still sits behind old code or a bridge design somebody already broke once, who on your team is paid to go and find that out before someone else does? —Adrian
The Big One. Aztec Connect’s Drain on a Contract Nobody Could Pause
The news. On 14 June, an attacker drained roughly $2.19M from the RollupProcessorV3 contract, the last live piece of Aztec Connect, a privacy zk-rollup bridge Aztec Labs wound down in 2023. There was no reentrancy, no flash loan, and no compromised key. The cryptography held. The root cause was a settlement-boundary bypass, where the zero-knowledge proof committed to transaction slots the L1 contract never verified at settlement, letting the attacker withdraw assets the proof had never backed. The funds left in a single atomic transaction, around 909 ETH plus DAI, wstETH, and smaller positions, routed through Tornado Cash on the way in.
What broke and how. Inside RollupProcessorV3 there is a structural gap between the range the L1 settlement loop walks and the range the proof’s public-input hash commits to. The proof committed 31 of 32 public-input slots into the L2 state root while the settlement layer enforced only one of them, so the contents of the other slots reached the L2 accounting without ever passing an L1 check. The attacker ran the exploit across fourteen processRollup() calls in a single transaction, first inserting forged deposits into the unverified slots, then withdrawing those balances from the L1 pool as if they were genuine. The proof verified one transaction list while the contract settled another, and the fix is to make a rollup’s on-chain settlement scope cover exactly the public inputs its proof commits.
Why it kept happening. Aztec Connect launched in mid-2022, stopped taking deposits in 2023, and had its off-chain sequencer wound down, but the on-chain contracts stayed live with user assets still inside them. RollupProcessorV3 was upgraded in April 2024, after the sunset, with no external audit. The contracts later became fully immutable, so Aztec Labs holds no admin keys and cannot pause or upgrade the system, and when the drain started no operator could stop it, leaving public warnings and tracing as the only response. The same week, retired Raydium pools were emptied the same way and a six-month industry tally put its largest losses in unverified and legacy contracts, both covered elsewhere in this issue, and all three involve code the owning teams had treated as closed but left reachable on-chain.
What to check now.
Pull a list of every contract your organisation has ever deployed that still holds a balance or a permission and is no longer in your active repo, monitoring, or front end, and treat anything labelled deprecated as live until its balance is zero.
For any contract you upgraded after you stopped actively running the system around it, confirm that upgrade went through the same audit gate as a live deployment, because a post-sunset change is still a production change.
Where a contract is immutable and cannot be paused, write down now what your only available response actually is, and confirm a named person is on the hook to execute it.
If you run zk circuits, verify that the scope of your on-chain settlement verification matches the public inputs your proof commits, and test the boundary between the slots the proof covers and the slots the contract acts on.
Decide who owns the question of when a retired system has its remaining funds moved to safety and its surface taken down for good.
Chain Reaction. Verus Fell to the Same Class of Failure as Wormhole and Nomad
The news. On 18 May an attacker drained roughly $11.58M from the Verus-Ethereum bridge by feeding the Ethereum-side contract a forged cross-chain transfer it accepted as genuine. The bridge checked the notarised Verus state root, the notary signatures, and the Merkle proof, with no key compromised anywhere, but never checked that the amount claimed on Verus matched the amount it paid out on Ethereum, a source-destination value-binding gap. Most of it came back within days through a negotiated bounty, the attacker returning about 75% and keeping the rest, which left Verus out roughly $2.8M.
What broke and how. The Ethereum-side contract did real verification work. It confirmed the root hash of the notarised Verus state, required eight of fifteen notary signatures, and validated the Merkle proof. What it never enforced was the economics. Nothing on the path required the payout on Ethereum to equal a real, locked deposit on Verus, so a forged transfer with a structurally valid proof could claim assets that were never backed. The attacker funded the wallet through Tornado Cash about fourteen hours ahead, took 1,625 ETH, 147,000 USDC, and 103.6 tBTC, and consolidated the haul into roughly 5,402 ETH. Verus had marketed the bridge as trustless and had shipped an emergency update for a separate issue two days earlier that did not touch this path.
Why it kept happening. Verus sits in the oldest family of bridge failures there is, where a destination chain releases assets against a cross-chain message that was never tied to an equal, locked deposit on the source. Calling it the same bug as the famous 2022 cases would be too neat, because the exact flaw differed in each. Wormhole’s attacker spoofed a Solana sysvar account to bypass signature verification and mint 120,000 wETH that nothing backed. Nomad’s upgrade set its trusted root to zero, so every message read as already proven. Verus did the verification work, checking the state root, the notary signatures, and the Merkle proof, and skipped only the check that the payout matched a real deposit. The three are different bugs that share one blind spot, which is that cryptographic validity was never bound to economic validity. The fix is the same in each, to assert that what leaves equals what was locked on every path. Teams keep rebuilding that blind spot because each one learns the lesson from its own incident rather than the ones before it.
What to check now.
For every bridge or cross-chain message handler you run, confirm there is an explicit check that the value released on the destination equals the value locked on the source, enforced on every path rather than only the common one.
Treat proof verification and value verification as two separate jobs, because a valid Merkle proof over a forged or unbound amount still passes.
Pull the Wormhole and Nomad post-mortems and the Verus analysis, and test your design against each specific failure, because the mechanism differed in all three.
If you call a bridge trustless in your own marketing, write down which checks earn the word, and have someone outside the team try to break the binding between the two chains.
The operator move.
Open your bridge and find the line that asserts the amount paid out equals the amount locked. If it takes you more than a minute to point at it, you do not have it, and you are one forged proof away from joining a list that already runs Wormhole, Nomad, and now Verus. Read all three before you ship another release.
— Adrian
Around the Forums
Zcash Community Grants closes its vulnerability bounty program. ZCG shut down its Vulnerability Bounty Program and Security and Vulnerability Disclosure Initiative, keeping responsible disclosure open only through private channels, and framed the move around AI-assisted tooling changing how bugs are found, reported, and duplicated. The community read closer to budget and triage, with ZcHub noting the program closed as AI-generated reports drove up the triage burden. It landed days before the Orchard soundness bug went public, which this newsletter walked through last issue, and a fully shielded network now has one fewer paid channel pointed at exactly the kind of circuit that bug lived in.
THORChain’s bounty is called permanently retired as a researcher threatens to publish. V12, an automated-auditing startup, says it reported a critical loss-of-funds bug, that THORChain silently patched it without credit or payment and told the firm the bounty is permanently retired, and that it is holding additional chain-halt findings it intends to disclose openly alongside published proof-of-concept code. THORChain’s account is that the self-hosted program was retired in March, before the firm’s late-April submission, because of low-signal report volume, though the protocol’s own security pages still advertise a bounty for verified critical bugs. A protocol fresh off a vault loss in May is now in an open dispute with a researcher sitting on unpatched findings, with its own documentation contradicting what it told the firm.
What Else Happened
LP-mint validation flaw on Raydium’s legacy AMM V3. On 10 June an attacker used a fake mint address to bypass validation in Raydium’s AMM V3 pools, retired from the exchange’s interface and SDK since the 2021 Serum shutdown but still funded on-chain, draining about $1.34M from five deprecated pools. Raydium confirmed its treasury will cover the loss and that no active users were exposed, and its contributors opened a review of live programs for the same gap.
Admin-key compromise on the MILC cross-chain bridge. A historical MILC bridge admin wallet was used to grant
DEFAULT_ADMIN_ROLEandMANAGER_ROLEto an attacker-controlled address on BNB Chain and Ethereum, which then drained the bridge and took over its admin control for around $161K, roughly 97,000 USDT plus 39 ETH moved via Rhino.fi.Protocol-owned liquidity drain on Dexlyn. Dexlyn said malicious activity hit its protocol-owned liquidity wallets and that user deposits were unaffected, with the team coordinating an on-chain trace and a whitehat bounty with Supra while the loss figure stays undisclosed.
Supply-chain compromise of the Mastra npm scope. On 17 June an attacker used a former contributor’s account to republish 141 packages under the
@mastra/*scope, each carrying one injected dependency,easy-day-js, a clone of dayjs whose postinstall hook drops a crypto-stealing remote access trojan. The package source was left untouched, so source review of@mastra/*shows nothing and only install-time scanning catches it.Supply-chain compromise of the Arch User Repository. Researchers disclosed Atomic Arch on 11 June, a campaign that took over hundreds of orphaned AUR packages and rewrote their build scripts to install a malicious npm package,
atomic-lockfile, that harvests credentials and SSH keys and drops an eBPF rootkit where it lands root. The packages’ own code never changed, and the attackers inherited trust by adopting projects their maintainers had abandoned rather than typosquatting.
On the Clock
Two clocks this week. The first is the supply-chain pair in the roundup above. If your CI or any developer machine pulled from the Mastra npm scope or adopted Arch AUR packages in the early-June windows, treat those hosts as compromised, rotate every credential reachable from them, and rebuild any box where the payload may have run as root. The second is a posture decision rather than a patch. If you run any contract you have deprecated that still holds funds, treat this week as the deadline to inventory it and decide your only available response, because the settlement and validation bugs that hit Aztec Connect and Raydium are being found in exactly that kind of retired code right now.
Long Reads
SlowMist on the Aztec Connect settlement-boundary bypass, the cleanest reconstruction of the slot-range gap from contract source and on-chain calldata, worth reading alongside The Defiant on why an abandoned contract had no operator left to stop it if you run anything on a zk rollup.
Chainalysis on the $36.7M drained from unverified DeFi contracts over six months, led by a Truebit contract unverified since 2021, for the data behind the claim that hiding source code has stopped working as a security control now that decompilation and models are cheap.
Perimeter on the Polkadot XCM origin-isolation bug it disclosed for a $75K bounty, a clean walk-through of how a missing AliasOrigin or ClearOrigin step combined with a surviving ReserveAssetDeposited instruction could have minted unlimited unbacked cross-chain assets, around $69M at risk, worth reading if you handle cross-chain messages and want the defensive version of the bug Verus shipped.
The Operator’s Read
Decommissioning Is the Stage Nobody Owns
Most teams have a deploy runbook, and after enough bad nights most have an incident runbook, but almost none have a plan for the day a system is meant to be switched off for good. The shutdown gets a Slack message and a calendar reminder nobody acts on. This week showed what that missing stage costs.
The Aztec Connect contract that lost $2.19M was sunset in 2023. Deposits stopped and the off-chain sequencer was wound down, but on-chain the contract still held user funds and still had every permission it was granted at deploy. It was upgraded once more in April 2024, after the sunset, and that change never went through an external audit. The contracts were later made immutable, so Aztec Labs held no keys and could not pause anything, and when the drain started the only response available was a public warning.
Deprecating a contract is an internal decision about budget and attention, and it does not change anything on-chain. The team stops monitoring, the engineers move to the next project, and the contract keeps its balance and its permissions exactly as before. Raydium saw a cheaper version of this when five of its 2021 pools were drained through a fake mint address, pools that had been gone from the front end and the SDK since 2021 but were still funded on-chain. Raydium could cover the loss from its treasury, which most teams carrying abandoned contracts cannot.
The same problem reaches code that was never verified rather than code that was sunset. Chainalysis counted $36.7M of losses over six months in unverified contracts, led by a Truebit contract that has been unverified on Ethereum since 2021. The assumption behind leaving source unpublished was that nobody could read the bytecode. That has stopped holding, because decompilation is good and models are cheap, and an attacker now reads an unverified contract about as easily as a verified one. Not publishing the source buys a delay and little else.
What connects these cases is ownership. A deployment has an owner and an incident usually has one too, but no one is given the job of shutting a system down properly. Funds stay in contracts the organisation has stopped thinking about. Permissions remain assigned to keys nobody rotates, and the surface stays reachable for years because closing it was never anyone’s objective. The DxSale lockers drained in late May, 2021 contracts whose ownership had been quietly moved and whose unlock was backdated to 1970, were the same story a month before Aztec, and that one does not even fall inside this issue’s window.
The channel that would normally catch a bug in forgotten code is also narrowing. Two teams closed their disclosure programs this fortnight, both citing the volume of AI-generated reports, which the forums section covers above. The cost for an attacker to find a flaw in old code is falling at the same time as the paid route for an honest researcher to report one is being cut.
There is a tactical response and a strategic one. The tactical response is the operator move above and takes an afternoon. The strategic response is to treat decommissioning as a real stage with an owner and a clear definition of done, meaning a zero balance, permissions renounced or moved to a key the team still controls, and the contract watched until it can be shown to be empty.
My expectation is that within a year one of these forgotten-surface drains passes nine figures, and the post-mortem will note that the team believed the system had been shut down years earlier. The tools to find these contracts are cheap and the balances in them are large, while the teams that deployed them have stopped watching. Teams that handle this well will treat “we deprecated that” as the beginning of the work.
— Adrian
P.S. A quarterly dead-contract audit becomes one more box to tick and changes little. What actually shrinks the surface is moving the funds out and giving up the permissions, since a contract with no balance and no powers is one an attacker can study at leisure and do nothing with.
Closing Tab.
Watch whether the next major drain traces to a bug a working bounty program would have caught, now that two of them have gone dark in a single fortnight.
Adrian Hetman Burn Notice Operational intelligence for Web3, every week.

