# Oracle price does not compound

ScalingPriceOracle resets startTime on requestCPIData, so fulfill recomputes oraclePrice from a near-zero timeDelta, collapsing the compounded CPI price back toward 1.0.

- Payout: Audit contest
- Severity: high
- Program: Volt Protocol
- Credited: cmichel
- Disclosed: 2022-06-29
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-03-volt-findings/issues/22
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-volt%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:oracle-manipulation

**Target:** ScalingPriceOracle.sol price oracle (Chainlink CPI fulfill callback)
**Root cause:** oraclePrice is only written in _updateCPIData during fulfill, computed as old price plus interpolation from startTime; but requestCPIData's afterTimeInit modifier resets startTime to now, so timeDelta at fulfill is ~0 and oraclePrice is set to itself.
**Steps:**
1. Observe oraclePrice=1e18, monthlyAPR=10%, 14 days elapsed; getCurrentOraclePrice() returns 1.05e18
2. On the 15th trigger `requestCPIData()` which resets `startTime = now` via afterTimeInit
3. Call `getCurrentOraclePrice()`: timeDelta=0 so priceDelta=0, returns oraclePriceInt = 1.0e18
4. Chainlink calls `fulfill`, which sets `oraclePrice = getCurrentOraclePrice()` ≈ 1.0e18, discarding accumulated CPI
**How found:** Code reading of ScalingPriceOracle: noticed oraclePrice storage is only assigned in _updateCPIData (fulfill callback) and that startTime is reset in requestCPIData, making the interpolation window collapse to zero at fulfill time.
**Exploitation:** Attacker can time a requestCPIData/fulfill cycle to force the oracle price to drop suddenly back to 1.0, then trade against the artificially reset price for profit (direction not detailed in text).
**Insight:** When an oracle interpolates from a stored startTime, check every path that mutates startTime — a reset between request and callback silently zeroes the accrued delta and pins the price to its base value.
