# Discrepency in the Uniswap V3 position price calculation because of decimals

Uniswap V3 oracle wrapper hardcodes 1E9 denominator ignoring token decimal delta, inflating position price when token1 decimals exceed token0, enabling over-borrowing.

- Payout: Contest reward
- Severity: high
- Program: ParaSpace
- Credited: Franfran
- Disclosed: 2023-04-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-paraspace-findings/issues/455
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-paraspace%3AH-06
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:oracle-manipulation

**Target:** UniswapV3OracleWrapper sqrtPriceX96 / getTokenPrice
**Root cause:** In the token1Decimal > token0Decimal branch, sqrtPriceX96 divides by hardcoded 1E9 instead of 10**(9 + token1Decimal - token0Decimal), so the price is over-inflated by the decimal delta.
**Steps:**
1. Identify a Uniswap V3 position where token1 decimals > token0 decimals (e.g. token0=9, token1=18).
2. Call `_getOracleData()` which computes sqrtPriceX96 using `(sqrt(token0Price*10**(18+token1Dec-token0Dec)/token1Price)*2**96)/1E9`.
3. Observe the result is inflated by 10**(token1Dec-token0Dec) magnitudes vs correct value.
4. `getAmountsForLiquidity()` returns huge token amounts, and `getTokenPrice()` returns an inflated position price.
**How found:** Code review of the decimal-handling branches in `_getOracleData()`; noticed the equal-decimals and token0>token1 branches scale the denominator but the token1>token0 branch keeps a hardcoded 1E9, then confirmed with a Foundry PoC comparing sqrtPriceX96 across decimal configurations.
**Exploitation:** An attacker holding a Uniswap V3 position with token1 decimals > token0 decimals benefits from an inflated collateral valuation in ParaSpace, allowing over-borrowing against the mispriced position and leaving bad debt.
**Insight:** When auditing oracle/price wrappers, check every decimal-normalization branch for asymmetric scaling — a hardcoded 1e9/1e18 denominator that isn't adjusted by the decimal delta silently inflates prices for one token ordering.
