# Stale reserve cache after mutation

Reserve mutated in memory but never cached or stored, so later math reads stale state

_Area: DeFi accounting and math bugs. Seen in 5 disclosed reports; latest 2025-08-13. Updated 2026-10-25._

## How it works
Code loads a reserve or pool state into memory, mutates it, and then either fails to write it back or reloads the old copy from storage before the next operation. The assumption that breaks is that in-memory mutation is automatically persisted. In a load/mutate/cache/store design, any path that mutates without a matching cache/store call leaves storage stale, and later math (utilization, rewards, reserves) runs on numbers that no longer match reality.

## Where it shows up
- Flash-loan or repay paths that mutate a reserve but skip the cache/store call other paths use [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md)
- Any two code paths that mutate the same field but only one persists it [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md)
- A mutation helper (e.g. add_liabilities) called on a loaded reserve with no follow-up cache_reserve [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md)
- Later operations that reload the same reserve from storage, discarding the in-memory change [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md)

## How to review
For every field that feeds accounting math, enumerate all writers and confirm each one persists before the next read. The invariant: after any mutation, the stored value equals the in-memory value, and no later operation reads a pre-mutation copy. Check that flash-loan, repay, and normal paths all call the same cache/store routine [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md). Compare each mutating path against a known-good one (apply_repay caches; execute_submit_with_flash_loan does not) and flag the asymmetry.

## Variants seen
- Flash-loan liability update lost because cache_reserve was never called; a same-asset repay reloads stale d_supply [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md)

## Impact and severity
Led to corrupted utilization and reward accounting [E1](https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md). Severity is high: stale state silently misprices shares and rewards, and the error persists until an unrelated write happens to overwrite it. Worse when the stale field gates borrowing capacity or reward payout, since the wrong number is trusted by downstream math rather than rejected.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2025-02-blend-v2-audit-certora-formal-verification%3AH-01.md
- E2: https://bugbountylibrary.com/r/dhl%3A20221129-mbc-zzsh.md
- E3: https://bugbountylibrary.com/r/dhl%3A20231228-dominott.md
- E4: https://bugbountylibrary.com/r/dhl%3A20230712-wgpt.md
