Skip to content

feat(uniswap-v3-core): add shared indexing crate with TxDeltaIndexer trait#981

Draft
kayibal wants to merge 6 commits into
mainfrom
feat/uniswap-v3-core-crate
Draft

feat(uniswap-v3-core): add shared indexing crate with TxDeltaIndexer trait#981
kayibal wants to merge 6 commits into
mainfrom
feat/uniswap-v3-core-crate

Conversation

@kayibal

@kayibal kayibal commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Extracts shared UniswapV3 indexing logic into a new uniswap-v3-core crate that compiles for both native and WASM targets. The substreams handlers in ethereum-uniswap-v3-logs-only become thin wrappers that delegate to it.

Adds a TxDeltaIndexer trait to tycho-common:

  • apply_block(block: &dto::BlockChanges) — hydrates internal state from a finalised block; the first call serves as initialisation from a full snapshot, subsequent calls apply incremental deltas.
  • generate_deltas(txs: &[TxInput]) -> dto::BlockChanges — applies a batch of in-flight transactions against the current state and returns the aggregated protocol state deltas they would produce. Does not mutate state; repeated calls with the same transactions return identical results.

The trait is designed as a native-code substitute for a Substreams package: an Ethereum block builder can feed it finalised BlockChanges from the Tycho client and then call generate_deltas to discover how a candidate transaction bundle would alter DEX state before deciding whether to include it.

UniswapV3Processor implements the trait. It stores chain/extractor metadata, running tick and liquidity maps, and token balances. generate_deltas operates on a clone of internal state so it is safe to call repeatedly.

LogInput and TxInput are defined in tycho-common with private fields and public constructors.

The integration test streams from substreams genesis (block 12_369_621) and compares processor output against substreams ground truth across 2000 blocks using apply_block / generate_deltas — 0 attribute mismatches, 0 balance mismatches across 136 attributes and 98 balances.

Also bumps the ethereum-uniswap-v3 and ethereum-uniswap-v3-logs-only substreams toolchains from 1.83.0 to 1.87.0 — hashbrown 0.17 (via indexmap 2.14) requires edition 2024 which needs Cargo ≥ 1.85.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-project-automation github-project-automation Bot moved this to Todo in Tycho May 5, 2026
@kayibal kayibal force-pushed the feat/uniswap-v3-core-crate branch 4 times, most recently from d6293b5 to 640e9d9 Compare May 6, 2026 09:02
@kayibal kayibal marked this pull request as draft May 6, 2026 11:33
@kayibal kayibal changed the title feat(uniswap-v3-core): add shared indexing crate with ProtocolProcessor feat(uniswap-v3-core): add shared indexing crate with TxDeltaIndexer trait May 6, 2026
@kayibal kayibal force-pushed the feat/uniswap-v3-core-crate branch 4 times, most recently from 283bcef to ee2cd7a Compare May 19, 2026 18:09
kayibal and others added 2 commits May 19, 2026 23:12
Adds a native-code indexing abstraction for pending block simulation:
- `TxDeltaIndexer` trait and `TxInput`/`LogInput` in tycho-common
- `PendingBlockProcessor` in tycho-simulation for generating ephemeral
  state updates from unconfirmed transactions
- `apply_deltas_ephemeral` on `TychoStreamDecoder` for read-only delta
  application without touching confirmed state
- `build_with_pending` on `ProtocolStreamBuilder` to wire a processor
  alongside the live feed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a native Rust implementation of UniswapV3 as a TxDeltaIndexer:
- `UniswapV3Processor` decodes pool-created, swap, mint, burn, and
  collect events directly from EVM logs without a Substreams package
- Tick and liquidity math ported from the Uniswap V3 reference impl
- Balance tracking for component token balances
- Substreams module updated to use the shared block_storage helper

Builds on the TxDeltaIndexer / PendingBlockProcessor infrastructure
from feat/pending-block-processor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kayibal kayibal force-pushed the feat/uniswap-v3-core-crate branch from ee2cd7a to 202d34f Compare May 20, 2026 00:42
kayibal and others added 4 commits June 12, 2026 16:04
Adds uniswap-v4-core, a native Rust TxDeltaIndexer that decodes UniswapV4
PoolManager logs (Initialize, Swap, ModifyLiquidity, ProtocolFeeUpdated)
without requiring a Substreams package at runtime. Mirrors the uniswap-v3
migration: shared event decoding, tick/liquidity tracking, fee-adjusted
balance deltas, and liquidity math ported from the substreams modules.

The integration test streams the ethereum-uniswap-v4-no-hooks substreams
package as ground truth and verifies byte-identical attribute and balance
values per block against raw RPC transaction inputs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documents the pattern used for the uniswap-v3/v4 migrations: extract
substreams transform logic into a native protocols/crates/<protocol>
crate implementing TxDeltaIndexer, and validate it with a parity
integration test against the spkg built from origin/main. Captures the
non-obvious parts: StreamingFast JWT exchange, active block window
selection, sequential event application matching store get_at semantics,
ordinal and component-id conventions, and tick change-type rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The v3 and v4 processors keyed pools by un-prefixed hex and emitted
un-prefixed component ids from generate_deltas, while the substreams
emit 0x-prefixed ids. In production this would make apply_block register
pools under keys generate_deltas never looks up, and emitted ids would
miss decoder state keys in apply_deltas_ephemeral — silently producing
empty pending deltas.

Normalize ids at the apply_block boundary for internal keys and emit
0x-prefixed lower-case hex from generate_deltas, matching the substreams
format. The parity tests now feed apply_block the raw substreams ids and
compare without normalization, so the id format itself is asserted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds uniswap-v2-core, a native Rust TxDeltaIndexer that decodes UniswapV2
Sync logs without a Substreams runtime. UniswapV2 is the simplest case: the
Sync event carries absolute reserves, so there are no ticks, no liquidity
math, and no running balance accumulators — the processor only maintains a
pool registry and emits reserve0/reserve1 attributes plus token balances
straight from each Sync.

The integration test streams the ethereum-uniswap-v2 substreams package
(built from origin/main) as ground truth and verifies byte-identical
attributes and balances per block. It aggregates the substreams side in
transaction-index order because that package emits per-tx changes unsorted,
which would otherwise flap on pools that sync in several txs per block.

Also extends the migrate-substreams-to-native skill with the uniswap-v2
reference, the absolute-vs-accumulated balance distinction, and the
transaction-ordering pitfall.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant