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:
@@ -13,10 +13,10 @@ import (
|
||||
// InputValidator provides comprehensive validation for external data
|
||||
type InputValidator struct {
|
||||
// Regex patterns for validation
|
||||
addressPattern *regexp.Regexp
|
||||
txHashPattern *regexp.Regexp
|
||||
blockHashPattern *regexp.Regexp
|
||||
hexDataPattern *regexp.Regexp
|
||||
addressPattern *regexp.Regexp
|
||||
txHashPattern *regexp.Regexp
|
||||
blockHashPattern *regexp.Regexp
|
||||
hexDataPattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// NewInputValidator creates a new input validator
|
||||
@@ -45,16 +45,16 @@ func (v *InputValidator) ValidateAddress(address string) error {
|
||||
if address == "" {
|
||||
return &ValidationError{"address", address, "address cannot be empty"}
|
||||
}
|
||||
|
||||
|
||||
if !v.addressPattern.MatchString(address) {
|
||||
return &ValidationError{"address", address, "invalid address format"}
|
||||
}
|
||||
|
||||
|
||||
// Additional validation: check for zero address
|
||||
if address == "0x0000000000000000000000000000000000000000" {
|
||||
return &ValidationError{"address", address, "zero address not allowed"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ func (v *InputValidator) ValidateTransactionHash(hash string) error {
|
||||
if hash == "" {
|
||||
return &ValidationError{"txHash", hash, "transaction hash cannot be empty"}
|
||||
}
|
||||
|
||||
|
||||
if !v.txHashPattern.MatchString(hash) {
|
||||
return &ValidationError{"txHash", hash, "invalid transaction hash format"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -81,11 +81,11 @@ func (v *InputValidator) ValidateBlockHash(hash string) error {
|
||||
if hash == "" {
|
||||
return &ValidationError{"blockHash", hash, "block hash cannot be empty"}
|
||||
}
|
||||
|
||||
|
||||
if !v.blockHashPattern.MatchString(hash) {
|
||||
return &ValidationError{"blockHash", hash, "invalid block hash format"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ func (v *InputValidator) ValidateHexData(data string) error {
|
||||
if data == "" {
|
||||
return nil // Empty data is valid
|
||||
}
|
||||
|
||||
|
||||
if !v.hexDataPattern.MatchString(data) {
|
||||
return &ValidationError{"hexData", data, "invalid hex data format"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -107,17 +107,17 @@ func (v *InputValidator) ValidateBigInt(value *big.Int, fieldName string) error
|
||||
if value == nil {
|
||||
return &ValidationError{fieldName, value, "value cannot be nil"}
|
||||
}
|
||||
|
||||
|
||||
// Check for reasonable bounds to prevent overflow attacks
|
||||
maxValue := new(big.Int).Exp(big.NewInt(10), big.NewInt(77), nil) // 10^77
|
||||
if value.Cmp(maxValue) > 0 {
|
||||
return &ValidationError{fieldName, value, "value exceeds maximum allowed"}
|
||||
}
|
||||
|
||||
|
||||
if value.Sign() < 0 {
|
||||
return &ValidationError{fieldName, value, "negative values not allowed"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -125,11 +125,11 @@ func (v *InputValidator) ValidateBigInt(value *big.Int, fieldName string) error
|
||||
func (v *InputValidator) ValidateBlockNumber(blockNumber uint64) error {
|
||||
// Check for reasonable block number bounds
|
||||
maxBlock := uint64(1000000000) // 1 billion - reasonable upper bound
|
||||
|
||||
|
||||
if blockNumber > maxBlock {
|
||||
return &ValidationError{"blockNumber", blockNumber, "block number exceeds reasonable bounds"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -138,53 +138,53 @@ func (v *InputValidator) ValidateTransaction(tx *types.Transaction) error {
|
||||
if tx == nil {
|
||||
return &ValidationError{"transaction", tx, "transaction cannot be nil"}
|
||||
}
|
||||
|
||||
|
||||
// Validate transaction hash
|
||||
if err := v.ValidateTransactionHash(tx.Hash().Hex()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate to address if present
|
||||
if tx.To() != nil {
|
||||
if err := v.ValidateCommonAddress(*tx.To()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Validate value
|
||||
if err := v.ValidateBigInt(tx.Value(), "value"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate gas limit
|
||||
gasLimit := tx.Gas()
|
||||
if gasLimit > 50000000 { // 50M gas limit seems reasonable
|
||||
return &ValidationError{"gasLimit", gasLimit, "gas limit exceeds reasonable bounds"}
|
||||
}
|
||||
|
||||
|
||||
// Validate gas price
|
||||
if tx.GasPrice() != nil {
|
||||
if err := v.ValidateBigInt(tx.GasPrice(), "gasPrice"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Check for reasonable gas price bounds (up to 1000 Gwei)
|
||||
maxGasPrice := big.NewInt(1000000000000) // 1000 Gwei in wei
|
||||
if tx.GasPrice().Cmp(maxGasPrice) > 0 {
|
||||
return &ValidationError{"gasPrice", tx.GasPrice(), "gas price exceeds reasonable bounds"}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Validate transaction data
|
||||
if err := v.ValidateHexData(common.Bytes2Hex(tx.Data())); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Check data size limits
|
||||
if len(tx.Data()) > 1024*1024 { // 1MB limit
|
||||
return &ValidationError{"data", len(tx.Data()), "transaction data exceeds size limit"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -193,45 +193,45 @@ func (v *InputValidator) ValidateBlock(block *types.Block) error {
|
||||
if block == nil {
|
||||
return &ValidationError{"block", block, "block cannot be nil"}
|
||||
}
|
||||
|
||||
|
||||
// Validate block number
|
||||
if err := v.ValidateBlockNumber(block.Number().Uint64()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate block hash
|
||||
if err := v.ValidateBlockHash(block.Hash().Hex()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate parent hash
|
||||
if err := v.ValidateBlockHash(block.ParentHash().Hex()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate coinbase address
|
||||
if err := v.ValidateCommonAddress(block.Coinbase()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Validate timestamp
|
||||
timestamp := block.Time()
|
||||
if timestamp == 0 {
|
||||
return &ValidationError{"timestamp", timestamp, "timestamp cannot be zero"}
|
||||
}
|
||||
|
||||
|
||||
// Check for future timestamps (with 5 minute tolerance)
|
||||
maxTimestamp := uint64(1<<63 - 1) // Max int64
|
||||
if timestamp > maxTimestamp {
|
||||
return &ValidationError{"timestamp", timestamp, "timestamp exceeds maximum value"}
|
||||
}
|
||||
|
||||
|
||||
// Validate transaction count
|
||||
txCount := len(block.Transactions())
|
||||
if txCount > 10000 { // Reasonable transaction count limit
|
||||
return &ValidationError{"txCount", txCount, "transaction count exceeds reasonable limit"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -240,19 +240,19 @@ func (v *InputValidator) ValidateAmount(amount *big.Int, tokenDecimals uint8, fi
|
||||
if err := v.ValidateBigInt(amount, fieldName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Check for dust amounts (too small to be meaningful)
|
||||
minAmount := big.NewInt(1)
|
||||
if amount.Cmp(minAmount) < 0 {
|
||||
return &ValidationError{fieldName, amount, "amount too small (dust)"}
|
||||
}
|
||||
|
||||
|
||||
// Check for unreasonably large amounts based on token decimals
|
||||
maxTokenAmount := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenDecimals+9)), nil) // 1B tokens
|
||||
if amount.Cmp(maxTokenAmount) > 0 {
|
||||
return &ValidationError{fieldName, amount, "amount exceeds reasonable token bounds"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -261,11 +261,11 @@ func (v *InputValidator) ValidateSlippageTolerance(slippage float64) error {
|
||||
if slippage < 0 {
|
||||
return &ValidationError{"slippage", slippage, "slippage cannot be negative"}
|
||||
}
|
||||
|
||||
|
||||
if slippage > 50.0 { // 50% max slippage
|
||||
return &ValidationError{"slippage", slippage, "slippage exceeds maximum allowed (50%)"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -274,14 +274,14 @@ func (v *InputValidator) ValidateDeadline(deadline uint64) error {
|
||||
if deadline == 0 {
|
||||
return &ValidationError{"deadline", deadline, "deadline cannot be zero"}
|
||||
}
|
||||
|
||||
|
||||
// Check if deadline is in the past (with 1 minute tolerance)
|
||||
// Note: This would need actual timestamp comparison in real implementation
|
||||
maxDeadline := uint64(1<<32 - 1) // Reasonable unix timestamp bound
|
||||
if deadline > maxDeadline {
|
||||
return &ValidationError{"deadline", deadline, "deadline exceeds reasonable bounds"}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -290,15 +290,15 @@ func (v *InputValidator) SanitizeString(input string) string {
|
||||
// Remove null bytes and control characters
|
||||
cleaned := strings.ReplaceAll(input, "\x00", "")
|
||||
cleaned = regexp.MustCompile(`[\x00-\x1F\x7F]`).ReplaceAllString(cleaned, "")
|
||||
|
||||
|
||||
// Trim whitespace
|
||||
cleaned = strings.TrimSpace(cleaned)
|
||||
|
||||
|
||||
// Limit length
|
||||
if len(cleaned) > 1000 {
|
||||
cleaned = cleaned[:1000]
|
||||
}
|
||||
|
||||
|
||||
return cleaned
|
||||
}
|
||||
|
||||
@@ -307,23 +307,23 @@ func (v *InputValidator) ValidateEvent(event interface{}) error {
|
||||
if event == nil {
|
||||
return &ValidationError{"event", event, "event cannot be nil"}
|
||||
}
|
||||
|
||||
|
||||
// Use reflection or type assertion to validate event fields
|
||||
// For now, just validate that it's not nil
|
||||
// In a real implementation, you'd validate specific event fields
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateMultiple validates multiple fields and returns all errors
|
||||
func (v *InputValidator) ValidateMultiple(validators ...func() error) []error {
|
||||
var errors []error
|
||||
|
||||
|
||||
for _, validator := range validators {
|
||||
if err := validator(); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return errors
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user