# Reth poolPrice calculation may overflow

Reth derivative's poolPrice multiplies sqrtPriceX96 by itself and 1e18 in uint256, overflowing for high pool prices and corrupting SafEth price accounting.

- Payout: Contest reward
- Severity: high
- Program: Asymmetry Finance
- Credited: adriro
- Disclosed: 2023-07-28
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-03-asymmetry-findings/issues/593
- Library page: https://bugbountylibrary.com/r/c4%3A2023-03-asymmetry%3AH-05
- 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:** SafEth Reth derivative poolPrice (Uniswap V3 slot0)
**Root cause:** Computes sqrtPriceX96 * sqrtPriceX96 * 1e18 in plain uint256 without checking whether sqrtPriceX96 exceeds uint128 max, so the intermediate product overflows for large sqrtPrice values.
**Steps:**
1. Read Reth.poolPrice: `(sqrtPriceX96 * uint(sqrtPriceX96) * 1e18) >> 192`.
2. Note sqrtPriceX96 is uint160; squaring can exceed 2^256 when sqrtPriceX96 > ~2^128.
3. Compare to Uniswap OracleLibrary.getQuoteAtTick which branches on `sqrtRatioX96 <= type(uint128).max` and uses FullMath.mulDiv to avoid overflow.
4. Observe that for a pool whose sqrtPriceX96 exceeds uint128 max, the multiplication wraps and returns a wrong (truncated) price.
**How found:** Code review of the poolPrice math against Uniswap's reference OracleLibrary.getQuoteAtTick, noticing the reference implementation explicitly guards the sqrtRatioX96 squaring overflow that the derivative omits.
**Insight:** When a contract reimplements Uniswap V3 price math, diff it against OracleLibrary.getQuoteAtTick: the `sqrtRatioX96 <= type(uint128).max` branch exists precisely because squaring a uint160 sqrtPrice overflows uint256, so any hand-rolled `sqrtPriceX96 * sqrtPriceX96` is suspect.
