June 10, 2025
|
Exploit Postmortem

How Dexodus Got Rekt by Reused Signatures and How Olympix Would've Prevented It

On May 26, Dexodus Finance was exploited for $300,000 by an attacker who didn’t need to break cryptography or manipulate an oracle. They simply reused a valid Chainlink report. The core failure wasn’t the data source; it was the absence of replay protection in the protocol’s signature verification logic.

Dexodus accepted any valid Chainlink-signed price report, regardless of when it was signed or how many times it had been submitted. That flaw let the attacker supply an old report showing ETH at $1816, open a 100x leveraged long at that artificially low price, then immediately close the position using a fresh price of $2520 , all in a single transaction. The pool was drained, and the protocol never checked if the signature had already been used.This wasn’t a novel attack. It was a preventable bug in how the _verifySignatures function processed oracle data. No nonce tracking, no timestamp validation, no hash deduplication. Just cryptographic signature verification with no state awareness.

Olympix would have flagged this instantly.

Our static analysis engine includes a Signature Replay Detector built specifically for scenarios like this, where off-chain signed data is trusted without enforcing single-use constraints. It scans for signature validation flows that lack replay defense, identifies the vulnerable function, and delivers precise, actionable guidance before code ever hits an audit.

Dexodus didn’t get exploited because it used Chainlink. It got exploited because it reused Chainlink.

What Happened

The attacker started with a $10,500 flash loan from the Balancer vault. With this temporary liquidity, they targeted Dexodus’ performUpkeep() function, which processes Chainlink price reports to update positions in the perpetuals market.

Instead of submitting fresh oracle data, they passed a valid but stale Chainlink-signed report. This report, though over a month old, still passed Dexodus’ signature verification because it was cryptographically intact and the contract lacked any logic to check the report’s timestamp or uniqueness.

The report pegged ETH at $1816. Using it, the attacker opened a 100x leveraged long position with $10K collateral, ballooning the notional exposure to $1 million. Immediately after, they submitted a second call to performUpkeep() with a fresh Chainlink price report showing the actual market value of $2520. This closed the long at a massive profit, draining approximately $300,000 from Dexodus’ liquidity pool.

The entire exploit was executed atomically. No multi-tx coordination, no race conditions, just a single transaction with two replayed inputs: one outdated, one current. The attack vector existed solely because the protocol didn’t track or bind signature usage in time or state.

Post-exploit, the attacker repaid the flash loan, bridged the funds to Ethereum via Stargate, and distributed the stolen ETH across multiple wallets. Some funds were later recovered to a Dexodus team-controlled multisig, possibly as part of a white-hat negotiation. But the vulnerability was real, and the damage was done.

The Root Cause

The failure point wasn’t Chainlink, it was the protocol’s implementation of signature validation. Dexodus used Chainlink Data Streams to fetch ETH price reports and relied on a function called _verifySignatures to authenticate them. This function checked that the report was properly signed by authorized oracles, but it did nothing to confirm whether that signature was recent, unique, or already used.

This is a textbook replay vulnerability.

Chainlink reports are cryptographically valid for up to 30 days. In low-frequency applications like lending, that window might be acceptable. But in high-frequency markets like perpetuals, stale data is an attack vector. Dexodus didn’t enforce any of the freshness guarantees that Chainlink explicitly defers to consumers at the application level.

There was no timestamp comparison between the report and the current block. No nonce or epoch tracking to prevent reuse. No mapping of previously used report hashes. As a result, any attacker with access to an old Chainlink report could replay it at will, and that’s exactly what happened.

The protocol even emitted a ReportVerified event, reinforcing the illusion that the stale report was legitimate. In reality, it was just valid, not fresh, not unique, and not safe to act on.

This was not a failure of cryptography. It was a failure of engineering rigor around cryptographic data.

Where Olympix Would’ve Caught It

Olympix’s Signature Replay Detector is specifically designed to identify the kind of vulnerability exploited in this attack. Its purpose is to flag functions that use off-chain signatures for authorization but fail to ensure those signatures are single-use. That’s exactly what went wrong in Dexodus.

Had Dexodus run Olympix during development, the Signature Replay Detector would have analyzed the _verifySignatures function and issued a high-severity alert. While the function verified that the signature matched the message and signer, it lacked any replay protection — no nonce, no epoch check, no mapping of used report hashes.

Olympix would’ve flagged this with precision. The detector targets signature verification patterns and verifies whether the contract is enforcing uniqueness or time-bounded usage. Seeing none, it would have directly pointed to _verifySignatures as the vulnerable entry point and explained that the signature could be reused without restriction.

This isn’t a vague warning. Olympix provides specific remediation guidance — suggesting nonce tracking, timestamp checks, or hash invalidation logic — all aimed at neutralizing replay-based vectors before they hit mainnet.

Had this detection run before deployment, the exploit path would have been eliminated. The reused Chainlink report wouldn’t have been accepted, the 100x leveraged trade wouldn’t have been executed, and Dexodus wouldn’t have been drained.

Olympix doesn’t just detect bugs. It identifies the exact decision point where security assumptions break and makes sure your team sees it before an attacker does.

Why This Pattern Keeps Repeating

This wasn’t a one-off mistake. It’s a recurring failure mode across DeFi protocols treat signature verification as sufficient security, without enforcing context or usage constraints.

The root issue is a blind spot in most static analysis tools and audits. They verify cryptographic correctness — is the signature valid, does it match the message — but they often skip over operational integrity. Was this signature already used? Was it recent enough to reflect real market conditions? Is its use atomic and state-bounded?

In signature-based flows — whether for oracle data, governance voting, or meta-transactions — lack of replay protection is a latent vulnerability. Developers assume validity means safety. It doesn’t. Without:

  • Nonces (to ensure uniqueness),
  • Timestamps (to enforce freshness),
  • State-bound checks (to tie data to a current market or contract condition),

You’re shipping time bombs.

Audits miss these when scope is narrow or tooling lacks intent awareness. Attackers don’t. They hoard old signatures, wait for bugs like this, and strike when liquidity’s high and attention is low.

This isn’t an oracle problem. It’s a protocol problem.

Builder Takeaways

If your protocol uses signed data, you’re on the hook for enforcing how and when it’s used. Chainlink doesn’t validate freshness. Auditors won’t catch intent gaps unless you flag them. Security tooling must understand flow, not just syntax.

Here’s how to avoid what happened to Dexodus:

  1. Treat all signatures as replayable by default. A signature is just cryptographic proof that someone signed something, not that it’s fresh or unique. Always assume an attacker can replay any signature you accept.
  2. Enforce data freshness. Every signed message should include a timestamp. Your contract must reject anything outside a narrow window — 10 to 30 seconds for high-frequency protocols. Use block.timestamp comparisons, not hope.
  3. Track usage of signed messages. Use a mapping of used hashes or nonces. Once a signature is used, it must not be usable again. This turns stateless signatures into stateful authorization.
  4. Bind data to state. If the report is for a specific round, epoch, or market condition, validate that explicitly. Don’t just check the signature — check the context it’s meant for.
  5. Integrate static analysis that catches intent-level bugs. Tools like Olympix catch these flows before audit. Our Signature Replay Detector doesn’t care that the signature is valid; it cares whether your protocol is letting attackers use it twice.

Uncover vulnerabilities early with Olympix’ free static analyzer. Trusted by over 30% of Solidity developers. Easy to use. Proven. Ready for your code. Get started for FREE!

Closing: Don’t Let Replays Drain Your Pool

Dexodus didn’t fail because they used Chainlink. They failed because they treated a signature as a guarantee, not a risk surface.

The attacker didn’t forge, front-run, or exploit some obscure VM edge case. They submitted an old, valid message that the protocol accepted without question. That’s not a novel exploit, that’s a missing require().

Olympix would’ve caught this, statically, before audit, before deployment. The Signature Replay Detector exists for this exact class of bug. It looks past the signature logic and asks the right question: what’s stopping someone from using this input twice?

If your protocol consumes external signatures and you’re not tracking usage, enforcing freshness, or validating context, you’re shipping Dexodus’ bug with a different label.

Build secure. Build defensively. Build with Olympix.

What’s a Rich Text element?

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

  1. Follow-up: Conduct a follow-up review to ensure that the remediation steps were effective and that the smart contract is now secure.
  2. Follow-up: Conduct a follow-up review to ensure that the remediation steps were effective and that the smart contract is now secure.

In Brief

  • Remitano suffered a $2.7M loss due to a private key compromise.
  • GAMBL’s recommendation system was exploited.
  • DAppSocial lost $530K due to a logic vulnerability.
  • Rocketswap’s private keys were inadvertently deployed on the server.

Hacks

Hacks Analysis

Huobi  |  Amount Lost: $8M

On September 24th, the Huobi Global exploit on the Ethereum Mainnet resulted in a $8 million loss due to the compromise of private keys. The attacker executed the attack in a single transaction by sending 4,999 ETH to a malicious contract. The attacker then created a second malicious contract and transferred 1,001 ETH to this new contract. Huobi has since confirmed that they have identified the attacker and has extended an offer of a 5% white hat bounty reward if the funds are returned to the exchange.

Exploit Contract: 0x2abc22eb9a09ebbe7b41737ccde147f586efeb6a

More from Olympix:

No items found.

Ready to Shift Security Assurance In-House? Talk to Our Security Experts Today.