# Oracle spot-price fallback manipulation

Pricing helpers that silently swap to pool spot or stale values when a feed or capacity check fails

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

## How it works
A price helper is supposed to return a trustworthy value, but it contains a branch: if the primary feed is unavailable, or an amount does not fit a capacity limit, it substitutes a secondary value — a pool spot price, a wrapped-asset feed, or a mis-weighted average. The caller assumes the returned number is the real price. The assumption that breaks is that the fallback is equivalent to the primary; in practice the fallback is easier to move, tracks the wrong asset, or is computed from the wrong inputs, so the price silently drifts from reality.

## Where it shows up
- Pricing functions with an `if (canDeposit) ... else poolPrice` shape, where the branch condition depends on an amount the caller controls or passes wrongly.
- Callers passing a contract-wide balance instead of the user's actual amount into a capacity check [E1](https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md).
- Wrapped/pegged assets priced off the underlying's feed (WBTC via BTC/USD) with no wrapper-specific feed [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md).
- Multi-value tuple returns destructured positionally, where same-typed values can be silently swapped [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md).
- Any aggregate oracle that combines spot, fast, slow or median values with fixed weights.

## How to review
For each price helper, identify every branch and ask what value each branch returns and who controls the branch condition. The invariant: the price used for minting, liquidation or collateral must not depend on an amount, balance or state the user can influence, and must track the exact asset being priced. Check that capacity checks receive the user's deposit, not the contract balance [E1](https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md). Confirm the feed matches the wrapper, not just the underlying [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md). For every destructuring of a multi-value return, compare position-by-position against the declared return order and confirm the weights land on the intended variables [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md).

## How finders spotted it
- Reading `stake()`'s loop and noticing `ethPerDerivative` was passed the whole derivative balance, not the deposit, flipping the capacity branch [E1](https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md).
- Reading the feed contract and tests, then cross-checking the feed list to confirm only BTC/USD was wired in [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md).
- Comparing 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
- Capacity-check fallback to inflated pool spot price [E1](https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md).
- Wrong-asset feed shortcut dropping depeg risk [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md).
- Tuple misassignment inverting EMA weights and anchoring to stale price [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md).

## Impact and severity
E1 caused depositors to receive fewer minted shares [E1](https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md). E2 lowered the number of oracles an attacker must move from two to one, making a single flash-loan swap feasible during a depeg [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md). E3 anchored liquidation price to a stale average, letting insolvent accounts dodge liquidation [E3](https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md). Impact rises when the fallback is cheap to move (flash-loanable spot) or when it gates liquidation.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-02.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-30.md
- E3: https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-03.md
