# x_last_price uses global timestamp incorrectly

x_last_price reads the global latest timestamp and fails to return a cross-price when only one asset of the pair was updated in that snapshot.

- Payout: Contest reward
- Severity: medium
- Program: Reflector
- Credited: HUNTERRRRRRR
- Disclosed: 2026-02-02
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-10-reflector-v3#m-05
- Library page: https://bugbountylibrary.com/r/c4%3A2025-10-reflector-v3%3AM-05
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:rust technique:source-review vuln:dos vuln:oracle-manipulation

**Target:** Soroban price oracle contract (price_oracle.rs)
**Root cause:** x_last_price uses the global last-record timestamp instead of the latest timestamp where both assets of the pair have records, so a partial update leaves one side missing at that tick and load_cross_price returns None.
**Steps:**
1. Publisher posts a snapshot updating only base_asset (or only quote_asset), advancing the global last-record timestamp.
2. Call `x_last_price(e, base_asset, quote_asset)`.
3. obtain_last_record_timestamp returns the new global tick; resolve_asset_pair_indexes succeeds.
4. load_cross_price at that timestamp finds no record for the un-updated asset and returns None.
5. Observe None despite a valid cross-price existing at the previous timestamp where both assets were present.
**How found:** Code reading of x_last_price versus x_prices/x_twap: noticed the global timestamp lookup diverges from the backward-scanning load_prices used by sibling APIs, then reasoned about partial-update snapshots.
**Insight:** When an oracle exposes a 'latest' price, check whether 'latest' is global or per-pair; a global last-tick lookup breaks on partial updates. Compare sibling APIs (x_prices, x_twap) that scan history to spot the inconsistency.
