Add 42 UniV2/V3 fork factories as 2 merged extractors#380
Add 42 UniV2/V3 fork factories as 2 merged extractors#380
Conversation
Add substreams YAML configurations for 44 UniswapV2 fork factories and 4 UniswapV3 fork factories on Ethereum mainnet. These are byte-for-byte UniV2/V3 code forks deployed through non-standard factory addresses, discovered through mainnet Swap event monitoring. All factories verified to emit standard PairCreated/PoolCreated events. Deployment blocks sourced from Etherscan contract creation data. No simulation or execution changes needed; pools use existing UniV2/V3 WASM binaries. Named forks: NineInch, Fraxswap, Linkswap, CroDefi, Oboswap, OrionPool, YouSwap, JMSwap, KingSwap, Kwikswap, SaitaSwap, HiSwap, PepeDex, Yape, SakeSwap, SumSwap, SafeSwap, MintyswapV2, BtSwap, ShibaswapV2, MintyswapV3, BlueprintV3, plus unnamed address-identified forks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix proto file references in all 48 YAML configs (remove non-existent entity.proto, match exact proto imports from base configs) - Add CLONE_TO_BASE_PROTOCOL entries for all 48 forks so the test runner knows which base substreams binary to use - Add integration test configs (47 files) with real pool creation data from Etherscan (1 factory has no pools yet) - Fix V3 test configs to use hardcoded "uniswap_v3_pool" protocol type (V3 module doesn't parameterize this like V2 does) Tested: NineInch V2, Fraxswap V2, ShibaSwap V3 all pass range tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enable skip_simulation: false for 8 factories across all priority levels (2 high V2, 2 medium V2, 2 low V2, 2 V3). Results: - 7/8 pass with simulations enabled - 1 V3 fork (0xbaceb8...) reverts on swap execution despite having liquidity; may have modified swap logic. Reverted to skip_simulation. All 47/47 factories pass indexing (range) tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Factory 0xbaceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f emits standard PoolCreated events and indexing works, but its pools revert on swap execution despite having liquidity. Not a true byte-for-byte V3 clone. Total: 47 factories -> 46 (44 V2 + 3 V3 remaining, 1 V3 removed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All V2 forks now use protocol_type_name=uniswap_v2_pool instead of custom names (e.g., nineinch_v2_pool). This ensures pools are automatically recognized by the existing simulation and execution layers without needing registration in tycho-simulation or tycho-execution. V3 forks already used the hardcoded uniswap_v3_pool type. All 46/46 integration tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove TransparentUpgradeableProxy factories that could be upgraded to produce non-standard pools: - 0x8ff485eed59e9931fbb984e6d9e8a4b2b459deeb (impl: 0x47db7a...) - 0x69bd16ae6f507bd3fc9ecc984d50b04f029ef677 (impl: 0xfbacbc...) Total: 44 factories remaining (42 V2 + 3 V3). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove Fraxswap (TWAMM), KingSwap (virtual price), and SafeSwap (LP dilution) as they are not pure CPMMs. Add optional fee parameter to V2 substreams so factories with non-standard fees emit the correct value. Update PepeDex and Linkswap to 25 bps, fork e1046f to 20 bps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assert fee <= 10000 bps after deserialization to catch misconfigured YAML params early instead of silently propagating invalid fee values to the simulation layer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review fixes pushedFee bounds check (
|
| Factory | YAML | Actual On-Chain | Verdict |
|---|---|---|---|
PepeDex (0x460b) |
fee=25 |
25 bps (modified formula: 25/10000) |
YAML correct, PR description wrong |
Linkswap (0x6967) |
fee=25 |
25 bps for LINK pairs, 30 bps for non-LINK | YAML correct for LINK pairs* |
Yape (0x46ad) |
default 30 | 30 bps (standard V2, unchanged) | Default correct, PR description wrong |
| Fork 880ae0 | default 30 | 30 bps (standard V2, RigelSwap) | Default correct, PR description wrong |
*Linkswap uses per-pool variable fees (25 bps for LINK pairs, 30 bps for non-LINK). The current architecture uses one fee per factory, so 25 bps is an approximation.
Fork 7386f6 — intentionally included
PR description says "no pools created yet" — confirmed the YAML is a placeholder for future indexing. No action needed.
Addresses review feedback: 44 individual extractors for low-liquidity forks is a poor indexing_load/coverage ratio. Instead, merge all V2 forks into one extractor (ethereum-univ2-forks.yaml) and all V3 forks into one (ethereum-univ3-forks.yaml). Changes: - V2 map_pools_created now parses comma-separated factory addresses with optional :fee suffix for per-factory fee overrides - V3 map_pools_created now parses comma-separated factory addresses - Delete 39 individual V2 fork YAMLs + 3 V3 fork YAMLs - Create ethereum-univ2-forks.yaml (39 factories, 1 extractor) - Create ethereum-univ3-forks.yaml (3 factories, 1 extractor) - Update all integration tests to reference merged YAMLs - Backward compatible: single-address params still work as before Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merged 42 extractors into 2Addressed the feedback about indexing_load/coverage ratio. Instead of 44 separate extractors (one per fork factory), all forks now share a single extractor per protocol version:
How it worksThe For V2, three factories have non-standard fees (PepeDex 25bps, Linkswap 25bps, fork e1046f 20bps). These are encoded inline with a At event time, the module looks up the emitting factory via For V3, no fee handling is needed since fees come from the Backward compatibilitySingle-address params (used by existing extractors like uniswap-v2, sushiswap, pancakeswap) still work exactly as before — a single address is just a one-element comma-split. What changed
Integration test results — 42/42 pass |
Summary
ethereum-univ2-forks.yaml), all V3 forks share one (ethereum-univ3-forks.yaml), reducing indexing load from 42 extractors to 2map_pools_created: comma-separated factory addresses with optional:feesuffix for per-factory fee overrides (V2), comma-separated addresses (V3)CLONE_TO_BASE_PROTOCOLmappings for all 42 forks inprotocol-testinguniswap_v2_pool/uniswap_v3_poolprotocol types (no changes needed in tycho-simulation or tycho-execution)map_pools_createdassertsfee <= 10000after param deserializationParams format
V2 (query string with multi-factory support):
Addresses without
:feesuffix use the defaultfeeparam (30 bps).V3 (comma-separated addresses):
V3 fees come from the PoolCreated event, so no per-factory fee config needed.
Non-standard fees (3 factories, V2 only)
0x460b2005...25/10000formula0x696708db...0xe1046fcb...Removed factories (4 total)
0x8ff485ee...and0x69bd16ae...(TransparentUpgradeableProxy)0xbaceb8ec...(swap execution reverts)0x7386f6f2...(no pools created yet, included as placeholder)Factories evaluated but not included (3)
Test plan
cargo build --target wasm32-unknown-unknown --release(V2 + V3)cargo test(V2 + V3)cargo checkon protocol-testing with new clone mappings🤖 Generated with Claude Code