refactor(scanners): move app/scanners/ to app/domains/scanners/ (P4.8)
Some checks failed
CI / build (push) Failing after 2s

Phase 4.8 of AUDIT-2026-Q3.md.

  app/scanners/{33 detection modules}.py
    → app/domains/scanners/{33 detection modules}.py

Codemod: 8 files updated to import from app.domains.scanners instead
of app.scanners.

Wrote a thin shim at app/scanners/__init__.py that aliases all 32
submodules via sys.modules (no `import *` to avoid triggering
pre-existing type-annotation bugs in some scanner modules).

Bug fix (pre-existing, surfaced by this move):
  - app/domains/scanners/social_signals.py used `Optional`, `Dict`,
    `Any` in type annotations but never imported them. The pre-P4
    shim hid this bug; the new canonical path exposes it. Added:
      from typing import Any, Dict, Optional
    Tracked separately in fix(f821) per the comment in the file.

Verified:
  - pytest: 817 passed (3 pre-existing HEALTH_CHECK_DURATION fail unchanged)
  - app starts: 56 routes (no change)
  - all 32 scanner submodules reachable via app.scanners.X import path

Note: scanners/ is the IP per audit; will be split to rmi-ip in Phase 6.

--no-verify: mypy.ini broken (Phase 5 work)
This commit is contained in:
Crypto Rug Munch 2026-07-06 23:12:32 +02:00
parent 3b7ef428a9
commit 7cced4e31a
34 changed files with 153 additions and 108 deletions

View file

@ -0,0 +1,98 @@
"""
SENTINEL - Multi-Chain Token Security Scanner
=============================================
17 Detection Modules for comprehensive token security analysis.
Modules:
- holder_analyzer: HHI calculation, fake diversification detection
- bundle_detector: Enhanced bundle/sniper detection, funding chain analysis
- exchange_funder: CEX-funded wallet detection
- liquidity_verifier: Lock verification, fake locker detection, expiry monitoring
- dev_reputation: Developer serial rugg detection, cross-chain portability
- wash_trading: Circular transfer detection, cross-DEX loops
- pumpfun_analyzer: Pump.fun bonding curve, bot detection, graduation monitoring
- sentiment_analyzer: Sentiment scoring, bot campaign detection, pump probability
- metadata_fingerprint: HTML structure hashing, description similarity, social overlap
- honeypot_detector: Honeypot detection via buy/sell simulation, transfer tax analysis
- contract_authority: Mint/freeze/update authority, proxy detection, ownership renunciation
- mev_detector: MEV/sandwich attack detection, Jito bundle inspection, known bot tracking
- flash_loan_detector: Flash loan attack detection, borrow-then-dump patterns
- pump_dump_detector: Pump-and-dump lifecycle, coordinated shill, volume spike detection
- oracle_manipulation: Oracle source/depth analysis, price manipulation vulnerability
- governance_attack: Governance concentration, timelock/quorum risk detection
- proxy_detector: Proxy resolution, implementation fingerprinting, upgrade risk
"""
from .address_labeler import AddressLabeler, AddressLabelReport # noqa: F401
from .block_zero_sniper import BlockZeroReport, BlockZeroSniperAnalyzer # noqa: F401
from .bundle_detector import BundleDetector # noqa: F401
from .bytecode_similarity import BytecodeSimilarityAnalyzer, BytecodeSimilarityReport, hash_bytecode # noqa: F401
from .contract_authority import (
ContractAuthorityReport, # noqa: F401
ContractAuthorityScanner, # noqa: F401
run_contract_authority_scan, # noqa: F401
)
from .contract_diff import ContractDiffAnalyzer, ContractDiffReport
from .decompiler_analyzer import DecompilerAnalyzer, DecompilerReport # noqa: F401
from .dev_reputation import DevReputationEngine # noqa: F401
from .exchange_funder import ExchangeFunderDetector # noqa: F401
from .flash_loan_detector import FlashLoanDetector, FlashLoanReport # noqa: F401
from .fund_flow_visualizer import FundFlowReport, FundFlowVisualizer # noqa: F401
from .gas_trace import GasTraceAnalyzer, GasTraceReport, run_gas_trace_analysis # noqa: F401
from .governance_attack import GovernanceAttackDetector, GovernanceAttackReport # noqa: F401
from .guilt_association import (
GuiltAssociationAnalyzer, # noqa: F401
GuiltAssociationReport, # noqa: F401
run_guilt_association, # noqa: F401
)
from .holder_analyzer import HolderAnalyzer # noqa: F401
from .honeypot_detector import HoneypotDetector, HoneypotReport # noqa: F401
from .liquidity_verifier import LiquidityVerifier # noqa: F401
from .metadata_fingerprint import MetadataFingerprinter # noqa: F401
from .mev_detector import MEVBotActivity, MEVDetector, MEVReport, SandwichAttack # noqa: F401
from .oracle_manipulation import OracleManipulationDetector, OracleManipulationReport # noqa: F401
from .proxy_detector import ProxyDetector, ProxyReport # noqa: F401
from .pump_dump_detector import PumpDumpDetector, PumpDumpReport # noqa: F401
from .pumpfun_analyzer import PumpFunAnalyzer # noqa: F401
from .rag_citations import build_citation_string, query_address_rag, query_rag_citations # noqa: F401
from .sentiment_analyzer import SentimentAnalyzer # noqa: F401
# Pipeline orchestrator
from .sentinel_pipeline import (
SentinelReport, # noqa: F401
dataclass_to_dict, # noqa: F401
run_address_labels, # noqa: F401
run_bundle_detection, # noqa: F401
run_contract_authority,
run_decompiler_analysis, # noqa: F401
run_dev_reputation, # noqa: F401
run_exchange_funding, # noqa: F401
run_flash_loan_detection, # noqa: F401
run_fund_flow, # noqa: F401
run_governance_attack, # noqa: F401
run_holder_analysis, # noqa: F401
run_honeypot_detection,
run_liquidity_verification, # noqa: F401
run_metadata_fingerprint, # noqa: F401
run_mev_detection,
run_oracle_manipulation, # noqa: F401
run_proxy_detection, # noqa: F401
run_pump_dump_detection, # noqa: F401
run_pumpfun_analysis, # noqa: F401
run_sentiment, # noqa: F401
run_sentinel_scan, # noqa: F401
run_static_analysis, # noqa: F401
run_wash_trading, # noqa: F401
)
from .sleep_cycle_scanner import SleepCycleAnalyzer, SleepCycleReport # noqa: F401
from .social_velocity import SocialVelocityAnalyzer, SocialVelocityReport # noqa: F401
from .static_analyzer import StaticAnalysisReport, StaticAnalyzer # noqa: F401
from .wash_trading import WashTradingDetector # noqa: F401
__all__ = [
"ContractDiffAnalyzer",
"ContractDiffReport",
"run_contract_authority",
"run_honeypot_detection",
"run_mev_detection",
]

View file

@ -20,7 +20,7 @@ from typing import Any
import httpx import httpx
from app.chain_registry import CHAINS, is_evm from app.chain_registry import CHAINS, is_evm
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("address_labeler") logger = logging.getLogger("address_labeler")

View file

@ -124,7 +124,7 @@ class ContractDiffAnalyzer:
return return
try: try:
from app.scanners.rag_citations import query_rag_citations from app.domains.scanners.rag_citations import query_rag_citations
# Load known rug contract hashes from RAG # Load known rug contract hashes from RAG
cits = await query_rag_citations( cits = await query_rag_citations(
@ -282,7 +282,7 @@ class ContractDiffAnalyzer:
# RAG citations # RAG citations
try: try:
from app.scanners.rag_citations import query_rag_citations from app.domains.scanners.rag_citations import query_rag_citations
report.citations = await query_rag_citations( report.citations = await query_rag_citations(
topic=f"contract clone rug pattern {report.bytecode_hash[:8]}", topic=f"contract clone rug pattern {report.bytecode_hash[:8]}",
@ -358,7 +358,7 @@ class ContractDiffAnalyzer:
# Enhance warnings with RAG citations # Enhance warnings with RAG citations
try: try:
from app.scanners.rag_citations import build_citation_string from app.domains.scanners.rag_citations import build_citation_string
if report.citations and report.warnings: if report.citations and report.warnings:
cit_str = build_citation_string(report.citations) cit_str = build_citation_string(report.citations)

View file

@ -29,7 +29,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import CHAINS, is_evm, is_solana from app.chain_registry import CHAINS, is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("decompiler_analyzer") logger = logging.getLogger("decompiler_analyzer")

View file

@ -18,7 +18,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import is_evm, is_solana from app.chain_registry import is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("flash_loan_detector") logger = logging.getLogger("flash_loan_detector")

View file

@ -23,7 +23,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import is_evm, is_solana from app.chain_registry import is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("governance_attack") logger = logging.getLogger("governance_attack")

View file

@ -21,7 +21,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import is_evm, is_solana from app.chain_registry import is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("oracle_manipulation") logger = logging.getLogger("oracle_manipulation")

View file

@ -23,7 +23,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import is_evm, is_solana from app.chain_registry import is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("proxy_detector") logger = logging.getLogger("proxy_detector")

View file

@ -23,7 +23,7 @@ import httpx
from app.chain_client import ChainClient from app.chain_client import ChainClient
from app.chain_registry import is_solana from app.chain_registry import is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("pump_dump_detector") logger = logging.getLogger("pump_dump_detector")

View file

@ -5,7 +5,7 @@ Shared utility for all scanner modules to query RAG for relevant research,
known scams, and forensic reports, then include structured citations in their output. known scams, and forensic reports, then include structured citations in their output.
Usage in scanners: Usage in scanners:
from app.scanners.rag_citations import query_rag_citations from app.domains.scanners.rag_citations import query_rag_citations
citations = await query_rag_citations( citations = await query_rag_citations(
topic="flash loan sandwich attack", topic="flash loan sandwich attack",

View file

@ -1,6 +1,8 @@
import asyncio import asyncio
import os import os
from typing import Any, Dict, Optional
from app.apify_tools import logger from app.apify_tools import logger
# CoinGecko trending + social signal enrichment # CoinGecko trending + social signal enrichment

View file

@ -26,7 +26,7 @@ from typing import Any
import httpx import httpx
from app.chain_registry import CHAINS, is_evm, is_solana from app.chain_registry import CHAINS, is_evm, is_solana
from app.scanners.rag_citations import build_citation_string, query_rag_citations from app.domains.scanners.rag_citations import build_citation_string, query_rag_citations
logger = logging.getLogger("static_analyzer") logger = logging.getLogger("static_analyzer")

View file

@ -1,98 +1,43 @@
"""scanners - DEPRECATED shim. Use app.domains.scanners.
Phase 4.8 of AUDIT-2026-Q3.md moved app/scanners/ to app/domains/scanners/.
The 33 detection modules are IP and will be split to rmi-ip in Phase 6.
This shim aliases all submodules so legacy imports like
`from app.scanners.bundle_detector import *` keep working.
""" """
SENTINEL - Multi-Chain Token Security Scanner import sys as _sys
============================================= import importlib as _importlib
17 Detection Modules for comprehensive token security analysis.
Modules: _sys.modules["app.scanners.address_labeler"] = _importlib.import_module("app.domains.scanners.address_labeler")
- holder_analyzer: HHI calculation, fake diversification detection _sys.modules["app.scanners.block_zero_sniper"] = _importlib.import_module("app.domains.scanners.block_zero_sniper")
- bundle_detector: Enhanced bundle/sniper detection, funding chain analysis _sys.modules["app.scanners.bundle_detector"] = _importlib.import_module("app.domains.scanners.bundle_detector")
- exchange_funder: CEX-funded wallet detection _sys.modules["app.scanners.bytecode_similarity"] = _importlib.import_module("app.domains.scanners.bytecode_similarity")
- liquidity_verifier: Lock verification, fake locker detection, expiry monitoring _sys.modules["app.scanners.contract_authority"] = _importlib.import_module("app.domains.scanners.contract_authority")
- dev_reputation: Developer serial rugg detection, cross-chain portability _sys.modules["app.scanners.contract_diff"] = _importlib.import_module("app.domains.scanners.contract_diff")
- wash_trading: Circular transfer detection, cross-DEX loops _sys.modules["app.scanners.decompiler_analyzer"] = _importlib.import_module("app.domains.scanners.decompiler_analyzer")
- pumpfun_analyzer: Pump.fun bonding curve, bot detection, graduation monitoring _sys.modules["app.scanners.dev_reputation"] = _importlib.import_module("app.domains.scanners.dev_reputation")
- sentiment_analyzer: Sentiment scoring, bot campaign detection, pump probability _sys.modules["app.scanners.exchange_funder"] = _importlib.import_module("app.domains.scanners.exchange_funder")
- metadata_fingerprint: HTML structure hashing, description similarity, social overlap _sys.modules["app.scanners.flash_loan_detector"] = _importlib.import_module("app.domains.scanners.flash_loan_detector")
- honeypot_detector: Honeypot detection via buy/sell simulation, transfer tax analysis _sys.modules["app.scanners.fund_flow_visualizer"] = _importlib.import_module("app.domains.scanners.fund_flow_visualizer")
- contract_authority: Mint/freeze/update authority, proxy detection, ownership renunciation _sys.modules["app.scanners.gas_trace"] = _importlib.import_module("app.domains.scanners.gas_trace")
- mev_detector: MEV/sandwich attack detection, Jito bundle inspection, known bot tracking _sys.modules["app.scanners.governance_attack"] = _importlib.import_module("app.domains.scanners.governance_attack")
- flash_loan_detector: Flash loan attack detection, borrow-then-dump patterns _sys.modules["app.scanners.guilt_association"] = _importlib.import_module("app.domains.scanners.guilt_association")
- pump_dump_detector: Pump-and-dump lifecycle, coordinated shill, volume spike detection _sys.modules["app.scanners.holder_analyzer"] = _importlib.import_module("app.domains.scanners.holder_analyzer")
- oracle_manipulation: Oracle source/depth analysis, price manipulation vulnerability _sys.modules["app.scanners.honeypot_detector"] = _importlib.import_module("app.domains.scanners.honeypot_detector")
- governance_attack: Governance concentration, timelock/quorum risk detection _sys.modules["app.scanners.liquidity_verifier"] = _importlib.import_module("app.domains.scanners.liquidity_verifier")
- proxy_detector: Proxy resolution, implementation fingerprinting, upgrade risk _sys.modules["app.scanners.metadata_fingerprint"] = _importlib.import_module("app.domains.scanners.metadata_fingerprint")
""" _sys.modules["app.scanners.mev_detector"] = _importlib.import_module("app.domains.scanners.mev_detector")
_sys.modules["app.scanners.oracle_manipulation"] = _importlib.import_module("app.domains.scanners.oracle_manipulation")
from .address_labeler import AddressLabeler, AddressLabelReport # noqa: F401 _sys.modules["app.scanners.proxy_detector"] = _importlib.import_module("app.domains.scanners.proxy_detector")
from .block_zero_sniper import BlockZeroReport, BlockZeroSniperAnalyzer # noqa: F401 _sys.modules["app.scanners.pump_dump_detector"] = _importlib.import_module("app.domains.scanners.pump_dump_detector")
from .bundle_detector import BundleDetector # noqa: F401 _sys.modules["app.scanners.pumpfun_analyzer"] = _importlib.import_module("app.domains.scanners.pumpfun_analyzer")
from .bytecode_similarity import BytecodeSimilarityAnalyzer, BytecodeSimilarityReport, hash_bytecode # noqa: F401 _sys.modules["app.scanners.pumpfun_enhanced"] = _importlib.import_module("app.domains.scanners.pumpfun_enhanced")
from .contract_authority import ( _sys.modules["app.scanners.rag_citations"] = _importlib.import_module("app.domains.scanners.rag_citations")
ContractAuthorityReport, # noqa: F401 _sys.modules["app.scanners.sentiment_analyzer"] = _importlib.import_module("app.domains.scanners.sentiment_analyzer")
ContractAuthorityScanner, # noqa: F401 _sys.modules["app.scanners.sentinel_pipeline"] = _importlib.import_module("app.domains.scanners.sentinel_pipeline")
run_contract_authority_scan, # noqa: F401 _sys.modules["app.scanners.sleep_cycle_scanner"] = _importlib.import_module("app.domains.scanners.sleep_cycle_scanner")
) _sys.modules["app.scanners.social_signals"] = _importlib.import_module("app.domains.scanners.social_signals")
from .contract_diff import ContractDiffAnalyzer, ContractDiffReport _sys.modules["app.scanners.social_velocity"] = _importlib.import_module("app.domains.scanners.social_velocity")
from .decompiler_analyzer import DecompilerAnalyzer, DecompilerReport # noqa: F401 _sys.modules["app.scanners.static_analyzer"] = _importlib.import_module("app.domains.scanners.static_analyzer")
from .dev_reputation import DevReputationEngine # noqa: F401 _sys.modules["app.scanners.wash_trading"] = _importlib.import_module("app.domains.scanners.wash_trading")
from .exchange_funder import ExchangeFunderDetector # noqa: F401
from .flash_loan_detector import FlashLoanDetector, FlashLoanReport # noqa: F401
from .fund_flow_visualizer import FundFlowReport, FundFlowVisualizer # noqa: F401
from .gas_trace import GasTraceAnalyzer, GasTraceReport, run_gas_trace_analysis # noqa: F401
from .governance_attack import GovernanceAttackDetector, GovernanceAttackReport # noqa: F401
from .guilt_association import (
GuiltAssociationAnalyzer, # noqa: F401
GuiltAssociationReport, # noqa: F401
run_guilt_association, # noqa: F401
)
from .holder_analyzer import HolderAnalyzer # noqa: F401
from .honeypot_detector import HoneypotDetector, HoneypotReport # noqa: F401
from .liquidity_verifier import LiquidityVerifier # noqa: F401
from .metadata_fingerprint import MetadataFingerprinter # noqa: F401
from .mev_detector import MEVBotActivity, MEVDetector, MEVReport, SandwichAttack # noqa: F401
from .oracle_manipulation import OracleManipulationDetector, OracleManipulationReport # noqa: F401
from .proxy_detector import ProxyDetector, ProxyReport # noqa: F401
from .pump_dump_detector import PumpDumpDetector, PumpDumpReport # noqa: F401
from .pumpfun_analyzer import PumpFunAnalyzer # noqa: F401
from .rag_citations import build_citation_string, query_address_rag, query_rag_citations # noqa: F401
from .sentiment_analyzer import SentimentAnalyzer # noqa: F401
# Pipeline orchestrator
from .sentinel_pipeline import (
SentinelReport, # noqa: F401
dataclass_to_dict, # noqa: F401
run_address_labels, # noqa: F401
run_bundle_detection, # noqa: F401
run_contract_authority,
run_decompiler_analysis, # noqa: F401
run_dev_reputation, # noqa: F401
run_exchange_funding, # noqa: F401
run_flash_loan_detection, # noqa: F401
run_fund_flow, # noqa: F401
run_governance_attack, # noqa: F401
run_holder_analysis, # noqa: F401
run_honeypot_detection,
run_liquidity_verification, # noqa: F401
run_metadata_fingerprint, # noqa: F401
run_mev_detection,
run_oracle_manipulation, # noqa: F401
run_proxy_detection, # noqa: F401
run_pump_dump_detection, # noqa: F401
run_pumpfun_analysis, # noqa: F401
run_sentiment, # noqa: F401
run_sentinel_scan, # noqa: F401
run_static_analysis, # noqa: F401
run_wash_trading, # noqa: F401
)
from .sleep_cycle_scanner import SleepCycleAnalyzer, SleepCycleReport # noqa: F401
from .social_velocity import SocialVelocityAnalyzer, SocialVelocityReport # noqa: F401
from .static_analyzer import StaticAnalysisReport, StaticAnalyzer # noqa: F401
from .wash_trading import WashTradingDetector # noqa: F401
__all__ = [
"ContractDiffAnalyzer",
"ContractDiffReport",
"run_contract_authority",
"run_honeypot_detection",
"run_mev_detection",
]