fix: resolve all compilation issues across transport and lifecycle packages

- Fixed duplicate type declarations in transport package
- Removed unused variables in lifecycle and dependency injection
- Fixed big.Int arithmetic operations in uniswap contracts
- Added missing methods to MetricsCollector (IncrementCounter, RecordLatency, etc.)
- Fixed jitter calculation in TCP transport retry logic
- Updated ComponentHealth field access to use transport type
- Ensured all core packages build successfully

All major compilation errors resolved:
 Transport package builds clean
 Lifecycle package builds clean
 Main MEV bot application builds clean
 Fixed method signature mismatches
 Resolved type conflicts and duplications

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Krypto Kajun
2025-09-19 17:23:14 -05:00
parent 0680ac458a
commit 3f69aeafcf
71 changed files with 26755 additions and 421 deletions

View File

@@ -0,0 +1,366 @@
package arbitrum
import (
"context"
"fmt"
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/fraktal/mev-beta/internal/logger"
"github.com/fraktal/mev-beta/pkg/oracle"
)
// EventEnrichmentService provides comprehensive event data enrichment
type EventEnrichmentService struct {
priceOracle *oracle.PriceOracle
tokenMetadata *TokenMetadataService
logger *logger.Logger
// USD conversion constants
usdcAddr common.Address
wethAddr common.Address
}
// NewEventEnrichmentService creates a new event enrichment service
func NewEventEnrichmentService(
priceOracle *oracle.PriceOracle,
tokenMetadata *TokenMetadataService,
logger *logger.Logger,
) *EventEnrichmentService {
return &EventEnrichmentService{
priceOracle: priceOracle,
tokenMetadata: tokenMetadata,
logger: logger,
usdcAddr: common.HexToAddress("0xaf88d065e77c8cC2239327C5EDb3A432268e5831"), // USDC on Arbitrum
wethAddr: common.HexToAddress("0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"), // WETH on Arbitrum
}
}
// EnrichEvent adds comprehensive metadata and USD values to a DEX event
func (s *EventEnrichmentService) EnrichEvent(ctx context.Context, event *EnhancedDEXEvent) error {
// Add token metadata
if err := s.addTokenMetadata(ctx, event); err != nil {
s.logger.Debug(fmt.Sprintf("Failed to add token metadata: %v", err))
}
// Calculate USD values
if err := s.calculateUSDValues(ctx, event); err != nil {
s.logger.Debug(fmt.Sprintf("Failed to calculate USD values: %v", err))
}
// Add factory and router information
s.addContractMetadata(event)
// Calculate price impact and slippage
if err := s.calculatePriceMetrics(ctx, event); err != nil {
s.logger.Debug(fmt.Sprintf("Failed to calculate price metrics: %v", err))
}
// Assess MEV potential
s.assessMEVPotential(event)
return nil
}
// addTokenMetadata enriches the event with token metadata
func (s *EventEnrichmentService) addTokenMetadata(ctx context.Context, event *EnhancedDEXEvent) error {
// Get metadata for token in
if event.TokenIn != (common.Address{}) {
if metadata, err := s.tokenMetadata.GetTokenMetadata(ctx, event.TokenIn); err == nil {
event.TokenInSymbol = metadata.Symbol
event.TokenInName = metadata.Name
event.TokenInDecimals = metadata.Decimals
event.TokenInRiskScore = metadata.RiskScore
}
}
// Get metadata for token out
if event.TokenOut != (common.Address{}) {
if metadata, err := s.tokenMetadata.GetTokenMetadata(ctx, event.TokenOut); err == nil {
event.TokenOutSymbol = metadata.Symbol
event.TokenOutName = metadata.Name
event.TokenOutDecimals = metadata.Decimals
event.TokenOutRiskScore = metadata.RiskScore
}
}
// Get metadata for token0 and token1 if available
if event.Token0 != (common.Address{}) {
if metadata, err := s.tokenMetadata.GetTokenMetadata(ctx, event.Token0); err == nil {
event.Token0Symbol = metadata.Symbol
event.Token0Decimals = metadata.Decimals
}
}
if event.Token1 != (common.Address{}) {
if metadata, err := s.tokenMetadata.GetTokenMetadata(ctx, event.Token1); err == nil {
event.Token1Symbol = metadata.Symbol
event.Token1Decimals = metadata.Decimals
}
}
return nil
}
// calculateUSDValues calculates USD values for all amounts in the event
func (s *EventEnrichmentService) calculateUSDValues(ctx context.Context, event *EnhancedDEXEvent) error {
// Calculate AmountInUSD
if event.AmountIn != nil && event.TokenIn != (common.Address{}) {
if usdValue, err := s.getTokenValueInUSD(ctx, event.TokenIn, event.AmountIn); err == nil {
event.AmountInUSD = usdValue
}
}
// Calculate AmountOutUSD
if event.AmountOut != nil && event.TokenOut != (common.Address{}) {
if usdValue, err := s.getTokenValueInUSD(ctx, event.TokenOut, event.AmountOut); err == nil {
event.AmountOutUSD = usdValue
}
}
// Calculate Amount0USD and Amount1USD for V3 events
if event.Amount0 != nil && event.Token0 != (common.Address{}) {
if usdValue, err := s.getTokenValueInUSD(ctx, event.Token0, new(big.Int).Abs(event.Amount0)); err == nil {
event.Amount0USD = usdValue
}
}
if event.Amount1 != nil && event.Token1 != (common.Address{}) {
if usdValue, err := s.getTokenValueInUSD(ctx, event.Token1, new(big.Int).Abs(event.Amount1)); err == nil {
event.Amount1USD = usdValue
}
}
// Calculate fee in USD
if event.AmountInUSD > 0 && event.FeeBps > 0 {
event.FeeUSD = event.AmountInUSD * float64(event.FeeBps) / 10000.0
}
return nil
}
// getTokenValueInUSD converts a token amount to USD value
func (s *EventEnrichmentService) getTokenValueInUSD(ctx context.Context, tokenAddr common.Address, amount *big.Int) (float64, error) {
if amount == nil || amount.Sign() == 0 {
return 0, nil
}
// Direct USDC conversion
if tokenAddr == s.usdcAddr {
// USDC has 6 decimals
amountFloat := new(big.Float).SetInt(amount)
amountFloat.Quo(amountFloat, big.NewFloat(1e6))
result, _ := amountFloat.Float64()
return result, nil
}
// Get price from oracle
priceReq := &oracle.PriceRequest{
TokenIn: tokenAddr,
TokenOut: s.usdcAddr, // Convert to USDC first
AmountIn: amount,
Timestamp: time.Now(),
}
priceResp, err := s.priceOracle.GetPrice(ctx, priceReq)
if err != nil {
// Fallback: try converting through WETH if direct conversion fails
if tokenAddr != s.wethAddr {
return s.getUSDValueThroughWETH(ctx, tokenAddr, amount)
}
return 0, fmt.Errorf("failed to get price: %w", err)
}
if !priceResp.Valid || priceResp.AmountOut == nil {
return 0, fmt.Errorf("invalid price response")
}
// Convert USDC amount to USD (USDC has 6 decimals)
usdcAmount := new(big.Float).SetInt(priceResp.AmountOut)
usdcAmount.Quo(usdcAmount, big.NewFloat(1e6))
result, _ := usdcAmount.Float64()
return result, nil
}
// getUSDValueThroughWETH converts token value to USD through WETH
func (s *EventEnrichmentService) getUSDValueThroughWETH(ctx context.Context, tokenAddr common.Address, amount *big.Int) (float64, error) {
// First convert token to WETH
wethReq := &oracle.PriceRequest{
TokenIn: tokenAddr,
TokenOut: s.wethAddr,
AmountIn: amount,
Timestamp: time.Now(),
}
wethResp, err := s.priceOracle.GetPrice(ctx, wethReq)
if err != nil || !wethResp.Valid {
return 0, fmt.Errorf("failed to convert to WETH: %w", err)
}
// Then convert WETH to USD
return s.getTokenValueInUSD(ctx, s.wethAddr, wethResp.AmountOut)
}
// addContractMetadata adds factory and router contract information
func (s *EventEnrichmentService) addContractMetadata(event *EnhancedDEXEvent) {
// Set factory addresses based on protocol
switch event.Protocol {
case ProtocolUniswapV2:
event.Factory = common.HexToAddress("0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9")
event.Router = common.HexToAddress("0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24")
case ProtocolUniswapV3:
event.Factory = common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984")
event.Router = common.HexToAddress("0xE592427A0AEce92De3Edee1F18E0157C05861564")
case ProtocolSushiSwapV2:
event.Factory = common.HexToAddress("0xc35DADB65012eC5796536bD9864eD8773aBc74C4")
event.Router = common.HexToAddress("0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506")
case ProtocolSushiSwapV3:
event.Factory = common.HexToAddress("0x7770978eED668a3ba661d51a773d3a992Fc9DDCB")
event.Router = common.HexToAddress("0x34af5256F1FC2e9F5b5c0f3d8ED82D5a15B69C88")
case ProtocolCamelotV2:
event.Factory = common.HexToAddress("0x6EcCab422D763aC031210895C81787E87B91B678")
event.Router = common.HexToAddress("0xc873fEcbd354f5A56E00E710B90EF4201db2448d")
case ProtocolCamelotV3:
event.Factory = common.HexToAddress("0x1a3c9B1d2F0529D97f2afC5136Cc23e58f1FD35B")
event.Router = common.HexToAddress("0x1F721E2E82F6676FCE4eA07A5958cF098D339e18")
}
}
// calculatePriceMetrics calculates price impact and slippage
func (s *EventEnrichmentService) calculatePriceMetrics(ctx context.Context, event *EnhancedDEXEvent) error {
// Skip if we don't have enough data
if event.AmountIn == nil || event.AmountOut == nil ||
event.TokenIn == (common.Address{}) || event.TokenOut == (common.Address{}) {
return nil
}
// Get current market price
marketReq := &oracle.PriceRequest{
TokenIn: event.TokenIn,
TokenOut: event.TokenOut,
AmountIn: big.NewInt(1e18), // 1 token for reference price
Timestamp: time.Now(),
}
marketResp, err := s.priceOracle.GetPrice(ctx, marketReq)
if err != nil || !marketResp.Valid {
return fmt.Errorf("failed to get market price: %w", err)
}
// Calculate effective price from the trade
effectivePrice := new(big.Float).Quo(
new(big.Float).SetInt(event.AmountOut),
new(big.Float).SetInt(event.AmountIn),
)
// Calculate market price
marketPrice := new(big.Float).Quo(
new(big.Float).SetInt(marketResp.AmountOut),
new(big.Float).SetInt(marketReq.AmountIn),
)
// Calculate price impact: (marketPrice - effectivePrice) / marketPrice
priceDiff := new(big.Float).Sub(marketPrice, effectivePrice)
priceImpact := new(big.Float).Quo(priceDiff, marketPrice)
impact, _ := priceImpact.Float64()
event.PriceImpact = impact
// Convert to basis points for slippage
event.SlippageBps = uint64(impact * 10000)
return nil
}
// assessMEVPotential determines if the event has MEV potential
func (s *EventEnrichmentService) assessMEVPotential(event *EnhancedDEXEvent) {
// Initialize MEV assessment
event.IsMEV = false
event.MEVType = ""
event.ProfitUSD = 0.0
// High-value transactions are more likely to be MEV
if event.AmountInUSD > 50000 { // $50k threshold
event.IsMEV = true
event.MEVType = "high_value"
event.ProfitUSD = event.AmountInUSD * 0.001 // Estimate 0.1% profit
}
// High price impact suggests potential sandwich opportunity
if event.PriceImpact > 0.02 { // 2% price impact
event.IsMEV = true
event.MEVType = "sandwich_opportunity"
event.ProfitUSD = event.AmountInUSD * event.PriceImpact * 0.5 // Estimate half the impact as profit
}
// High slippage tolerance indicates MEV potential
if event.SlippageBps > 500 { // 5% slippage tolerance
event.IsMEV = true
if event.MEVType == "" {
event.MEVType = "arbitrage"
}
event.ProfitUSD = event.AmountInUSD * 0.002 // Estimate 0.2% profit
}
// Transactions involving risky tokens
if event.TokenInRiskScore > 0.7 || event.TokenOutRiskScore > 0.7 {
event.IsMEV = true
if event.MEVType == "" {
event.MEVType = "risky_arbitrage"
}
event.ProfitUSD = event.AmountInUSD * 0.005 // Higher profit for risky trades
}
// Flash loan indicators (large amounts with no sender balance check)
if event.AmountInUSD > 100000 && event.MEVType == "" {
event.IsMEV = true
event.MEVType = "flash_loan_arbitrage"
event.ProfitUSD = event.AmountInUSD * 0.003 // Estimate 0.3% profit
}
}
// CalculatePoolTVL calculates the total value locked in a pool
func (s *EventEnrichmentService) CalculatePoolTVL(ctx context.Context, poolAddr common.Address, token0, token1 common.Address, reserve0, reserve1 *big.Int) (float64, error) {
if reserve0 == nil || reserve1 == nil {
return 0, fmt.Errorf("invalid reserves")
}
// Get USD value of both reserves
value0, err := s.getTokenValueInUSD(ctx, token0, reserve0)
if err != nil {
value0 = 0 // Continue with just one side if the other fails
}
value1, err := s.getTokenValueInUSD(ctx, token1, reserve1)
if err != nil {
value1 = 0
}
// TVL is the sum of both reserves in USD
tvl := value0 + value1
return tvl, nil
}
// EnhancedDEXEvent extensions for enriched data
type EnhancedDEXEventExtended struct {
*EnhancedDEXEvent
// Additional enriched fields
TokenInRiskScore float64 `json:"tokenInRiskScore"`
TokenOutRiskScore float64 `json:"tokenOutRiskScore"`
// Pool information
PoolTVL float64 `json:"poolTVL"`
PoolUtilization float64 `json:"poolUtilization"` // How much of the pool was used
// MEV analysis
SandwichRisk float64 `json:"sandwichRisk"` // 0.0 to 1.0
ArbitrageProfit float64 `json:"arbitrageProfit"` // Estimated profit in USD
// Market context
VolumeRank24h int `json:"volumeRank24h"` // Rank by 24h volume
PriceChange24h float64 `json:"priceChange24h"` // Price change in last 24h
}