Anatomy of the $223 Million Cetus Hack: When a Single Line of Code Drains a Protocol
A deep dive into the May 2025 Cetus Protocol exploit, how an integer overflow bug in a shared library led to one of the year's largest DeFi hacks, and what it teaches us about smart contract security.
On the morning of May 22, 2025, something went catastrophically wrong on the Sui blockchain. Cetus Protocol, the largest decentralized exchange in the ecosystem, began hemorrhaging funds. Within fifteen minutes, an attacker had drained approximately $223 million from the platform's liquidity pools. It was the second-largest hack of the year, behind only the Bybit breach, and it stemmed from a vulnerability so subtle that multiple professional audits had failed to catch it.
The Cetus exploit offers a masterclass in how small oversights become massive disasters. Understanding what happened, and why it wasn't prevented, reveals uncomfortable truths about the state of smart contract security.
The Attack Unfolds
The attacker moved with surgical precision. They began by taking out a flash loan, borrowing a large amount of tokens that would need to be repaid within the same transaction. This is a common setup for DeFi exploits because it allows attackers to manipulate systems with capital they don't actually possess.
Next, they opened a liquidity position on Cetus with an unusually narrow price range: just 200 ticks wide in a pool that could span millions. This detail mattered because of how Cetus calculated the tokens required to mint liquidity. The narrower your range, the more precise the math needs to be.
Here's where the vulnerability came into play. When you add liquidity to a concentrated liquidity DEX like Cetus, the protocol calculates how many tokens you need to deposit based on the amount of liquidity you're requesting and the price range you've selected. The attacker requested an astronomical amount of liquidity, a number so large that it would overflow during the protocol's internal calculations.
Normally, overflow protection would catch this. The Move programming language, which Sui uses, automatically aborts transactions when additions or multiplications would overflow. But there's an exception: bit shift operations. Shifting bits left, equivalent to multiplying by powers of two, doesn't trigger Move's overflow protection. The language designers made this choice intentionally, following conventions from other programming languages, but it created a gap that the attacker exploited.
Cetus used a function called checked_shlw to verify that a value wouldn't overflow before performing a left shift. The function was supposed to reject values that were too large. But the check itself was flawed. It compared the input against a threshold that was slightly wrong, allowing certain large values to slip through. When these values were then shifted, the overflow truncated the result, producing a much smaller number than the true mathematical answer.
The practical effect was devastating. The attacker deposited a trivial amount of tokens, sometimes just a single unit, but the broken math told the protocol they had contributed millions in liquidity. Based on this false accounting, Cetus allowed them to withdraw real assets in proportion to their phantom stake. They repeated this across multiple pools, draining tens of millions in SUI, USDC, and other tokens before anyone could react.
Why the Audits Missed It
Cetus had been audited multiple times by reputable security firms. The auditors reviewed the code, analyzed the logic, and signed off on the protocol's security. Yet this bug survived every review.
Part of the explanation lies in where the vulnerability lived. The flawed function wasn't in Cetus's own contracts but in a shared library called integer-mate, a utility package for mathematical operations in Move. When auditors scope their work, they often focus on the protocol's custom logic rather than third-party dependencies. The assumption is that widely-used libraries have been vetted by others. Sometimes that assumption is wrong.
Another factor is the nature of Move itself. The language is often described as "safe by default" because it prevents many common vulnerability classes. Auditors may have reasoned that overflow bugs were impossible in Move, since the language aborts on most overflow conditions. But that reasoning overlooked the exception for bit shifts. Security is never a property of a language alone. It's a property of how carefully the code is written and reviewed.
The specific bug was also easy to miss visually. The checked_shlw function compared its input against a magic number, a 78-digit integer representing the maximum safe value before overflow. Verifying that this constant was correct would require manually computing the threshold, a tedious calculation that's easy to skip when you're reviewing thousands of lines of code under time pressure.
Finally, the vulnerability required a specific chain of conditions to exploit. The attacker needed to use a narrow tick range, request an enormous liquidity amount, and target the particular code path that used the flawed check. Testing for this scenario would require either extraordinary foresight or comprehensive fuzzing that explored extreme edge cases. Neither happened.
The Response and Recovery
Once the attack was detected, Cetus moved quickly. The protocol paused all smart contracts within an hour, freezing approximately $162 million in stolen assets before they could be moved off-chain. The remaining $60 million had already been bridged to Ethereum, beyond the protocol's reach.
The Sui validator community took an unusual step: they coordinated to ignore transactions from the attacker's known wallet addresses. This meant those transactions were never processed or included in blocks, effectively freezing the assets on-chain. It was a controversial decision that raised questions about decentralization, but it preserved the majority of the stolen funds.
Cetus offered the attacker a $6 million white-hat bounty to return the remaining funds and cooperate with the investigation. They published detailed post-mortems, held public Q&A sessions, and worked with blockchain analytics firms to trace the stolen assets. By late May, the protocol announced a compensation plan for affected users, funded by its treasury and a loan from the Sui Foundation.
Other protocols that used the same integer-mate library paused operations and rushed emergency upgrades. The bug wasn't unique to Cetus; it was a shared-library failure that could have affected any protocol with the same dependency. The incident became a wake-up call for the entire Sui ecosystem about the risks lurking in common infrastructure.
Lessons for Smart Contract Security
The Cetus hack reinforces several principles that should guide how we think about protocol security.
First, safe languages aren't enough. Move's overflow protection gives developers a false sense of security if they don't understand its limitations. Every language has edge cases and exceptions. Security requires understanding those exceptions and coding defensively around them. The Cetus bug would have been caught by an explicit assertion that the mathematical result matched expectations, a check that doesn't trust the language to handle everything automatically.
Second, dependencies are part of your attack surface. Modern protocols are built on layers of libraries, frameworks, and shared code. A vulnerability anywhere in that stack is a vulnerability in your protocol. Auditing only your own contracts while trusting everything else is like locking your front door while leaving the windows open. Comprehensive security requires understanding and monitoring your entire dependency graph.
Third, audits are necessary but insufficient. Multiple professional audits failed to catch this bug. That's not because the auditors were incompetent; it's because point-in-time audits have inherent limitations. They can only test the scenarios that auditors think to test. They can only review the code that exists at the moment of the audit. They can't catch vulnerabilities introduced by later updates or newly discovered attack techniques. Audits should be one layer of a defense-in-depth strategy, not the entire security program.
Fourth, extreme inputs reveal hidden assumptions. The Cetus attacker succeeded by using values far outside normal operating ranges. Most testing focuses on typical usage patterns, but attackers specifically look for edge cases where assumptions break down. Effective security testing must include adversarial fuzzing that explores the boundaries of what's mathematically possible, not just what's operationally expected.
Continuous Security as the Standard
The Cetus hack illustrates why smart contract security can't be a checkbox exercise. A single audit before launch, however thorough, cannot guarantee safety against evolving threats and newly discovered vulnerability classes. Protocols need continuous monitoring that catches issues in real-time, not months after deployment.
This is the approach Valkra was built around. Rather than relying solely on periodic manual reviews, Valkra provides automated analysis that runs continuously against your codebase. The platform scans for known vulnerability patterns including the exact type of integer overflow that hit Cetus. It traces dependencies to identify risks in shared libraries. It monitors for anomalous behavior that might indicate an attack in progress.
When the Cetus vulnerability came to light, it highlighted patterns that automated tools should flag: unchecked bit shift operations, magic number thresholds without derivation, and mathematical calculations that bypass language safety features. Valkra's analysis engine identifies these patterns and surfaces them for review before they become exploit headlines.
The platform also provides what we call a Security Health Score, a continuous assessment of your protocol's risk posture that updates as your code changes and as new vulnerability classes emerge. Rather than a single pass/fail from an audit months ago, you get an ongoing view of where you stand and what needs attention.
Moving Forward
The $223 million taken from Cetus represents more than financial loss. It represents broken trust, disrupted users, and months of recovery work for a team that thought they had done security right. The protocol had audits. It used a language designed for safety. It followed what seemed like best practices. And still, a single flawed function brought everything down.
The lesson isn't that security is hopeless. It's that security requires layers: careful coding, comprehensive testing, professional audits, and continuous monitoring. Skip any layer and you're leaving gaps that attackers will eventually find.
For teams building on any blockchain, the Cetus hack should prompt hard questions. Do you understand every cryptographic and mathematical operation in your code? Have you audited your dependencies as carefully as your own contracts? Are you testing with adversarial inputs that push the boundaries of what's possible? Do you have continuous monitoring that would catch an attack in progress?
If you're uncertain about any of these answers, that uncertainty is itself a risk. The Cetus team probably felt confident before May 22nd, too.