- 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>
114 lines
4.6 KiB
Go
114 lines
4.6 KiB
Go
package database
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/fraktal/mev-beta/internal/config"
|
|
"github.com/fraktal/mev-beta/internal/logger"
|
|
)
|
|
|
|
func TestDatabaseOperations(t *testing.T) {
|
|
// Create a temporary database for testing
|
|
cfg := &config.DatabaseConfig{
|
|
File: ":memory:", // In-memory database for testing
|
|
MaxOpenConnections: 10,
|
|
MaxIdleConnections: 5,
|
|
}
|
|
|
|
// Create logger
|
|
log := logger.New("debug", "text", "")
|
|
|
|
// Create database
|
|
db, err := NewDatabase(cfg, log)
|
|
require.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Test inserting a swap event
|
|
swapEvent := &SwapEvent{
|
|
Timestamp: time.Now(),
|
|
BlockNumber: 12345678,
|
|
TxHash: common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"),
|
|
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
|
|
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC
|
|
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH
|
|
Amount0In: big.NewInt(1000000000), // 1000 USDC
|
|
Amount1In: big.NewInt(0),
|
|
Amount0Out: big.NewInt(0),
|
|
Amount1Out: big.NewInt(500000000000000000), // 0.5 WETH
|
|
Sender: common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678"),
|
|
Recipient: common.HexToAddress("0x8765432109fedcba8765432109fedcba87654321"),
|
|
Protocol: "uniswap_v3",
|
|
}
|
|
|
|
err = db.InsertSwapEvent(swapEvent)
|
|
assert.NoError(t, err)
|
|
|
|
// Test inserting a liquidity event
|
|
liquidityEvent := &LiquidityEvent{
|
|
Timestamp: time.Now(),
|
|
BlockNumber: 12345679,
|
|
TxHash: common.HexToHash("0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"),
|
|
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
|
|
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC
|
|
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH
|
|
Liquidity: big.NewInt(1000000000000000000), // 1 ETH equivalent
|
|
Amount0: big.NewInt(2000000000), // 2000 USDC
|
|
Amount1: big.NewInt(1000000000000000000), // 1 WETH
|
|
EventType: "add",
|
|
Protocol: "uniswap_v3",
|
|
}
|
|
|
|
err = db.InsertLiquidityEvent(liquidityEvent)
|
|
assert.NoError(t, err)
|
|
|
|
// Test inserting pool data
|
|
poolData := &PoolData{
|
|
Address: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
|
|
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), // USDC
|
|
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH
|
|
Fee: 3000, // 0.3%
|
|
Liquidity: big.NewInt(1000000000000000000), // 1 ETH equivalent
|
|
SqrtPriceX96: big.NewInt(2505414483750470000), // Realistic price
|
|
Tick: 200000, // Corresponding tick
|
|
LastUpdated: time.Now().UTC(), // Use UTC for consistent format
|
|
Protocol: "uniswap_v3",
|
|
}
|
|
|
|
err = db.InsertPoolData(poolData)
|
|
assert.NoError(t, err)
|
|
|
|
// Test retrieving recent swap events
|
|
swaps, err := db.GetRecentSwapEvents(10)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, swaps, 1)
|
|
assert.Equal(t, swapEvent.PoolAddress, swaps[0].PoolAddress)
|
|
assert.Equal(t, swapEvent.Token0, swaps[0].Token0)
|
|
assert.Equal(t, swapEvent.Token1, swaps[0].Token1)
|
|
assert.Equal(t, swapEvent.Protocol, swaps[0].Protocol)
|
|
|
|
// Test retrieving recent liquidity events
|
|
liquidityEvents, err := db.GetRecentLiquidityEvents(10)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, liquidityEvents, 1)
|
|
assert.Equal(t, liquidityEvent.PoolAddress, liquidityEvents[0].PoolAddress)
|
|
assert.Equal(t, liquidityEvent.Token0, liquidityEvents[0].Token0)
|
|
assert.Equal(t, liquidityEvent.Token1, liquidityEvents[0].Token1)
|
|
assert.Equal(t, liquidityEvent.EventType, liquidityEvents[0].EventType)
|
|
assert.Equal(t, liquidityEvent.Protocol, liquidityEvents[0].Protocol)
|
|
|
|
// Test retrieving pool data
|
|
retrievedPool, err := db.GetPoolData(poolData.Address)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, poolData.Address, retrievedPool.Address)
|
|
assert.Equal(t, poolData.Token0, retrievedPool.Token0)
|
|
assert.Equal(t, poolData.Token1, retrievedPool.Token1)
|
|
assert.Equal(t, poolData.Fee, retrievedPool.Fee)
|
|
assert.Equal(t, poolData.Protocol, retrievedPool.Protocol)
|
|
}
|