Hook
Block 19,874,312. 14:03 UTC. A single transaction triggers a cascade of four liquidations on Morpho Blue. Total value extracted: 12.4 million USDC. The attacker didn't exploit a smart contract bug. They manipulated the price feed of a relatively obscure LST — pufETH — on a secondary oracle.
I've spent the last six hours crawling through the transaction logs, wallet clusters, and the exact block timestamps. The story is not about code failure. It's about latency asymmetry. A gap the attacker saw and used before anyone else could react.
Gas spike detected. Run. But not fast enough.
Context
Morpho Blue is a permissionless lending protocol built on a single-pool architecture. Unlike Aave or Compound, it doesn't use a pooled liquidity model for each asset. Instead, it allows anyone to create isolated lending markets with custom oracles and collateral factors. This flexibility is its strongest feature — and its most dangerous attack surface.
The protocol relies on Chainlink price feeds for most assets. But for newer, less liquid LSTs like pufETH, it also integrates a fallback oracle from RedStone. The attacker targeted this dual-oracle setup. They didn't break the smart contract. They broke the timing between two price updates.
Core
Here's the technical sequence.
At 14:02:48, a large swap on Uniswap V3 pushed pufETH/ETH from 0.998 to 1.023 — a 2.5% deviation. Chainlink's price feed for pufETH/USD has a 1% deviation threshold and a minimum update delay of 60 seconds. The deviation triggered an update, but the on-chain transaction confirming that update didn't land until block 19,874,310 at 14:03:11.
Meanwhile, RedStone's oracle uses a different model — it pushes updates every 30 seconds regardless of deviation, but relies on a validator set that signs the data. The RedStone update for the same period showed pufETH at 1.018, a 2% deviation from the previous round.
Uniswap V2 moved the needle. Here's how.
The attacker deposited 5,000 ETH as collateral into a newly created Morpho Blue market for pufETH. They then borrowed 9.8 million USDC against it — using the inflated RedStone price as the reference. At the moment of borrowing, the Chainlink feed still showed the old price. The Morpho Blue contract checks both oracles and takes the higher of the two for liquidation calculations. The attacker exploited this by borrowing just before the Chainlink update confirmed the true lower price.
When the Chainlink update finally landed at 14:03:11, the collateral value dropped below the borrow threshold. But the liquidator bots couldn't act immediately because the next block was mined 3 seconds later — and the attacker had already submitted a second transaction to drain the remaining liquidity from the market.
The entire attack took 45 seconds from deposit to full extraction. The funds moved through a series of cross-chain bridges — first to Arbitrum, then to Base, then to a privacy wallet. The trail ends at a Tornado Cash deposit on Ethereum mainnet.
ERC-20 rush vibes. Proceed with caution.
Contrarian
Most initial reports blame the oracle design. They call it a "price manipulation" or a "flash loan attack." It wasn't either. The attacker didn't manipulate prices — they exploited a temporal inconsistency between two honest oracles. Chainlink and RedStone both provided accurate data. The problem is that they were accurate at different times.
The real blind spot is the assumption that multi-oracle setups increase security. In practice, if the oracles are not synchronized to the same block timestamp, they create an arbitrage window. This is not a bug in the smart contract. It's a flaw in the protocol's risk model — specifically, the decision to use the maximum of two prices for collateral valuation.
Morpho Blue's documentation explicitly states: "Liquidation is triggered when the oracle price falls below the collateral factor." But it doesn't specify which oracle takes priority during a price divergence. The attacker read the code, found the max() function, and saw the window.
Based on my audit experience from the 2022 LUNA collapse, this is eerily similar to the UST depeg. The root cause was not a failure of the underlying algorithm but a failure of the arbitrage mechanism to close a latency gap. Here, the gap is measured in blocks, not minutes. But the result is the same: a temporary discrepancy that compounds into a full drain.
Takeaway
The next attack won't be on the oracle itself. It will be on the synchronization layer between two oracles. Protocols running multi-oracle setups need to ask: "What happens when these two feeds disagree for more than one block?"
If the answer is not a deterministic priority rule — with a clear fallback and a time lock — then the protocol is a ticking bomb. The attacker already knows the gap. The question is whether the developers will find it before the next block.