The Next Privileged Change Is Where Proactive Web3 Security Starts
Web3 teams say they want proactive security. The real test is simpler: can they prove the next privileged change will not widen authority or falsify state before capital touches it?
Establish the problem with technical depth
Too many teams still call their security program "proactive" because they have an audit archive, a Slack war room, and some monitoring after deployment. That is not proactive. That is reactive with better branding.
The real danger zone is the next privileged change: the upgrade that changes execution, the signer-approved transaction that changes ownership, the new facet that inherits old approvals, the new market listing that widens what the system believes about collateral or rewards. That is where protocols usually get into trouble, because that is where live authority changes faster than most teams review it.
Bybit's March 3, 2025 incident timeline is the bluntest example. Bybit says a single Ethereum cold wallet was compromised on February 21, 2025, and that the loss was $1.46 billion: 401,347 ETH, 90,375 stETH, 15,000 cmETH, and 8,000 mETH. The same timeline says attackers exploited the Safe multisig UI through a phishing attack that changed the wallet's smart contract logic. That was not a failure of a small helper function buried in Solidity. It was a failure at the exact moment a privileged production change was being authorized.
Radiant Capital's October 18, 2024 post-mortem shows the same shape in a DeFi protocol. Radiant says the October 16 breach cost about $50 million after attackers compromised devices belonging to three trusted contributors. Its more uncomfortable detail is that Safe showed legitimate transaction data while malicious transactions were signed in the background, and Tenderly simulations looked normal on the affected machines. In other words, the team had procedures, simulations, and multiple reviewers. The problem was that the verification path itself had become untrustworthy.
LI.FI's July 18, 2024 incident report is the contract-side version of the same lesson. LI.FI says that shortly after adding a new smart contract facet, attackers used a vulnerability in that facet to reach wallets that had granted infinite approvals. The result was about $11.6 million stolen from 153 wallets across Ethereum and Arbitrum. The issue was not merely "a bug in new code." The issue was that new code inherited old authority the moment it went live.
This matters to founders and investors because the expensive mistake is rarely "we had no security work at all." It is usually "we let the next meaningful change go live without proving what power it inherited." It matters even more to CTOs and Solidity engineers because the production attack surface is not just the repository. It is the repository plus signers, upgrades, approvals, modules, bridges, and every role that can still rewrite protocol truth.
The mechanism, the mistake, the misunderstanding
The mechanism is not mysterious. A protocol prepares a legitimate-looking change. That change widens authority, state reach, or execution flexibility. The team reviews part of the path, but not all of it. The attacker only needs one place where review and live authority no longer match.
Sometimes that privileged change looks explicit:
function upgradeToAndCall(address newImplementation, bytes calldata data)
external
onlyRole(UPGRADER_ROLE)
{
_upgradeToAndCallUUPS(newImplementation, data);
}
There is nothing automatically wrong with code like this. The real question is everything around it. Who has UPGRADER_ROLE? How is that role granted and revoked? What exact implementation hash was reviewed? What initialization calldata is being executed with it? Which storage assumptions change after the upgrade? What independent path verifies the signed transaction matches the reviewed intent?
OpenZeppelin's access control docs reduce the core issue to plain language: who is allowed to do this thing? That is the right framing because "this thing" is not limited to minting or pausing. It includes upgrading logic, adding modules, changing signers, changing routers, widening call targets, or making a new contract path live against existing user approvals.
The common mistake is thinking proactive security means "audit earlier" or "monitor harder." Both help. Neither is enough. An audit is a point-in-time statement about a scope. Monitoring often tells you what already happened. Proactive security starts earlier than both. It starts when the team treats the next privileged change as the thing that needs proof before it reaches production.
The deeper misunderstanding is confusing a threshold with independent verification. Bybit and Radiant are the warning. A multisig does not buy real independence if every signer is reading the same manipulated interface, trusting the same compromised preparation path, or validating the same misleading transaction rendering. Safe's own transaction-check guide tells users to verify transaction data across multiple tools and devices before signing, including to, value, raw data, operation, and nonce. That is not ceremonial process. It is an admission that the signing path itself is a security boundary.
LI.FI exposes a second misunderstanding: teams separate user approvals from release risk. Attackers do not. Old approvals are stored authority. New code is fresh reachability. The dangerous moment is where they meet.
What good looks like
Good looks like treating every meaningful privileged change as a production security event before it becomes a production security incident.
Start by classifying diffs by trust impact, not by file count. A small change that widens router targets, installs a module, changes a signer workflow, modifies collateral assumptions, or adds a new upgrade path deserves more scrutiny than a large refactor in a harmless view layer. Teams should be able to answer one plain question before merge: if this exact change is wrong in the worst plausible way, what money or authority does it newly reach on day one?
Next, treat transaction preparation as a separate job from transaction approval. Safe's proposer model exists for a reason: proposers can prepare transactions without being able to sign them, which helps separate assembly from approval. That separation does not solve everything, but it is much healthier than asking signers to trust ad hoc transaction construction from the same people and machines that will later approve it.
Then treat the signed transaction as a release artifact, not as a clerical step. Safe's guidance to verify to, value, data, operation, and nonce across tools and devices should be normal for high-impact actions. So should raw calldata review, destination verification, and a second trusted path for confirming what will execute. "Trusted path" here means a separate verification route, not one more browser tab showing the same lie.
Good also means encoding system truths as executable checks around the changed surface. Foundry's invariant testing guide is useful because it focuses on properties that should always remain true regardless of call sequence. Its fork testing guide matters for the same reason: it lets teams test against real chain state before a production transaction exists. If a change touches liquidation math, approvals, signer modules, or upgrade flows, the relevant invariants should be exercised on realistic state before anyone asks users to trust the release.
Good teams also kill dormant power aggressively. LI.FI explicitly noted that the exploit was limited to infinite approvals and did not affect finite approvals, which were the default in its API, SDK, and widget. That is a concrete reminder that stale authority compounds release risk. Blanket approvals, old allowlists, forgotten modules, and lingering emergency roles are all future attack surface.
Finally, monitor meaning, not just uptime. Watch for implementation changes, role grants, ownership transfers, unexpected delegatecalls, approval spikes, unusual withdrawals, and module installs. Incident response still matters. But if the first useful alarm fires only after balances drop, the system is built for autopsy.
ChainShield's angle
ChainShield's view is that proactive Web3 security starts where most teams still get vague: the live change surface.
We care less about whether a protocol can repeat that it was audited and more about whether it can prove what changed yesterday, what exact transaction is about to be signed today, what authority that change inherits, and which invariant demonstrates the system still behaves as claimed. That is a stricter standard than most teams want. It is also much cheaper than learning onchain.
The market does not mainly punish protocols for lacking vocabulary. It punishes them for letting a privileged change become real before anyone proved the surrounding trust path was still intact. That is why the next privileged change is where proactive security starts. If your process cannot defend that moment, your program is still reactive, no matter how polished the postmortem will be.
ChainShield Discovery Runs are designed to identify high-risk issues quickly, validate what matters, and give engineering teams a faster path to remediation.
Request Security Quote