fix(arbitrage): critical fixes for struct initialization and price impact calculations
- Triangular arbitrage: populate all 25+ ArbitrageOpportunity fields - Direct arbitrage: complete field initialization with gas cost calculation - Price impact: add division-by-zero protection and validation - Absolute value handling for swap amounts to prevent uint256 max display Remaining issue: Some events still show uint256 max - needs investigation of alternative parsing code path (possibly pkg/pools/discovery.go)
This commit is contained in:
@@ -554,13 +554,33 @@ func (s *MarketScanner) findTriangularArbitrageOpportunities(event events.Event)
|
||||
// Close the loop by adding the first token at the end
|
||||
tokenPaths = append(tokenPaths, path.Tokens[0].Hex())
|
||||
|
||||
// Properly initialize all required fields
|
||||
now := time.Now()
|
||||
opportunity := stypes.ArbitrageOpportunity{
|
||||
Path: tokenPaths,
|
||||
Pools: []string{}, // Pool addresses will be discovered dynamically
|
||||
Profit: netProfit,
|
||||
GasEstimate: gasEstimate,
|
||||
ROI: roi,
|
||||
Protocol: fmt.Sprintf("Triangular_%s", path.Name),
|
||||
ID: fmt.Sprintf("arb_%d_%s", now.Unix(), path.Tokens[0].Hex()[:10]),
|
||||
Path: tokenPaths,
|
||||
Pools: []string{}, // Pool addresses will be discovered dynamically
|
||||
AmountIn: testAmount,
|
||||
Profit: profit,
|
||||
NetProfit: netProfit,
|
||||
GasEstimate: gasEstimate,
|
||||
GasCost: gasEstimate, // Set gas cost same as estimate
|
||||
EstimatedProfit: netProfit,
|
||||
RequiredAmount: testAmount,
|
||||
ROI: roi,
|
||||
Protocol: fmt.Sprintf("Triangular_%s", path.Name),
|
||||
ExecutionTime: 500, // Estimated 500ms for triangular arb
|
||||
Confidence: 0.5, // Medium confidence for triangular
|
||||
PriceImpact: 0.0, // Will be calculated dynamically
|
||||
MaxSlippage: 2.0, // 2% max slippage
|
||||
TokenIn: path.Tokens[0],
|
||||
TokenOut: path.Tokens[0], // Circular, starts and ends with same token
|
||||
Timestamp: now.Unix(),
|
||||
DetectedAt: now,
|
||||
ExpiresAt: now.Add(5 * time.Second), // 5 second expiry
|
||||
Urgency: 5, // Medium urgency
|
||||
Risk: 0.3, // Low-medium risk
|
||||
Profitable: netProfit.Sign() > 0,
|
||||
}
|
||||
|
||||
opportunities = append(opportunities, opportunity)
|
||||
@@ -1111,8 +1131,12 @@ func (s *MarketScanner) fetchPoolData(poolAddress string) (*CachedData, error) {
|
||||
LastUpdated: time.Now(),
|
||||
}
|
||||
|
||||
liquidityStr := "0"
|
||||
if poolState.Liquidity != nil {
|
||||
liquidityStr = poolState.Liquidity.String()
|
||||
}
|
||||
s.logger.Info(fmt.Sprintf("Fetched real pool data for %s: Token0=%s, Token1=%s, Fee=%d, Liquidity=%s",
|
||||
address.Hex(), poolState.Token0.Hex(), poolState.Token1.Hex(), poolState.Fee, poolState.Liquidity.String()))
|
||||
address.Hex(), poolState.Token0.Hex(), poolState.Token1.Hex(), poolState.Fee, liquidityStr))
|
||||
|
||||
return poolData, nil
|
||||
}
|
||||
@@ -1309,8 +1333,20 @@ func (s *MarketScanner) calculateUniswapV3Output(amountIn *big.Int, pool *Cached
|
||||
// Subtract fee from output
|
||||
finalAmountOut := new(big.Int).Sub(amountOut, feeAmount)
|
||||
|
||||
amountInStr := "0"
|
||||
if amountIn != nil {
|
||||
amountInStr = amountIn.String()
|
||||
}
|
||||
amountOutStr := "0"
|
||||
if amountOut != nil {
|
||||
amountOutStr = amountOut.String()
|
||||
}
|
||||
finalAmountOutStr := "0"
|
||||
if finalAmountOut != nil {
|
||||
finalAmountOutStr = finalAmountOut.String()
|
||||
}
|
||||
s.logger.Debug(fmt.Sprintf("V3 calculation: amountIn=%s, amountOut=%s, fee=%d, finalOut=%s",
|
||||
amountIn.String(), amountOut.String(), fee, finalAmountOut.String()))
|
||||
amountInStr, amountOutStr, fee, finalAmountOutStr))
|
||||
|
||||
return finalAmountOut, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user