Reproduced Exploit
ParaSpace — [H-09] UniswapV3 tokens of certain pairs will be wrongly valued
1. Same-decimal branch: sqrt(token0Price 1e18 / token1Price) 2^96 / 1e9. 2. If token1Price > token0Price * 1e18, inner div is 0 → sqrtPriceX96 = 0. 3. Amount math treats position as pure amount0 → severe undervaluation → false liquidation.
Chain
Other
Category
untagged
Date
Nov 2022
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 15982-h-09-uniswapv3-tokens-of-certain-pairs-will-be-wrongly-value. Standalone Foundry PoC and full write-up: 15982-h-09-uniswapv3-tokens-of-certain-pairs-will-be-wrongly-value_exp in the
evm-hack-registrymirror.
Vulnerability classes: arithmetic/decimal-mismatch · false liquidation
Reproduction: self-contained Foundry PoC with only
forge-std— no fork. Full trace: output.txt.
AuditVault taxonomy: lang/solidity · platform/code4rena · severity/high · sector/dex · sector/lending · sector/oracle · genome: decimal-mismatch · variant · token-decimal-normalization
Key info#
| Impact | HIGH — extreme price ratios zero sqrtPriceX96; healthy UniV3 LP falsely liquidatable |
| Protocol | ParaSpace |
| Vulnerable code | UniswapV3OracleWrapper._getOracleData same-decimal sqrtPriceX96 branch |
| Bug class | Integer division truncates before fixed-point scale |
| Finding | Code4rena 2022-11-paraspace · #15982 (H-09) · reporter Trust |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
- Same-decimal branch:
sqrt(token0Price * 1e18 / token1Price) * 2^96 / 1e9. - If
token1Price > token0Price * 1e18, inner div is 0 →sqrtPriceX96 = 0. - Amount math treats position as pure amount0 → severe undervaluation → false liquidation.
The vulnerable code#
oracleData.sqrtPriceX96 = uint160(
(SqrtLib.sqrt(
((oracleData.token0Price * (10 ** 18)) / (oracleData.token1Price)) // @> VULN
) * 2 ** 96) / 1e9
);
// FIX: scale (e.g. multiply by 2**96) before the truncating division
Diagrams#
Impact#
Users holding UniV3 NFTs on extreme-ratio pairs can be liquidated while economically healthy.
Remediation#
Multiply by 2**96 (or use higher intermediate precision) before the division that can zero.
Sources#
- AuditVault #15982
- Code4rena 2022-11-paraspace
code-423n4/2022-11-paraspace@c6820a2paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 15982-h-09-uniswapv3-tokens-of-certain-pairs-will-be-wrongly-value_exp (evm-hack-registry mirror).
- AuditVault finding: 15982-h-09-uniswapv3-tokens-of-certain-pairs-will-be-wrongly-value.
Alerts & third-party analyses
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.