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

1""" 

2Multi-Chain Blockchain Scanner 

3 

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""" 

10 

11from enum import Enum 

12from typing import Dict, List, Any, Optional 

13from dataclasses import dataclass 

14 

15class BlockchainType(Enum): 

16 ETHEREUM = "ethereum" 

17 POLYGON = "polygon" 

18 BSC = "bsc" 

19 ARBITRUM = "arbitrum" 

20 OPTIMISM = "optimism" 

21 AVALANCHE = "avalanche" 

22 SOLANA = "solana" 

23 

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] 

36 

37class MultiChainScanner: 

38 """ 

39 Multi-chain blockchain scanner for comprehensive Web3 security 

40 """ 

41 

42 def __init__(self): 

43 self.supported_chains = self._initialize_chain_profiles() 

44 self.chain_specific_patterns = self._initialize_chain_patterns() 

45 

46 def scan_blockchain_context(self, code: str, context_chain: str = "ethereum") -> Dict[str, Any]: 

47 """ 

48 Analyze blockchain-specific security considerations 

49  

50 Args: 

51 code: Contract or program code 

52 context_chain: Target blockchain platform 

53  

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}'} 

60 

61 profile = self.supported_chains[chain_type] 

62 

63 # Chain-specific security patterns 

64 patterns = self.chain_specific_patterns.get(chain_type, {}) 

65 

66 security_analysis = { 

67 'blockchain': profile.name, 

68 'chain_specific_vulnerabilities': [], 

69 'gas_optimizations': [], 

70 'cross_chain_considerations': [], 

71 'economic_impact_factors': [] 

72 } 

73 

74 # Analyze for chain-specific patterns 

75 code_lower = code.lower() 

76 

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) 

88 

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 

92 

93 # Add economic impact factors 

94 economic_factors = self._analyze_economic_impact_factors(code, chain_type) 

95 security_analysis['economic_impact_factors'] = economic_factors 

96 

97 return security_analysis 

98 

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 [] 

106 

107 vulnerabilities = [] 

108 

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 } 

154 

155 return chain_vulns.get(chain_type, []) 

156 

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) 

163 

164 if not source or not target: 

165 return {'error': 'Unsupported blockchain for bridge analysis'} 

166 

167 bridge_analysis = { 

168 'source_chain': source_chain, 

169 'target_chain': target_chain, 

170 'vulnerabilities': [], 

171 'economic_risks': [], 

172 'recommendations': [] 

173 } 

174 

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 ] 

183 

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) 

194 

195 # Add economic risk assessment 

196 economic_risks = self._assess_bridge_economic_risks(bridge_code, source, target) 

197 bridge_analysis['economic_risks'] = economic_risks 

198 

199 return bridge_analysis 

200 

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 } 

269 

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 } 

298 

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 } 

312 

313 return chain_map.get(chain_name.lower()) 

314 

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") 

326 

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') 

347 

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 = [] 

351 

352 code_lower = code.lower() 

353 

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) 

363 

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) 

373 

374 return cross_chain_risks 

375 

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 = [] 

379 

380 profile = self.supported_chains.get(chain_type) 

381 if not profile: 

382 return impact_factors 

383 

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 }) 

397 

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 }) 

411 

412 return impact_factors 

413 

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 = [] 

417 

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) 

427 

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) 

438 

439 return economic_risks