# Oracle feed selection and weighting errors

Aggregators that skip reverting feeds, liquidation paths using a different price source, and mis-ordered tuple destructuring in EMA/TWAP math.

_Area: DeFi oracles, liquidations and flash loans. Seen in 3 disclosed reports; latest 2026-03-09. Updated 2026-11-06._

## How it works
Oracle aggregation assumes every configured feed contributes to the final price. That assumption breaks in three ways: an aggregator that *skips* feeds which revert lets an attacker silence honest sources and leave only a manipulable one [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md); a liquidation path that reads a *different* price than core market accounting evaluates debt against a stale or wrong number [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md); and positional tuple unpacking that silently misassigns same-typed values inverts the intended weighting of fast/slow/spot EMAs [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md). In each case the code runs without error but the price it produces is not the price the designer intended.

## Where it shows up
- Aggregators with try/catch or skip-on-revert around feed calls, especially where submodules have attacker-triggerable reverts (reentrancy locks, deviation guards, vault-context checks) [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md)
- Median/average strategies with special cases like "first non-zero price when only two valid" [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md)
- Liquidation math calling `latest()` or a raw oracle read while the market uses a "latest valid" price [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md)
- Multi-value returns destructured positionally, where several elements share a type (all `uint`/`int`) [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md)
- Weighted EMA/TWAP blends mixing spot, fast, slow and eons components [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md)

## How to review
For each feed, ask: can an outside actor make this call revert? If yes, and the aggregator tolerates reverts, the feed is a switch, not a source. The invariant: the set of feeds contributing to a price must not be attacker-controllable, and a revert in any required feed must revert the whole computation [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md). For liquidations, the exact property is that the price used to decide liquidation equals the price used by core market accounting, from the same function and same freshness rule [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md). For tuple returns, check every destructuring site against the declared return order and confirm each variable's type and role match; do not trust names, verify positions [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md).

## How finders spotted it
- Read each price submodule and noted reentrancy/deviation guards that revert; combined with the aggregator's skip-on-revert and the two-valid-price rule, hypothesized selective silencing of honest feeds [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md)
- Protocol team self-review compared the price source in the liquidation path against the price the Market process uses, catching the divergence [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md)
- Code-reading compared the destructuring in `twapEMA` against the actual return tuple of `getEMAs()`, spotting the positional mismatch and weight inversion [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md)

## Variants seen
- Forced-revert feed removal from a median strategy [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md)
- Wrong/stale price source in liquidation calculation [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md)
- Tuple destructuring order error inverting EMA weights and dropping a component [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md)

## Impact and severity
E1 turned single-feed manipulation into a full median bypass, moving a price from ~6.3 to ~29.5 [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md). E2 silently mispriced liquidations against a stale price [E2](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md). E3 anchored liquidation TWAP to a slow EMA, letting insolvent accounts dodge liquidation [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md). Impact rises when the flaw is combined with reserve manipulation [E1](https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md) or when it blocks liquidations entirely, letting bad debt accumulate [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md).

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2023-11-olympus%3AM-4.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-7.md
- E3: https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md
