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:
143
orig/examples/marketmanager/main.go
Normal file
143
orig/examples/marketmanager/main.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/fraktal/mev-beta/pkg/marketmanager"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a new market manager
|
||||
config := &marketmanager.MarketManagerConfig{
|
||||
VerificationWindow: 500 * time.Millisecond,
|
||||
MaxMarkets: 1000,
|
||||
}
|
||||
|
||||
manager := marketmanager.NewMarketManager(config)
|
||||
|
||||
// Create some sample markets
|
||||
market1 := marketmanager.NewMarket(
|
||||
common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"), // Uniswap V3 Factory
|
||||
common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"), // USDC/WETH 0.3% Pool
|
||||
common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC
|
||||
common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH
|
||||
3000, // 0.3% fee
|
||||
"USDC_WETH",
|
||||
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
"UniswapV3",
|
||||
)
|
||||
|
||||
// Set price data for market1
|
||||
market1.UpdatePriceData(
|
||||
big.NewFloat(2000.0), // Price: 2000 USDC per WETH
|
||||
big.NewInt(1000000000000000000), // Liquidity: 1 ETH
|
||||
big.NewInt(2505414483750470000), // sqrtPriceX96
|
||||
200000, // Tick
|
||||
)
|
||||
|
||||
// Set metadata for market1
|
||||
market1.UpdateMetadata(
|
||||
time.Now().Unix(),
|
||||
12345678,
|
||||
common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"),
|
||||
marketmanager.StatusConfirmed,
|
||||
)
|
||||
|
||||
// Create another market with a different price
|
||||
market2 := marketmanager.NewMarket(
|
||||
common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"), // Uniswap V3 Factory
|
||||
common.HexToAddress("0xC6962004f452bE9203591991D15f6b388e09E8D0"), // USDC/WETH 0.05% Pool
|
||||
common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC
|
||||
common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH
|
||||
500, // 0.05% fee
|
||||
"USDC_WETH",
|
||||
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
"UniswapV3",
|
||||
)
|
||||
|
||||
// Set price data for market2 (slightly higher price)
|
||||
market2.UpdatePriceData(
|
||||
big.NewFloat(2010.0), // Price: 2010 USDC per WETH
|
||||
big.NewInt(500000000000000000), // Liquidity: 0.5 ETH
|
||||
big.NewInt(2511697847297280000), // sqrtPriceX96
|
||||
200500, // Tick
|
||||
)
|
||||
|
||||
// Set metadata for market2
|
||||
market2.UpdateMetadata(
|
||||
time.Now().Unix(),
|
||||
12345679,
|
||||
common.HexToHash("0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"),
|
||||
marketmanager.StatusConfirmed,
|
||||
)
|
||||
|
||||
// Add markets to manager
|
||||
fmt.Println("Adding markets to manager...")
|
||||
manager.AddMarket(market1)
|
||||
manager.AddMarket(market2)
|
||||
|
||||
// Get markets by raw ticker
|
||||
fmt.Println("\nGetting markets by raw ticker...")
|
||||
markets, err := manager.GetMarketsByRawTicker("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting markets: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Found %d markets for raw ticker\n", len(markets))
|
||||
|
||||
// Create arbitrage detector
|
||||
minProfit := big.NewInt(10000000000000000) // 0.01 ETH minimum profit
|
||||
minROI := 0.1 // 0.1% minimum ROI
|
||||
detector := marketmanager.NewArbitrageDetector(minProfit, minROI)
|
||||
|
||||
// Detect arbitrage opportunities
|
||||
fmt.Println("\nDetecting arbitrage opportunities...")
|
||||
opportunities := detector.DetectArbitrageOpportunities(markets)
|
||||
|
||||
fmt.Printf("Found %d arbitrage opportunities\n", len(opportunities))
|
||||
|
||||
// Display opportunities
|
||||
for i, opportunity := range opportunities {
|
||||
fmt.Printf("\nOpportunity %d:\n", i+1)
|
||||
fmt.Printf(" Path: %s -> %s\n", opportunity.Path[0], opportunity.Path[1])
|
||||
fmt.Printf(" Input Amount: %s wei\n", opportunity.AmountIn.String())
|
||||
fmt.Printf(" Profit: %s wei\n", opportunity.Profit.String())
|
||||
fmt.Printf(" Gas Estimate: %s wei\n", opportunity.GasEstimate.String())
|
||||
fmt.Printf(" ROI: %.2f%%\n", opportunity.ROI)
|
||||
}
|
||||
|
||||
// Show market counts
|
||||
fmt.Printf("\nTotal markets in manager: %d\n", manager.GetMarketCount())
|
||||
fmt.Printf("Total unique raw tickers: %d\n", manager.GetRawTickerCount())
|
||||
|
||||
// Demonstrate market updates
|
||||
fmt.Println("\nUpdating market price...")
|
||||
market1.UpdatePriceData(
|
||||
big.NewFloat(2005.0), // New price
|
||||
market1.Liquidity, // Same liquidity
|
||||
big.NewInt(2508556165523880000), // New sqrtPriceX96
|
||||
200250, // New tick
|
||||
)
|
||||
|
||||
err = manager.UpdateMarket(market1)
|
||||
if err != nil {
|
||||
fmt.Printf("Error updating market: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Market updated successfully")
|
||||
|
||||
// Get updated market
|
||||
updatedMarket, err := manager.GetMarket(market1.RawTicker, market1.Key)
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting updated market: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Updated market price: %s\n", updatedMarket.Price.Text('f', -1))
|
||||
}
|
||||
306
orig/examples/profitability_calculator.go
Normal file
306
orig/examples/profitability_calculator.go
Normal file
@@ -0,0 +1,306 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// ProfitabilityCalculator performs detailed MEV bot profitability analysis
|
||||
type ProfitabilityCalculator struct {
|
||||
// Market parameters
|
||||
dailyArbitrageVolume float64 // USD
|
||||
averageOpportunitySize float64 // USD
|
||||
marketSharePercentage float64 // 0-100
|
||||
successRate float64 // 0-1
|
||||
averageProfitMargin float64 // 0-1
|
||||
|
||||
// Cost parameters
|
||||
gasPerTransaction float64 // USD
|
||||
infrastructureCostMonthly float64 // USD
|
||||
developmentCostMonthly float64 // USD
|
||||
capitalRequirement float64 // USD
|
||||
|
||||
// Competition parameters
|
||||
competitionLevel float64 // 0-1 (0 = no competition, 1 = intense)
|
||||
gasPremiumFactor float64 // Gas multiplier due to competition
|
||||
|
||||
// Risk parameters
|
||||
maxDailyLoss float64 // USD
|
||||
slippageImpact float64 // 0-1
|
||||
failureRate float64 // 0-1
|
||||
}
|
||||
|
||||
// ProfitabilityResults contains the results of profitability analysis
|
||||
type ProfitabilityResults struct {
|
||||
// Revenue metrics
|
||||
DailyOpportunities int
|
||||
DailyGrossRevenue float64
|
||||
DailyNetRevenue float64
|
||||
MonthlyNetProfit float64
|
||||
AnnualNetProfit float64
|
||||
|
||||
// Cost metrics
|
||||
DailyGasCosts float64
|
||||
MonthlyOperatingCosts float64
|
||||
AnnualOperatingCosts float64
|
||||
|
||||
// Performance metrics
|
||||
ROIPercentage float64
|
||||
BreakEvenDays int
|
||||
ProfitPerTrade float64
|
||||
|
||||
// Risk metrics
|
||||
MaxDrawdownDaily float64
|
||||
WorstCaseScenario float64
|
||||
ProfitabilityScore float64 // 0-100
|
||||
}
|
||||
|
||||
// NewProfitabilityCalculator creates a calculator with Arbitrum L2 defaults
|
||||
func NewProfitabilityCalculator() *ProfitabilityCalculator {
|
||||
return &ProfitabilityCalculator{
|
||||
// Realistic Arbitrum market estimates
|
||||
dailyArbitrageVolume: 2000000, // $2M daily arbitrage volume
|
||||
averageOpportunitySize: 100, // $100 average opportunity
|
||||
marketSharePercentage: 1.0, // 1% market capture (realistic)
|
||||
successRate: 0.75, // 75% success rate
|
||||
averageProfitMargin: 0.015, // 1.5% average profit margin
|
||||
|
||||
// Arbitrum L2 cost structure (much lower than Ethereum)
|
||||
gasPerTransaction: 0.25, // $0.25 average gas per transaction
|
||||
infrastructureCostMonthly: 800, // $800/month infrastructure
|
||||
developmentCostMonthly: 3000, // $3000/month development equivalent
|
||||
capitalRequirement: 5000, // $5000 working capital
|
||||
|
||||
// Competition assumptions
|
||||
competitionLevel: 0.6, // Moderate competition
|
||||
gasPremiumFactor: 1.2, // 20% gas premium for priority
|
||||
|
||||
// Risk parameters
|
||||
maxDailyLoss: 500, // $500 max daily loss
|
||||
slippageImpact: 0.002, // 0.2% slippage impact
|
||||
failureRate: 0.15, // 15% transaction failure rate
|
||||
}
|
||||
}
|
||||
|
||||
// CalculateProfitability performs comprehensive profitability analysis
|
||||
func (pc *ProfitabilityCalculator) CalculateProfitability() *ProfitabilityResults {
|
||||
// Calculate daily opportunities
|
||||
marketValue := pc.dailyArbitrageVolume * (pc.marketSharePercentage / 100)
|
||||
dailyOpportunities := int(marketValue / pc.averageOpportunitySize)
|
||||
|
||||
// Calculate successful trades
|
||||
successfulTrades := float64(dailyOpportunities) * pc.successRate
|
||||
|
||||
// Calculate gross revenue
|
||||
grossProfitPerTrade := pc.averageOpportunitySize * pc.averageProfitMargin
|
||||
dailyGrossRevenue := successfulTrades * grossProfitPerTrade
|
||||
|
||||
// Apply competition impact
|
||||
competitionReduction := pc.competitionLevel * 0.3 // 30% max reduction
|
||||
dailyGrossRevenue *= (1 - competitionReduction)
|
||||
|
||||
// Apply slippage impact
|
||||
dailyGrossRevenue *= (1 - pc.slippageImpact)
|
||||
|
||||
// Calculate costs
|
||||
dailyGasCosts := successfulTrades * pc.gasPerTransaction * pc.gasPremiumFactor
|
||||
|
||||
// Add failed transaction costs
|
||||
failedTrades := float64(dailyOpportunities) * pc.failureRate
|
||||
dailyGasCosts += failedTrades * pc.gasPerTransaction * 0.5 // Partial gas on failure
|
||||
|
||||
// Calculate net revenue
|
||||
dailyNetRevenue := dailyGrossRevenue - dailyGasCosts
|
||||
|
||||
// Monthly calculations
|
||||
monthlyGrossRevenue := dailyGrossRevenue * 30
|
||||
monthlyGasCosts := dailyGasCosts * 30
|
||||
monthlyOperatingCosts := monthlyGasCosts + pc.infrastructureCostMonthly + pc.developmentCostMonthly
|
||||
monthlyNetProfit := monthlyGrossRevenue - monthlyOperatingCosts
|
||||
|
||||
// Annual calculations
|
||||
annualNetProfit := monthlyNetProfit * 12
|
||||
annualOperatingCosts := monthlyOperatingCosts * 12
|
||||
|
||||
// ROI calculation
|
||||
roiPercentage := (annualNetProfit / pc.capitalRequirement) * 100
|
||||
|
||||
// Break-even calculation
|
||||
breakEvenDays := int(pc.capitalRequirement / math.Max(dailyNetRevenue, 1))
|
||||
|
||||
// Profit per trade
|
||||
profitPerTrade := dailyNetRevenue / successfulTrades
|
||||
|
||||
// Risk calculations
|
||||
maxDrawdownDaily := math.Min(pc.maxDailyLoss, dailyNetRevenue*0.5)
|
||||
worstCaseScenario := monthlyNetProfit * 0.3 // 70% reduction scenario
|
||||
|
||||
// Profitability score (0-100)
|
||||
profitabilityScore := pc.calculateProfitabilityScore(roiPercentage, float64(breakEvenDays), profitPerTrade)
|
||||
|
||||
return &ProfitabilityResults{
|
||||
DailyOpportunities: dailyOpportunities,
|
||||
DailyGrossRevenue: dailyGrossRevenue,
|
||||
DailyNetRevenue: dailyNetRevenue,
|
||||
MonthlyNetProfit: monthlyNetProfit,
|
||||
AnnualNetProfit: annualNetProfit,
|
||||
DailyGasCosts: dailyGasCosts,
|
||||
MonthlyOperatingCosts: monthlyOperatingCosts,
|
||||
AnnualOperatingCosts: annualOperatingCosts,
|
||||
ROIPercentage: roiPercentage,
|
||||
BreakEvenDays: breakEvenDays,
|
||||
ProfitPerTrade: profitPerTrade,
|
||||
MaxDrawdownDaily: maxDrawdownDaily,
|
||||
WorstCaseScenario: worstCaseScenario,
|
||||
ProfitabilityScore: profitabilityScore,
|
||||
}
|
||||
}
|
||||
|
||||
// calculateProfitabilityScore creates a composite score for profitability
|
||||
func (pc *ProfitabilityCalculator) calculateProfitabilityScore(roi, breakEven float64, profitPerTrade float64) float64 {
|
||||
// ROI component (0-40 points)
|
||||
roiScore := math.Min(roi/10, 40) // 10% ROI = 1 point, capped at 40
|
||||
|
||||
// Break-even component (0-30 points)
|
||||
breakEvenScore := math.Max(30-(breakEven/2), 0) // Faster break-even = higher score
|
||||
|
||||
// Profit per trade component (0-30 points)
|
||||
profitScore := math.Min(profitPerTrade*3, 30) // $10 per trade = 30 points
|
||||
|
||||
return roiScore + breakEvenScore + profitScore
|
||||
}
|
||||
|
||||
// RunScenarioAnalysis runs multiple scenarios for sensitivity analysis
|
||||
func (pc *ProfitabilityCalculator) RunScenarioAnalysis() map[string]*ProfitabilityResults {
|
||||
scenarios := make(map[string]*ProfitabilityResults)
|
||||
|
||||
// Store original values
|
||||
originalSuccess := pc.successRate
|
||||
originalCompetition := pc.competitionLevel
|
||||
originalMarketShare := pc.marketSharePercentage
|
||||
|
||||
// Conservative scenario
|
||||
pc.successRate = 0.65
|
||||
pc.competitionLevel = 0.8
|
||||
pc.marketSharePercentage = 1.5
|
||||
scenarios["Conservative"] = pc.CalculateProfitability()
|
||||
|
||||
// Moderate scenario
|
||||
pc.successRate = 0.75
|
||||
pc.competitionLevel = 0.6
|
||||
pc.marketSharePercentage = 2.5
|
||||
scenarios["Moderate"] = pc.CalculateProfitability()
|
||||
|
||||
// Optimistic scenario
|
||||
pc.successRate = 0.85
|
||||
pc.competitionLevel = 0.4
|
||||
pc.marketSharePercentage = 4.0
|
||||
scenarios["Optimistic"] = pc.CalculateProfitability()
|
||||
|
||||
// Restore original values
|
||||
pc.successRate = originalSuccess
|
||||
pc.competitionLevel = originalCompetition
|
||||
pc.marketSharePercentage = originalMarketShare
|
||||
|
||||
return scenarios
|
||||
}
|
||||
|
||||
// PrintDetailedReport prints a comprehensive profitability report
|
||||
func PrintDetailedReport(results *ProfitabilityResults, scenario string) {
|
||||
fmt.Printf("\n=== %s SCENARIO PROFITABILITY REPORT ===\n", scenario)
|
||||
fmt.Printf("📊 REVENUE METRICS:\n")
|
||||
fmt.Printf(" Daily Opportunities: %d\n", results.DailyOpportunities)
|
||||
fmt.Printf(" Daily Gross Revenue: $%.2f\n", results.DailyGrossRevenue)
|
||||
fmt.Printf(" Daily Net Revenue: $%.2f\n", results.DailyNetRevenue)
|
||||
fmt.Printf(" Monthly Net Profit: $%.2f\n", results.MonthlyNetProfit)
|
||||
fmt.Printf(" Annual Net Profit: $%.2f\n", results.AnnualNetProfit)
|
||||
|
||||
fmt.Printf("\n💸 COST METRICS:\n")
|
||||
fmt.Printf(" Daily Gas Costs: $%.2f\n", results.DailyGasCosts)
|
||||
fmt.Printf(" Monthly Operating Costs: $%.2f\n", results.MonthlyOperatingCosts)
|
||||
fmt.Printf(" Annual Operating Costs: $%.2f\n", results.AnnualOperatingCosts)
|
||||
|
||||
fmt.Printf("\n📈 PERFORMANCE METRICS:\n")
|
||||
fmt.Printf(" ROI Percentage: %.1f%%\n", results.ROIPercentage)
|
||||
fmt.Printf(" Break-even Days: %d\n", results.BreakEvenDays)
|
||||
fmt.Printf(" Profit per Trade: $%.2f\n", results.ProfitPerTrade)
|
||||
|
||||
fmt.Printf("\n⚠️ RISK METRICS:\n")
|
||||
fmt.Printf(" Max Daily Drawdown: $%.2f\n", results.MaxDrawdownDaily)
|
||||
fmt.Printf(" Worst Case Monthly: $%.2f\n", results.WorstCaseScenario)
|
||||
fmt.Printf(" Profitability Score: %.1f/100\n", results.ProfitabilityScore)
|
||||
}
|
||||
|
||||
// GetProfitabilityGrade returns a letter grade based on profitability score
|
||||
func GetProfitabilityGrade(score float64) string {
|
||||
switch {
|
||||
case score >= 90:
|
||||
return "A+ (Exceptional)"
|
||||
case score >= 80:
|
||||
return "A (Excellent)"
|
||||
case score >= 70:
|
||||
return "B+ (Very Good)"
|
||||
case score >= 60:
|
||||
return "B (Good)"
|
||||
case score >= 50:
|
||||
return "C+ (Fair)"
|
||||
case score >= 40:
|
||||
return "C (Marginal)"
|
||||
default:
|
||||
return "D (Poor)"
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("🏦 MEV Bot Profitability Calculator")
|
||||
fmt.Println("=====================================")
|
||||
|
||||
calculator := NewProfitabilityCalculator()
|
||||
|
||||
// Run base scenario
|
||||
fmt.Println("\n🎯 BASE SCENARIO ANALYSIS:")
|
||||
baseResults := calculator.CalculateProfitability()
|
||||
PrintDetailedReport(baseResults, "BASE")
|
||||
|
||||
// Run scenario analysis
|
||||
fmt.Println("\n🔄 SCENARIO SENSITIVITY ANALYSIS:")
|
||||
scenarios := calculator.RunScenarioAnalysis()
|
||||
|
||||
for scenario, results := range scenarios {
|
||||
PrintDetailedReport(results, scenario)
|
||||
fmt.Printf(" Profitability Grade: %s\n", GetProfitabilityGrade(results.ProfitabilityScore))
|
||||
}
|
||||
|
||||
// Summary comparison
|
||||
fmt.Println("\n📋 SCENARIO COMPARISON SUMMARY:")
|
||||
fmt.Println("Scenario | Annual Profit | ROI | Break-even | Grade")
|
||||
fmt.Println("------------- | ------------- | ------ | ---------- | -----")
|
||||
|
||||
for scenario, results := range scenarios {
|
||||
fmt.Printf("%-13s | $%11.0f | %5.1f%% | %8d d | %s\n",
|
||||
scenario,
|
||||
results.AnnualNetProfit,
|
||||
results.ROIPercentage,
|
||||
results.BreakEvenDays,
|
||||
GetProfitabilityGrade(results.ProfitabilityScore))
|
||||
}
|
||||
|
||||
// Investment recommendation
|
||||
fmt.Println("\n💡 INVESTMENT RECOMMENDATION:")
|
||||
avgROI := (scenarios["Conservative"].ROIPercentage +
|
||||
scenarios["Moderate"].ROIPercentage +
|
||||
scenarios["Optimistic"].ROIPercentage) / 3
|
||||
|
||||
if avgROI > 200 {
|
||||
fmt.Println("🟢 HIGHLY RECOMMENDED - Exceptional returns with manageable risk")
|
||||
} else if avgROI > 100 {
|
||||
fmt.Println("🟡 RECOMMENDED - Good returns, monitor competition carefully")
|
||||
} else if avgROI > 50 {
|
||||
fmt.Println("🟠 PROCEED WITH CAUTION - Moderate returns, higher risk")
|
||||
} else {
|
||||
fmt.Println("🔴 NOT RECOMMENDED - Returns too low for risk level")
|
||||
}
|
||||
|
||||
fmt.Printf("\nAverage ROI across scenarios: %.1f%%\n", avgROI)
|
||||
fmt.Printf("Risk-adjusted recommendation: Deploy with conservative parameters\n")
|
||||
}
|
||||
214
orig/examples/profitability_demo.go
Normal file
214
orig/examples/profitability_demo.go
Normal file
@@ -0,0 +1,214 @@
|
||||
// Package main demonstrates MEV bot profitability calculations
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/fraktal/mev-beta/pkg/math"
|
||||
)
|
||||
|
||||
// Uncomment the main function below to run this demo
|
||||
// func main() {
|
||||
// runProfitabilityDemo()
|
||||
// }
|
||||
|
||||
func runProfitabilityDemo() {
|
||||
fmt.Println("=== MEV Bot Profitability Demonstration ===")
|
||||
fmt.Println()
|
||||
|
||||
// Create a decimal converter for handling different denominations
|
||||
dc := math.NewDecimalConverter()
|
||||
|
||||
// Example 1: Basic arbitrage calculation
|
||||
fmt.Println("1. Basic Arbitrage Profitability:")
|
||||
|
||||
// Simulate a trade: 1 ETH -> USDC -> DAI -> ETH
|
||||
inputETH, _ := dc.FromString("1.0", 18, "ETH")
|
||||
|
||||
// Exchange rates (simplified for demonstration)
|
||||
// 1 ETH = 3000 USDC
|
||||
usdcPerETH, _ := dc.FromString("3000.0", 6, "USDC")
|
||||
usdcAmount, _ := dc.Multiply(inputETH, usdcPerETH, 6, "USDC")
|
||||
|
||||
// 1 USDC = 0.999 DAI (0.1% slippage)
|
||||
daiPerUSDC, _ := dc.FromString("0.999", 18, "DAI")
|
||||
daiAmount, _ := dc.Multiply(usdcAmount, daiPerUSDC, 18, "DAI")
|
||||
|
||||
// 1 DAI = 0.000333 ETH (slightly less than 1/3000 due to slippage)
|
||||
ethPerDAI, _ := dc.FromString("0.000333", 18, "ETH")
|
||||
outputETH, _ := dc.Multiply(daiAmount, ethPerDAI, 18, "ETH")
|
||||
|
||||
fmt.Printf(" Input: %s ETH\n", formatDecimal(inputETH))
|
||||
fmt.Printf(" Route: ETH -> USDC -> DAI -> ETH\n")
|
||||
fmt.Printf(" Output: %s ETH\n", formatDecimal(outputETH))
|
||||
|
||||
// Calculate gross profit
|
||||
grossProfit, _ := dc.Subtract(outputETH, inputETH)
|
||||
fmt.Printf(" Gross Profit: %s ETH\n", formatDecimal(grossProfit))
|
||||
|
||||
// Estimate gas costs (0.001 ETH for a 3-hop arbitrage)
|
||||
gasCost, _ := dc.FromString("0.001", 18, "ETH")
|
||||
netProfit, _ := dc.Subtract(grossProfit, gasCost)
|
||||
fmt.Printf(" Gas Cost: %s ETH\n", formatDecimal(gasCost))
|
||||
fmt.Printf(" Net Profit: %s ETH\n", formatDecimal(netProfit))
|
||||
|
||||
profitPercentage, _ := dc.CalculatePercentage(netProfit, inputETH)
|
||||
fmt.Printf(" Profit Percentage: %s%%\n", formatDecimal(profitabilityToPercentage(profitPercentage)))
|
||||
|
||||
// Check if profitable (minimum 0.01 ETH profit)
|
||||
minProfit, _ := dc.FromString("0.01", 18, "ETH")
|
||||
isProfitable := netProfit.Value.Cmp(minProfit.Value) > 0
|
||||
fmt.Printf(" Is Profitable (>0.01 ETH)? %t\n", isProfitable)
|
||||
fmt.Println()
|
||||
|
||||
// Example 2: Price impact analysis
|
||||
fmt.Println("2. Price Impact Analysis:")
|
||||
|
||||
// Simulate large trade affecting pool price
|
||||
poolLiquidity, _ := dc.FromString("1000.0", 18, "ETH")
|
||||
tradeSize, _ := dc.FromString("50.0", 18, "ETH")
|
||||
|
||||
// Price impact = (tradeSize / (tradeSize + liquidity))^2
|
||||
// Simplified calculation for demonstration
|
||||
priceImpact := calculateSimplePriceImpact(tradeSize, poolLiquidity)
|
||||
fmt.Printf(" Pool Liquidity: %s ETH\n", formatDecimal(poolLiquidity))
|
||||
fmt.Printf(" Trade Size: %s ETH\n", formatDecimal(tradeSize))
|
||||
fmt.Printf(" Price Impact: %.2f%%\n", priceImpact*100)
|
||||
|
||||
// High price impact increases slippage and reduces profitability
|
||||
fmt.Println(" Note: High price impact leads to increased slippage and reduced profitability")
|
||||
fmt.Println()
|
||||
|
||||
// Example 3: Gas cost formatting demonstrations
|
||||
fmt.Println("3. Gas Cost Formatting Examples:")
|
||||
weiAmount := big.NewInt(1000000000000000000) // 1 ETH in wei
|
||||
fmt.Printf(" Wei amount: %s\n", weiAmount.String())
|
||||
fmt.Printf(" Formatted as ETH: %s\n", formatEtherFromWei(weiAmount))
|
||||
fmt.Printf(" Formatted as Gwei: %s\n", formatGweiFromWei(weiAmount))
|
||||
fmt.Printf(" Direct ether format: %s\n", formatEther(big.NewFloat(1.0)))
|
||||
fmt.Println()
|
||||
|
||||
// Example 4: Risk assessment
|
||||
fmt.Println("4. Key Profitability Factors:")
|
||||
|
||||
fmt.Println(" • Accurate price calculations and slippage modeling")
|
||||
fmt.Println(" • Realistic gas cost estimation")
|
||||
fmt.Println(" • Competition analysis for optimal bidding")
|
||||
fmt.Println(" • Risk assessment to avoid unprofitable opportunities")
|
||||
fmt.Println(" • Proper sizing to balance profits and price impact")
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// Helper function to format decimals for display
|
||||
func formatDecimal(d *math.UniversalDecimal) string {
|
||||
if d == nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
// Convert to float for easier formatting
|
||||
f := new(big.Float).SetInt(d.Value)
|
||||
f.Quo(f, big.NewFloat(float64(power(10, int(d.Decimals)))))
|
||||
|
||||
// Format based on symbol
|
||||
switch d.Symbol {
|
||||
case "PERCENT":
|
||||
return fmt.Sprintf("%.2f", mustFloat64(f))
|
||||
case "ETH":
|
||||
return fmt.Sprintf("%.6f", mustFloat64(f))
|
||||
case "USDC", "DAI":
|
||||
return fmt.Sprintf("%.2f", mustFloat64(f))
|
||||
default:
|
||||
return fmt.Sprintf("%.4f", mustFloat64(f))
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to convert profitability percentage to readable format
|
||||
func profitabilityToPercentage(d *math.UniversalDecimal) *math.UniversalDecimal {
|
||||
if d == nil {
|
||||
return &math.UniversalDecimal{Value: big.NewInt(0), Decimals: 2, Symbol: "PERCENT"}
|
||||
}
|
||||
|
||||
// Convert from decimal to percentage (multiply by 100)
|
||||
f := new(big.Float).SetInt(d.Value)
|
||||
f.Quo(f, big.NewFloat(float64(power(10, int(d.Decimals)))))
|
||||
f.Mul(f, big.NewFloat(100))
|
||||
|
||||
// Convert back to big.Int with 2 decimal places
|
||||
result := big.NewInt(0)
|
||||
f.Mul(f, big.NewFloat(100)).Int(result)
|
||||
|
||||
return &math.UniversalDecimal{Value: result, Decimals: 2, Symbol: "PERCENT"}
|
||||
}
|
||||
|
||||
// Simple price impact calculation
|
||||
func calculateSimplePriceImpact(tradeSize, liquidity *math.UniversalDecimal) float64 {
|
||||
// Price impact = tradeSize / (tradeSize + liquidity)
|
||||
// This is a simplified model
|
||||
|
||||
if liquidity.Value.Sign() == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
ratio := new(big.Float).Quo(
|
||||
new(big.Float).SetInt(tradeSize.Value),
|
||||
new(big.Float).SetInt(liquidity.Value),
|
||||
)
|
||||
|
||||
// Square the ratio for concentrated liquidity impact
|
||||
result := new(big.Float).Mul(ratio, ratio)
|
||||
|
||||
f, _ := result.Float64()
|
||||
return f
|
||||
}
|
||||
|
||||
// Helper function for integer powers
|
||||
func power(base, exp int) int {
|
||||
result := 1
|
||||
for i := 0; i < exp; i++ {
|
||||
result *= base
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Helper function to convert big.Float to float64
|
||||
func mustFloat64(f *big.Float) float64 {
|
||||
if f == nil {
|
||||
return 0
|
||||
}
|
||||
result, _ := f.Float64()
|
||||
return result
|
||||
}
|
||||
|
||||
// formatEther formats a big.Float as ETH
|
||||
func formatEther(amount *big.Float) string {
|
||||
if amount == nil {
|
||||
return "0 ETH"
|
||||
}
|
||||
f, _ := amount.Float64()
|
||||
return fmt.Sprintf("%.6f ETH", f)
|
||||
}
|
||||
|
||||
// formatEtherFromWei formats wei amount as ETH
|
||||
func formatEtherFromWei(wei *big.Int) string {
|
||||
if wei == nil {
|
||||
return "0 ETH"
|
||||
}
|
||||
// Convert wei to ETH (divide by 10^18)
|
||||
eth := new(big.Float).SetInt(wei)
|
||||
eth.Quo(eth, big.NewFloat(1e18))
|
||||
f, _ := eth.Float64()
|
||||
return fmt.Sprintf("%.6f ETH", f)
|
||||
}
|
||||
|
||||
// formatGweiFromWei formats wei amount as Gwei
|
||||
func formatGweiFromWei(wei *big.Int) string {
|
||||
if wei == nil {
|
||||
return "0 Gwei"
|
||||
}
|
||||
// Convert wei to Gwei (divide by 10^9)
|
||||
gwei := new(big.Float).SetInt(wei)
|
||||
gwei.Quo(gwei, big.NewFloat(1e9))
|
||||
f, _ := gwei.Float64()
|
||||
return fmt.Sprintf("%.2f Gwei", f)
|
||||
}
|
||||
Reference in New Issue
Block a user