# MEV Bot Mathematical Audit Report ## Comprehensive Review of Calculation Correctness **Date**: November 1, 2025 **Scope**: All mathematical calculations in MEV bot **Status**: CRITICAL ISSUES IDENTIFIED --- ## Executive Summary The MEV bot contains **multiple critical mathematical errors** that could lead to: - Incorrect profit calculations (overestimation) - Invalid arbitrage execution decisions - Gas cost underestimation - Price impact miscalculations - Precision loss and rounding errors - Potential for negative profits despite calculations showing positive **Severity**: HIGH - Immediate fixes required before production execution --- ## CRITICAL ISSUES FOUND ### 1. PROFIT CALCULATION - ROUNDING ERROR IN profit_calc.go **Location**: `/home/administrator/projects/mev-beta/pkg/profitcalc/profit_calc.go:199-210` **Issue**: Profit margin calculation uses integer division which truncates decimal places ```go // PROBLEMATIC CODE (Line 199-210) if amountOut.Sign() > 0 && amountOut.Cmp(big.NewFloat(0)) != 0 { profitMargin := new(big.Float).Quo(netProfit, amountOut) profitMarginFloat, _ := profitMargin.Float64() // Ensure the profit margin is reasonable and not extremely high if profitMarginFloat > 1.0 { // 100% profit margin is unrealistic opportunity.ProfitMargin = 0.0 // Set to 0 if profit margin is unrealistic opportunity.IsExecutable = false opportunity.RejectReason = "unrealistic profit margin" opportunity.Confidence = 0.0 } else { opportunity.ProfitMargin = profitMarginFloat } } ``` **Problem**: - The condition `profitMarginFloat > 1.0` is checking if profit margin exceeds 100% - However, this is mathematically incorrect: a 1:1 profit (100% margin) IS possible in arbitrage - This check REJECTS valid opportunities with 100%+ margins - The code incorrectly assumes profitable arbitrage cannot exceed 100% margin **Impact**: HIGH - Rejects all highly profitable arbitrage opportunities **Fix Required**: Remove the artificial 100% profit margin cap and implement proper validation --- ### 2. SLIPPAGE CALCULATION ERROR - slippage_protection.go **Location**: `/home/administrator/projects/mev-beta/pkg/profitcalc/slippage_protection.go:59-67` **Issue**: Slippage formula is oversimplified and incorrect for actual AMM pools ```go // PROBLEMATIC CODE (Line 59-67) // Estimate slippage using simplified AMM formula // For constant product AMMs: slippage ≈ trade_size / (2 * liquidity) estimatedSlippage := tradeSizeFloat / 2.0 // Apply curve adjustment for larger trades (non-linear slippage) if tradeSizeFloat > 0.1 { // > 10% of pool // Quadratic increase for large trades estimatedSlippage = estimatedSlippage * (1 + tradeSizeFloat) } ``` **Problems**: 1. Formula `tradeSize / (2 * liquidity)` is NOT the correct slippage formula - Actual formula for Uniswap V2: `slippage = tradeSize / (2 * liquidity + tradeSize)` (more complex) 2. The curve adjustment `(1 + tradeSizeFloat)` is arbitrary - When tradeSizeFloat = 0.5 (50% of pool), multiplier = 1.5 - This doesn't match actual AMM behavior 3. Does NOT account for: - Fee structures (different by DEX) - Token decimals - Actual liquidity state changes **Impact**: CRITICAL - Slippage estimates are wildly inaccurate, leading to: - Overestimation of profit margins - Approval of trades that will result in losses - Risk assessment is completely unreliable **Math Error**: Should use proper AMM invariant formulas instead of linear approximation --- ### 3. GAS COST CALCULATION - ARBITRARY BUFFER **Location**: `/home/administrator/projects/mev-beta/pkg/profitcalc/profit_calc.go:271-273` **Issue**: Gas cost calculation adds arbitrary 20% buffer ```go // PROBLEMATIC CODE (Line 271-273) // Add 20% buffer for MEV competition buffer := new(big.Int).Div(gasCostWei, big.NewInt(5)) // 20% gasCostWei.Add(gasCostWei, buffer) ``` **Problems**: 1. 20% buffer is ARBITRARY and not based on: - Actual MEV competition on Arbitrum - Historical gas price volatility - Current network conditions 2. May be: - TOO HIGH: Underestimates profitability unnecessarily - TOO LOW: Insufficient for actual MEV competition 3. No dynamic adjustment based on: - Network congestion - Price impact size - Complexity of transaction **Impact**: MEDIUM - Profit calculations are systematically offset **Fix**: Calculate actual expected gas based on transaction complexity and network state --- ### 4. PRICE IMPACT CALCULATION - MISSING FEE DEDUCTION **Location**: `/home/administrator/projects/mev-beta/pkg/math/exchange_math.go:114-147` **Issue**: Price impact is calculated WITHOUT considering trading fees in initial step ```go // PROBLEMATIC CODE (Line 128-146) // Calculate amount out amountOut, err := u.CalculateAmountOut(amountIn, reserveIn, reserveOut, 3000) if err != nil { return 0, err } // New reserves after swap newReserveIn := new(big.Int).Add(reserveIn, amountIn) // ← WRONG: doesn't account for fee deduction newReserveOut := new(big.Int).Sub(reserveOut, amountOut) // Price after = newReserveOut / newReserveIn priceAfter := new(big.Float).Quo(new(big.Float).SetInt(newReserveOut), new(big.Float).SetInt(newReserveIn)) // Price impact = (priceBefore - priceAfter) / priceBefore impact := new(big.Float).Sub(priceBefore, priceAfter) impact.Quo(impact, priceBefore) ``` **Problem**: - `newReserveIn` is calculated as `reserveIn + amountIn` - But in reality, the input amount is `amountInWithFee` after fee deduction - This causes price impact to be UNDERESTIMATED - The actual price movement is larger than calculated **Impact**: CRITICAL - Price impact is underestimated by 0.3-2% depending on fee tier **Fix**: Use `amountInWithFee` in reserve calculation instead of raw `amountIn` --- ### 5. DIVISION BY ZERO RISK - Multiple Locations **Location 1**: `/home/administrator/projects/mev-beta/pkg/profitcalc/slippage_protection.go:56` ```go // PROBLEMATIC CODE tradeSizeRatio := new(big.Float).Quo(tradeAmount, poolLiquidity) ``` **Issue**: If `poolLiquidity` is zero or extremely small, division fails silently **Location 2**: `/home/administrator/projects/mev-beta/pkg/math/decimal_handler.go:308-312` ```go // PROBLEMATIC CODE (Line 308-312) // Scale numerator to maintain precision totalDecimals := numerator.Decimals + resultDecimals scalingFactor := dc.getScalingFactor(totalDecimals - denominator.Decimals) scaledNumerator := new(big.Int).Mul(numerator.Value, scalingFactor) quotient := new(big.Int).Div(scaledNumerator, denominator.Value) // ← No zero check ``` **Impact**: MEDIUM - Silent failures in calculations --- ### 6. OVERFLOW RISK IN MULTIPLICATION - arbitrage_calculator.go **Location**: `/home/administrator/projects/mev-beta/pkg/math/arbitrage_calculator.go:278` **Issue**: Large number multiplication without overflow checking ```go // PROBLEMATIC CODE product := new(big.Int).Mul(a.Value, b.Value) // Adjust for decimal places totalInputDecimals := a.Decimals + b.Decimals ``` **Problem**: - While Go's `big.Int` can handle large numbers, the multiplication is done BEFORE overflow check - For very large token amounts (18 decimals), multiplying two large numbers can be slow - No explicit overflow detection before performing expensive multiplication **Impact**: LOW - Go handles this, but inefficient --- ### 7. NEGATIVE VALUE HANDLING - decimal_handler.go **Location**: `/home/administrator/projects/mev-beta/pkg/math/decimal_handler.go:54-58` ```go // PROBLEMATIC CODE if value != nil { // Check for reasonable bounds - max value should not exceed what can be represented // in financial calculations (roughly 2^256 / 10^18 for safety) maxValue := new(big.Int) maxValue.Exp(big.NewInt(10), big.NewInt(60), nil) // 10^60 max value for safety absValue := new(big.Int).Abs(value) // ← Using Abs() is correct but... ``` **Problem**: - Code correctly checks `Abs(value)` for upper bound - But `NewUniversalDecimal` doesn't properly handle NEGATIVE values - Negative amounts should not be allowed in profit calculations - No check for negative amounts in critical functions **Impact**: MEDIUM - Could allow invalid negative profit amounts --- ### 8. UNISWAP V3 PRICE CALCULATION - PRECISION LOSS **Location**: `/home/administrator/projects/mev-beta/pkg/uniswap/pricing.go:22-45` **Issue**: SqrtPriceX96 to Price conversion loses precision ```go // PROBLEMATIC CODE // Convert to big.Float for precision sqrtPrice := new(big.Float).SetPrec(256).SetInt(sqrtPriceX96) // Calculate sqrtPrice^2 price := new(big.Float).SetPrec(256) price.Mul(sqrtPrice, sqrtPrice) // Divide by 2^192 using global cached constant denominator := new(big.Float).SetPrec(256).SetInt(GetQ192()) price.Quo(price, denominator) ``` **Problem**: - Precision of 256 bits = ~77 decimal digits - Actual prices are often in 10-18 decimal range - Converting from `big.Int` to `big.Float` and back loses lower bits - SetFloat64(0.0) for invalid input silently returns 0 **Impact**: MEDIUM - Slight precision loss in V3 price calculations --- ### 9. PROFIT THRESHOLD COMPARISON - TYPE MISMATCH **Location**: `/home/administrator/projects/mev-beta/pkg/profitcalc/profit_calc.go:214-216` ```go // PROBLEMATIC CODE if netProfit.Sign() > 0 { netProfitWei, _ := netProfit.Int(nil) // ← Converts big.Float to big.Int if netProfitWei.Cmp(spc.minProfitThreshold) >= 0 { ``` **Problem**: - `netProfit` is `*big.Float` - Converting to `big.Int` truncates ALL decimal places - For ETH with 18 decimals: 0.0001 ETH becomes 0 (100 wei becomes 0 in Int representation) - This causes profits < 1 wei to be rejected as "below threshold" **Impact**: CRITICAL - Legitimate small profit opportunities are rejected **Example Bug**: ``` netProfit = 0.00005 ETH (50000 wei as float) netProfitWei, _ := netProfit.Int(nil) // Returns 0 (rounds down) netProfitWei.Cmp(0.01 ETH) >= 0 // FALSE - rejects valid opportunity ``` --- ### 10. MISSING ROUND-UP IN AMOUNT CALCULATIONS **Location**: `/home/administrator/projects/mev-beta/pkg/math/exchange_math.go:107-109` ```go // PROBLEMATIC CODE // amountIn = numerator / denominator + 1 (round up) amountIn := new(big.Int).Div(numerator, denominator) amountIn.Add(amountIn, big.NewInt(1)) ``` **Problem**: - Comment says "round up" but this ALWAYS adds 1 - Should use proper banker's rounding or conditional rounding - Adding 1 to every result causes slight overestimation **Impact**: LOW-MEDIUM - Slight overestimation of required input amounts --- ## SUMMARY TABLE | Issue | Severity | Type | Impact | |-------|----------|------|--------| | 1. Profit margin cap at 100% | HIGH | Logic Error | Rejects valid opportunities | | 2. Slippage formula incorrect | CRITICAL | Math Error | Wildly inaccurate slippage | | 3. Gas cost buffer arbitrary | MEDIUM | Configuration | Systematic bias in profits | | 4. Price impact misses fees | CRITICAL | Calculation Error | Underestimates price movement | | 5. Division by zero risk | MEDIUM | Input Validation | Silent failures | | 6. Overflow in multiplication | LOW | Performance | Slow for large numbers | | 7. Negative value handling | MEDIUM | Validation | Invalid states allowed | | 8. V3 price precision loss | MEDIUM | Precision | Slight accuracy loss | | 9. Float to Int conversion | CRITICAL | Type Error | Legitimate profits rejected | | 10. Always round up by 1 | LOW | Rounding | Slight overestimation | --- ## RECOMMENDATIONS ### Immediate (Critical Priority) 1. **Fix profit margin check** - Remove 100% cap, allow any positive profit 2. **Fix slippage calculation** - Implement proper AMM invariant formulas 3. **Fix profit threshold comparison** - Properly compare float values without truncation 4. **Fix price impact** - Use fee-adjusted amounts in reserve calculations ### Short-term (High Priority) 5. Add division-by-zero checks everywhere 6. Implement proper rounding strategies 7. Add overflow detection before large multiplications 8. Test against known Arbitrum DEX prices ### Medium-term (Medium Priority) 9. Dynamic gas cost calculation based on network state 10. More accurate slippage models for each DEX type 11. Proper handling of negative values and edge cases --- ## TESTING RECOMMENDATIONS Create test cases for: - Arbitrage with >100% profit margins - Small profit amounts (<0.001 ETH) - Very large trade sizes (>50% of pool) - Extreme price impacts (>10%) - Zero and near-zero liquidity - Fee-adjusted amount calculations --- Generated: November 1, 2025