Files
mev-beta/docs/MATHEMATICAL_AUDIT_DETAILED_20251101.md

12 KiB

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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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)

  1. Add division-by-zero checks everywhere
  2. Implement proper rounding strategies
  3. Add overflow detection before large multiplications
  4. Test against known Arbitrum DEX prices

Medium-term (Medium Priority)

  1. Dynamic gas cost calculation based on network state
  2. More accurate slippage models for each DEX type
  3. 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