Files
mev-beta/orig/tests/calculation-validation/replay.go
Administrator c54c569f30 refactor: move all remaining files to orig/ directory
Completed clean root directory structure:
- Root now contains only: .git, .env, docs/, orig/
- Moved all remaining files and directories to orig/:
  - Config files (.claude, .dockerignore, .drone.yml, etc.)
  - All .env variants (except active .env)
  - Git config (.gitconfig, .github, .gitignore, etc.)
  - Tool configs (.golangci.yml, .revive.toml, etc.)
  - Documentation (*.md files, @prompts)
  - Build files (Dockerfiles, Makefile, go.mod, go.sum)
  - Docker compose files
  - All source directories (scripts, tests, tools, etc.)
  - Runtime directories (logs, monitoring, reports)
  - Dependency files (node_modules, lib, cache)
  - Special files (--delete)

- Removed empty runtime directories (bin/, data/)

V2 structure is now clean:
- docs/planning/ - V2 planning documents
- orig/ - Complete V1 codebase preserved
- .env - Active environment config (not in git)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:53:05 +01:00

263 lines
9.3 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"math/big"
"os"
"path/filepath"
"time"
validation "mev-bot/tests/calculation-validation"
)
func main() {
// Parse command line flags
testDir := flag.String("dir", "tests/calculation-validation", "Test directory containing extracted logs")
tolerance := flag.Float64("tolerance", 1.0, "Tolerance percentage for validation")
verbose := flag.Bool("verbose", false, "Verbose output")
flag.Parse()
fmt.Println("═══════════════════════════════════════════════════════════════════════")
fmt.Println(" MEV Bot - Calculation Replay & Validation Tool")
fmt.Println("═══════════════════════════════════════════════════════════════════════")
fmt.Println()
// Initialize parser and validator
parser := validation.NewLogParser()
validator := validation.NewProfitValidator(*tolerance)
// Define file paths
extractedDir := filepath.Join(*testDir, "extracted")
executableFile := filepath.Join(extractedDir, "executable_opportunities.log")
detailsFile := filepath.Join(extractedDir, "opportunity_details.log")
v3CalcFile := filepath.Join(extractedDir, "v3_calculations.log")
thresholdFile := filepath.Join(extractedDir, "threshold_checks.log")
fmt.Println("📂 Loading test data...")
// Parse executable opportunities
executableOpps, err := parser.ParseExecutableOpportunities(executableFile)
if err != nil {
log.Printf("Warning: Could not parse executable opportunities: %v\n", err)
executableOpps = []*validation.OpportunityTestData{}
}
fmt.Printf(" ✓ Loaded %d executable opportunities\n", len(executableOpps))
// Parse detailed opportunities
detailedOpps, err := parser.ParseOpportunityDetails(detailsFile)
if err != nil {
log.Printf("Warning: Could not parse opportunity details: %v\n", err)
detailedOpps = []*validation.OpportunityTestData{}
}
fmt.Printf(" ✓ Loaded %d detailed opportunities\n", len(detailedOpps))
// Parse V3 calculations
v3Calcs, err := parser.ParseV3Calculations(v3CalcFile)
if err != nil {
log.Printf("Warning: Could not parse V3 calculations: %v\n", err)
v3Calcs = []validation.SwapCalculation{}
}
fmt.Printf(" ✓ Loaded %d V3 calculations\n", len(v3Calcs))
// Parse threshold checks
thresholdChecks, err := parser.ParseThresholdChecks(thresholdFile)
if err != nil {
log.Printf("Warning: Could not parse threshold checks: %v\n", err)
thresholdChecks = []*validation.ThresholdCheck{}
}
fmt.Printf(" ✓ Loaded %d threshold checks\n", len(thresholdChecks))
fmt.Println()
fmt.Println("🔍 Validating calculations...")
fmt.Println()
// Validate executable opportunities
if len(executableOpps) > 0 {
fmt.Println("━━━ Executable Opportunities ━━━")
report := validator.ValidateBatch(executableOpps)
printReport(report, *verbose)
}
// Validate detailed opportunities
if len(detailedOpps) > 0 {
fmt.Println("\n━━━ Detailed Opportunities ━━━")
report := validator.ValidateBatch(detailedOpps)
printReport(report, *verbose)
}
// Validate V3 calculations
if len(v3Calcs) > 0 {
fmt.Println("\n━━━ V3 Swap Calculations ━━━")
validV3 := 0
invalidV3 := 0
warningsV3 := 0
for i, calc := range v3Calcs {
result := validator.ValidateV3Calculation(calc)
if result.IsValid {
validV3++
} else {
invalidV3++
}
if len(result.Warnings) > 0 {
warningsV3++
}
if *verbose && (!result.IsValid || len(result.Warnings) > 0) {
fmt.Printf(" V3 Calc #%d:\n", i+1)
fmt.Printf(" AmountIn: %s\n", calc.AmountIn.String())
fmt.Printf(" AmountOut: %s\n", calc.AmountOut.String())
fmt.Printf(" Fee: %d\n", calc.Fee)
fmt.Printf(" FinalOut: %s\n", calc.FinalOut.String())
if len(result.Errors) > 0 {
fmt.Printf(" ❌ Errors: %v\n", result.Errors)
}
if len(result.Warnings) > 0 {
fmt.Printf(" ⚠️ Warnings: %v\n", result.Warnings)
}
}
}
fmt.Printf(" Total: %d\n", len(v3Calcs))
fmt.Printf(" ✅ Valid: %d\n", validV3)
fmt.Printf(" ❌ Invalid: %d\n", invalidV3)
fmt.Printf(" ⚠️ Warnings: %d\n", warningsV3)
}
// Validate threshold checks
if len(thresholdChecks) > 0 {
fmt.Println("\n━━━ Profit Threshold Checks ━━━")
validThresholds := 0
invalidThresholds := 0
for i, check := range thresholdChecks {
// Validate the threshold comparison logic
wasExecutable := check.Passed
result := validator.ValidateThresholdComparison(
check.NetProfit,
big.NewInt(100000000000000), // 0.0001 ETH in wei (default threshold)
wasExecutable,
)
if result.IsValid {
validThresholds++
} else {
invalidThresholds++
if *verbose {
fmt.Printf(" ❌ Threshold Check #%d FAILED:\n", i+1)
fmt.Printf(" Net Profit: %s ETH\n", check.NetProfit.String())
fmt.Printf(" Min Threshold: %s ETH\n", check.MinThreshold.String())
fmt.Printf(" Marked Executable: %v\n", wasExecutable)
fmt.Printf(" Errors: %v\n", result.Errors)
}
}
}
fmt.Printf(" Total: %d\n", len(thresholdChecks))
fmt.Printf(" ✅ Valid: %d\n", validThresholds)
fmt.Printf(" ❌ Invalid: %d\n", invalidThresholds)
fmt.Printf(" Success Rate: %.2f%%\n", float64(validThresholds)/float64(len(thresholdChecks))*100)
}
// Calculate and display profit statistics
if len(executableOpps) > 0 {
fmt.Println("\n━━━ Profit Statistics ━━━")
profits := validation.ExtractProfitValues(executableOpps)
total, average, max, min := validation.CalculateStatistics(profits)
totalFloat, _ := total.Float64()
avgFloat, _ := average.Float64()
maxFloat, _ := max.Float64()
minFloat, _ := min.Float64()
fmt.Printf(" Total Profit: %.6f ETH\n", totalFloat)
fmt.Printf(" Average Profit: %.6f ETH\n", avgFloat)
fmt.Printf(" Maximum Profit: %.6f ETH\n", maxFloat)
fmt.Printf(" Minimum Profit: %.6f ETH\n", minFloat)
fmt.Printf(" Opportunities: %d\n", len(profits))
}
// Test the CRITICAL bug fix
fmt.Println("\n━━━ Critical Bug Fix Validation ━━━")
testCriticalBugFix(validator)
fmt.Println()
fmt.Println("═══════════════════════════════════════════════════════════════════════")
fmt.Println(" Validation Complete!")
fmt.Println("═══════════════════════════════════════════════════════════════════════")
}
func printReport(report *validation.TestReport, verbose bool) {
fmt.Printf(" Total: %d\n", report.TotalOpportunities)
fmt.Printf(" ✅ Valid: %d\n", report.ValidCalculations)
fmt.Printf(" ❌ Invalid: %d\n", report.InvalidCalculations)
fmt.Printf(" Success Rate: %.2f%%\n", float64(report.ValidCalculations)/float64(report.TotalOpportunities)*100)
if verbose {
for _, result := range report.ValidationResults {
if !result.IsValid || len(result.Warnings) > 0 {
fmt.Printf("\n Opportunity: %s\n", result.OpportunityID)
if len(result.Errors) > 0 {
fmt.Printf(" ❌ Errors: %v\n", result.Errors)
}
if len(result.Warnings) > 0 {
fmt.Printf(" ⚠️ Warnings: %v\n", result.Warnings)
}
}
}
}
}
func testCriticalBugFix(validator *validation.ProfitValidator) {
// Test the exact bug scenario: 834.210302 ETH profit vs 0.0001 ETH threshold
netProfit := big.NewFloat(834.210302)
minThresholdWei := big.NewInt(100000000000000) // 0.0001 ETH in wei
fmt.Println(" Testing bug fix scenario:")
fmt.Printf(" Net Profit: %.6f ETH\n", mustFloat64(netProfit))
fmt.Printf(" Min Threshold: 0.0001 ETH (100000000000000 wei)\n")
// Before fix: netProfit.Int(nil) would return 834, comparing 834 < 100000000000000 = FALSE (rejected)
// After fix: Should compare 834.210302 >= 0.0001 = TRUE (executable)
result := validator.ValidateThresholdComparison(netProfit, minThresholdWei, true)
if result.IsValid {
fmt.Println(" ✅ BUG FIX VALIDATED: Correctly marked as executable")
} else {
fmt.Println(" ❌ BUG FIX FAILED: Incorrectly rejected")
fmt.Printf(" Errors: %v\n", result.Errors)
}
// Test edge case: profit exactly at threshold
edgeProfit := big.NewFloat(0.0001)
edgeResult := validator.ValidateThresholdComparison(edgeProfit, minThresholdWei, true)
fmt.Println("\n Testing edge case (profit == threshold):")
fmt.Printf(" Net Profit: %.6f ETH\n", mustFloat64(edgeProfit))
if edgeResult.IsValid {
fmt.Println(" ✅ Edge case handled correctly")
} else {
fmt.Println(" ❌ Edge case failed")
}
// Test rejection case: profit below threshold
lowProfit := big.NewFloat(0.00001)
lowResult := validator.ValidateThresholdComparison(lowProfit, minThresholdWei, false)
fmt.Println("\n Testing rejection case (profit < threshold):")
fmt.Printf(" Net Profit: %.6f ETH\n", mustFloat64(lowProfit))
if lowResult.IsValid {
fmt.Println(" ✅ Correctly rejected")
} else {
fmt.Println(" ❌ Should have been rejected")
}
}
func mustFloat64(f *big.Float) float64 {
val, _ := f.Float64()
return val
}