# Oracle price seeding at initialization

Pool or pair created or seeded at an attacker-chosen price before guards apply

_Area: DeFi oracles, liquidations and flash loans. Seen in 3 disclosed reports; latest 2026-02-05. Updated 2026-10-24._

## How it works
A protocol assumes that when it first creates or funds a pool, the pool starts at a fair price. That assumption breaks when pool creation is permissionless and idempotent, or when the address the protocol checks is not the address it actually uses. An attacker acts first: they create the pool, seed reserves, or move the rate before the protocol's own deposit lands. The protocol then adds liquidity or deposits at the attacker's price, and the attacker unwinds at a profit. The root cause is always the same: the price-setting step trusts state that an outside party can set beforehand.

## Where to show up
- Migration or launch code calling an idempotent create-and-initialize helper (e.g. `createAndInitializePoolIfNecessary`) without first checking that the pool does not already exist.
- Token or pool addresses that are predictable before launch, so an attacker can front-run creation.
- Address derivation (a `pairFor`-style function) whose CREATE2 salt differs from the factory's actual salt, so guards compare against the wrong address.
- A permissionless entry point (`start()`, migrate, harvest) that pushes a large, predictable deposit into an external pool at a known time.
- Donation or pre-seed guards that only cover some of the addresses involved.

## How to review
Identify every place the protocol sets or accepts an initial price, then ask who can act on that pool before the protocol does. The invariant: at the moment the protocol adds liquidity or deposits, the pool's price and reserves must be either freshly set by the protocol itself or validated against a trusted reference. Concretely, check that creation reverts if the pool exists, that any derived address exactly matches the factory's salt inputs, and that large predictable deposits are bounded or slippage-checked.

## Variants seen
- Pre-created DEX pool at a skewed `sqrtPriceX96` before launchpad migration [E1](https://bugbountylibrary.com/r/dhl%3A20250211-fourmeme.md).
- Mismatched CREATE2 salt lets the donation guard miss the real pair, so reserves are pre-seeded [E2](https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-21.md).
- Permissionless `start()` deposits the whole pool into a pre-manipulated strategy at a known time [E3](https://bugbountylibrary.com/r/c4%3A2022-03-sublime%3AM-03.md).

## Impact and severity
E1 drained roughly 186k. Severity is high when the moved price directly releases funds; lower when it only skews a rate. It gets worse with predictable addresses, public timing, and large single-shot deposits.

## Why fixes fail
E2 shows a guard added earlier failing because its address derivation did not mirror the factory's salt; verify any fix compares against the real address [E2](https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-21.md).

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20250211-fourmeme.md
- E2: https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-21.md
- E3: https://bugbountylibrary.com/r/c4%3A2022-03-sublime%3AM-03.md
