Smart contracts are blind by default
A contract on Ethereum has no idea what ETH costs in dollars, whether a flight landed, or how cold it is in Chicago. It only knows what lives on its own chain: balances, contract state, block numbers. Everything else has to be delivered to it. That delivery job is what an oracle does, taking off-chain data and putting it on-chain in a format a contract can actually read.
In DeFi that data is load-bearing. A lending protocol needs the price of your collateral to decide if the loan is underwater and should be liquidated. A concentrated-liquidity DEX needs a reference price to work at all. A synthetic-asset protocol needs feeds to hold its peg. Get any of those prices wrong for even a few seconds and the damage rolls straight through every protocol downstream.
Three ways to source a price
Chainlink is the one most people picture. It pulls price data from a bunch of independent node operators, each of them reading from centralized exchanges, DEXes, and OTC desks, and the on-chain aggregator takes the median. The point is that no single node and no single source can move the answer on its own. Manipulating the median of 21 independent submissions is a lot more work than corrupting one data point.
Uniswap v3's TWAP oracle goes the opposite direction. Instead of trusting outside providers it reads its own trading activity, recording the cumulative price each block so you can average across any window by comparing two observations. Fully on-chain, fully permissionless, which is nice. The catch is that anyone willing to spend enough to distort trading in that pool can distort the oracle too.
Pyth, which grew up on Solana, does a third thing. It takes prices straight from first-party sources, so the trading firms, exchanges, and market makers who are generating the prices in the first place. The idea is that people actively trading have the freshest numbers. Pyth also updates way faster than Chainlink, sometimes several times a second, which matters if your application is latency-sensitive.
Why they get attacked
Oracle manipulation is still one of the most common and most expensive attack patterns in DeFi, and the shape of it is almost always the same. An attacker borrows a big pile of capital through a flash loan, uses it to shove the price of an asset around on one specific venue, then interacts with a protocol that happens to read its price from that venue. The protocol sees the distorted number and does something it shouldn't: lets them borrow too much, liquidates a position that was fine, or mints synthetics at the wrong ratio.
Mango Markets in October 2022 is the textbook version. The attacker took a large MNGO perpetuals position, then pumped MNGO spot on thin-liquidity venues that Mango's oracle happened to trust. The protocol's view of their collateral suddenly spiked, they borrowed about $110 million against that inflated collateral, and walked. The protocol was drained.
Flash loan attacks squeeze that whole sequence into a single transaction. Because the borrow and the repay land in the same block, the attacker never has to actually hold the money. Their cost is the flash loan fee, usually around 0.09%, plus gas. That's often nothing next to what they pull out.
The quieter failure: staleness
Not every oracle failure is an attack. Sometimes the feed just stops updating. Chainlink feeds run on a heartbeat, a maximum time between updates, and if the price hasn't moved past the deviation threshold the feed might sit still for up to an hour. In a violent tape that means a protocol can be pricing off a number that's minutes or tens of minutes stale.
It gets worse on L2s and alt-L1s because the economics of updating are different. Every update costs the node operator gas. On mainnet that gas is expensive, so update frequency is tuned to balance freshness against cost. On a cheaper chain updates might come more often, or the operator might not treat that chain as a priority, and you get longer gaps either way.
March 2023 showed exactly this. When USDC briefly lost its peg, several protocols on Arbitrum kept processing transactions on stale Chainlink prices. The feeds were technically inside their heartbeat window, but that window was set for normal conditions, not for a stablecoin coming off its peg. Anything without an extra sanity check, like a circuit breaker for large deviations, just ran with the old number.
What actually holds up
The protocols that survive oracle risk tend to stack a few defenses rather than trust one feed.
- Read more than one source and require them to agree. If Chainlink says ETH is $3,500 and the Uniswap TWAP says $3,200, something is off, and the right move is to pause, not pick a number.
- Wire in circuit breakers. If the price jumps past some threshold, say 15%, inside a short window, freeze liquidations and new borrows so a human can decide whether the move is real or someone poking the oracle.
- Cap exposure. Even with perfect data, anything that lets users borrow the absolute max against their collateral is brittle. Higher collateral ratios, limits on how fast big positions can open, and caps on per-asset exposure all shrink the blast radius when a feed goes wrong.
If you're the one putting money in, the useful habit is to look at which oracles a protocol uses and how it treats the edge cases before you deposit anything meaningful. Read the docs on oracle config, update frequency, and failure modes. A team that's open about that setup is usually safer to trust than one that files oracle infrastructure under implementation detail.