# Disabled oracle assets remain usable through the batch-price TTL cache

K2 PriceOracle batch path serves TTL-cached prices for disabled assets, letting users keep borrowing against collateral whose oracle was disabled.

- Payout: Contest reward
- Severity: medium
- Program: K2
- Credited: droopytoops
- Disclosed: 2026-08-20
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2026-04-k2#m-25
- Library page: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-25
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:medium tech:rust technique:source-review vuln:access-control vuln:business-logic vuln:oracle-manipulation

**Target:** PriceOracleContract::get_asset_prices_vec batch price endpoint (Soroban/Rust)
**Root cause:** The TTL cache lookup and `continue` execute before loading asset config and checking `config.enabled`, so cached prices bypass the disabled-asset guard that the single-asset path enforces.
**Steps:**
1. Admin calls set_asset_enabled(asset, false).
2. Confirm get_asset_price_data(asset) now returns AssetDisabled.
3. Call get_asset_prices_vec([asset]) within cache_ttl and price_staleness_threshold of the last cached price.
4. Observe the cached price is returned because the cache branch `continue`s before the enabled check.
5. Use that batch price in router account-data/borrow validation to open fresh debt against the disabled asset.
**How found:** Code review of get_asset_prices_vec: noticed the cache branch `continue` precedes get_asset_config and the `config.enabled` check, then compared against the single-asset path which rejects disabled assets, revealing the inconsistency.
**Exploitation:** Attacker waits for an asset to be disabled (e.g. compromised/stale feed) while a fresh LastPriceData remains cached, then calls the router borrow path which consumes get_asset_prices_vec; the stale cached valuation is accepted and new debt is minted against unsafe collateral.
**Insight:** When a contract has both single-item and batch accessors, diff their guard ordering: a cache fast-path that `continue`s before authorization/enablement checks silently bypasses risk controls only on the batch route.
