Zelcore
Z
Zelcore TeamMulti-Asset Crypto Wallet & Web3 Ecosystem

Oracles and the Price Problem: How DeFi Knows What Anything Is Worth

10 min read
Oracles and the Price Problem: How DeFi Knows What Anything Is Worth

A smart contract running on Ethereum cannot look up the price of ETH. It cannot call an API, scrape a website, or read a Bloomberg terminal. The Ethereum Virtual Machine is a sealed deterministic sandbox: every node in the network must arrive at the same state by re-executing the same instructions, so any source of non-determinism — a network call, a random number, a timestamp with sub-second resolution — would fracture consensus. The sandbox is the feature. It is also the problem.

This is the oracle problem, and it sits under almost every DeFi application you have ever used. A lending market needs to know when your collateral has fallen below the liquidation threshold. A perpetual futures exchange needs a mark price. A stablecoin needs to know what a dollar is worth in the reference asset it tracks. None of those numbers live on-chain natively. Something outside the sandbox has to reach in through a signed conduit and drop a number into a contract's storage, and every other contract downstream has to trust that number enough to move real money on its say-so.

Get the conduit wrong and the consequences are not abstract. In October 2022, an attacker drained roughly 114 million dollars from Mango Markets by manipulating the price of a single token for long enough to borrow against a position that should not have existed. The contracts worked exactly as written. The oracle worked exactly as designed. The combination was catastrophic.

Why on-chain code is blind by construction

Ethereum, and every EVM chain that inherits its execution model, is a replicated state machine. When you submit a transaction, thousands of nodes independently execute the same bytecode against the same prior state and must agree on the resulting state root. Any instruction whose output varies between nodes — a live HTTP fetch, a reading of the host machine's wall clock in milliseconds, a call to /dev/urandom — would produce different results on different nodes and break consensus.

So the EVM exposes none of those. It exposes block number, block timestamp (coarse, proposer-influenced), the calldata the user sent, the contract's own storage, and the storage of other contracts on the same chain. That is the entire information surface. If the price of ETH in USD is not already written into some contract's storage slot, the contract you are writing simply cannot know it.

This is why oracles exist. An oracle is any mechanism that takes a fact from outside the chain and writes it into a storage slot where on-chain code can read it. The mechanism varies wildly in sophistication and in what it is actually trusting, and that variation is where almost all the risk lives.

What an oracle actually is

Strip away the branding and an oracle is three things: a data source, a reporter, and an on-chain contract that stores the latest reported value. A reporter fetches the fact — say, the midpoint price of ETH/USD across a set of exchanges — signs a message attesting to it, and submits a transaction that updates the storage slot. Downstream contracts call a read function on that storage and receive the number.

Everything interesting about oracle design is a variation on three questions. Where does the data come from? Who is allowed to report it? What happens when reporters disagree or go silent?

The simplest design is a single trusted reporter: one address, controlled by a single team, pushes prices whenever it decides to. This is cheap, fast, and a single compromised key away from total failure. The next rung up is a multi-signature committee — several reporters sign, and the contract only accepts an update when a threshold agrees. Chainlink's price feeds work roughly this way at the aggregation layer: a decentralised set of node operators each fetch the price from multiple venues, sign their observation, and a contract on-chain takes the median of the signed submissions and writes it to storage if enough fresh reports have arrived. The median is load-bearing — a single malicious or broken reporter gets outvoted rather than believed.

A second family of push-style feeds — Pyth is the canonical example — uses first-party publishers (exchanges and major market makers) that sign prices off-chain roughly every 400 milliseconds and let any user pay to pull the freshest update on-chain the moment they need it. Consumer contracts must then enforce a maximum-staleness check and verify the reported confidence interval, or they inherit Pyth's freshness guarantees without any of its safety.

A third family avoids external reporters entirely by reading prices from on-chain sources. Uniswap's time-weighted average price (TWAP) feeds expose the geometric mean price of an asset over a trailing window, computed from the constant-product invariant of a pool. No off-chain signer is involved; the oracle is the AMM itself, observed over time. The tradeoff is that the price it reports is whatever someone was willing to trade at inside that specific pool, smoothed over a window you choose. Smooth it too little and flash-loan-funded attackers can push it wherever they want for one block. Smooth it too much and it lags real prices during genuine market moves, which is its own kind of wrong.

Mango Markets, step by step

Mango Markets ran on Solana rather than Ethereum, but the oracle problem is identical across chains — the sandbox constraint is about determinism, not about which VM enforces it. Mango was a margin trading venue: users deposited collateral, borrowed against it, and took leveraged positions. The protocol marked positions to an oracle price to decide borrow limits, liquidation thresholds, and — critically — how much a user's portfolio was worth if they wanted to borrow against it.

The attack went like this. The attacker deposited about 5 million USDC as collateral and used it to take a very large long position in a perpetual futures contract on MNGO, Mango's governance token, which traded thinly on a handful of venues. From a second account they took the equal and opposite short, so their net market exposure was near zero. Then, on those thin spot venues, they bought enough MNGO to pump its price from a few cents to roughly 91 cents — a greater-than-tenfold move — using only a few million dollars of buying pressure against shallow order books.

Mango's oracle reflected that pump. Mango's oracle was essentially doing the honest thing: reading the price from the venues where MNGO actually traded. Those venues said MNGO was now worth 91 cents. The oracle reported 91 cents. The lending contract, doing exactly what it was written to do, looked at the attacker's long position — now showing an enormous unrealised profit at mark-to-market — and concluded their account was worth several hundred million dollars. Against that inflated collateral, the attacker borrowed roughly 114 million dollars of real assets from Mango's lending pools and withdrew.

Nothing in the chain of reasoning was buggy. Each contract read its inputs and produced correct outputs given those inputs. The failure was architectural: the oracle pointed at a price that could be moved by a single participant with a few million dollars, and the lending logic trusted that price as if it reflected a genuine market consensus. This is the canonical shape of an oracle exploit, and versions of it have hit lending protocols, stablecoins, and perpetuals repeatedly since — including KiloEx in April 2025, where an under-guarded price-setting function let an attacker push ETH/USD from $100 to $10,000 in a single transaction for $3.12M of profit.

Risks, and the defences that shape modern oracles

Every production oracle today is scarred by a specific past exploit, and those scars are the design. If you are planning to deposit into any protocol that uses price feeds — which is almost all of them — these are the risks to understand before you participate, and what a serious protocol does about each.

Source manipulation. If your oracle's underlying venues have thin liquidity, the oracle can be pushed. Defences: aggregate across many venues, volume-weight the aggregation, and refuse to list markets whose underlying has too little depth to matter.

Flash-loan amplification. Uncollateralised flash loans let an attacker temporarily command enormous capital inside a single transaction. A spot-price oracle read at a single instant can be manipulated for the length of that transaction and read by a borrowing contract inside the same transaction. Defences: TWAP windows long enough that a single-block move cannot dominate the average, or off-chain oracle designs that do not observe in-block spot prices at all.

Stale data. A reporter network that goes silent leaves the last-reported price in storage, possibly hours or days old, while the real market moves elsewhere. Defences: heartbeat requirements that force an update every N minutes even when prices are flat, and on-chain staleness checks that refuse to act on a quote older than some threshold.

Reporter collusion or capture. A small multi-sig of reporters can be bribed, subpoenaed, or compromised. Defences: large decentralised reporter sets, economically staked nodes with slashing for provably wrong reports, and consumer contracts that require multiple independent oracle sources to agree before a sensitive action — such as liquidating a position — proceeds.

Oracle-contract trust. You trust not just the feed but the contract address you are reading from. A spoofed feed address pasted into a protocol's configuration is functionally the same as a compromised oracle. Defences: governance-gated feed address changes, timelocks, and the same attack-surface awareness you would apply to anything else you sign.

None of these defences are free. Longer TWAP windows mean slower liquidations during real crashes. Larger reporter sets cost more gas per update. Multi-source aggregation means one source going down can halt the whole feed. The job of a protocol designer is to pick the failure mode they can live with, because there is no oracle that cannot fail — only oracles that fail differently.

Key takeaways


Further Reading

Wallets, Gas, and Approvals: The Three Things Every DeFi User Must Understand

Wallets, Gas, and Approvals: The Three Things Every DeFi User Must Understand

Before you swap, lend, or farm anything, you need to understand the three primitives every DeFi interaction depends on: your wallet, gas, and token approvals.

7 min read
Impermanent Loss: Why Providing Liquidity Isn't Free Money

Impermanent Loss: Why Providing Liquidity Isn't Free Money

Impermanent loss is the hidden cost of being an AMM liquidity provider. Here's the math, a reference table, and a checklist to decide if the fees are worth it.

4 min read
The Multi-Chain Custody Problem — One Seed, Many Ledgers

The Multi-Chain Custody Problem — One Seed, Many Ledgers

Why a single BIP-32/44 seed unlocks accounts across Bitcoin, Ethereum, Solana, and 80+ other chains in Zelcore — and the practical implications for address reuse, chain-specific metadata, and protecting your one point of failure.

8 min read

Join Our Newsletter

Get a friendly update from us once a month. No spam, just the latest from Zelcore.

Join Our Newsletter