Coverage for src/alprina_cli/agents/web3_auditor/multi_chain_scanner.py: 25%
103 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
1"""
2Multi-Chain Blockchain Scanner
4Supports analysis across multiple blockchain platforms:
5- Ethereum & EVM compatible chains (Polygon, BSC, Arbitrum, Optimism)
6- Solana blockchain programs
7- Cross-chain bridge security analysis
8- Chain-specific vulnerability patterns
9"""
11from enum import Enum
12from typing import Dict, List, Any, Optional
13from dataclasses import dataclass
15class BlockchainType(Enum):
16 ETHEREUM = "ethereum"
17 POLYGON = "polygon"
18 BSC = "bsc"
19 ARBITRUM = "arbitrum"
20 OPTIMISM = "optimism"
21 AVALANCHE = "avalanche"
22 SOLANA = "solana"
24@dataclass
25class ChainProfile:
26 """Profile for each blockchain platform"""
27 type: BlockchainType
28 name: str
29 network_id: int
30 rpc_url: str
31 native_token: str
32 max_gas_limit: int
33 average_block_time: int # seconds
34 typical_gas_cost: int # gwei
35 security_considerations: List[str]
37class MultiChainScanner:
38 """
39 Multi-chain blockchain scanner for comprehensive Web3 security
40 """
42 def __init__(self):
43 self.supported_chains = self._initialize_chain_profiles()
44 self.chain_specific_patterns = self._initialize_chain_patterns()
46 def scan_blockchain_context(self, code: str, context_chain: str = "ethereum") -> Dict[str, Any]:
47 """
48 Analyze blockchain-specific security considerations
50 Args:
51 code: Contract or program code
52 context_chain: Target blockchain platform
54 Returns:
55 Blockchain-specific security analysis
56 """
57 chain_type = self._parse_chain_type(context_chain)
58 if not chain_type:
59 return {'error': f'Unsupported blockchain: {context_chain}'}
61 profile = self.supported_chains[chain_type]
63 # Chain-specific security patterns
64 patterns = self.chain_specific_patterns.get(chain_type, {})
66 security_analysis = {
67 'blockchain': profile.name,
68 'chain_specific_vulnerabilities': [],
69 'gas_optimizations': [],
70 'cross_chain_considerations': [],
71 'economic_impact_factors': []
72 }
74 # Analyze for chain-specific patterns
75 code_lower = code.lower()
77 for pattern_type, pattern_list in patterns.items():
78 for pattern in pattern_list:
79 if pattern in code_lower:
80 vulnerability = {
81 'type': pattern_type,
82 'pattern': pattern,
83 'description': self._get_pattern_description(pattern_type, chain_type),
84 'severity': self._get_pattern_severity(pattern_type, chain_type),
85 'blockchain': profile.name
86 }
87 security_analysis['chain_specific_vulnerabilities'].append(vulnerability)
89 # Add cross-chain considerations
90 cross_chain_risks = self._analyze_cross_chain_risks(code, chain_type)
91 security_analysis['cross_chain_considerations'] = cross_chain_risks
93 # Add economic impact factors
94 economic_factors = self._analyze_economic_impact_factors(code, chain_type)
95 security_analysis['economic_impact_factors'] = economic_factors
97 return security_analysis
99 def get_chain_vulnerabilities(self, blockchain: str) -> List[Dict[str, Any]]:
100 """
101 Get known vulnerabilities and attack vectors for specific blockchain
102 """
103 chain_type = self._parse_chain_type(blockchain)
104 if not chain_type:
105 return []
107 vulnerabilities = []
109 # Chain-specific vulnerability database
110 chain_vulns = {
111 BlockchainType.ETHEREUM: [
112 {
113 'type': 'gas_limit',
114 'description': 'Gas limit exhaustion attacks',
115 'severity': 'medium',
116 'examples': ['Bancor exploitation', 'Parity wallet freeze']
117 },
118 {
119 'type': 'self_destruct',
120 'description': 'Self-destruct function abuse',
121 'severity': 'high',
122 'examples': ['Parity multisig wallet', 'Multiple DeFi hacks']
123 }
124 ],
125 BlockchainType.POLYGON: [
126 {
127 'type': 'low_gas_fees',
128 'description': 'Low gas enables cheap spam attacks',
129 'severity': 'medium',
130 'examples': ['MEV extraction exploitation']
131 },
132 {
133 'type': 'bridge_dependency',
134 'description': 'Cross-chain bridge dependency risks',
135 'severity': 'high',
136 'examples': ['Cross-chain bridge exploits']
137 }
138 ],
139 BlockchainType.SOLANA: [
140 {
141 'type': 'account_rent',
142 'description': 'Account rent exhaustion attacks',
143 'severity': 'medium',
144 'examples': ['Account rent bug']
145 },
146 {
147 'type': 'network_partition',
148 'description': 'Network partition vulnerabilities',
149 'severity': 'high',
150 'examples': ['DDoS attacks on validators']
151 }
152 ]
153 }
155 return chain_vulns.get(chain_type, [])
157 def analyze_cross_chain_bridge(self, bridge_code: str, source_chain: str, target_chain: str) -> Dict[str, Any]:
158 """
159 Analyze cross-chain bridge security
160 """
161 source = self._parse_chain_type(source_chain)
162 target = self._parse_chain_type(target_chain)
164 if not source or not target:
165 return {'error': 'Unsupported blockchain for bridge analysis'}
167 bridge_analysis = {
168 'source_chain': source_chain,
169 'target_chain': target_chain,
170 'vulnerabilities': [],
171 'economic_risks': [],
172 'recommendations': []
173 }
175 # Common bridge vulnerability patterns
176 bridge_patterns = [
177 ('mint', 'Fake token minting', 'critical'),
178 ('burn', 'Invalid burn validation', 'high'),
179 ('swap', 'Exchange rate manipulation', 'high'),
180 ('fee', 'Fee manipulation attacks', 'medium'),
181 ('delay', 'Withdrawal delay exploitation', 'medium')
182 ]
184 code_lower = bridge_code.lower()
185 for pattern, description, severity in bridge_patterns:
186 if pattern in code_lower:
187 vulnerability = {
188 'pattern': pattern,
189 'description': description,
190 'severity': severity,
191 'context': 'cross-chain bridge'
192 }
193 bridge_analysis['vulnerabilities'].append(vulnerability)
195 # Add economic risk assessment
196 economic_risks = self._assess_bridge_economic_risks(bridge_code, source, target)
197 bridge_analysis['economic_risks'] = economic_risks
199 return bridge_analysis
201 def _initialize_chain_profiles(self) -> Dict[BlockchainType, ChainProfile]:
202 """Initialize blockchain profiles"""
203 return {
204 BlockchainType.ETHEREUM: ChainProfile(
205 type=BlockchainType.ETHEREUM,
206 name="Ethereum Mainnet",
207 network_id=1,
208 rpc_url="https://eth.llamarpc.com",
209 native_token="ETH",
210 max_gas_limit=30000000,
211 average_block_time=12,
212 typical_gas_cost=20,
213 security_considerations=[
214 "High gas costs limit attack viability",
215 "Mature security ecosystem",
216 "Extensive tooling available",
217 "Complex DeFi ecosystem increases attack surface"
218 ]
219 ),
220 BlockchainType.POLYGON: ChainProfile(
221 type=BlockchainType.POLYGON,
222 name="Polygon",
223 network_id=137,
224 rpc_url="https://polygon.llamarpc.com",
225 native_token="MATIC",
226 max_gas_limit=20000000,
227 average_block_time=2,
228 typical_gas_cost=30,
229 security_considerations=[
230 "Low gas costs enable cheap attacks",
231 "Cross-chain bridge dependencies",
232 "Fast block times increase race condition risks",
233 "Less mature security tools than Ethereum"
234 ]
235 ),
236 BlockchainType.BSC: ChainProfile(
237 type=BlockchainType.BSC,
238 name="BNB Smart Chain",
239 network_id=56,
240 rpc_url="https://bsc.llamarpc.com",
241 native_token="BNB",
242 max_gas_limit=30000000,
243 average_block_time=3,
244 typical_gas_cost=5,
245 security_considerations=[
246 "Validator centralization risks",
247 "Lower security standards than Ethereum",
248 "Faster transactions increase attack vectors",
249 "BSC bridge vulnerabilities"
250 ]
251 ),
252 BlockchainType.SOLANA: ChainProfile(
253 type=BlockchainType.SOLANA,
254 name="Solana",
255 network_id=0, # Solana uses different ID system
256 rpc_url="https://api.mainnet-beta.solana.com",
257 native_token="SOL",
258 max_gas_limit=1400000, # Compute units, not gas
259 average_block_time=0.4, # ~400ms
260 typical_gas_cost=0, # Transactions prioritized by fees
261 security_considerations=[
262 "No gas limits → possible DoS vectors",
263 "Account rent system creates new attack surface",
264 "Network partition vulnerabilities",
265 "Different programming model requires specialized tools"
266 ]
267 )
268 }
270 def _initialize_chain_patterns(self) -> Dict[BlockchainType, Dict[str, List[str]]]:
271 """Initialize chain-specific vulnerability patterns"""
272 return {
273 BlockchainType.ETHEREUM: {
274 'gas_griefing': ['selfdestruct', 'gas', 'block.gaslimit'],
275 'reentrancy': ['call', 'send', 'transfer'],
276 'access_control': ['onlyOwner', 'require', 'modifiers'],
277 'gas_optimization': ['assembly', 'bytes', 'memory']
278 },
279 BlockchainType.POLYGON: {
280 'low_gas_spam': ['spam', 'attacker', 'griefing'],
281 'bridge_risks': ['polygon_bridge', 'cross_chain', 'withdraw'],
282 'mev_extraction': ['mev', 'arbitrage', 'front_run'],
283 'gas_optimization': ['optimistic', 'rollups']
284 },
285 BlockchainType.BSC: {
286 'validator_risks': ['validator', 'staking', 'centralized'],
287 'cross_chain': ['bridge', 'wormhole', 'bnb'],
288 'copy_ethereum_patterns': ['fork', 'ethereum', 'hardhat'],
289 'speed_attacks': ['fast_blocks', 'race_condition']
290 },
291 BlockchainType.SOLANA: {
292 'rent_attack': ['account_rent', 'rent exemption', 'lamports'],
293 'network_partition': ['partition', 'ddos', 'validators'],
294 'account_model': ['account_info', 'system_program', 'pda'],
295 'mev_exploitation': ['mev', 'priority_fee', 'jito']
296 }
297 }
299 def _parse_chain_type(self, chain_name: str) -> Optional[BlockchainType]:
300 """Parse chain name to enum type"""
301 chain_map = {
302 'ethereum': BlockchainType.ETHEREUM,
303 'eth': BlockchainType.ETHEREUM,
304 'mainnet': BlockchainType.ETHEREUM,
305 'polygon': BlockchainType.POLYGON,
306 'matic': BlockchainType.POLYGON,
307 'bsc': BlockchainType.BSC,
308 'binance': BlockchainType.BSC,
309 'solana': BlockchainType.SOLANA,
310 'sol': BlockchainType.SOLANA
311 }
313 return chain_map.get(chain_name.lower())
315 def _get_pattern_description(self, pattern_type: str, chain: BlockchainType) -> str:
316 """Get description for chain-specific pattern"""
317 descriptions = {
318 'gas_griefing': "Gas exhaustion attack vectors",
319 'reentrancy': "Reentrancy vulnerabilities",
320 'low_gas_spam': "Low gas enables spam attacks",
321 'bridge_risks': "Cross-chain bridge vulnerabilities",
322 'rent_attack': "Account rent exhaustion attacks",
323 'network_partition': "Network partition vulnerabilities"
324 }
325 return descriptions.get(pattern_type, f"{pattern_type} vulnerability")
327 def _get_pattern_severity(self, pattern_type: str, chain: BlockchainType) -> str:
328 """Get severity level for chain-specific pattern"""
329 severity_map = {
330 BlockchainType.ETHEREUM: {
331 'gas_griefing': 'medium', # High gas limits mitigate
332 'reentrancy': 'high',
333 'mev_extraction': 'high'
334 },
335 BlockchainType.POLYGON: {
336 'low_gas_spam': 'high', # Low gas enables spam
337 'bridge_risks': 'critical', # Bridge dependencies are critical
338 'mev_extraction': 'high'
339 },
340 BlockchainType.SOLANA: {
341 'rent_attack': 'medium',
342 'network_partition': 'critical',
343 'mev_exploitation': 'high'
344 }
345 }
346 return severity_map.get(chain, {}).get(pattern_type, 'medium')
348 def _analyze_cross_chain_risks(self, code: str, chain_type: BlockchainType) -> List[Dict[str, Any]]:
349 """Analyze cross-chain bridge and protocol interaction risks"""
350 cross_chain_risks = []
352 code_lower = code.lower()
354 # Check for bridge integrations
355 if any(bridge_token in code_lower for bridge_token in ['bridge', 'wormhole', 'layerzero']):
356 risk = {
357 'type': 'bridge_dependency',
358 'description': 'Cross-chain bridge integration detected',
359 'severity': 'high',
360 'mitigation': 'Validate bridge security and implement withdrawal delays'
361 }
362 cross_chain_risks.append(risk)
364 # Check for multi-chain deployment patterns
365 if any(multi_token in code_lower for multi_token in ['polygon', 'bsc', 'arbitrum']):
366 risk = {
367 'type': 'multi_chain_deployment',
368 'description': 'Multi-chain deployment increases attack surface',
369 'severity': 'medium',
370 'mitigation': 'Ensure consistent security across all chains'
371 }
372 cross_chain_risks.append(risk)
374 return cross_chain_risks
376 def _analyze_economic_impact_factors(self, code: str, chain_type: BlockchainType) -> List[Dict[str, Any]]:
377 """Analyze factors affecting economic impact of vulnerabilities"""
378 impact_factors = []
380 profile = self.supported_chains.get(chain_type)
381 if not profile:
382 return impact_factors
384 # Gas cost impact
385 if profile.typical_gas_cost > 50:
386 impact_factors.append({
387 'factor': 'high_gas_costs',
388 'impact': 'reduces attack viability but increases user cost',
389 'severity': 'medium'
390 })
391 elif profile.typical_gas_cost < 10:
392 impact_factors.append({
393 'factor': 'low_gas_costs',
394 'impact': 'enables cheap attacks and spam',
395 'severity': 'high'
396 })
398 # Block time impact
399 if profile.average_block_time > 10:
400 impact_factors.append({
401 'factor': 'slow_blocks',
402 'impact': 'slower response to attacks but higher finality',
403 'severity': 'low'
404 })
405 elif profile.average_block_time < 2:
406 impact_factors.append({
407 'factor': 'fast_blocks',
408 'impact': 'enables faster attacks and MEV extraction',
409 'severity': 'medium'
410 })
412 return impact_factors
414 def _assess_bridge_economic_risks(self, code: str, source: BlockchainType, target: BlockchainType) -> List[Dict[str, Any]]:
415 """Assess economic risks in cross-chain bridges"""
416 economic_risks = []
418 # Check for liquidity provision risks
419 if 'liquidity' in code.lower() or 'pool' in code.lower():
420 risk = {
421 'type': 'liquidity_manipulation',
422 'description': 'Liquidity pool manipulation attacks',
423 'potential_loss': 'Complete liquidity drain',
424 'severity': 'critical'
425 }
426 economic_risks.append(risk)
428 # Check for mint/burn validation
429 if ('mint' in code.lower() and 'require' not in code.lower()) or \
430 ('burn' in code.lower() and 'require' not in code.lower()):
431 risk = {
432 'type': 'token_manipulation',
433 'description': 'Invalid token mint/burn validation',
434 'potential_loss': 'Token supply manipulation',
435 'severity': 'critical'
436 }
437 economic_risks.append(risk)
439 return economic_risks