# Griefable oracle monotonic update guards

Shared forward-only timestamp/version guards that outsiders can advance to block legitimate oracle updates

_Area: DeFi oracles, liquidations and flash loans. Seen in 3 disclosed reports; latest 2024-08-22. Updated 2026-10-30._

## How it works
Oracle updates assume a forward-only guard (a stored timestamp or version that must only increase) is safe because it only advances on valid, newer data. The assumption breaks when that guard is writable by an unprivileged caller, or shared between a privileged path (keeper commit, settlement) and an open path. An outsider advances the guard with data that passes the check but is not what the protocol needs, so the legitimate update is now "older" and reverts. Separately, an exceptional path (invalid oracle version) can mutate position accounting without the limit checks normal updates enforce, leaving global state that later reverts every update [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md).

## Where it shows up
- A stored timestamp/version compared with `>=` or `>` against caller-supplied data, then overwritten.
- Two entrypoints (`commit` vs `commitRequested`, `extract_price` vs settlement) sharing one monotonicity check on the same variable [E3](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md).
- Invalidation branches that adjust accumulated values without running position-limit checks [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md).
- Global invariants (e.g. `maker <= makerLimit`) that revert the whole update entrypoint rather than the offending position [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md).
- A monotonic assertion stricter than the feed's own validity window: RedStone permits prices 3 minutes old to 1 minute future, but the contract requires non-decreasing timestamps [E2](https://bugbountylibrary.com/r/sherlock%3A2024-08-velar-artha%3AM-5.md).

## How to review
Identify every forward-only state variable and every writer to it. The invariant: no unprivileged caller can advance that variable to a value that makes a legitimate pending update fail its check. Ask: can a caller supply data that passes the guard but differs from what the keeper will submit [E3](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md)? Does the guard compare against the oracle's own validity window rather than a stored high-water mark [E2](https://bugbountylibrary.com/r/sherlock%3A2024-08-velar-artha%3AM-5.md)? For invalidation, verify exceptional paths apply the same limit checks as normal paths, and that a limit breach reverts only the affected position, not the global update function [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md).

## Variants seen
- Invalid oracle version invalidates pending maker positions without limit checks, pushing global maker over `makerLimit` and bricking all updates [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md).
- Monotonic timestamp assertion conflicts with the feed's tolerance window; a newer-timestamp tx reverts older-but-valid pending txs [E2](https://bugbountylibrary.com/r/sherlock%3A2024-08-velar-artha%3AM-5.md).
- Front-running `commitRequested()` with a `commit()` carrying an older version but newer publish time, stalling keeper updates [E3](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md).

## Why fixes fail
Guarding one direction of an accounting asymmetry (underflow via `closable`) left the mirror increase case unguarded, so the invalidation path still skipped limit enforcement [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md). Fixing one entrypoint's guard without the shared writer leaves the griefing path open [E3](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md).

## Impact and severity
Temporary or permanent denial of service on core update/settlement paths: bricked Market updates [E1](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md), DoS for protocol users [E2](https://bugbountylibrary.com/r/sherlock%3A2024-08-velar-artha%3AM-5.md), stalled oracle updates [E3](https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md). Severity rises when the block is permanent (limit cannot be lowered) or affects all users rather than one, and when no privileged recovery path exists.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-3.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2024-08-velar-artha%3AM-5.md
- E3: https://bugbountylibrary.com/r/sherlock%3A2023-09-perennial%3AM-2.md
