# CompositeMultiOracle returns wrong decimals for prices?

CompositeMultiOracle mis-scales chained oracle prices by token decimals instead of oracle decimals, inflating converted amounts by up to 1e12x.

- Payout: Audit contest
- Severity: high
- Program: Yield
- Found by: cmichel
- Disclosed: 2021-09-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-08-yield-findings/issues/26
- Library page: https://bugbountylibrary.com/r/c4%3A2021-08-yield%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:oracle-manipulation vuln:precision-loss

**Target:** CompositeMultiOracle price aggregation contract
**Root cause:** The _peek/_get chain divides by 10**source.decimals (token decimals) rather than the underlying oracle's decimals, so the returned price is not normalized to 18 decimals as the caller's value = price*amount/1e18 assumes.
**Steps:**
1. Call CompositeMultiOracle.peek(USDC, USDT, 1e18) with path [DAI].
2. First hop _peek(USDC, DAI, 1e18) returns priceIn*1e18/1e6 = 1e30 due to USDC 6 decimals.
3. Second hop _peek(DAI, USDT, 1e30) returns 1e30 unchanged (DAI 18 decimals).
4. Final value = 1e30 * 1e6 / 1e18 = 1e18, i.e. 1e12x the true USDT amount.
**How found:** Code reading of the _peek chaining logic; noticed the division by source.decimals and questioned whether it should be the underlying oracle's decimals, then traced a USDC->DAI->USDT path numerically.
**Insight:** When an oracle chains multiple price sources, verify the intermediate price is normalized to the precision the final value=price*amount/1e18 formula expects; token decimals and oracle decimals are distinct and mixing them silently inflates amounts.

