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.0is 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:
-
Formula
tradeSize / (2 * liquidity)is NOT the correct slippage formula- Actual formula for Uniswap V2:
slippage = tradeSize / (2 * liquidity + tradeSize)(more complex)
- Actual formula for Uniswap V2:
-
The curve adjustment
(1 + tradeSizeFloat)is arbitrary- When tradeSizeFloat = 0.5 (50% of pool), multiplier = 1.5
- This doesn't match actual AMM behavior
-
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:
-
20% buffer is ARBITRARY and not based on:
- Actual MEV competition on Arbitrum
- Historical gas price volatility
- Current network conditions
-
May be:
- TOO HIGH: Underestimates profitability unnecessarily
- TOO LOW: Insufficient for actual MEV competition
-
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:
newReserveInis calculated asreserveIn + amountIn- But in reality, the input amount is
amountInWithFeeafter 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.Intcan 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
NewUniversalDecimaldoesn'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.Inttobig.Floatand 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:
netProfitis*big.Float- Converting to
big.Inttruncates 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)
- Fix profit margin check - Remove 100% cap, allow any positive profit
- Fix slippage calculation - Implement proper AMM invariant formulas
- Fix profit threshold comparison - Properly compare float values without truncation
- Fix price impact - Use fee-adjusted amounts in reserve calculations
Short-term (High Priority)
- Add division-by-zero checks everywhere
- Implement proper rounding strategies
- Add overflow detection before large multiplications
- Test against known Arbitrum DEX prices
Medium-term (Medium Priority)
- Dynamic gas cost calculation based on network state
- More accurate slippage models for each DEX type
- 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