feat(core): implement core MEV bot functionality with market scanning and Uniswap V3 pricing
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -5,53 +5,53 @@ import (
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/fraktal/mev-beta/internal/logger"
|
||||
"github.com/fraktal/mev-beta/pkg/validation"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
// SlippageProtection provides comprehensive slippage protection for trades
|
||||
type SlippageProtection struct {
|
||||
validator *validation.InputValidator
|
||||
logger *logger.Logger
|
||||
maxSlippagePercent float64
|
||||
priceUpdateWindow time.Duration
|
||||
emergencyStopLoss float64
|
||||
minimumLiquidity *big.Int
|
||||
validator *validation.InputValidator
|
||||
logger *logger.Logger
|
||||
maxSlippagePercent float64
|
||||
priceUpdateWindow time.Duration
|
||||
emergencyStopLoss float64
|
||||
minimumLiquidity *big.Int
|
||||
}
|
||||
|
||||
// TradeParameters represents parameters for a trade
|
||||
type TradeParameters struct {
|
||||
TokenIn common.Address
|
||||
TokenOut common.Address
|
||||
AmountIn *big.Int
|
||||
MinAmountOut *big.Int
|
||||
MaxSlippage float64
|
||||
Deadline uint64
|
||||
Pool common.Address
|
||||
ExpectedPrice *big.Float
|
||||
CurrentLiquidity *big.Int
|
||||
TokenIn common.Address
|
||||
TokenOut common.Address
|
||||
AmountIn *big.Int
|
||||
MinAmountOut *big.Int
|
||||
MaxSlippage float64
|
||||
Deadline uint64
|
||||
Pool common.Address
|
||||
ExpectedPrice *big.Float
|
||||
CurrentLiquidity *big.Int
|
||||
}
|
||||
|
||||
// SlippageCheck represents the result of slippage validation
|
||||
type SlippageCheck struct {
|
||||
IsValid bool
|
||||
IsValid bool
|
||||
CalculatedSlippage float64
|
||||
MaxAllowedSlippage float64
|
||||
PriceImpact float64
|
||||
Warnings []string
|
||||
Errors []string
|
||||
PriceImpact float64
|
||||
Warnings []string
|
||||
Errors []string
|
||||
}
|
||||
|
||||
// NewSlippageProtection creates a new slippage protection instance
|
||||
func NewSlippageProtection(logger *logger.Logger) *SlippageProtection {
|
||||
return &SlippageProtection{
|
||||
validator: validation.NewInputValidator(),
|
||||
logger: logger,
|
||||
maxSlippagePercent: 5.0, // 5% maximum slippage
|
||||
priceUpdateWindow: 30 * time.Second,
|
||||
emergencyStopLoss: 20.0, // 20% emergency stop loss
|
||||
minimumLiquidity: big.NewInt(10000), // Minimum liquidity threshold
|
||||
validator: validation.NewInputValidator(),
|
||||
logger: logger,
|
||||
maxSlippagePercent: 5.0, // 5% maximum slippage
|
||||
priceUpdateWindow: 30 * time.Second,
|
||||
emergencyStopLoss: 20.0, // 20% emergency stop loss
|
||||
minimumLiquidity: big.NewInt(10000), // Minimum liquidity threshold
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,16 +79,16 @@ func (sp *SlippageProtection) ValidateTradeParameters(params *TradeParameters) (
|
||||
|
||||
// Check slippage limits
|
||||
if slippage > params.MaxSlippage {
|
||||
check.Errors = append(check.Errors,
|
||||
fmt.Sprintf("Calculated slippage %.2f%% exceeds maximum allowed %.2f%%",
|
||||
check.Errors = append(check.Errors,
|
||||
fmt.Sprintf("Calculated slippage %.2f%% exceeds maximum allowed %.2f%%",
|
||||
slippage, params.MaxSlippage))
|
||||
check.IsValid = false
|
||||
}
|
||||
|
||||
// Check emergency stop loss
|
||||
if slippage > sp.emergencyStopLoss {
|
||||
check.Errors = append(check.Errors,
|
||||
fmt.Sprintf("Slippage %.2f%% exceeds emergency stop loss %.2f%%",
|
||||
check.Errors = append(check.Errors,
|
||||
fmt.Sprintf("Slippage %.2f%% exceeds emergency stop loss %.2f%%",
|
||||
slippage, sp.emergencyStopLoss))
|
||||
check.IsValid = false
|
||||
}
|
||||
@@ -99,10 +99,10 @@ func (sp *SlippageProtection) ValidateTradeParameters(params *TradeParameters) (
|
||||
check.Warnings = append(check.Warnings, fmt.Sprintf("Could not calculate price impact: %v", err))
|
||||
} else {
|
||||
check.PriceImpact = priceImpact
|
||||
|
||||
|
||||
// Warn about high price impact
|
||||
if priceImpact > 3.0 {
|
||||
check.Warnings = append(check.Warnings,
|
||||
check.Warnings = append(check.Warnings,
|
||||
fmt.Sprintf("High price impact detected: %.2f%%", priceImpact))
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (sp *SlippageProtection) ValidateTradeParameters(params *TradeParameters) (
|
||||
|
||||
check.MaxAllowedSlippage = params.MaxSlippage
|
||||
|
||||
sp.logger.Debug(fmt.Sprintf("Slippage check completed: valid=%t, slippage=%.2f%%, impact=%.2f%%",
|
||||
sp.logger.Debug(fmt.Sprintf("Slippage check completed: valid=%t, slippage=%.2f%%, impact=%.2f%%",
|
||||
check.IsValid, check.CalculatedSlippage, check.PriceImpact))
|
||||
|
||||
return check, nil
|
||||
@@ -227,7 +227,7 @@ func (sp *SlippageProtection) checkLiquidity(params *TradeParameters, check *Sli
|
||||
|
||||
// Check minimum liquidity threshold
|
||||
if params.CurrentLiquidity.Cmp(sp.minimumLiquidity) < 0 {
|
||||
return fmt.Errorf("liquidity %s below minimum threshold %s",
|
||||
return fmt.Errorf("liquidity %s below minimum threshold %s",
|
||||
params.CurrentLiquidity.String(), sp.minimumLiquidity.String())
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ func (sp *SlippageProtection) checkLiquidity(params *TradeParameters, check *Sli
|
||||
ratioPercent, _ := ratio.Float64()
|
||||
|
||||
if ratioPercent > 0.1 { // 10% of liquidity
|
||||
check.Warnings = append(check.Warnings,
|
||||
check.Warnings = append(check.Warnings,
|
||||
fmt.Sprintf("Trade size is %.2f%% of available liquidity", ratioPercent*100))
|
||||
}
|
||||
|
||||
@@ -255,13 +255,13 @@ func (sp *SlippageProtection) checkSandwichAttackRisk(params *TradeParameters, c
|
||||
|
||||
// Large trades are more susceptible to sandwich attacks
|
||||
if ratioPercent > 0.05 { // 5% of liquidity
|
||||
return fmt.Errorf("large trade size (%.2f%% of liquidity) may be vulnerable to sandwich attacks",
|
||||
return fmt.Errorf("large trade size (%.2f%% of liquidity) may be vulnerable to sandwich attacks",
|
||||
ratioPercent*100)
|
||||
}
|
||||
|
||||
// Check slippage tolerance - high tolerance increases sandwich risk
|
||||
if params.MaxSlippage > 1.0 { // 1%
|
||||
return fmt.Errorf("high slippage tolerance (%.2f%%) increases sandwich attack risk",
|
||||
return fmt.Errorf("high slippage tolerance (%.2f%%) increases sandwich attack risk",
|
||||
params.MaxSlippage)
|
||||
}
|
||||
|
||||
@@ -276,13 +276,13 @@ func (sp *SlippageProtection) AdjustForMarketConditions(params *TradeParameters,
|
||||
if volatility > 0.05 { // 5% volatility
|
||||
volatilityMultiplier := 1.0 + volatility
|
||||
adjusted.MaxSlippage = params.MaxSlippage * volatilityMultiplier
|
||||
|
||||
|
||||
// Cap at maximum allowed slippage
|
||||
if adjusted.MaxSlippage > sp.maxSlippagePercent {
|
||||
adjusted.MaxSlippage = sp.maxSlippagePercent
|
||||
}
|
||||
|
||||
sp.logger.Info(fmt.Sprintf("Adjusted slippage tolerance to %.2f%% due to high volatility %.2f%%",
|
||||
sp.logger.Info(fmt.Sprintf("Adjusted slippage tolerance to %.2f%% due to high volatility %.2f%%",
|
||||
adjusted.MaxSlippage, volatility*100))
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ func (sp *SlippageProtection) CreateSafeTradeParameters(
|
||||
conservativeSlippage := 0.5 // 0.5%
|
||||
amountInFloat := new(big.Float).SetInt(amountIn)
|
||||
expectedAmountOut := new(big.Float).Mul(amountInFloat, expectedPrice)
|
||||
|
||||
|
||||
// Apply slippage buffer
|
||||
slippageMultiplier := new(big.Float).SetFloat64(1.0 - conservativeSlippage/100.0)
|
||||
minAmountOut := new(big.Float).Mul(expectedAmountOut, slippageMultiplier)
|
||||
@@ -332,8 +332,8 @@ func (sp *SlippageProtection) SetMaxSlippage(maxSlippage float64) error {
|
||||
if err := sp.validator.ValidateSlippageTolerance(maxSlippage); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
sp.maxSlippagePercent = maxSlippage
|
||||
sp.logger.Info(fmt.Sprintf("Updated maximum slippage to %.2f%%", maxSlippage))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user