The Web2 Perimeter of DeFi: Where the Money Actually Leaves

Author(s): Viktor Yurov, Ilya Teterin
Security researcher(s) at MixBytes
Abstract
Introduction
Two axes: channel × payload
ᅠ• The universal template
The surface, layer by layer
ᅠ• Build & supply chain
ᅠ• Serving & naming
ᅠ• Reaching the user
ᅠ• The client & the signature
ᅠ• The AI layer
What's actually most dangerous right now
The patterns worth remembering
What auditors should do
What protocols should do
Conclusion

Abstract
As of 2026, most DeFi losses do not come from smart-contract bugs. They come from the Web2 infrastructure around the contract: DNS, dependencies, hosting, signer UIs, wallet software, cloud keys, and hijacked accounts. This layer is under-audited because security review is scoped to on-chain code. The useful way to organize it is two axes - delivery channel (how attacker code reaches the user) and payload (what actually removes the funds). The channels keep multiplying; the payloads are few. This piece maps the perimeter, ranks the risk, and says what auditors and protocols should change.
Introduction
On-chain code is the most scrutinized part of a DeFi system: public, formally analyzable, repeatedly audited. It usually holds. The losses come in through everything around it - the pipeline that gets code from a developer's keyboard to a user's signed transaction.

Two structural facts explain why this perimeter is soft. First, attention asymmetry: auditors are retained to review contracts, so the contract layer is heavily monitored while DNS, CDN, dependency graphs, and signer UIs are barely watched. Second, severity inflation through connected wallets: a Web2 bug that is "low" in a normal app is critical here. An open redirect is a nuisance on a marketing site; on a dApp with a connected wallet it is a path to asset loss. Cross-site scripting has no single severity - OWASP rates it by context - and in a conventional app its impact is bounded by the session: a stolen cookie, a defaced page. Connect a wallet and the same injected script can rewrite the transaction the user is about to sign, and the impact ceiling jumps to permanent asset loss.

The headline number: in 2025, Web3 lost $3.35B across 630 incidents (CertiK Hack3d 2025). The costliest attack vector of the year was supply chain - $1.45B, 43% of all losses (99.7% of it the Bybit signing-interface compromise), followed by phishing - $723M, 22% across 248 incidents, the most of any vector. Smart-contract code vulnerabilities were second by incident count (240 incidents) but CertiK publishes no annual loss total for them - the money concentrates on the perimeter, not in the contract. (Figures are Web3-wide, not DeFi-only; no major tracker publishes a DeFi split, and category boundaries vary by source.) The same security budget will often buy more risk reduction on the perimeter than on an already well-audited contract - yet comparatively little of it tends to be spent there.

The pipeline below is the model for the whole piece. Read the perimeter as one path:

The delivery path from a developer's keyboard to the user's funds. Every stage is an injection point; a smart-contract audit covers only the last one.
Every stage is an injection point, and the smart-contract audit covers only the last node before the funds - the rest of the path is where the incidents below happened.
Two axes: channel × payload
The incidents below span DNS, npm, cloud, mobile, and AI - dozens of them. Listed channel by channel they look like a sprawling zoo, and each new one feels like a new threat. The single most useful idea in this piece is the opposite: stop classifying incidents by "which system broke" and split each one into two independent axes.

Payloads - what actually steals the money - are few:

  • Approval / permit-phishing drainer. The user is lured by something routine - a claim, a swap, a "verify wallet" prompt - and asked to sign. What they sign is an ERC-20 approve (often for an unlimited allowance) or a gasless ERC-2612 Permit, which lets the attacker's address pull the tokens later with transferFrom. The key is never stolen; the user authorizes the theft, and the tokens leave in a separate transaction minutes or days afterward. Permit is the fastest-growing variant because it is an off-chain signature, not an on-chain transaction: there is no gas prompt and no "transaction" warning. Modern wallets increasingly decode Permit and can surface - even flag - the spender and amount, but it still presents as a "signature request" rather than a transfer, which is easier to wave through.
  • Man-in-the-browser drainer. Injected code sits between the page and the wallet, hooking window.ethereum.request (and the Solana provider) to intercept eth_sendTransaction / signTypedData calls. It rewrites the recipient or calldata on the way to the wallet - often to a visually similar look-alike address - so the wallet only ever receives the tampered version and displays that. Unless the user verifies the destination on a hardware screen, the correct-looking page and the tampered signature are never checked against each other. Clipboard-swap variants do the same to copied addresses.
  • Credential / key stealer. Harvests seed phrases, private keys, .env files, cloud credentials (AWS/GCP), and - increasingly the real prize - npm and GitHub publish tokens, from a developer machine, a CI runner, or a cloud environment. The stolen data is used either for direct theft or as a stepping stone: a stolen maintainer token becomes the next supply-chain compromise.
  • Signing-interface deception. The signer is legitimate and the key is intact, but the interface shows one thing while another is signed - an ordinary transfer on screen, a delegatecall or owner-swap in the bytes. Hardware wallets only partly help here: they can clear-sign standard, decodable transactions, but complex calldata - a delegatecall, an unknown contract - tends to fall back to blind-signing, where the display looks the same whether the payload is harmless or malicious (this is the Bybit mechanism, below).

The first two are worth seeing as flows, because every later mention of "drainer" and "Permit" reduces to these two pictures. Approval-phishing gets the user to authorize the theft:

The user is tricked into signing a Permit/approve that hands the attacker an allowance - then transferFrom drains the tokens. The private key is never stolen. A man-in-the-browser drainer never asks for a special signature - it rewrites a normal one as it is being sent:

Injected code hooks the wallet API and rewrites the transaction on the way through. The page shows the original; the wallet receives the attacker's version.

The difference is where the lie lives: approval-phishing lies about what a visible signature means; man-in-the-browser lies about what is being signed while the page looks correct.

Channels - how the payload arrives - are many and interchangeable: DNS, a compromised dependency, a third-party frontend vendor, a dev/CI machine, a hijacked social account, a cloud bucket, the signer's own UI. The attacker's goal is just to run the payload next to a connected wallet; which door it comes through is a matter of opportunity, not a different kind of attack. Close DNS and the same drainer arrives via npm or a vendor script.

That is the whole thesis in one line: a small, stable set of payloads distributed through a growing set of doors. A direct consequence - severity ≠ reach: the chalk/debug npm compromise touched ~2B weekly downloads and stole ~$500; the Polymarket vendor compromise touched one supplier and stole ~$3M. How long the malicious code stayed live and who it targeted decide the loss - not how widely it spread.

The table below puts the two axes side by side. Each row is one channel (one door into the wallet): the payload that usually rides it, a real incident that anchors it, and the first practical defense for that door. Read it two ways. Down the payload column, the same few payloads keep reappearing - proof that the channel is interchangeable and the payload is not. Down the defense column, the countermeasures are all different, because each is tied to the specific door, not to the payload - which is exactly why defending channel-by-channel never ends. It is a map of the perimeter, not a checklist; every row is expanded in the sections that follow.
The universal template
Underneath the two axes is a single template that every case in this article is an instance of:

The single template every case reduces to: a trust boundary breaks, attacker code runs next to a connected wallet, and the payload moves the funds.

This is why DNS, npm, Cloudflare, a Safe UI, an MCP server, an AI agent, and an XSS bug all belong in one taxonomy: they are different trust boundaries feeding the same four steps. The channel is which boundary broke; the payload is how steps three and four are achieved. Everything below is a variation on this.
The surface, layer by layer
The channels group into five clusters along the pipeline. For each: the mechanism, the cases that anchor it, and the takeaway.
Build & supply chain
The frontend is assembled from dependencies and shipped by CI/CD, so anything upstream of the build can plant code inside the legitimate bundle. Three sub-classes reach the same outcome: maintainer account takeover of a trusted package, dependency confusion (a public package shadowing a private one), and a poisoned third-party vendor script already trusted on the domain. What makes this hard to catch is that the activation keeps moving: a postinstall hook (code that runs at install time) is blockable with --ignore-scripts, but code that runs the moment the package is imported (require()) is not, and a manifest-only edit adds a malicious dependency without touching a line of source.

  • chalk/debug (Sep 2025) - the largest compromise by reach. The maintainer was phished by a fake npm 2FA-reset email from npmjs.help, a look-alike domain registered days earlier; within ~16 minutes the attacker republished ~18–20 foundational utility packages (chalk, debug, ansi-styles, and more) that sit as transitive dependencies inside thousands of frontends and dev tools - ~2 billion weekly downloads combined. The payload was a man-in-the-browser drainer that ran only in a browser context, hooked window.ethereum/Solana, and swapped destination addresses for near-identical look-alike ones across several chains. It stole only ~$500 - the malicious versions were live for ~2 hours and CI pipelines flagged them (a browser-only fetch call threw in Node) - but the reach was effectively the whole ecosystem.
  • node-ipc (May 2026) - runtime-triggered: the payload fires on require() (when the package is imported), not on install, so npm ci --ignore-scripts - the standard mitigation - does nothing. Initial access needed no phishing at all: the maintainer's personal email domain had lapsed, so the attacker simply re-registered it and used it to reset the npm password (an expired-domain takeover). The payload harvested 90+ credential categories - cloud keys, SSH keys, and notably AI dev-tool configs (.claude.json, MCP files) - exfiltrating over HTTPS and DNS tunneling.
  • Axios (Mar 2026) - a manifest-only injection: the package's runtime code was untouched; instead its package.json pulled in a malicious sibling (plain-crypto-js) whose postinstall hook installed a cross-platform RAT (remote-access trojan). Because no source changed, a code review of Axios itself would see nothing. Microsoft Threat Intelligence attributed it to Sapphire Sleet (DPRK), a group targeting crypto, VC, and blockchain developers. Axios is among npm's most-downloaded packages - npm's counter shows ~100M weekly downloads (Microsoft's report cited 70M) - which set how far it could spread.
  • Polymarket (Jun 2026) - not npm but a compromised third-party frontend vendor: a script the vendor served on Polymarket's own legitimate domain was swapped for an approval-phishing drainer. Crucially it was delivered only to some users, so security scanners fetching a clean copy saw nothing wrong. ~$3M in pUSD, bridged to ~1,893 ETH - the same blueprint as the December 2023 Ledger Connect Kit hijack.
Takeaway: one payload class reaches the wallet identically whether it rides an npm dependency or a vendor script; --ignore-scripts no longer covers it (runtime activation and manifest-only edits slip past it); and conditional delivery defeats periodic scanning.

How the attacker gets to the developer in the first place. Every case above starts one step earlier, with a person or an account being compromised. This "step 0" is where the whole pipeline is actually seeded, and it is worth treating on its own because the methods are few, repeat across unrelated incidents, and are far more mundane than the payloads they enable. Six recur:

  • Credential phishing. A fake login or 2FA-reset page on a look-alike domain captures the maintainer's credentials. The detail that matters: modern phishing kits are usually adversary-in-the-middle (AiTM) - the fake page is a live reverse proxy sitting in front of the real login, so it relays the victim's password and one-time code to the genuine site in real time and steals back the resulting session cookie (the token that keeps you logged in). That means an authenticator app (TOTP) or an SMS code does not save you - only origin-bound factors (hardware keys, passkeys) do, because they refuse to authenticate to the wrong domain. chalk/debug began exactly here: an npmjs.help reset email, the look-alike registered days before, and ~18–20 packages republished within ~16 minutes of the maintainer's account falling. It remains the single most common entry point.
  • Expired-domain takeover. No phishing, no malware - just an expired renewal. The maintainer's personal email domain lapses; the attacker re-registers it for a few dollars, recreates the mailbox that account-recovery routes to, and triggers a password reset that now lands in their inbox. At node-ipc the lapsed domain was the maintainer's own, and it was enough to reset the npm password and publish. The uncomfortable part is that this needs zero interaction from the victim and leaves nothing on their machine to detect.
  • Residual / inherited access. A token, SSO grant, deploy key, or shared account that was never revoked after a job change, a departure, or an ended vendor relationship - access that exists on nobody's current org chart. This is a live intrusion vector, not hygiene trivia: an identity a developer still carries from a previous employer, whose grants the current org has no way to confirm were revoked, is exactly the kind of unwatched door an attacker walks through - into a foothold, then laterally into production infrastructure, where an intrusion seeded this way can sit for weeks before it is used. The vendor-side version of the same gap is the LastPass breach reaching teams through the compromised third party Klue. Every offboarding you skip is a permanent door.
  • Infostealer on the dev machine. The developer's everyday laptop holds a logged-in browser session, an ssh-agent, logged-in cloud CLIs, and a .npmrc publish token all in one place - so a single stealer run collects the whole set. Delivery is usually a poisoned dependency, a trojanized tool, or a fake-interview "take-home coding test": a repo the "recruiter" asks the candidate to run, whose postinstall or obfuscated dependency executes on the dev's own machine. DPRK's Sapphire Sleet used exactly this lure behind the Axios compromise; node-ipc's payload harvested 90+ credential categories including AI-tool configs (.claude.json, MCP files); and QUIETVAULT - an AI-assisted stealer - is built specifically to grab npm and GitHub tokens, feeding the stolen tokens straight back into the supply-chain cluster above.
  • Insider by hire. Sometimes the access is simply granted. DPRK IT-worker crews (Famous Chollima / Wagemole) apply for remote developer roles at crypto firms and pass live video interviews behind real-time deepfake face filters; once hired, the insider converts legitimate access into backdoored commits, stolen keys, and leaked secrets. The barrier has collapsed - a working fake identity was built in 70 minutes on a five-year-old computer by someone with no prior experience. The filters still break under liveness stress (a hand passed across the face, abrupt head turns, lip-sync lag), which is why video verification with motion checks is a real control here.
  • Session-token theft and SIM-swap. Both skip the password entirely. A stolen session cookie (from an infostealer or an AiTM proxy above) is replayed to land already-authenticated, past both password and 2FA. A SIM-swap ports the target's number to the attacker's SIM and turns SMS-based 2FA and phone-based recovery into the attacker's own second factor. Mandiant's X account was taken "likely [by] a brute force password attack" amid a 2FA-policy gap during team transitions - the account-takeover mechanics that also drive the social-channel hijacks two clusters down.
The through-line is that the developer's laptop and publish credentials sit at the head of the delivery pipeline - production-level power, rarely production-level defenses. That asymmetry is the whole story of chalk/debug: a ~$500 phishing kit reaching ~2 billion weekly downloads because the one account guarding that reach had recoverable, phishable 2FA. The controls that actually close step 0 are unglamorous and specific: phishing-resistant hardware-2FA / passkeys (never SMS or plain TOTP, both of which the methods above defeat), scoped and short-lived publish tokens with provenance, key material isolated from the everyday machine, alerting on new API-key/token creation, and revoking every grant the day a person or vendor relationship ends.
Serving & naming
Between the build and the browser is where the bundle is stored, named, and routed - and each of those is a distinct account to compromise, with the domain and TLS still perfectly valid afterward. The shape is the same whichever account breaks:

A hijacked registrar, DNS, or hosting account serves the attacker's frontend on the correct URL with a valid TLS certificate - so the padlock proves nothing.

  • CDN / edge account. BadgerDAO ($120M, Dec 2021) - the attacker compromised the project's Cloudflare account and created an API key the team never knew about, then used Cloudflare Workers - code that runs on the CDN's edge servers and rewrites the HTTP response between the origin and the browser - to inject an ice-phishing script (a prompt that tricks the user into approving token spending). Because the injection happens at the edge, the original bundle stays untouched, so origin-side integrity checks see nothing. The script rotated in and out and fired only for a subset of users, which made it extremely hard to reproduce; the theft was finally stopped only by freezing transferFrom on-chain. (This is the earliest example of the conditional-delivery trick Polymarket later reused.)
  • Cloud storage. Bybit (Feb 2025) - the Safe{Wallet} web app's JavaScript was served from an AWS S3 bucket, and the attacker - having compromised a Safe developer's workstation, hijacked its AWS session, and bypassed MFA (per Safe's post-mortem with Mandiant) - replaced that JavaScript in the bucket. An activation condition kept the malicious code dormant for everyone except Bybit's specific cold-wallet address, so it fired exactly once, on the intended target - then was pulled from S3 within minutes to erase the evidence. Correct domain, valid TLS, the bundle swapped underneath.
  • Cloud key management. A different cloud failure mode, with no frontend involved at all: a protocol that authorizes privileged issuance - mints, upgrades, withdrawals - through an off-chain signer whose key is a single cloud-held EOA (sitting in a KMS rather than a multisig or HSM). Breaking into the cloud infrastructure gets you the key, and if the contract accepts whatever that signer produces - no on-chain cap, no collateral check - a single fabricated authorization can mint unbacked supply and break a peg. The signing authority behind privileged issuance is exactly the single point that belongs behind a multisig or HSM and a hard on-chain mint limit, so that no off-chain signature, however obtained, can move unlimited value.
  • Domain / registrar. Take the name and you redirect the entire frontend to attacker infrastructure. CoW Swap (~$1.2M) fell to forged documents submitted to the .fi registrar. The Squarespace mass campaign was structurally different - a migration-induced auth bypass: when Google Domains accounts were moved to Squarespace, admin emails were pre-linked without validating ownership and MFA was left off, so whoever controlled a linked email could seize the domain. That put 228 DeFi frontends at risk and hijacked about a dozen at once - not support social engineering, but a vendor-side flaw at scale.
  • Below DNS: BGP. KLAYswap (~$1.9M, Feb 2022) - the attacker announced a more-specific BGP route for the IP range of a third-party SDK the frontend loaded, so the internet started delivering that traffic through them. They then man-in-the-middled certificate issuance itself, obtaining a valid TLS certificate for the hijacked prefix and serving malicious JavaScript under it - so the browser saw a perfectly valid padlock. TLS trusts the routing it rides on; this was the third BGP-hijack against a crypto service (2018 MyEtherWallet, via a Route 53 hijack, was an earlier one).

Takeaway: DNSSEC, SRI, and a contract audit all miss this layer, and one cloud account often holds the frontend, edge, storage, and the protocol's keys - so its compromise is total. Valid TLS and the right URL prove nothing here.
Reaching the user
Before a user can be phished, they have to arrive - and the channels that bring them are attackable too.

  • Social / comms. Two patterns: hijacking a trusted account (the Mandiant X account, hijacked via weak 2FA to push CLINKSINK phishing, ≥$900K across the campaign), or running a network of aged, verified-looking accounts that hide malicious links among legitimate reposts (Rublevka, 260+ dApp URLs; an AngelFerno cluster of 20 accounts).
  • Mobile. The official stores are the delivery channel, and their review is beatable. A fake WalletConnect app (published as a calculator) ran the MS Drainer flow, survived five months on Google Play using cloaking (showing reviewers a clean version and real users the malicious one), and buried complaints under fake five-star reviews (>$70K). SparkCat was the first OCR stealer found in Apple's App Store: a Google ML Kit module scanned the photo gallery for screenshots of seed phrases. Clipboard hijackers and fake Ledger/Trezor apps complete the picture.

Takeaway: "it's the official account" and "it's the official store" are not security properties - cloaking, aged accounts, and fake reviews defeat both human and automated review.
The client & the signature
At the far end the money moves - and the largest theft on record lives here: Bybit ($1.46B), a signing-interface compromise, not a smart-contract bug. Drift ($285M), below, is the slow variant of the same class - a signer deceived, not a contract broken.

A signing-interface compromise is not a key compromise. The key is never stolen; the lie lives entirely in the gap between what the UI shows and what gets signed.

Bybit (Feb 2025, $1.46B) - the largest theft on record, and worth going through step by step, because nothing about it was a contract bug. The signers saw, in the Safe{Wallet} web interface, an ordinary transfer from the cold multisig - the amounts and destinations looked exactly as expected. What they actually signed was a delegatecall that replaced the wallet's implementation and overwrote storage slot 0, handing the attacker control of the multisig. The malicious code was JavaScript injected into the Safe{Wallet} frontend, served from the app's own AWS S3 bucket, so it ran on the real domain for that session and was pulled from S3 minutes after the transaction landed. The hardware wallets did not help: a Ledger faithfully displays and signs the payload it is handed, and here that payload - dense, unreadable delegatecall calldata - was already the malicious one, so blind-signing it looked identical to blind-signing a legitimate complex transaction. And Safe showed false data for the simple reason that the compromised frontend controlled everything the signer saw; the displayed intent and the signed bytes had diverged, with nothing in the flow to reconcile them. (Confirmed by Safe's post-mortem with Mandiant: the attacker compromised a Safe{Wallet} developer's workstation, hijacked its AWS session, and bypassed MFA to reach the S3 bucket, where the injected JS altered the transaction the signers approved. Only how the malware first landed on that laptop - likely a malicious Docker project - remains unconfirmed.)

Drift ($285M) - the slow variant: ~6 months of social engineering plus Solana Durable Nonces to execute a transaction that had been pre-signed by deceiving the signer. Off-line pre-signing opens a gap between signature and execution in which the signer has no real-time feedback.
Takeaway (signer-side): the answer here is independent transaction verification - a second device, hardware-wallet confirmation - plus on-chain rate limits and caps, not signer diligence alone.

One more actor sits underneath every channel in this article, not just this one: the drainer market itself. The payloads described throughout are rarely hand-built - they are bought. Drainer-as-a-Service kits like Inferno ($80M+, ~137K victims), which handed off to Angel and then AngelFerno, are rented commodities with revenue splits and affiliates - so the entire perimeter above is really just their distribution network. That is why the same drainer keeps surfacing behind a DNS hijack, an npm compromise, and a fake mobile app alike.
The AI layer
AI sits across all of the above as both a new attack surface and a force-multiplier - it makes the existing attacks cheaper and larger. (The research version treats each of these as its own subsection.)

A new surface. A wallet-holding agent is exploitable when three things hold at once: untrusted text enters its context, a tool can execute transactions with no human in the loop, and the wallet can move funds. The Grok–Bankr drain (~$150K on Base) hit all three - an NFT that escalated the agent's permissions, an instruction hidden in Morse code that slipped the safety filter, and a tool that executed the decoded output on-chain. The root property is general and now a consensus among AI-security practitioners: an LLM cannot reliably separate instructions from data, so it cannot be used as a security boundary - authorization and limits belong in deterministic code outside the model. The same property produces two supply-chain variants: slopsquatting (attackers pre-register package names that assistants reliably hallucinate - in one study 43% of hallucinated names recurred on every run, so they can be farmed) and MCP tool poisoning (instructions hidden in the tool-description field the model treats as authoritative but the user never sees).

A force-multiplier. AI lowers the cost and the skill needed for the classic attacks. Anthropic documented a single actor using an agentic coding tool to run reconnaissance, credential harvesting, and intrusion across ~17 organizations in a month; no-code ransomware and DPRK operators passing Fortune-500 interviews show that the skill barrier is nearly gone; and runtime-LLM malware (PROMPTFLUX, PROMPTSTEAL) rewrites itself on each run to defeat signature-based detection. One strain, QUIETVAULT, steals GitHub and npm tokens - feeding straight back into the supply-chain cluster above. Takeaway: the old inference "a capable attack implies a capable actor" no longer holds, and signature-based detection collapses against code that morphs on every execution.
What's actually most dangerous right now
The empirical anchor: the three largest crypto losses of the 2025–2026 cycle were all infrastructure or operational compromises, not smart-contract bugs.
The first contract-code exploit on the cycle's list is Cetus (~$223M, May 2025), in fourth place. Two of the top three (KelpDAO, Drift) are linked to DPRK state-sponsored groups, weeks apart.

Not all of the above is equally urgent. Ranked by realized loss, frequency, and how catastrophic a single failure is:

Critical
  • Signer UI / multisig compromise - the largest theft on record (Bybit $1.46B), and Drift ($285M) again in 2026.
  • Hosting & cloud (CDN / bucket / KMS) - total control from one account (BadgerDAO $120M, Bybit-S3).
  • Frontend supply chain (npm + vendors) - widest reach, and accelerating (chalk/debug, Polymarket).
  • DNS / registrar - recurring and mass, low attacker cost (Squarespace's 228 frontends, CoW Swap, a 2026 wave).

High
  • Social / comms hijack - cheap, high-trust distribution.
  • Mobile - official stores are not a filter.
  • AI (prompt injection + offensive AI) - small losses today, rising fast.
  • RPC / BGP - rare, but not small: poisoning a bridge's verifier RPC cost KelpDAO ~$292M, and MITM defeats TLS when it happens.

Medium
  • Wallet-software RNG / nonce - catastrophic per incident but concentrated in specific software and legacy keys.
The patterns worth remembering
The core lessons, stated once:

  • One payload, many channels. Defend around the payloads and the few narrow points near the wallet, not around chasing each new channel.
  • Valid TLS and the right URL prove nothing. A BGP hijack can intercept the certificate-issuance process itself; a compromised cloud account serves malicious code on the real domain. Base your trust on something deeper than the padlock - provenance, integrity, routing security.
  • A patch does not undo a leaked or computable key, or a signed approval. These classes need prevention and migration, not remediation.
  • Assume the key will leak - bound the blast radius on-chain. Two-thirds of losses come from keys and access, and no patch undoes a stolen key or a signed approval - so the one control that survives full compromise is the one that limits what a single authorized action can do: on-chain withdrawal/mint caps, per-block/per-day rate limits, timelocks on large or sensitive operations (a window for monitoring to catch it and for a human to veto), circuit breakers, and least-privilege so one key can't touch everything. The counter-example is the failure this prevents - one compromised off-chain signer minting unbacked supply because nothing on-chain capped it. The goal is not "never lose a key," it is "make losing one survivable."
  • The DPRK cluster is a systems problem, not a bug. Linked actors account for >$2B in ~14 months (Bybit, KelpDAO, Drift, Axios) across signer UI, cross-chain verifier RPC, signer social engineering, and npm - none of it touched by contract auditing.
  • The asymmetry is structural. The attacker spends hours on one door; the defender must hold every door, which is a discipline almost nobody turns into routine. That is why the same registrar social engineering and the same npm compromise keep working.
What auditors should do
A contract audit engagement reviews on-chain code. The single most impactful change is to state - and where possible review - the perimeter that the contract audit does not cover. Concretely:

  1. Name the boundary in the report. Write explicitly that DNS, hosting, CI/CD, dependencies, signer infrastructure, and comms are out of the contract-audit scope. Clients routinely assume "audited" means "safe"; that assumption is the most expensive one in the space.
  2. Review the off-chain signing authority. Is any privileged mint / upgrade / withdrawal gated by a single EOA or a cloud KMS key rather than a multisig or HSM? Are there on-chain caps, rate limits, timelocks on large operations, and circuit breakers so that no off-chain signature - however obtained - can move unlimited value in a single transaction? Unbacked supply has been minted in exactly this way - a contract trusting whatever the off-chain signer authorized, with nothing on-chain to cap or delay it.
  3. Review the frontend supply chain. Lockfile + provenance on dependencies, --ignore-scripts in CI, strict CSP and SRI on the served bundle, and a hard limit on third-party scripts on any wallet-connect page.
  4. Check registrar and cloud hardening. DNSSEC + RegistryLock + CAA, hardware-2FA on the registrar, DNS, cloud, CDN, and npm accounts, least-privilege API keys with alerting on key creation.
  5. Review the signer flow, not just the contracts it calls. Safe{Wallet} integrity, independent transaction verification on a second device, and exposure from pre-signed / durable-nonce flows.
  6. Flag wallet-holding AI agents as a distinct finding: hard human-in-the-loop on transfers, least agency (give the agent the minimum power it needs to act), and a policy engine outside the LLM.
What protocols should do
The same approach, from the other side: treat the whole perimeter as production, and push every security decision toward something deterministic and verifiable.

  • Phishing-resistant hardware-2FA/passkeys on every registrar, DNS, cloud, CDN, npm, and social account; revoke access the day a person or vendor relationship ends.
  • Make what you ship verifiable: dependency pinning, provenance, an SBOM (software bill of materials), CSP/SRI, external integrity monitoring that survives conditional delivery.
  • Keep protocol keys out of single points of failure: multisig or HSM (hardware security module), plus on-chain caps, rate limits, timelocks on large or sensitive operations, and circuit breakers - so that even a fully compromised key can only move a bounded amount before monitoring or a human can intervene.
  • Assume the frontend and RPC can lie: wallet-level simulation, multi-RPC cross-checks, hardware-wallet address verification.
  • Make incident response routine: key rotation, out-of-band verification (through a separate, trusted channel) of any payout or address change, brand-protection monitoring - the layers that failed hardest (the Squarespace domain-migration wave among them) failed on process, not cryptography.
Conclusion
Five years of incidents point to one uncomfortable conclusion: in DeFi, the contract is usually the safest part of the system. The loss came in through DNS, a dependency, a cloud bucket, a signer's screen, or a hijacked account. The question a protocol should be able to answer is not "is the contract safe?" but "can I still be trusted to serve the right code, hold the right keys, and show the user the truth after one of my accounts is compromised?" Answering yes is cheaper than any single incident in the record - and almost nobody is spending it there yet.

This is the layer we review at MixBytes - the whole perimeter, not just the contract. If that's the gap you want closed, we're ready to help.
  • Who is MixBytes?
    MixBytes is a team of expert blockchain auditors and security researchers specializing in providing comprehensive smart contract audits and technical advisory services for EVM-compatible and Substrate-based projects. Join us on X to stay up-to-date with the latest industry trends and insights.
  • Disclaimer
    The information contained in this Website is for educational and informational purposes only and shall not be understood or construed as financial or investment advice.
Other posts