Rujira FIN Exploit: CCL Skew Math Costs $200K | PandaSecurity
Web3 Security

Rujira FIN Exploit: CCL Skew Math Costs $200K

PandaSecurity Team •
#Web3 Security#DeFi Exploit#THORChain#Smart Contract Audit
Diagram of the Rujira FIN incident: a price spike in the BTC/USDC order book pushes skewed concentrated liquidity ranges out of balance

On the evening of Tuesday, 10 November 2026, someone found a way to make money from the liquidity providers on Rujira Trade, the order book that runs as a CosmWasm application on THORChain. Rujira says an attacker “exploited an issue with the CCL skew calculations”, which let them unbalance existing BTC/USDC Custom Concentrated Liquidity (CCL) positions. The estimated loss is about $200,000: roughly $175,000 from positions run by Liquidy Finance and roughly $25,000 from other users.

Rujira has said all losses will be reimbursed. THORChain node operators halted the CosmWasm app layer, and the team is preparing an upgraded FIN contract that removes the skew parameter entirely. This is the second FIN incident in about six weeks, which makes it worth a closer look at what a “skew” knob is and why pricing code inside a market maker is such a sensitive place for bugs.

What Happened

Rujira’s first update, posted on X on 11 November, describes the sequence in plain terms. Suspicious activity on Rujira Trade caused “a sharp price spike in the BTC/USDC market”, followed by “a surge in trading activity across the orderbook”. The team’s investigation tied this to the skew calculations used by CCL ranges.

DefiLlama’s hacks database lists the incident on 11 November with the same $200,000 figure, classifies it as a protocol logic issue and labels the technique a swap logic flaw. No attacker address or transaction hash has been published by Rujira or by the trackers we checked, so we do not name any here.

Timeline

Background: How CCL Ranges Work

Rujira Trade is an on-chain order book. CCL lets a user turn a pile of base and quote assets into an automated market-making strategy that lives inside the same FIN contract as ordinary limit orders. According to Rujira’s integration docs, each range is defined by a handful of parameters:

With skew = 0 liquidity is spread evenly. A non-zero value moves more of the position toward the centre of the band or toward its edges. Rujira’s strategy docs give the intent: for a stable pair you might pack liquidity near parity, and for a volatile pair like BTC/USDC you might overweight the edges so you sell more BTC near the top of the range and buy more near the bottom.

That is a useful feature, but notice what it implies. The contract is no longer quoting from a simple formula. Every time the price moves, the range has to recompute how much it offers at each price level, and the quotes it publishes are what takers trade against.

The Root Cause: Liquidity Shape Math That Could Be Gamed

Rujira has not published a full post-mortem, so we will stick to what it has said: the attacker exploited the skew calculations and used them to imbalance existing BTC/USDC ranges. The fix is to remove the skew parameter rather than patch it.

That combination tells us a few things.

  1. The flaw sat in pricing, not in access control. Nobody stole a key or bypassed an owner check. The attacker traded against positions that were quoting prices the contract computed.
  2. The attack needed market movement. The price spike and surge of trades fit a pattern where the attacker pushes the market, causes ranges to reprice using the faulty skew curve, and then trades back against quotes that are worse for the LP than a correct curve would allow.
  3. The losers were the liquidity providers. Most of the loss came from one market maker’s ranges, the rest from ordinary users. The protocol’s own balance sheet was not the target; the LPs’ inventory was.

An earlier warning about the same model

FailSafe, which Rujira names as its audit partner, has published an audit report for FIN v2.1.1 on its website. One medium-severity finding in that report, marked resolved, is titled “Linear SCL skew misprices positive-skew ranges and enables systematic LP extraction”. It describes a linear weight function that was asymmetric around the range midpoint, so positive skew pushed liquidity in opposite directions on the ask and bid sides, and warns that “sophisticated takers can detect this systematic misplacement and route flow” through the misweighted side.

We cannot confirm that the November exploit used that exact issue, and Rujira has not said so. But the finding shows the category of risk clearly: when a liquidity shape is configurable, a small error in the curve becomes a price that a taker can repeatedly hit.

A simplified illustration

The snippet below is simplified illustrative Rust, not Rujira’s code. It shows the property a range should keep after any fill: the value of what it holds, measured at a fair reference price, should not fall by more than the spread it was paid.

// Simplified illustration, not Rujira's code.
fn check_fill(before: &Range, after: &Range, ref_price: Decimal) -> StdResult<()> {
    let value_before = before.base * ref_price + before.quote;
    let value_after  = after.base * ref_price + after.quote;

    // A correct range sells above and buys below the reference price,
    // so a fill should never leave it worse off than this tolerance.
    let tolerance = value_before * Decimal::permille(1);
    if value_after + tolerance < value_before {
        return Err(StdError::generic_err("range lost value on fill"));
    }
    Ok(())
}

A real implementation needs a robust reference price that the attacker cannot move in the same transaction, which is exactly the hard part. The point is that a curve which can be pushed into selling low and buying high should fail a test like this long before it reaches mainnet.

Why This Is Hard to Get Right

Concentrated liquidity math has repeatedly hurt protocols because three things interact:

We saw a related pattern in the ACryptoS depositMulti vault exploit, where valuing a two-token position with only one token’s numbers let attackers mint cheap shares, and in the Premia v3 empty option pool exploit, where edge-case pool states broke pricing assumptions.

Lessons for Builders

Fuzz the pricing curve, not just the entry points. Generate random ranges across the full parameter space, apply random sequences of fills and price moves, and assert that the LP never ends a round trip with less value than it started with, apart from the spread it earned.

Treat every resolved audit finding as a regression test. If an auditor shows a curve can be gamed, the fix should come with a property test that would catch any return of the same shape of bug, including in later versions of the math.

Ship advanced knobs behind limits. Rujira’s own docs told integrators to keep skew at zero. A new pricing feature can launch with caps on position size or on the allowed skew range until it has real trading history.

Monitor for value leaving LPs, not just the contract. Here the protocol’s reserves were not drained directly; liquidity providers were. Alerts on unusual LP losses per block, or on sudden one-sided fills, can catch this kind of attack in minutes. Rujira’s plan for continuous monitoring and a withdrawal-slowing system called Gleipnir is aimed at exactly that gap, much like the rate limit that capped losses in the Arcus Perps subaccount exploit.

Have a clean pause. The ability to halt the CosmWasm layer without stopping THORChain’s base layer kept the incident to one market and gave the team time to plan a fix.

What Users Should Know

Rujira says all losses will be reimbursed and that the upgraded FIN contract restores affected CCL positions. The app layer is paused, so trading, lending and range management are unavailable until node operators resume it, which Rujira currently targets for next week. Follow only official Rujira channels for updates and ignore unsolicited “refund” or “claim” links. This article is technical commentary, not financial advice.

Sources

Closing Thoughts

The Rujira loss was modest next to this month’s larger incidents, but the lesson travels well. When a contract quotes prices for its users, any error in the quoting math is a standing offer to whoever finds it first, and every extra parameter widens the search space. Removing skew is the safest short-term fix; bringing it back will need invariant tests that prove LPs cannot be traded into a loss. If you are building an AMM, order book or vault with custom liquidity curves, talk to our team or check our audit pricing to have your pricing invariants reviewed before the market tests them.

Related articles

← Back to Blog
Need an audit? Contact us