Restructured project for V2 refactor: **Structure Changes:** - Moved all V1 code to orig/ folder (preserved with git mv) - Created docs/planning/ directory - Added orig/README_V1.md explaining V1 preservation **Planning Documents:** - 00_V2_MASTER_PLAN.md: Complete architecture overview - Executive summary of critical V1 issues - High-level component architecture diagrams - 5-phase implementation roadmap - Success metrics and risk mitigation - 07_TASK_BREAKDOWN.md: Atomic task breakdown - 99+ hours of detailed tasks - Every task < 2 hours (atomic) - Clear dependencies and success criteria - Organized by implementation phase **V2 Key Improvements:** - Per-exchange parsers (factory pattern) - Multi-layer strict validation - Multi-index pool cache - Background validation pipeline - Comprehensive observability **Critical Issues Addressed:** - Zero address tokens (strict validation + cache enrichment) - Parsing accuracy (protocol-specific parsers) - No audit trail (background validation channel) - Inefficient lookups (multi-index cache) - Stats disconnection (event-driven metrics) Next Steps: 1. Review planning documents 2. Begin Phase 1: Foundation (P1-001 through P1-010) 3. Implement parsers in Phase 2 4. Build cache system in Phase 3 5. Add validation pipeline in Phase 4 6. Migrate and test in Phase 5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
31 KiB
MEV Bot V2 - Detailed Task Breakdown
How to Use This Document
Each task is broken down into the smallest possible actionable unit. Tasks are:
- Atomic: Can be completed in one sitting (< 2 hours)
- Testable: Has clear success criteria
- Independent: Minimal dependencies on other incomplete tasks
Task Format:
### [PHASE-ID-NUMBER] Task Title
**Est**: X hours
**Dependencies**: [ID, ID, ...]
**Success Criteria**:
- Criterion 1
- Criterion 2
**Steps**:
1. Step 1
2. Step 2
Phase 1: Foundation
[P1-001] Create V2 Directory Structure
Est: 0.5 hours Dependencies: None Success Criteria:
- All directories created as per master plan
- README.md in each major directory
.gitkeepfiles where needed
Steps:
- Create
cmd/mev-bot/directory - Create
pkg/parsers/directory - Create
pkg/validation/directory - Create
pkg/cache/directory - Create
pkg/discovery/directory - Create
pkg/monitor/directory - Create
pkg/events/directory - Create
pkg/arbitrage/directory - Create
pkg/observability/directory - Create
tests/unit/directory - Create
tests/integration/directory - Create
tests/e2e/directory - Add README.md to each directory
[P1-002] Define Event Types
Est: 1 hour Dependencies: [P1-001] Success Criteria:
- Event type constants defined
- Event struct with all fields
- String methods for debugging
- Unit tests for type conversions
Steps:
- Create
pkg/events/types.go - Define
EventTypeconstants (Swap, Mint, Burn, etc.) - Define
Eventstruct with fields:- Type
- Protocol
- PoolAddress
- Token0, Token1
- Amount0In, Amount0Out
- Amount1In, Amount1Out
- Sender, Recipient
- TxHash, BlockNumber, LogIndex
- Timestamp
- Add
String()method to EventType - Add validation helper methods
- Write unit tests
[P1-003] Define Parser Interface
Est: 0.5 hours Dependencies: [P1-002] Success Criteria:
- Interface defined with all methods
- Documentation for each method
- Mock implementation for testing
Steps:
- Create
pkg/parsers/interface.go - Define
Parserinterface:type Parser interface { ParseLog(log *types.Log, tx *types.Transaction) (*Event, error) ParseReceipt(receipt *types.Receipt, tx *types.Transaction) ([]*Event, error) SupportedProtocols() []Protocol ValidateEvent(event *Event) error } - Add comprehensive documentation
- Create
pkg/parsers/mock_parser_test.go - Implement mock for unit tests
[P1-004] Define PoolCache Interface
Est: 0.5 hours Dependencies: None Success Criteria:
- Interface defined
- All lookup methods specified
- Documentation complete
Steps:
- Create
pkg/cache/interface.go - Define
PoolCacheinterface:type PoolCache interface { Get(address common.Address) (*PoolInfo, error) GetByTokenPair(token0, token1 common.Address) ([]*PoolInfo, error) GetByProtocol(protocol Protocol) ([]*PoolInfo, error) GetTopByLiquidity(limit int) ([]*PoolInfo, error) Add(pool *PoolInfo) error Update(address common.Address, pool *PoolInfo) error Remove(address common.Address) error Size() int } - Document each method
- Create mock implementation
[P1-005] Define Validator Interface
Est: 0.5 hours Dependencies: [P1-002] Success Criteria:
- Interface defined
- Rule types specified
- Documentation complete
Steps:
- Create
pkg/validation/interface.go - Define
Validatorinterface:type Validator interface { Validate(event *Event) ValidationResult AddRule(rule ValidationRule) RemoveRule(name string) GetMetrics() ValidationMetrics } - Define
ValidationRuleinterface - Define
ValidationResultstruct - Document everything
[P1-006] Setup Logging Infrastructure
Est: 1.5 hours Dependencies: None Success Criteria:
- Structured logger wrapping slog
- Log levels (Debug, Info, Warn, Error)
- Context support
- JSON and text formatters
- Unit tests
Steps:
- Create
pkg/observability/logger.go - Define
Loggerstruct wrapping*slog.Logger - Add methods: Debug(), Info(), Warn(), Error(), Fatal()
- Add WithContext() for context support
- Add WithFields() for structured fields
- Create constructor
NewLogger(level, format string) - Write unit tests for each log level
- Write test for JSON vs text formatting
[P1-007] Setup Metrics Infrastructure
Est: 2 hours Dependencies: None Success Criteria:
- Prometheus metrics integration
- Counter, Gauge, Histogram, Summary types
- Metric registration
- HTTP endpoint for scraping
- Unit tests
Steps:
- Create
pkg/observability/metrics.go - Add prometheus dependency:
go get github.com/prometheus/client_golang/prometheus - Create
MetricsRegistrystruct - Implement Counter registration and increment
- Implement Gauge registration and set/inc/dec
- Implement Histogram registration and observe
- Implement Summary registration and observe
- Create HTTP handler for
/metricsendpoint - Write unit tests for each metric type
- Write integration test for scraping
[P1-008] Define PoolInfo Struct
Est: 0.5 hours Dependencies: None Success Criteria:
- Complete struct definition
- All necessary fields
- Validation methods
- Unit tests
Steps:
- Create
pkg/cache/pool_info.go - Define
PoolInfostruct:type PoolInfo struct { Address common.Address Protocol Protocol PoolType PoolType Factory common.Address Token0 common.Address Token1 common.Address Token0Decimals uint8 Token1Decimals uint8 Fee uint32 TickSpacing uint32 Liquidity *big.Int CreatedBlock uint64 CreatedTx common.Hash LastUpdated time.Time } - Add
Validate()method - Add
IsValid()helper - Write unit tests
[P1-009] Setup Connection Manager
Est: 2 hours Dependencies: [P1-006] Success Criteria:
- RPC connection pooling
- Automatic reconnection
- Health checks
- Failover support
- Unit tests
Steps:
- Create
pkg/monitor/connection.go - Define
ConnectionManagerstruct - Implement connection pool (max 5 connections)
- Add
GetConnection()with round-robin - Add
HealthCheck()for connection testing - Implement automatic reconnection on failure
- Add failover to backup endpoints
- Add circuit breaker pattern
- Write unit tests for each failure scenario
- Write integration test with real endpoint
[P1-010] Create Base Test Framework
Est: 1 hour Dependencies: None Success Criteria:
- Test utilities created
- Mock data generators
- Assertion helpers
- Test fixtures
Steps:
- Create
tests/testutil/helpers.go - Add
CreateMockLog()function - Add
CreateMockTransaction()function - Add
CreateMockReceipt()function - Add
CreateMockEvent()function - Add
AssertEventEquals()helper - Add
AssertNoError()helper - Create
tests/fixtures/directory - Add sample log JSON files
- Add sample transaction JSON files
- Write tests for test helpers
Phase 2: Parser Refactor
[P2-001] Create Parser Factory
Est: 1 hour Dependencies: [P1-003] Success Criteria:
- Factory pattern implementation
- Parser registration
- Parser selection by protocol
- Unit tests
Steps:
- Create
pkg/parsers/factory.go - Define
ParserFactorystruct - Add
Register(protocol Protocol, parser Parser)method - Add
GetParser(protocol Protocol) (Parser, error)method - Add
GetParserForLog(log *types.Log) (Parser, error)method - Create global registry instance
- Write unit tests for registration
- Write unit tests for retrieval
- Write test for unknown protocol handling
[P2-002] Implement UniswapV2 Parser - Base Structure
Est: 1 hour Dependencies: [P1-003, P2-001] Success Criteria:
- Struct defined
- Constructor implemented
- Interface methods stubbed
- Compiles without errors
Steps:
- Create
pkg/parsers/uniswap_v2.go - Define
UniswapV2Parserstruct:type UniswapV2Parser struct { logger *Logger cache PoolCache } - Implement
NewUniswapV2Parser(logger, cache)constructor - Stub
ParseLog(log, tx)- return nil, nil - Stub
ParseReceipt(receipt, tx)- return nil, nil - Implement
SupportedProtocols()- return []Protocol{ProtocolUniswapV2} - Stub
ValidateEvent(event)- return nil - Register in factory init function
- Write basic constructor test
[P2-003] UniswapV2 Parser - Parse Swap Event
Est: 2 hours Dependencies: [P2-002] Success Criteria:
- Swap event signature recognized
- Amounts decoded correctly
- Event struct populated
- Unit tests with real log data
Steps:
- Define Swap event signature constant
- Add signature recognition in
ParseLog() - Implement ABI decoding for Swap event:
- sender (address)
- amount0In (uint256)
- amount1In (uint256)
- amount0Out (uint256)
- amount1Out (uint256)
- to (address)
- Create Event struct from decoded data
- Set event type to EventTypeSwap
- Set protocol to ProtocolUniswapV2
- Extract pool address from log.Address
- Write unit test with sample Swap log
- Write test with zero amounts (should handle)
- Write test with invalid log (should error)
[P2-004] UniswapV2 Parser - Extract Token Addresses
Est: 1.5 hours Dependencies: [P2-003] Success Criteria:
- Tokens extracted from pool cache
- Fallback to RPC if cache miss
- Zero addresses handled
- Unit tests
Steps:
- Add
getPoolTokens(poolAddress)helper method - Check pool cache first:
cache.Get(poolAddress) - If found, return cached Token0 and Token1
- If not found, query RPC (use multicall):
- Call
pool.token0() - Call
pool.token1()
- Call
- Handle RPC errors gracefully
- If both fail, return zero addresses with error
- Update event with token addresses
- Write unit test with cache hit
- Write unit test with cache miss + RPC success
- Write unit test with cache miss + RPC failure
- Write test for zero address detection
[P2-005] UniswapV2 Parser - Validate Swap Event
Est: 1 hour Dependencies: [P2-004] Success Criteria:
- All validation rules implemented
- Invalid events rejected
- Unit tests for each rule
Steps:
- Implement
ValidateEvent(event *Event) errormethod - Check: Token0 != zero address
- Check: Token1 != zero address
- Check: PoolAddress != zero address
- Check: NOT (Amount0In == 0 AND Amount0Out == 0)
- Check: NOT (Amount1In == 0 AND Amount1Out == 0)
- Check: Sender != zero address
- Check: Recipient != zero address
- Return detailed error for each failure
- Write unit test for each validation rule
- Write test for valid event (should pass)
[P2-006] UniswapV2 Parser - Parse Mint Event
Est: 1.5 hours Dependencies: [P2-003] Success Criteria:
- Mint event signature recognized
- Liquidity amounts decoded
- Event struct populated
- Unit tests
Steps:
- Define Mint event signature constant
- Add signature recognition in
ParseLog() - Implement ABI decoding for Mint event:
- sender (address)
- amount0 (uint256)
- amount1 (uint256)
- Create Event struct from decoded data
- Set event type to EventTypeMint
- Extract token addresses using existing helper
- Write unit test with sample Mint log
- Write validation test
- Integration test with Swap parsing
[P2-007] UniswapV2 Parser - Parse Burn Event
Est: 1.5 hours Dependencies: [P2-006] Success Criteria:
- Burn event signature recognized
- Withdrawal amounts decoded
- Event struct populated
- Unit tests
Steps:
- Define Burn event signature constant
- Add signature recognition in
ParseLog() - Implement ABI decoding for Burn event:
- sender (address)
- amount0 (uint256)
- amount1 (uint256)
- to (address)
- Create Event struct from decoded data
- Set event type to EventTypeBurn
- Extract token addresses
- Write unit test with sample Burn log
- Write validation test
[P2-008] UniswapV2 Parser - ParseReceipt Implementation
Est: 1 hour Dependencies: [P2-007] Success Criteria:
- All logs in receipt parsed
- Multiple events handled
- Transaction context available
- Unit tests
Steps:
- Implement
ParseReceipt(receipt, tx)method - Loop through
receipt.Logs - Call
ParseLog(log, tx)for each - Collect all non-nil events
- Return event slice
- Handle errors gracefully (log, don't fail)
- Write test with single event
- Write test with multiple events
- Write test with mixed event types
- Write test with invalid logs
[P2-009] UniswapV2 Parser - Integration Tests
Est: 1.5 hours Dependencies: [P2-008] Success Criteria:
- Real transaction tested
- All event types covered
- Edge cases tested
- Arbiscan data validated
Steps:
- Find real UniswapV2 transaction on Arbiscan
- Download transaction JSON
- Download receipt JSON
- Create integration test fixture
- Parse transaction using parser
- Assert correct number of events
- Assert event details match Arbiscan
- Test with multicall transaction
- Test with failed transaction
- Verify no zero addresses in output
[P2-010] Implement UniswapV3 Parser - Base Structure
Est: 1 hour Dependencies: [P1-003, P2-001] Success Criteria:
- Struct defined
- Constructor implemented
- Interface methods stubbed
Steps: (Similar to P2-002 but for UniswapV3)
- Create
pkg/parsers/uniswap_v3.go - Define
UniswapV3Parserstruct - Implement constructor
- Stub interface methods
- Register in factory
- Write basic test
[P2-011] UniswapV3 Parser - Parse Swap Event
Est: 2.5 hours Dependencies: [P2-010] Success Criteria:
- V3 Swap event decoded
- Tick and sqrtPrice captured
- Amounts calculated correctly
- Unit tests
Steps:
- Define V3 Swap event signature
- Implement ABI decoding for V3 Swap:
- sender (address)
- recipient (address)
- amount0 (int256) - note: signed!
- amount1 (int256) - note: signed!
- sqrtPriceX96 (uint160)
- liquidity (uint128)
- tick (int24)
- Convert signed amounts to In/Out format
- Handle negative amounts (indicate direction)
- Extract token addresses from pool cache
- Create Event struct
- Write unit test with sample V3 Swap log
- Write test for each swap direction
- Write test for zero liquidity edge case
- Validate against real Arbiscan transaction
[P2-012] UniswapV3 Parser - Extract Tokens from Transaction
Est: 2 hours Dependencies: [P2-011] Success Criteria:
- Tokens extracted from calldata
- Router calls decoded
- Multi-hop swaps handled
- Unit tests
Steps:
- Add
extractTokensFromCalldata(tx)helper - Recognize SwapRouter signatures:
- exactInputSingle
- exactOutputSingle
- exactInput (multi-hop)
- exactOutput (multi-hop)
- Decode token path from params
- Match pool address to correct token pair
- Handle multi-hop by splitting path
- Fallback to pool cache if calldata unavailable
- Write test for single-hop swap
- Write test for multi-hop swap
- Write test for failed decoding
- Integration test with real transaction
[P2-013] UniswapV3 Parser - Parse Mint Event
Est: 1.5 hours Dependencies: [P2-011] Success Criteria:
- V3 Mint event decoded
- Liquidity and tick range captured
- Unit tests
Steps:
- Define V3 Mint event signature
- Implement ABI decoding:
- sender (address)
- owner (address)
- tickLower (int24)
- tickUpper (int24)
- amount (uint128)
- amount0 (uint256)
- amount1 (uint256)
- Create Event struct
- Write unit tests
- Validate amounts match
[P2-014] UniswapV3 Parser - Parse Burn Event
Est: 1.5 hours Dependencies: [P2-013] Success Criteria:
- V3 Burn event decoded
- Liquidity removal captured
- Unit tests
Steps: (Similar structure to P2-013 but for Burn)
- Define V3 Burn signature
- Implement ABI decoding
- Create Event struct
- Write unit tests
[P2-015] UniswapV3 Parser - Integration Tests
Est: 2 hours Dependencies: [P2-014] Success Criteria:
- Real V3 transactions tested
- Multi-hop swaps validated
- No zero addresses
Steps:
- Find real V3 swap on Arbiscan
- Find real V3 multi-hop swap
- Download fixtures
- Parse and validate
- Assert zero-free outputs
- Performance benchmark
[P2-016-025] Implement SushiSwap, Camelot, Curve Parsers
Est: 8-10 hours each Dependencies: [P2-001, P2-009, P2-015] Success Criteria:
- Each parser follows same pattern as Uniswap
- All event types supported
- Comprehensive tests
- Zero address guarantees
Steps: (Replicate P2-002 through P2-009 for each exchange)
- SushiSwap is V2-like, reuse much of UniswapV2 logic
- Camelot has V2 and V3 variants
- Curve has unique stable swap math
Phase 3: Cache System
[P3-001] Implement Address Index
Est: 2 hours Dependencies: [P1-004, P1-008] Success Criteria:
- O(1) lookup by address
- Thread-safe
- Add/Update/Remove operations
- Unit tests
Steps:
- Create
pkg/cache/index_by_address.go - Define
AddressIndexstruct:type AddressIndex struct { pools map[common.Address]*PoolInfo mu sync.RWMutex } - Implement
Get(address)with RLock - Implement
Add(pool)with Lock - Implement
Update(address, pool)with Lock - Implement
Remove(address)with Lock - Implement
Size()method - Write unit test for each operation
- Write concurrency test (multiple goroutines)
- Benchmark lookup performance
[P3-002] Implement Token-Pair Index
Est: 2.5 hours Dependencies: [P3-001] Success Criteria:
- O(1) lookup by token pair
- Handles token order (A-B == B-A)
- Thread-safe
- Unit tests
Steps:
- Create
pkg/cache/index_by_tokens.go - Define
TokenPairIndexstruct:type TokenPairIndex struct { pools map[string][]*PoolInfo // key: "token0-token1" sorted mu sync.RWMutex } - Add
makeKey(token0, token1)helper (sorts addresses) - Implement
Get(token0, token1)with RLock - Implement
Add(pool)- add to both token orders - Implement
Update(pool) - Implement
Remove(pool) - Write unit test for token order independence
- Write test for multiple pools per pair
- Benchmark lookup performance
[P3-003] Implement Liquidity Index
Est: 2 hours Dependencies: [P3-001] Success Criteria:
- Pools sorted by liquidity
- Fast top-N retrieval
- Auto-reorder on updates
- Unit tests
Steps:
- Create
pkg/cache/index_by_liquidity.go - Define
LiquidityIndexstruct:type LiquidityIndex struct { pools []*PoolInfo // sorted by liquidity desc mu sync.RWMutex } - Implement
GetTop(limit)with RLock - Implement
Add(pool)- insert in sorted position - Implement
Update(pool)- remove and re-insert - Implement
Remove(pool)- binary search and remove - Use binary search for efficient insertion
- Write unit test for sorting
- Write test for top-N retrieval
- Benchmark insertion and lookup
[P3-004] Implement Protocol Index
Est: 1.5 hours Dependencies: [P3-001] Success Criteria:
- Fast lookup by protocol
- Multiple protocols per pool
- Thread-safe
- Unit tests
Steps:
- Create
pkg/cache/index_by_protocol.go - Define
ProtocolIndexstruct:type ProtocolIndex struct { pools map[Protocol][]*PoolInfo mu sync.RWMutex } - Implement
Get(protocol)with RLock - Implement
Add(pool)with Lock - Implement
Update(pool)with Lock - Implement
Remove(pool)with Lock - Write unit test for each protocol
- Write test for unknown protocol
- Benchmark lookup
[P3-005] Implement Multi-Index PoolCache
Est: 3 hours Dependencies: [P3-001, P3-002, P3-003, P3-004] Success Criteria:
- All indexes integrated
- Consistent updates across all indexes
- Thread-safe
- Unit tests
Steps:
- Create
pkg/cache/pool_cache.go - Define
PoolCachestruct:type PoolCache struct { addressIndex *AddressIndex tokenPairIndex *TokenPairIndex liquidityIndex *LiquidityIndex protocolIndex *ProtocolIndex mu sync.RWMutex } - Implement
Get(address)- delegate to addressIndex - Implement
GetByTokenPair(t0, t1)- delegate - Implement
GetByProtocol(proto)- delegate - Implement
GetTopByLiquidity(limit)- delegate - Implement
Add(pool)- update ALL indexes atomically - Implement
Update(address, pool)- update ALL indexes - Implement
Remove(address)- remove from ALL indexes - Write unit test for consistency across indexes
- Write concurrency test
- Benchmark full cache operations
[P3-006] Implement Cache Persistence
Est: 2 hours Dependencies: [P3-005] Success Criteria:
- Save cache to disk
- Load cache from disk
- JSON format
- Corruption handling
Steps:
- Add
SaveToFile(path string)method - Marshal all pools to JSON
- Write atomically (temp file + rename)
- Add
LoadFromFile(path string)method - Read JSON from disk
- Unmarshal pools
- Rebuild all indexes
- Handle file not found gracefully
- Handle corrupted JSON
- Write unit test for save/load round-trip
- Write test for corruption recovery
[P3-007] Implement Cache TTL and Eviction
Est: 2 hours Dependencies: [P3-005] Success Criteria:
- Pools have TTL
- Auto-eviction of expired pools
- Background cleanup goroutine
- Unit tests
Steps:
- Add
LastUpdated time.Timeto PoolInfo - Add
ttl time.Durationto PoolCache config - Add
StartCleanup()method - launch goroutine - Implement cleanup loop (every 5 minutes):
- Lock cache
- Find expired pools
- Remove from all indexes
- Log evictions
- Add
StopCleanup()method - stop goroutine - Write unit test with short TTL
- Write test for cleanup goroutine
- Write test for manual cleanup trigger
Phase 4: Validation Pipeline
[P4-001] Implement Validation Rules
Est: 2 hours Dependencies: [P1-005] Success Criteria:
- Rule interface implemented
- Built-in rules created
- Composable rules
- Unit tests
Steps:
- Create
pkg/validation/rules.go - Implement
ValidationRuleinterface:type ValidationRule interface { Name() string Validate(event *Event) error } - Implement
ZeroAddressRule- check Token0, Token1, Pool - Implement
ZeroAmountRule- check amounts not all zero - Implement
PoolCacheRule- validate against cache - Implement
CompositeRule- combine multiple rules - Write unit test for each rule
- Write test for rule composition
[P4-002] Implement Event Validator
Est: 2 hours Dependencies: [P4-001] Success Criteria:
- Validator struct
- Rule registration
- Validation execution
- Detailed error messages
Steps:
- Create
pkg/validation/validator.go - Define
EventValidatorstruct:type EventValidator struct { rules map[string]ValidationRule mu sync.RWMutex } - Implement
AddRule(rule) - Implement
RemoveRule(name) - Implement
Validate(event):- Run all rules
- Collect errors
- Return ValidationResult
- Define
ValidationResultstruct:type ValidationResult struct { Valid bool Errors []ValidationError } - Write unit test for validation
- Write test for multiple rules
- Write test for error collection
[P4-003] Implement Validation Metrics
Est: 1.5 hours Dependencies: [P4-002, P1-007] Success Criteria:
- Metrics for validation results
- Counters for each rule
- Histogram for validation time
- Unit tests
Steps:
- Create
pkg/validation/metrics.go - Define metrics:
validation_totalcounter (label: result=pass/fail)validation_rule_failurescounter (label: rule_name)validation_duration_secondshistogram
- Add
RecordValidation(result, duration)method - Add
RecordRuleFailure(ruleName)method - Integrate metrics into EventValidator
- Write unit test for metrics recording
- Write integration test with Prometheus
[P4-004] Implement Background Validation Channel
Est: 2 hours Dependencies: [P4-002] Success Criteria:
- Channel for async validation
- Background goroutine
- Discrepancy logging
- Unit tests
Steps:
- Create
pkg/validation/background.go - Define
BackgroundValidatorstruct:type BackgroundValidator struct { validationChan chan *ValidationRequest cache PoolCache logger *Logger stopChan chan struct{} } - Define
ValidationRequeststruct:type ValidationRequest struct { Event *Event ParsedData *ParsedPoolData CachedData *PoolInfo } - Implement
Start()method - launch goroutine - Implement validation loop:
- Receive from validationChan
- Compare parsed vs cached
- Log discrepancies
- Update metrics
- Implement
Stop()method - Implement
Submit(req)method - Write unit test for comparison logic
- Write test for goroutine lifecycle
- Write test for channel backpressure
[P4-005] Implement Discrepancy Logger
Est: 1.5 hours Dependencies: [P4-004] Success Criteria:
- Structured discrepancy logs
- JSON output
- Queryable fields
- Unit tests
Steps:
- Add
LogDiscrepancy(event, field, parsed, cached)to BackgroundValidator - Create structured log entry:
{ "timestamp": "", "event_type": "", "pool": "", "field": "", "parsed_value": "", "cached_value": "", "tx_hash": "" } - Write to dedicated log file
validation_discrepancies.log - Add log rotation
- Write unit test for log format
- Write test for file writing
- Integration test reading log back
[P4-006] Implement Validation Alerts
Est: 2 hours Dependencies: [P4-003, P4-005] Success Criteria:
- Alert thresholds configurable
- Email/Slack notification
- Alert deduplication
- Unit tests
Steps:
- Create
pkg/validation/alerts.go - Define
AlertManagerstruct:type AlertManager struct { thresholds map[string]float64 notifiers []Notifier mu sync.RWMutex } - Define
Notifierinterface:type Notifier interface { Notify(alert Alert) error } - Implement
EmailNotifier - Implement
SlackNotifier - Add threshold checking in validator
- Implement alert deduplication (1 per hour)
- Write unit test for threshold detection
- Write test for notifier integration
- Write test for deduplication
[P4-007] Integration Test - Validation Pipeline
Est: 2 hours Dependencies: [P4-001 through P4-006] Success Criteria:
- End-to-end validation flow
- Real event data
- All components integrated
- Performance benchmarks
Steps:
- Create test with real Uniswap transaction
- Parse event with parser
- Validate with EventValidator
- Submit to BackgroundValidator
- Assert discrepancies logged
- Assert metrics recorded
- Verify alerts not triggered (good data)
- Test with intentionally bad data
- Verify alerts triggered
- Benchmark full pipeline
Phase 5: Migration & Testing
[P5-001] Create V1/V2 Comparison Harness
Est: 3 hours Dependencies: [P2-025, P4-007] Success Criteria:
- Run V1 and V2 parsers in parallel
- Compare outputs
- Log differences
- Statistical analysis
Steps:
- Create
tests/migration/comparison_test.go - Load 1000 real transactions
- Parse with V1 parser
- Parse with V2 parser
- Compare events:
- Count
- Event types
- Addresses
- Amounts
- Log all differences
- Calculate metrics:
- Agreement rate
- V2 improvements (zero addresses eliminated)
- Performance difference
- Generate comparison report
- Identify regressions
- Create visual diff tool
[P5-002] Load Testing
Est: 2 hours Dependencies: [P5-001] Success Criteria:
- 10,000 events/second throughput
- Latency < 10ms p99
- No memory leaks
- CPU usage acceptable
Steps:
- Create
tests/load/load_test.go - Generate synthetic event stream
- Feed to V2 pipeline
- Measure throughput
- Measure latency (p50, p95, p99)
- Profile memory usage
- Profile CPU usage
- Identify bottlenecks
- Optimize hot paths
- Re-test and verify improvements
[P5-003] Chaos Testing
Est: 3 hours Dependencies: [P5-002] Success Criteria:
- System survives RPC failures
- Graceful degradation
- Automatic recovery
- No data loss
Steps:
- Create
tests/chaos/chaos_test.go - Test scenario: RPC connection drops
- Test scenario: RPC returns errors
- Test scenario: Cache corruption
- Test scenario: High memory pressure
- Test scenario: Concurrent load
- Test scenario: Malformed event data
- Verify circuit breakers activate
- Verify automatic reconnection
- Verify event replay from checkpoint
[P5-004] Create Migration Plan
Est: 2 hours Dependencies: [P5-003] Success Criteria:
- Step-by-step migration guide
- Rollback procedure
- Monitoring checklist
- Risk assessment
Steps:
- Create
docs/MIGRATION_PLAN.md - Document prerequisites
- Document migration steps:
- Deploy V2 alongside V1
- Enable V2 shadow mode (no writes)
- Monitor for 24 hours
- Compare outputs
- Gradually increase V2 traffic
- Full cutover
- Document rollback procedure
- Create monitoring dashboard
- Define success criteria
- Define rollback triggers
- Document post-migration tasks
- Review with team
- Get approval
[P5-005] Production Deployment
Est: 4 hours Dependencies: [P5-004] Success Criteria:
- V2 deployed to production
- Monitoring active
- No regressions
- Performance improved
Steps:
- Create deployment branch
- Run full test suite
- Deploy to staging
- Smoke test staging
- Enable shadow mode in production
- Monitor for 2 hours
- Compare V1 vs V2 outputs
- Gradual traffic shift (10% -> 50% -> 100%)
- Full cutover to V2
- Decommission V1 after 7 days
Task Dependencies Visualization
Phase 1: Foundation
[P1-001] -> [P1-002] -> [P1-003] -> [P2-001]
-> [P1-005] -> [P4-001]
[P1-006] -> All phases
[P1-007] -> [P4-003]
[P1-004] -> [P1-008] -> [P3-001]
[P1-009] -> [P2-002]
[P1-010] -> All test tasks
Phase 2: Parsers
[P2-001] -> [P2-002] -> ... -> [P2-009] (UniswapV2)
-> [P2-010] -> ... -> [P2-015] (UniswapV3)
-> [P2-016] -> ... (SushiSwap, Camelot, Curve)
Phase 3: Cache
[P3-001] -> [P3-002], [P3-003], [P3-004]
-> [P3-005] -> [P3-006], [P3-007]
Phase 4: Validation
[P4-001] -> [P4-002] -> [P4-003]
-> [P4-004] -> [P4-005]
[P4-003], [P4-005] -> [P4-006]
All Phase 4 -> [P4-007]
Phase 5: Migration
All phases -> [P5-001] -> [P5-002] -> [P5-003] -> [P5-004] -> [P5-005]
Estimation Summary
- Phase 1: ~11 hours
- Phase 2: ~45 hours (all parsers)
- Phase 3: ~16 hours
- Phase 4: ~13 hours
- Phase 5: ~14 hours
Total: ~99 hours (approximately 12-13 working days for 1 developer)
With parallel work and multiple developers, target 4-6 weeks total.
Document Status: Detailed Task Breakdown Created: 2025-11-10 Last Updated: 2025-11-10 Version: 1.0