Files
explorer-monorepo/backend/analytics/address_risk.go

101 lines
2.1 KiB
Go

package analytics
import (
"context"
"github.com/jackc/pgx/v5/pgxpool"
)
// AddressRiskAnalyzer analyzes address risk
type AddressRiskAnalyzer struct {
db *pgxpool.Pool
chainID int
}
// NewAddressRiskAnalyzer creates a new address risk analyzer
func NewAddressRiskAnalyzer(db *pgxpool.Pool, chainID int) *AddressRiskAnalyzer {
return &AddressRiskAnalyzer{
db: db,
chainID: chainID,
}
}
// RiskAnalysis represents address risk analysis
type RiskAnalysis struct {
Address string
RiskScore float64
RiskLevel string
Factors map[string]bool
Flags []string
}
// AnalyzeAddress analyzes risk for an address
func (ara *AddressRiskAnalyzer) AnalyzeAddress(ctx context.Context, address string) (*RiskAnalysis, error) {
// Get address statistics
query := `
SELECT
tx_count_sent,
tx_count_received,
total_sent_wei,
total_received_wei
FROM addresses
WHERE address = $1 AND chain_id = $2
`
var txSent, txReceived int
var totalSent, totalReceived string
err := ara.db.QueryRow(ctx, query, address, ara.chainID).Scan(&txSent, &txReceived, &totalSent, &totalReceived)
if err != nil {
// Address not found, return low risk
return &RiskAnalysis{
Address: address,
RiskScore: 0.0,
RiskLevel: "low",
Factors: make(map[string]bool),
Flags: []string{},
}, nil
}
// Calculate risk score (simplified)
riskScore := 0.0
factors := make(map[string]bool)
flags := []string{}
// High volume = lower risk
if txSent+txReceived > 100 {
factors["high_volume"] = true
riskScore -= 0.1
}
// Check for suspicious patterns (simplified)
if txSent > 1000 && txReceived == 0 {
factors["suspicious_activity"] = true
riskScore += 0.3
flags = append(flags, "high_outbound_only")
}
// Normalize risk score
if riskScore < 0 {
riskScore = 0
}
if riskScore > 1 {
riskScore = 1
}
riskLevel := "low"
if riskScore > 0.7 {
riskLevel = "high"
} else if riskScore > 0.4 {
riskLevel = "medium"
}
return &RiskAnalysis{
Address: address,
RiskScore: riskScore,
RiskLevel: riskLevel,
Factors: factors,
Flags: flags,
}, nil
}