fix(multicall): resolve critical multicall parsing corruption issues

- Added comprehensive bounds checking to prevent buffer overruns in multicall parsing
- Implemented graduated validation system (Strict/Moderate/Permissive) to reduce false positives
- Added LRU caching system for address validation with 10-minute TTL
- Enhanced ABI decoder with missing Universal Router and Arbitrum-specific DEX signatures
- Fixed duplicate function declarations and import conflicts across multiple files
- Added error recovery mechanisms with multiple fallback strategies
- Updated tests to handle new validation behavior for suspicious addresses
- Fixed parser test expectations for improved validation system
- Applied gofmt formatting fixes to ensure code style compliance
- Fixed mutex copying issues in monitoring package by introducing MetricsSnapshot
- Resolved critical security vulnerabilities in heuristic address extraction
- Progress: Updated TODO audit from 10% to 35% complete

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Krypto Kajun
2025-10-17 00:12:55 -05:00
parent f358f49aa9
commit 850223a953
8621 changed files with 79808 additions and 7340 deletions

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/fraktal/mev-beta/internal/logger"
"github.com/fraktal/mev-beta/pkg/market"
"github.com/fraktal/mev-beta/pkg/math"
@@ -480,34 +481,14 @@ func (ta *TransactionAnalyzer) estimateUniswapV2PriceImpact(ctx context.Context,
// Access the market discovery to get real pool reserves
poolInfo, err := ta.marketDiscovery.GetPool(ctx, poolAddr)
if err != nil || poolInfo == nil {
// Fallback estimation based on amount if pool info not available
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.01 // 1%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.005 // 0.5%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.001 // 0.1%
} else {
return 0.0005 // 0.05%
}
return ta.estimateFallbackV2PriceImpact(swapParams.AmountIn)
}
// Check if pool reserves are properly initialized
// Note: PoolData doesn't have Reserve0/Reserve1, it has Liquidity, SqrtPriceX96, Tick
// So for Uniswap V2, we need liquidity or sqrtPriceX96 values to be non-zero
if poolInfo.Liquidity == nil || poolInfo.Liquidity.Sign() <= 0 {
// Fallback estimation based on amount if pool info not available or improperly initialized
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.01 // 1%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.005 // 0.5%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.001 // 0.1%
} else {
return 0.0005 // 0.05%
}
return ta.estimateFallbackV2PriceImpact(swapParams.AmountIn)
}
// Convert uint256 values to big.Int for math engine
@@ -522,22 +503,26 @@ func (ta *TransactionAnalyzer) estimateUniswapV2PriceImpact(ctx context.Context,
// Calculate price impact using approximated reserves
impact, err := mathEngine.CalculatePriceImpact(swapParams.AmountIn, reserve0Big, reserve1Big)
if err != nil {
// Fallback if calculation fails
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.01 // 1%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.005 // 0.5%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.001 // 0.1%
} else {
return 0.0005 // 0.05%
}
return ta.estimateFallbackV2PriceImpact(swapParams.AmountIn)
}
return impact
}
// estimateFallbackV2PriceImpact provides a fallback estimation for Uniswap V2 based on amount
func (ta *TransactionAnalyzer) estimateFallbackV2PriceImpact(amountIn *big.Int) float64 {
amountFloat, _ := new(big.Float).SetInt(amountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.01 // 1%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.005 // 0.5%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.001 // 0.1%
} else {
return 0.0005 // 0.05%
}
}
// estimateUniswapV3PriceImpact estimates price impact for Uniswap V3
func (ta *TransactionAnalyzer) estimateUniswapV3PriceImpact(ctx context.Context, swapParams *SwapParams, mathEngine math.ExchangeMath) float64 {
// Get actual pool data from market discovery
@@ -546,32 +531,12 @@ func (ta *TransactionAnalyzer) estimateUniswapV3PriceImpact(ctx context.Context,
// Access the market discovery to get real pool data
poolInfo, err := ta.marketDiscovery.GetPool(ctx, poolAddr)
if err != nil || poolInfo == nil || poolInfo.SqrtPriceX96 == nil || poolInfo.Liquidity == nil {
// Fallback estimation based on amount if pool info not available
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.005 // 0.5%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.002 // 0.2%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.0005 // 0.05%
} else {
return 0.0002 // 0.02%
}
return ta.estimateFallbackPriceImpact(swapParams.AmountIn)
}
// Check if pool data is properly initialized
if poolInfo.SqrtPriceX96 == nil || poolInfo.Liquidity == nil {
// Fallback estimation based on amount if pool info not available or improperly initialized
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.005 // 0.5%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.002 // 0.2%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.0005 // 0.05%
} else {
return 0.0002 // 0.02%
}
return ta.estimateFallbackPriceImpact(swapParams.AmountIn)
}
// Convert uint256 values to big.Int for math engine
@@ -581,22 +546,26 @@ func (ta *TransactionAnalyzer) estimateUniswapV3PriceImpact(ctx context.Context,
// Calculate price impact using V3-specific math with converted values
impact, err := mathEngine.CalculatePriceImpact(swapParams.AmountIn, sqrtPriceX96Big, liquidityBig)
if err != nil {
// Fallback if calculation fails
amountFloat, _ := new(big.Float).SetInt(swapParams.AmountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.005 // 0.5%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.002 // 0.2%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.0005 // 0.05%
} else {
return 0.0002 // 0.02%
}
return ta.estimateFallbackPriceImpact(swapParams.AmountIn)
}
return impact
}
// estimateFallbackPriceImpact provides a fallback estimation based on amount
func (ta *TransactionAnalyzer) estimateFallbackPriceImpact(amountIn *big.Int) float64 {
amountFloat, _ := new(big.Float).SetInt(amountIn).Float64()
if amountFloat > 10e18 { // > 10 ETH
return 0.005 // 0.5%
} else if amountFloat > 1e18 { // > 1 ETH
return 0.002 // 0.2%
} else if amountFloat > 0.1e18 { // > 0.1 ETH
return 0.0005 // 0.05%
} else {
return 0.0002 // 0.02%
}
}
// estimateCurvePriceImpact estimates price impact for Curve Finance
func (ta *TransactionAnalyzer) estimateCurvePriceImpact(ctx context.Context, swapParams *SwapParams, mathEngine math.ExchangeMath) float64 {
// Get actual pool data from market discovery
@@ -858,6 +827,10 @@ func (ta *TransactionAnalyzer) findArbitrageOpportunity(ctx context.Context, swa
arbOp.Profit = profit
arbOp.NetProfit = netProfit
arbOp.GasEstimate = gasCost
arbOp.EstimatedProfit = profit
arbOp.RequiredAmount = amountIn
arbOp.DetectedAt = time.Now()
arbOp.ExpiresAt = time.Now().Add(5 * time.Minute)
// Handle empty token addresses to prevent slice bounds panic
tokenInDisplay := "unknown"
@@ -918,8 +891,6 @@ func (ta *TransactionAnalyzer) findArbitrageOpportunity(ctx context.Context, swa
}()
return arbOp
return arbOp
}
func (ta *TransactionAnalyzer) findSandwichOpportunity(ctx context.Context, swapData *SwapData, tx *RawL2Transaction) *SandwichOpportunity {