# Oracle update skipped on reserve change

Reserve or supply mutating paths that skip the oracle/checkpoint update they feed

_Area: DeFi oracles, liquidations and flash loans. Seen in 2 disclosed reports; latest 2024-08-06. Updated 2026-10-25._

## How it works
A price, interest rate, or utilization score is derived from a mutable global (pool reserves, total supply). The system assumes every path that changes that global also refreshes the derived value. When one path mutates the global without writing the update, the derived value is computed from stale inputs, or a later legitimate update overwrites the change before it is ever recorded. An attacker who can trigger the skipped path controls the derived value for the next reader.

## Where it shows up
- Functions that mint, burn, deposit, redeem, shift, sync, donate, or skim, changing reserves or supply.
- AMM swap paths that call an update hook while sibling entry points do not.
- Interest/utilization math reading total supply, with checkpoints written only on some paths.
- Oracle accumulators (Pumps, checkpoints) fed by reserve changes.
- Price feeders anchored to a single pool or updated infrequently.

## How to review
Enumerate every function that mutates the global the oracle depends on. For each, confirm it calls the update/checkpoint routine before any subsequent read or overwrite. The invariant: any state change affecting the derived value must be recorded in the same transaction, before the next consumer reads it. Check that a fresh reserves array is not built without pushing to the oracle [E2](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AH-01.md). For supply-based rates, verify deposit, redeem, and swap hooks all write checkpoints [E1](https://bugbountylibrary.com/r/sherlock%3A2024-08-flayer%3AH-15.md). For price feeds, confirm freshness bounds and deviation checks against an independent source [E3](https://bugbountylibrary.com/r/dhl%3A20240223-compounduni.md).

## Variants seen
- Supply-changing hooks (deposit, redeem, afterSwap) skip checkpoints, inflating utilization [E1](https://bugbountylibrary.com/r/sherlock%3A2024-08-flayer%3AH-15.md).
- shift()/sync() rebuild reserves without updating Pumps, so a shift-then-swap-back feeds manipulated reserves to the oracle [E2](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AH-01.md).
- Price feeder returns stale or bad price, letting an asset be borrowed undervalued [E3](https://bugbountylibrary.com/r/dhl%3A20240223-compounduni.md).

## Impact and severity
Victims overpay interest or get liquidated [E1](https://bugbountylibrary.com/r/sherlock%3A2024-08-flayer%3AH-15.md); oracle manipulation via reserve shifts [E2](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AH-01.md); ~$439k profit from borrowing a mispriced asset [E3](https://bugbountylibrary.com/r/dhl%3A20240223-compounduni.md). Severity rises when the skipped path is attacker-triggerable in one transaction and the derived value gates borrowing or liquidation.

## Why fixes fail
Partial coverage: adding the update to swap paths but not shift/sync leaves the invariant broken [E2](https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AH-01.md).

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2024-08-flayer%3AH-15.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-07-basin%3AH-01.md
- E3: https://bugbountylibrary.com/r/dhl%3A20240223-compounduni.md
