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>
This commit is contained in:
7
orig/tools/gas-audit/go.mod
Normal file
7
orig/tools/gas-audit/go.mod
Normal file
@@ -0,0 +1,7 @@
|
||||
module github.com/fraktal/mev-beta/tools/gas-audit
|
||||
|
||||
go 1.24
|
||||
|
||||
replace github.com/fraktal/mev-beta => ../../
|
||||
|
||||
require github.com/fraktal/mev-beta v0.0.0-00010101000000-000000000000
|
||||
577
orig/tools/gas-audit/internal/gas_auditor.go
Normal file
577
orig/tools/gas-audit/internal/gas_auditor.go
Normal file
@@ -0,0 +1,577 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/fraktal/mev-beta/pkg/math"
|
||||
)
|
||||
|
||||
// GasAuditConfig holds configuration for gas auditing
|
||||
type GasAuditConfig struct {
|
||||
Network string
|
||||
GasPrice string
|
||||
ScenariosFile string
|
||||
OutputDir string
|
||||
Verbose bool
|
||||
Tolerance float64 // Percentage tolerance for gas estimation accuracy
|
||||
}
|
||||
|
||||
// GasAuditor audits gas cost estimations and optimizations
|
||||
type GasAuditor struct {
|
||||
config *GasAuditConfig
|
||||
converter *math.DecimalConverter
|
||||
scenarios *GasScenarios
|
||||
results *GasAuditResults
|
||||
}
|
||||
|
||||
// GasScenarios defines test scenarios for gas estimation
|
||||
type GasScenarios struct {
|
||||
Version string `json:"version"`
|
||||
Network string `json:"network"`
|
||||
Scenarios map[string]*GasScenario `json:"scenarios"`
|
||||
}
|
||||
|
||||
// GasScenario represents a gas estimation test case
|
||||
type GasScenario struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Operation string `json:"operation"` // "swap", "arbitrage", "flashloan"
|
||||
Exchange string `json:"exchange"`
|
||||
TokenIn string `json:"token_in"`
|
||||
TokenOut string `json:"token_out"`
|
||||
AmountIn string `json:"amount_in"`
|
||||
ExpectedGasUsed int64 `json:"expected_gas_used"`
|
||||
MaxGasPrice string `json:"max_gas_price"`
|
||||
Priority string `json:"priority"` // "low", "medium", "high"
|
||||
Complexity string `json:"complexity"` // "simple", "medium", "complex"
|
||||
}
|
||||
|
||||
// GasAuditResults holds comprehensive gas audit results
|
||||
type GasAuditResults struct {
|
||||
Network string `json:"network"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
TotalScenarios int `json:"total_scenarios"`
|
||||
PassedScenarios int `json:"passed_scenarios"`
|
||||
FailedScenarios int `json:"failed_scenarios"`
|
||||
AverageGasUsed int64 `json:"average_gas_used"`
|
||||
AverageGasPrice string `json:"average_gas_price"`
|
||||
TotalGasCostETH string `json:"total_gas_cost_eth"`
|
||||
EstimationAccuracy float64 `json:"estimation_accuracy"`
|
||||
ScenarioResults []*GasScenarioResult `json:"scenario_results"`
|
||||
FailedCases []*GasEstimationFailure `json:"failed_cases"`
|
||||
Recommendations []string `json:"recommendations"`
|
||||
Duration time.Duration `json:"duration"`
|
||||
}
|
||||
|
||||
// GasScenarioResult represents the result of a gas estimation test
|
||||
type GasScenarioResult struct {
|
||||
ScenarioName string `json:"scenario_name"`
|
||||
Passed bool `json:"passed"`
|
||||
EstimatedGas int64 `json:"estimated_gas"`
|
||||
ActualGas int64 `json:"actual_gas"`
|
||||
EstimationError float64 `json:"estimation_error_percent"`
|
||||
GasPriceGwei string `json:"gas_price_gwei"`
|
||||
GasCostETH string `json:"gas_cost_eth"`
|
||||
OptimizationSuggestions []string `json:"optimization_suggestions"`
|
||||
Duration time.Duration `json:"duration"`
|
||||
ErrorMessage string `json:"error_message,omitempty"`
|
||||
}
|
||||
|
||||
// GasEstimationFailure represents a failed gas estimation
|
||||
type GasEstimationFailure struct {
|
||||
ScenarioName string `json:"scenario_name"`
|
||||
Reason string `json:"reason"`
|
||||
ExpectedGas int64 `json:"expected_gas"`
|
||||
EstimatedGas int64 `json:"estimated_gas"`
|
||||
ErrorPercent float64 `json:"error_percent"`
|
||||
Severity string `json:"severity"`
|
||||
Impact string `json:"impact"`
|
||||
}
|
||||
|
||||
// NewGasAuditor creates a new gas auditor
|
||||
func NewGasAuditor(config *GasAuditConfig) (*GasAuditor, error) {
|
||||
converter := math.NewDecimalConverter()
|
||||
|
||||
// Load gas scenarios
|
||||
scenarios, err := loadGasScenarios(config.ScenariosFile, config.Network)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load gas scenarios: %w", err)
|
||||
}
|
||||
|
||||
return &GasAuditor{
|
||||
config: config,
|
||||
converter: converter,
|
||||
scenarios: scenarios,
|
||||
results: &GasAuditResults{
|
||||
Network: config.Network,
|
||||
ScenarioResults: []*GasScenarioResult{},
|
||||
FailedCases: []*GasEstimationFailure{},
|
||||
Recommendations: []string{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AuditGasCosts performs comprehensive gas cost auditing
|
||||
func (ga *GasAuditor) AuditGasCosts(ctx context.Context) error {
|
||||
startTime := time.Now()
|
||||
ga.results.Timestamp = startTime
|
||||
|
||||
if ga.config.Verbose {
|
||||
fmt.Printf("Starting gas cost audit for %s network...\n", ga.config.Network)
|
||||
}
|
||||
|
||||
ga.results.TotalScenarios = len(ga.scenarios.Scenarios)
|
||||
var totalGasUsed int64
|
||||
var totalGasCostETH *math.UniversalDecimal
|
||||
|
||||
// Initialize total gas cost
|
||||
totalGasCostETH, _ = math.NewUniversalDecimal(big.NewInt(0), 18, "ETH")
|
||||
|
||||
for name, scenario := range ga.scenarios.Scenarios {
|
||||
result, err := ga.runGasScenario(ctx, name, scenario)
|
||||
if err != nil {
|
||||
if ga.config.Verbose {
|
||||
fmt.Printf(" Failed scenario %s: %v\n", name, err)
|
||||
}
|
||||
|
||||
failure := &GasEstimationFailure{
|
||||
ScenarioName: name,
|
||||
Reason: err.Error(),
|
||||
ExpectedGas: scenario.ExpectedGasUsed,
|
||||
Severity: "high",
|
||||
Impact: "Gas estimation unreliable",
|
||||
}
|
||||
ga.results.FailedCases = append(ga.results.FailedCases, failure)
|
||||
ga.results.FailedScenarios++
|
||||
continue
|
||||
}
|
||||
|
||||
ga.results.ScenarioResults = append(ga.results.ScenarioResults, result)
|
||||
|
||||
if result.Passed {
|
||||
ga.results.PassedScenarios++
|
||||
totalGasUsed += result.EstimatedGas
|
||||
|
||||
// Add to total gas cost
|
||||
scenarioGasCost, _ := ga.converter.FromString(result.GasCostETH, 18, "ETH")
|
||||
totalGasCostETH, _ = ga.converter.Add(totalGasCostETH, scenarioGasCost)
|
||||
} else {
|
||||
ga.results.FailedScenarios++
|
||||
|
||||
failure := &GasEstimationFailure{
|
||||
ScenarioName: name,
|
||||
Reason: result.ErrorMessage,
|
||||
ExpectedGas: scenario.ExpectedGasUsed,
|
||||
EstimatedGas: result.EstimatedGas,
|
||||
ErrorPercent: result.EstimationError,
|
||||
Severity: ga.calculateGasSeverity(result.EstimationError),
|
||||
Impact: ga.calculateGasImpact(result.EstimationError),
|
||||
}
|
||||
ga.results.FailedCases = append(ga.results.FailedCases, failure)
|
||||
}
|
||||
|
||||
if ga.config.Verbose {
|
||||
status := "✓"
|
||||
if !result.Passed {
|
||||
status = "✗"
|
||||
}
|
||||
fmt.Printf(" %s %s: Gas=%d, Cost=%s ETH, Error=%.1f%%\n",
|
||||
status, name, result.EstimatedGas, result.GasCostETH, result.EstimationError)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate summary statistics
|
||||
if ga.results.PassedScenarios > 0 {
|
||||
ga.results.AverageGasUsed = totalGasUsed / int64(ga.results.PassedScenarios)
|
||||
ga.results.EstimationAccuracy = float64(ga.results.PassedScenarios) / float64(ga.results.TotalScenarios) * 100
|
||||
}
|
||||
|
||||
ga.results.TotalGasCostETH = ga.converter.ToHumanReadable(totalGasCostETH)
|
||||
ga.results.Duration = time.Since(startTime)
|
||||
|
||||
// Generate recommendations
|
||||
ga.generateRecommendations()
|
||||
|
||||
if ga.config.Verbose {
|
||||
fmt.Printf("Gas audit completed: %d/%d scenarios passed (%.1f%% accuracy)\n",
|
||||
ga.results.PassedScenarios, ga.results.TotalScenarios, ga.results.EstimationAccuracy)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// runGasScenario executes a single gas estimation scenario
|
||||
func (ga *GasAuditor) runGasScenario(ctx context.Context, name string, scenario *GasScenario) (*GasScenarioResult, error) {
|
||||
startTime := time.Now()
|
||||
|
||||
// Simulate gas estimation based on operation complexity
|
||||
estimatedGas, err := ga.estimateGasForScenario(scenario)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("gas estimation failed: %w", err)
|
||||
}
|
||||
|
||||
// Get current gas price
|
||||
gasPrice, err := ga.getCurrentGasPrice()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get gas price: %w", err)
|
||||
}
|
||||
|
||||
// Calculate gas cost in ETH
|
||||
gasCostWei := new(big.Int).Mul(big.NewInt(estimatedGas), gasPrice)
|
||||
gasCostETH, err := math.NewUniversalDecimal(gasCostWei, 18, "ETH")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to calculate gas cost: %w", err)
|
||||
}
|
||||
|
||||
// Calculate estimation error
|
||||
estimationError := ga.calculateEstimationError(scenario.ExpectedGasUsed, estimatedGas)
|
||||
|
||||
// Determine if estimation is within tolerance
|
||||
passed := estimationError <= ga.config.Tolerance
|
||||
|
||||
// Generate optimization suggestions
|
||||
optimizations := ga.generateOptimizationSuggestions(scenario, estimatedGas)
|
||||
|
||||
result := &GasScenarioResult{
|
||||
ScenarioName: name,
|
||||
Passed: passed,
|
||||
EstimatedGas: estimatedGas,
|
||||
ActualGas: scenario.ExpectedGasUsed,
|
||||
EstimationError: estimationError,
|
||||
GasPriceGwei: ga.weiToGwei(gasPrice),
|
||||
GasCostETH: ga.converter.ToHumanReadable(gasCostETH),
|
||||
OptimizationSuggestions: optimizations,
|
||||
Duration: time.Since(startTime),
|
||||
}
|
||||
|
||||
if !passed {
|
||||
result.ErrorMessage = fmt.Sprintf("Gas estimation error %.1f%% exceeds tolerance %.1f%%",
|
||||
estimationError, ga.config.Tolerance)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// estimateGasForScenario estimates gas for a specific scenario
|
||||
func (ga *GasAuditor) estimateGasForScenario(scenario *GasScenario) (int64, error) {
|
||||
// Base gas costs for different operations
|
||||
baseGas := map[string]int64{
|
||||
"swap": 150000,
|
||||
"arbitrage": 300000,
|
||||
"flashloan": 500000,
|
||||
}
|
||||
|
||||
// Complexity multipliers
|
||||
complexityMultiplier := map[string]float64{
|
||||
"simple": 1.0,
|
||||
"medium": 1.3,
|
||||
"complex": 1.8,
|
||||
}
|
||||
|
||||
// Exchange-specific adjustments
|
||||
exchangeAdjustment := map[string]float64{
|
||||
"uniswap_v2": 1.0,
|
||||
"uniswap_v3": 1.2,
|
||||
"curve": 0.8,
|
||||
"balancer": 1.5,
|
||||
}
|
||||
|
||||
base, exists := baseGas[scenario.Operation]
|
||||
if !exists {
|
||||
return 0, fmt.Errorf("unknown operation: %s", scenario.Operation)
|
||||
}
|
||||
|
||||
complexityMult, exists := complexityMultiplier[scenario.Complexity]
|
||||
if !exists {
|
||||
complexityMult = 1.0
|
||||
}
|
||||
|
||||
exchangeMult, exists := exchangeAdjustment[scenario.Exchange]
|
||||
if !exists {
|
||||
exchangeMult = 1.0
|
||||
}
|
||||
|
||||
// Calculate estimated gas
|
||||
estimated := float64(base) * complexityMult * exchangeMult
|
||||
|
||||
// Add some random variation to simulate real-world conditions
|
||||
variation := 0.9 + (0.2 * 0.5) // ±10% variation
|
||||
estimated *= variation
|
||||
|
||||
return int64(estimated), nil
|
||||
}
|
||||
|
||||
// getCurrentGasPrice returns current gas price for the network
|
||||
func (ga *GasAuditor) getCurrentGasPrice() (*big.Int, error) {
|
||||
// Simulate gas price based on network
|
||||
var gasPriceGwei int64
|
||||
|
||||
switch ga.config.Network {
|
||||
case "arbitrum":
|
||||
gasPriceGwei = 1 // Arbitrum typically has very low gas prices
|
||||
case "ethereum":
|
||||
gasPriceGwei = 20 // Ethereum mainnet
|
||||
default:
|
||||
gasPriceGwei = 10 // Default
|
||||
}
|
||||
|
||||
// Convert gwei to wei
|
||||
gweiToWei := new(big.Int).Exp(big.NewInt(10), big.NewInt(9), nil)
|
||||
gasPrice := new(big.Int).Mul(big.NewInt(gasPriceGwei), gweiToWei)
|
||||
|
||||
return gasPrice, nil
|
||||
}
|
||||
|
||||
// calculateEstimationError calculates the percentage error in gas estimation
|
||||
func (ga *GasAuditor) calculateEstimationError(expected, estimated int64) float64 {
|
||||
if expected == 0 {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
diff := float64(estimated - expected)
|
||||
if diff < 0 {
|
||||
diff = -diff
|
||||
}
|
||||
|
||||
return (diff / float64(expected)) * 100.0
|
||||
}
|
||||
|
||||
// generateOptimizationSuggestions generates gas optimization suggestions
|
||||
func (ga *GasAuditor) generateOptimizationSuggestions(scenario *GasScenario, estimatedGas int64) []string {
|
||||
var suggestions []string
|
||||
|
||||
// High gas usage suggestions
|
||||
if estimatedGas > 400000 {
|
||||
suggestions = append(suggestions, "Consider breaking complex operations into smaller transactions")
|
||||
suggestions = append(suggestions, "Evaluate if flash loans are necessary for this operation")
|
||||
}
|
||||
|
||||
// Exchange-specific suggestions
|
||||
switch scenario.Exchange {
|
||||
case "uniswap_v3":
|
||||
suggestions = append(suggestions, "Consider using single-hop swaps when possible")
|
||||
case "balancer":
|
||||
suggestions = append(suggestions, "Batch multiple operations to amortize gas costs")
|
||||
case "curve":
|
||||
suggestions = append(suggestions, "Leverage Curve's low slippage for stable swaps")
|
||||
}
|
||||
|
||||
// Operation-specific suggestions
|
||||
switch scenario.Operation {
|
||||
case "arbitrage":
|
||||
suggestions = append(suggestions, "Use multicall to bundle swap operations")
|
||||
suggestions = append(suggestions, "Consider gas price optimization strategies")
|
||||
case "flashloan":
|
||||
suggestions = append(suggestions, "Minimize logic in flash loan callback")
|
||||
}
|
||||
|
||||
return suggestions
|
||||
}
|
||||
|
||||
// calculateGasSeverity determines severity of gas estimation error
|
||||
func (ga *GasAuditor) calculateGasSeverity(errorPercent float64) string {
|
||||
switch {
|
||||
case errorPercent > 50:
|
||||
return "critical"
|
||||
case errorPercent > 30:
|
||||
return "high"
|
||||
case errorPercent > 15:
|
||||
return "medium"
|
||||
default:
|
||||
return "low"
|
||||
}
|
||||
}
|
||||
|
||||
// calculateGasImpact determines impact of gas estimation error
|
||||
func (ga *GasAuditor) calculateGasImpact(errorPercent float64) string {
|
||||
switch {
|
||||
case errorPercent > 50:
|
||||
return "Severe profit impact, transactions may fail"
|
||||
case errorPercent > 30:
|
||||
return "Significant profit reduction"
|
||||
case errorPercent > 15:
|
||||
return "Moderate profit impact"
|
||||
default:
|
||||
return "Minimal impact on profitability"
|
||||
}
|
||||
}
|
||||
|
||||
// generateRecommendations generates overall audit recommendations
|
||||
func (ga *GasAuditor) generateRecommendations() {
|
||||
if ga.results.EstimationAccuracy < 80 {
|
||||
ga.results.Recommendations = append(ga.results.Recommendations,
|
||||
"Gas estimation accuracy is below 80%. Consider improving estimation algorithms.")
|
||||
}
|
||||
|
||||
if ga.results.AverageGasUsed > 300000 {
|
||||
ga.results.Recommendations = append(ga.results.Recommendations,
|
||||
"Average gas usage is high. Consider optimizing transaction complexity.")
|
||||
}
|
||||
|
||||
if ga.results.FailedScenarios > ga.results.TotalScenarios/4 {
|
||||
ga.results.Recommendations = append(ga.results.Recommendations,
|
||||
"High failure rate detected. Review gas estimation methodology.")
|
||||
}
|
||||
|
||||
if ga.config.Network == "ethereum" {
|
||||
ga.results.Recommendations = append(ga.results.Recommendations,
|
||||
"Consider implementing EIP-1559 gas price optimization for Ethereum mainnet.")
|
||||
}
|
||||
}
|
||||
|
||||
// MonitorRealTimeGas monitors real-time gas costs and variations
|
||||
func (ga *GasAuditor) MonitorRealTimeGas(ctx context.Context) error {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
fmt.Printf("Monitoring real-time gas costs for %s...\n", ga.config.Network)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
gasPrice, err := ga.getCurrentGasPrice()
|
||||
if err != nil {
|
||||
if ga.config.Verbose {
|
||||
fmt.Printf("Error getting gas price: %v\n", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if ga.config.Verbose {
|
||||
fmt.Printf("[%s] Current gas price: %s gwei\n",
|
||||
time.Now().Format("15:04:05"), ga.weiToGwei(gasPrice))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateReport generates comprehensive gas audit reports
|
||||
func (ga *GasAuditor) GenerateReport() error {
|
||||
// Generate JSON report
|
||||
jsonPath := filepath.Join(ga.config.OutputDir, "gas_audit.json")
|
||||
if err := ga.generateJSONReport(jsonPath); err != nil {
|
||||
return fmt.Errorf("failed to generate JSON report: %w", err)
|
||||
}
|
||||
|
||||
// Generate Markdown report
|
||||
markdownPath := filepath.Join(ga.config.OutputDir, "gas_audit.md")
|
||||
if err := ga.generateMarkdownReport(markdownPath); err != nil {
|
||||
return fmt.Errorf("failed to generate Markdown report: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateJSONReport generates JSON format report
|
||||
func (ga *GasAuditor) generateJSONReport(path string) error {
|
||||
data, err := json.MarshalIndent(ga.results, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(path, data, 0644)
|
||||
}
|
||||
|
||||
// generateMarkdownReport generates Markdown format report
|
||||
func (ga *GasAuditor) generateMarkdownReport(path string) error {
|
||||
content := fmt.Sprintf("# Gas Cost Audit Report\n\n")
|
||||
content += fmt.Sprintf("**Network:** %s\n", ga.results.Network)
|
||||
content += fmt.Sprintf("**Generated:** %s\n\n", ga.results.Timestamp.Format(time.RFC3339))
|
||||
|
||||
content += fmt.Sprintf("## Summary\n\n")
|
||||
content += fmt.Sprintf("- Total Scenarios: %d\n", ga.results.TotalScenarios)
|
||||
content += fmt.Sprintf("- Passed: %d\n", ga.results.PassedScenarios)
|
||||
content += fmt.Sprintf("- Failed: %d\n", ga.results.FailedScenarios)
|
||||
content += fmt.Sprintf("- Estimation Accuracy: %.1f%%\n", ga.results.EstimationAccuracy)
|
||||
content += fmt.Sprintf("- Average Gas Used: %d\n", ga.results.AverageGasUsed)
|
||||
content += fmt.Sprintf("- Total Gas Cost: %s ETH\n\n", ga.results.TotalGasCostETH)
|
||||
|
||||
if len(ga.results.Recommendations) > 0 {
|
||||
content += fmt.Sprintf("## Recommendations\n\n")
|
||||
for _, rec := range ga.results.Recommendations {
|
||||
content += fmt.Sprintf("- %s\n", rec)
|
||||
}
|
||||
content += "\n"
|
||||
}
|
||||
|
||||
return os.WriteFile(path, []byte(content), 0644)
|
||||
}
|
||||
|
||||
// weiToGwei converts wei to gwei for display
|
||||
func (ga *GasAuditor) weiToGwei(wei *big.Int) string {
|
||||
gwei := new(big.Int).Div(wei, big.NewInt(1000000000))
|
||||
return gwei.String()
|
||||
}
|
||||
|
||||
// loadGasScenarios loads gas estimation scenarios
|
||||
func loadGasScenarios(filename, network string) (*GasScenarios, error) {
|
||||
// Create default scenarios if none specified
|
||||
if filename == "default" {
|
||||
return createDefaultGasScenarios(network), nil
|
||||
}
|
||||
|
||||
// TODO: Load from actual file
|
||||
return createDefaultGasScenarios(network), nil
|
||||
}
|
||||
|
||||
// createDefaultGasScenarios creates default gas estimation scenarios
|
||||
func createDefaultGasScenarios(network string) *GasScenarios {
|
||||
scenarios := &GasScenarios{
|
||||
Version: "1.0.0",
|
||||
Network: network,
|
||||
Scenarios: make(map[string]*GasScenario),
|
||||
}
|
||||
|
||||
// Base scenarios
|
||||
scenarios.Scenarios["simple_swap"] = &GasScenario{
|
||||
Name: "simple_swap",
|
||||
Description: "Simple token swap",
|
||||
Operation: "swap",
|
||||
Exchange: "uniswap_v2",
|
||||
TokenIn: "ETH",
|
||||
TokenOut: "USDC",
|
||||
AmountIn: "1000000000000000000",
|
||||
ExpectedGasUsed: 150000,
|
||||
MaxGasPrice: "50000000000",
|
||||
Priority: "medium",
|
||||
Complexity: "simple",
|
||||
}
|
||||
|
||||
scenarios.Scenarios["complex_arbitrage"] = &GasScenario{
|
||||
Name: "complex_arbitrage",
|
||||
Description: "Multi-hop arbitrage",
|
||||
Operation: "arbitrage",
|
||||
Exchange: "uniswap_v3",
|
||||
TokenIn: "ETH",
|
||||
TokenOut: "USDC",
|
||||
AmountIn: "10000000000000000000",
|
||||
ExpectedGasUsed: 400000,
|
||||
MaxGasPrice: "100000000000",
|
||||
Priority: "high",
|
||||
Complexity: "complex",
|
||||
}
|
||||
|
||||
scenarios.Scenarios["flashloan_arbitrage"] = &GasScenario{
|
||||
Name: "flashloan_arbitrage",
|
||||
Description: "Flash loan arbitrage",
|
||||
Operation: "flashloan",
|
||||
Exchange: "balancer",
|
||||
TokenIn: "ETH",
|
||||
TokenOut: "USDC",
|
||||
AmountIn: "100000000000000000000",
|
||||
ExpectedGasUsed: 600000,
|
||||
MaxGasPrice: "150000000000",
|
||||
Priority: "high",
|
||||
Complexity: "complex",
|
||||
}
|
||||
|
||||
return scenarios
|
||||
}
|
||||
67
orig/tools/gas-audit/main.go
Normal file
67
orig/tools/gas-audit/main.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/fraktal/mev-beta/tools/gas-audit/internal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
network = flag.String("network", "arbitrum", "Network to audit (arbitrum, ethereum)")
|
||||
gasPrice = flag.String("gas-price", "auto", "Gas price in gwei (auto for dynamic)")
|
||||
scenarios = flag.String("scenarios", "default", "Gas estimation scenarios")
|
||||
outputDir = flag.String("output", "reports/gas", "Output directory")
|
||||
verbose = flag.Bool("verbose", false, "Enable verbose output")
|
||||
realtime = flag.Bool("realtime", false, "Monitor real-time gas costs")
|
||||
duration = flag.Duration("duration", 5*time.Minute, "Duration for real-time monitoring")
|
||||
tolerance = flag.Float64("tolerance", 15.0, "Gas estimation tolerance percentage")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
// Create output directory
|
||||
if err := os.MkdirAll(*outputDir, 0755); err != nil {
|
||||
log.Fatalf("Failed to create output directory: %v", err)
|
||||
}
|
||||
|
||||
// Initialize gas auditor
|
||||
auditor, err := internal.NewGasAuditor(&internal.GasAuditConfig{
|
||||
Network: *network,
|
||||
GasPrice: *gasPrice,
|
||||
ScenariosFile: *scenarios,
|
||||
OutputDir: *outputDir,
|
||||
Verbose: *verbose,
|
||||
Tolerance: *tolerance,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize gas auditor: %v", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if *realtime {
|
||||
fmt.Printf("Starting real-time gas cost monitoring for %v...\n", *duration)
|
||||
ctx, cancel := context.WithTimeout(ctx, *duration)
|
||||
defer cancel()
|
||||
|
||||
if err := auditor.MonitorRealTimeGas(ctx); err != nil {
|
||||
log.Fatalf("Real-time gas monitoring failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Running gas cost audit for %s network...\n", *network)
|
||||
if err := auditor.AuditGasCosts(ctx); err != nil {
|
||||
log.Fatalf("Gas audit failed: %v", err)
|
||||
}
|
||||
|
||||
if err := auditor.GenerateReport(); err != nil {
|
||||
log.Fatalf("Report generation failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Gas audit complete. Reports saved to: %s\n", *outputDir)
|
||||
}
|
||||
Reference in New Issue
Block a user