defirisk.co
rubric v1.7.0

Public initialize() without initializer modifier

Uniswap (v2 + v3)'s assessment for RD-F-022 — scored green on the v1.7.0 rubric. The evidence below is the curator's reasoning for this score.

Evidence summary #

V2: UniswapV2Pair initialize() protected by `require(msg.sender == factory)` — only factory can call, in same deployment transaction. V3: UniswapV3Pool initialize() protected by `require(slot0.sqrtPriceX96 == 0, 'AI')` — cannot be re-initialized. Factory calls initialize() atomically. 5+ years, thousands of pools, zero exploit. Combined: green.

Detail #

V2 UniswapV2Pair.sol has an `initialize(address _token0, address _token1)` function gated by `require(msg.sender == factory)`. The factory deploys the pair via CREATE2 and immediately calls initialize() in the same transaction — there is no front-running window. V3 UniswapV3Pool.sol has an `initialize(uint160 sqrtPriceX96)` function that uses `require(slot0.sqrtPriceX96 == 0, 'AI')` as an equivalent re-initialization guard (since sqrtPriceX96 can only be 0 before the pool has been initialized). Source comment states 'not locked because it initializes unlocked' — deliberate design. Factory createPool() calls initialize() in the same transaction, eliminating any front-running window. Over 5 years with thousands of pools created, this pattern has never been exploited.

Sources #

Methodology #

Determine whether any implementation contract exposes `initialize(…)` without the OpenZeppelin `initializer` modifier or equivalent initialization lock.

See the full factor methodology and distribution across all protocols →

rubric_version v1.7.0 protocol uniswap factor RD-F-022 score green collected_at 2026-05-12 10:36:11