Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ Indexes:
- jit\_user\_order\_creation\_timestamp: btree(`owner`, `creation_timestamp` DESC)
- jit\_event\_id: btree(`block_number`, `log_index`)

The `pool-indexer` service uses its own per-network database, not these shared DBs. Its tables (`pool_indexer_checkpoints`, `uniswap_v3_pools`, `uniswap_v3_pool_states`, `uniswap_v3_ticks`) and migrations live in [`sql-pool-indexer/`](sql-pool-indexer/).
The `pool-indexer` service uses its own per-network database, not these shared DBs. Its tables (`pool_indexer_checkpoints`, `uniswap_v3_pools`, `uniswap_v3_pool_states`, `uniswap_v3_ticks`, `balancer_v2_pools`, `balancer_v2_pool_tokens`) and migrations live in [`sql-pool-indexer/`](sql-pool-indexer/).

### Enums

Expand Down
37 changes: 35 additions & 2 deletions database/sql-pool-indexer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ applied migrations) so it's cancelled there by `../sql/V111`.
## Schema

The tables below live in the indexer's own per-network database (e.g.
`ink_pool_indexer`), created by the migrations in this directory.
`ink_pool_indexer`), created by the migrations in this directory. `V110` defines
the Uniswap V3 discovery schema and `V111` the Balancer V2 one; a pool-indexer
process indexes whichever protocol(s) its network config enables.

### pool\_indexer\_checkpoints

Highest finalized block processed per `contract_address` by `pool-indexer`. `contract_address` is the factory address. The indexer runs one process per network against its own DB, so there's no `chain_id` column.
Highest finalized block processed per `contract_address` (the factory address) by `pool-indexer`. Shared by the Uniswap V3 and Balancer V2 indexers: their factory addresses are distinct contracts so rows never collide, and each protocol's queries filter to its own configured factories. One process per network against its own DB, so there's no `chain_id` column.

Column | Type | Nullable | Details
--------------------|--------|----------|--------
Expand Down Expand Up @@ -97,3 +99,34 @@ Quoters consult these to predict liquidity changes at tick crossings during swap

Indexes:
- PRIMARY KEY: btree (`pool_address`, `tick_idx`)

### balancer\_v2\_pools

One row per pool, discovered from each factory's `PoolCreated` event. `pool_type` is derived from the creating factory (weighted V0 and V3-plus both map to `Weighted`) and stored as the string the API serves. Referenced by `balancer_v2_pool_tokens`. Discovery metadata only — dynamic state (balances, amplification, LBP weights, scaling factors, swap fee) stays on-chain and is fetched by the driver at query time.

Column | Type | Nullable | Details
----------------|--------|----------|--------
pool\_id | bytea | not null | 32-byte Balancer poolId
address | bytea | not null | Pool address (poolId's first 20 bytes)
factory | bytea | not null | Factory that emitted `PoolCreated`
pool\_type | text | not null | `Weighted`, `Stable`, `ComposableStable`, or `LiquidityBootstrapping` (`CHECK`)
created\_block | bigint | not null | Block the pool was created on-chain

Indexes:
- PRIMARY KEY: btree (`pool_id`)

### balancer\_v2\_pool\_tokens

Tokens per pool in `Vault.getPoolTokens` order. `decimals` is backfilled; `weight` is set only for weighted pools. FK → `balancer_v2_pools`.

Column | Type | Nullable | Details
-----------|----------|----------|--------
pool\_id | bytea | not null | FK → `balancer_v2_pools(pool_id)`
position | int | not null | Index in `getPoolTokens` order
token | bytea | not null | Token address
decimals | smallint | nullable | `NULL` = not yet fetched. `-1` = sentinel for "fetched but call failed"
weight | numeric | nullable | Bfp (1e18) normalized weight; weighted pools only, else `NULL`

Indexes:
- PRIMARY KEY: btree (`pool_id`, `position`)
- Partial index on `(token)` with predicate `decimals IS NULL` to power the backfill scan.
36 changes: 36 additions & 0 deletions database/sql-pool-indexer/V111__balancer_v2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- Balancer V2 discovery tables, applied on top of V110's uniswap_v3_* schema in
-- the pool-indexer's per-network DB. Checkpoints reuse `pool_indexer_checkpoints`
-- (keyed by factory address): Balancer and Uniswap V3 factory addresses are
-- distinct contracts, so both protocols share that table without collision.

-- One row per registered pool, discovered from each factory's `PoolCreated`
-- event. `pool_type` is derived from which factory created the pool (no on-chain
-- classification); weighted V0 and V3-plus both map to `Weighted` (the variant
-- is recoverable from `factory`). Stored as the string the API serves, so
-- there's no int<->enum mapping at the boundary.
CREATE TABLE balancer_v2_pools (
pool_id BYTEA NOT NULL, -- 32-byte Balancer poolId
address BYTEA NOT NULL, -- pool address (poolId's first 20 bytes)
factory BYTEA NOT NULL,
pool_type TEXT NOT NULL CHECK (pool_type IN ('Weighted', 'Stable', 'ComposableStable', 'LiquidityBootstrapping')),
created_block BIGINT NOT NULL,
PRIMARY KEY (pool_id)
);

-- Tokens per pool, in `Vault.getPoolTokens` order (`position`). `decimals` is
-- nullable and filled in by the backfill task. `weight` is the Balancer Bfp
-- (1e18 fixed-point) normalized weight, set only for weighted pools; NULL for
-- stable/composable-stable/LBP (their weights are absent or fetched on-chain).
CREATE TABLE balancer_v2_pool_tokens (
pool_id BYTEA NOT NULL,
position INT NOT NULL,
token BYTEA NOT NULL,
decimals SMALLINT, -- NULL = not yet fetched; -1 = fetched but call failed
weight NUMERIC, -- Bfp (1e18); weighted pools only, else NULL
PRIMARY KEY (pool_id, position),
FOREIGN KEY (pool_id) REFERENCES balancer_v2_pools(pool_id)
);

-- Decimals backfill hot path. Partial on `IS NULL` so the index shrinks to
-- near-empty once most rows are populated (real value or the `-1` sentinel).
CREATE INDEX ON balancer_v2_pool_tokens (token) WHERE decimals IS NULL;
Loading