athena-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +477 -0
  2. package/install.js +327 -0
  3. package/mcp/servers.json +100 -0
  4. package/mcp/tools/README.md +64 -0
  5. package/mcp/tools/__init__.py +1 -0
  6. package/mcp/tools/aderyn_runner.py +226 -0
  7. package/mcp/tools/eas_attest.py +404 -0
  8. package/mcp/tools/evidence_chain.py +363 -0
  9. package/mcp/tools/exploit_simulator.py +545 -0
  10. package/mcp/tools/fuzz_runner.py +440 -0
  11. package/mcp/tools/gev_analyzer.py +362 -0
  12. package/mcp/tools/halmos_runner.py +408 -0
  13. package/mcp/tools/incremental_auditor.py +441 -0
  14. package/mcp/tools/knowledge_base.py +378 -0
  15. package/mcp/tools/poc_generator.py +479 -0
  16. package/mcp/tools/protocol_scanner.py +456 -0
  17. package/mcp/tools/repair_validator.py +421 -0
  18. package/mcp/tools/slither_runner.py +221 -0
  19. package/package.json +52 -0
  20. package/requirements.txt +20 -0
  21. package/skills/glm-audit-skill/SKILL.md +73 -0
  22. package/skills/glm-audit-skill/references/audit-agents/access-control-agent.md +42 -0
  23. package/skills/glm-audit-skill/references/audit-agents/asymmetry-agent.md +42 -0
  24. package/skills/glm-audit-skill/references/audit-agents/boundary-agent.md +42 -0
  25. package/skills/glm-audit-skill/references/audit-agents/economic-security-agent.md +42 -0
  26. package/skills/glm-audit-skill/references/audit-agents/execution-trace-agent.md +42 -0
  27. package/skills/glm-audit-skill/references/audit-agents/first-principles-agent.md +42 -0
  28. package/skills/glm-audit-skill/references/audit-agents/flow-gap-agent.md +38 -0
  29. package/skills/glm-audit-skill/references/audit-agents/invariant-agent.md +37 -0
  30. package/skills/glm-audit-skill/references/audit-agents/math-precision-agent.md +37 -0
  31. package/skills/glm-audit-skill/references/audit-agents/numerical-gap-agent.md +37 -0
  32. package/skills/glm-audit-skill/references/audit-agents/periphery-agent.md +37 -0
  33. package/skills/glm-audit-skill/references/audit-agents/shared-rules.md +37 -0
  34. package/skills/glm-audit-skill/references/audit-agents/trust-gap-agent.md +39 -0
  35. package/skills/glm-audit-skill/references/judging.md +45 -0
  36. package/skills/glm-audit-skill/references/report-formatting.md +22 -0
  37. package/skills/glm-audit-skill/references/senior-auditor-sop.md +34 -0
@@ -0,0 +1,362 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP Server: GEV Analyzer
4
+ Generalized Extractable Value (GEV) analysis tool.
5
+ Based on "Extraction Is Conserved: From MEV to GEV" (2026-05-25)
6
+ """
7
+ import sys
8
+ import json
9
+ import asyncio
10
+ import logging
11
+
12
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
13
+ logger = logging.getLogger("gev_analyzer")
14
+
15
+ TOOL_NAME = "gev_analyzer"
16
+ TOOL_VERSION = "1.0.0"
17
+
18
+ # GEV extraction layers
19
+ EXTRACTION_LAYERS = {
20
+ "l1_consensus": {
21
+ "name": "L1 Consensus Layer",
22
+ "description": "Block proposer extraction (traditional MEV)",
23
+ "examples": ["sandwich attacks", "front-running", "back-running", "liquidation MEV"]
24
+ },
25
+ "l2_execution": {
26
+ "name": "L2 Execution Layer",
27
+ "description": "L2 sequencer extraction",
28
+ "examples": ["sequencer MEV", "cross-domain MEV", "L2 priority gas"]
29
+ },
30
+ "application": {
31
+ "name": "Application Layer",
32
+ "description": "Protocol-level extraction",
33
+ "examples": ["oracle manipulation", "governance attacks", "liquidity provision MEV"]
34
+ },
35
+ "user": {
36
+ "name": "User Layer",
37
+ "description": "User-initiated extraction",
38
+ "examples": ["arbitrage", "liquidation bots", "JIT liquidity"]
39
+ }
40
+ }
41
+
42
+ # GEV attack patterns
43
+ ATTACK_PATTERNS = {
44
+ "oracle_manipulation": {
45
+ "name": "Oracle Manipulation",
46
+ "severity": "critical",
47
+ "layers": ["application"],
48
+ "description": "Manipulate price oracle to extract value",
49
+ "indicators": ["spot_price_dependency", "single_source_oracle", "no_twap"]
50
+ },
51
+ "cross_domain_mev": {
52
+ "name": "Cross-Domain MEV",
53
+ "severity": "high",
54
+ "layers": ["l1_consensus", "l2_execution"],
55
+ "description": "Extract value across L1/L2 boundaries",
56
+ "indicators": ["bridge_dependency", "async_finality", "cross_layer_calls"]
57
+ },
58
+ "governance_extraction": {
59
+ "name": "Governance Extraction",
60
+ "severity": "high",
61
+ "layers": ["application"],
62
+ "description": "Manipulate governance for value extraction",
63
+ "indicators": ["flash_loan_voting", "timelock_manipulation", "proposal_front_running"]
64
+ },
65
+ "liquidity_mev": {
66
+ "name": "Liquidity MEV",
67
+ "severity": "medium",
68
+ "layers": ["application", "user"],
69
+ "description": "Extract value from liquidity provision/removal",
70
+ "indicators": ["jit_liquidity", "sandwich_lp", "impermanent_loss_exploitation"]
71
+ },
72
+ "sequencer_mev": {
73
+ "name": "Sequencer MEV",
74
+ "severity": "high",
75
+ "layers": ["l2_execution"],
76
+ "description": "L2 sequencer extracting value from transaction ordering",
77
+ "indicators": ["centralized_sequencer", "no_fair_ordering", "soft_commitments"]
78
+ }
79
+ }
80
+
81
+
82
+ def build_tool_definitions() -> list:
83
+ return [
84
+ {
85
+ "name": "analyze_gev_surface",
86
+ "description": "Analyze a contract's Generalized Extractable Value (GEV) surface",
87
+ "inputSchema": {
88
+ "type": "object",
89
+ "properties": {
90
+ "contract_code": {
91
+ "type": "string",
92
+ "description": "Solidity source code to analyze"
93
+ },
94
+ "network": {
95
+ "type": "string",
96
+ "enum": ["ethereum_l1", "optimism", "arbitrum", "base", "polygon"],
97
+ "description": "Target network"
98
+ }
99
+ },
100
+ "required": ["contract_code"]
101
+ }
102
+ },
103
+ {
104
+ "name": "list_gev_patterns",
105
+ "description": "List all known GEV attack patterns with descriptions",
106
+ "inputSchema": {
107
+ "type": "object",
108
+ "properties": {}
109
+ }
110
+ },
111
+ {
112
+ "name": "calculate_gev_risk",
113
+ "description": "Calculate GEV risk score for a contract based on its features",
114
+ "inputSchema": {
115
+ "type": "object",
116
+ "properties": {
117
+ "features": {
118
+ "type": "array",
119
+ "items": {"type": "string"},
120
+ "description": "Contract features (e.g., 'oracle_dependency', 'flash_loan', 'governance')"
121
+ }
122
+ },
123
+ "required": ["features"]
124
+ }
125
+ }
126
+ ]
127
+
128
+
129
+ async def analyze_gev_surface(contract_code: str, network: str = "ethereum_l1") -> dict:
130
+ """Analyze contract's GEV surface."""
131
+ code_lower = contract_code.lower()
132
+ vulnerabilities = []
133
+ risk_factors = []
134
+
135
+ # Check for oracle dependency
136
+ if "price" in code_lower or "oracle" in code_lower or "getprice" in code_lower:
137
+ vulnerabilities.append({
138
+ "pattern": "oracle_manipulation",
139
+ "risk": "high",
140
+ "description": "Contract depends on price oracle - vulnerable to manipulation",
141
+ "mitigation": "Use TWAP oracle, multiple sources, or Chainlink"
142
+ })
143
+ risk_factors.append("oracle_dependency")
144
+
145
+ # Check for flash loan vectors
146
+ if "flashloan" in code_lower or "flash_loan" in code_lower or "borrow(" in code_lower:
147
+ vulnerabilities.append({
148
+ "pattern": "flash_loan_attack",
149
+ "risk": "high",
150
+ "description": "Flash loan can be used for governance/price manipulation",
151
+ "mitigation": "Add timelock, use snapshot voting, or limit flash loan impact"
152
+ })
153
+ risk_factors.append("flash_loan")
154
+
155
+ # Check for governance
156
+ if "governance" in code_lower or "voting" in code_lower or "proposal" in code_lower:
157
+ vulnerabilities.append({
158
+ "pattern": "governance_extraction",
159
+ "risk": "medium",
160
+ "description": "Governance can be manipulated for value extraction",
161
+ "mitigation": "Use time-weighted voting, quorum requirements, timelocks"
162
+ })
163
+ risk_factors.append("governance")
164
+
165
+ # Check for cross-layer calls (L2 specific)
166
+ if network != "ethereum_l1":
167
+ if "l1" in code_lower or "bridge" in code_lower or "cross" in code_lower:
168
+ vulnerabilities.append({
169
+ "pattern": "cross_domain_mev",
170
+ "risk": "high",
171
+ "description": "Cross-layer calls enable cross-domain MEV",
172
+ "mitigation": "Use atomic cross-layer calls or delay finality"
173
+ })
174
+ risk_factors.append("cross_layer")
175
+
176
+ # Check for liquidity manipulation
177
+ if "liquidity" in code_lower or "swap" in code_lower or "pool" in code_lower:
178
+ vulnerabilities.append({
179
+ "pattern": "liquidity_mev",
180
+ "risk": "medium",
181
+ "description": "Liquidity operations can be front-run",
182
+ "mitigation": "Use commit-reveal, private mempool, or MEV-Share"
183
+ })
184
+ risk_factors.append("liquidity")
185
+
186
+ # Calculate overall risk score
187
+ risk_score = _calculate_risk_score(risk_factors)
188
+
189
+ return {
190
+ "success": True,
191
+ "network": network,
192
+ "vulnerabilities": vulnerabilities,
193
+ "risk_factors": risk_factors,
194
+ "risk_score": risk_score,
195
+ "risk_level": _risk_level(risk_score),
196
+ "recommendations": _generate_recommendations(risk_factors)
197
+ }
198
+
199
+
200
+ def list_gev_patterns() -> dict:
201
+ """List all known GEV attack patterns."""
202
+ return {
203
+ "success": True,
204
+ "patterns": ATTACK_PATTERNS,
205
+ "layers": EXTRACTION_LAYERS,
206
+ "total_patterns": len(ATTACK_PATTERNS)
207
+ }
208
+
209
+
210
+ async def calculate_gev_risk(features: list) -> dict:
211
+ """Calculate GEV risk score based on features."""
212
+ risk_score = _calculate_risk_score(features)
213
+
214
+ return {
215
+ "success": True,
216
+ "features": features,
217
+ "risk_score": risk_score,
218
+ "risk_level": _risk_level(risk_score),
219
+ "recommendations": _generate_recommendations(features)
220
+ }
221
+
222
+
223
+ def _calculate_risk_score(features: list) -> int:
224
+ """Calculate risk score (0-100) based on features."""
225
+ base_score = 20 # Base risk for any contract
226
+
227
+ feature_weights = {
228
+ "oracle_dependency": 25,
229
+ "flash_loan": 20,
230
+ "governance": 15,
231
+ "cross_layer": 20,
232
+ "liquidity": 15,
233
+ "reentrancy": 25,
234
+ "unchecked_calls": 20,
235
+ "centralized_control": 15
236
+ }
237
+
238
+ for feature in features:
239
+ if feature in feature_weights:
240
+ base_score += feature_weights[feature]
241
+
242
+ return min(base_score, 100)
243
+
244
+
245
+ def _risk_level(score: int) -> str:
246
+ """Convert risk score to level."""
247
+ if score >= 80:
248
+ return "critical"
249
+ elif score >= 60:
250
+ return "high"
251
+ elif score >= 40:
252
+ return "medium"
253
+ elif score >= 20:
254
+ return "low"
255
+ return "minimal"
256
+
257
+
258
+ def _generate_recommendations(features: list) -> list:
259
+ """Generate recommendations based on risk factors."""
260
+ recommendations = []
261
+
262
+ if "oracle_dependency" in features:
263
+ recommendations.append("Use TWAP oracle with multiple sources (Chainlink, Uniswap TWAP)")
264
+
265
+ if "flash_loan" in features:
266
+ recommendations.append("Add timelock for governance actions, use snapshot voting")
267
+
268
+ if "governance" in features:
269
+ recommendations.append("Implement time-weighted voting and quorum requirements")
270
+
271
+ if "cross_layer" in features:
272
+ recommendations.append("Use atomic cross-layer calls or add finality delay")
273
+
274
+ if "liquidity" in features:
275
+ recommendations.append("Use commit-reveal scheme or private mempool (Flashbots)")
276
+
277
+ if not recommendations:
278
+ recommendations.append("No specific GEV risks identified - standard security practices apply")
279
+
280
+ return recommendations
281
+
282
+
283
+ async def execute_tool(tool_name: str, arguments: dict) -> dict:
284
+ if tool_name == "analyze_gev_surface":
285
+ return await analyze_gev_surface(
286
+ arguments.get("contract_code", ""),
287
+ arguments.get("network", "ethereum_l1")
288
+ )
289
+ elif tool_name == "list_gev_patterns":
290
+ return list_gev_patterns()
291
+ elif tool_name == "calculate_gev_risk":
292
+ return await calculate_gev_risk(arguments.get("features", []))
293
+ return {"success": False, "error": f"Unknown tool: {tool_name}"}
294
+
295
+
296
+ async def handle_request(request: dict) -> dict:
297
+ method = request.get("method")
298
+ params = request.get("params", {})
299
+
300
+ if method == "initialize":
301
+ return {
302
+ "protocolVersion": "2024-11-05",
303
+ "capabilities": {"tools": {}},
304
+ "serverInfo": {"name": TOOL_NAME, "version": TOOL_VERSION}
305
+ }
306
+ elif method == "tools/list":
307
+ return {"tools": build_tool_definitions()}
308
+ elif method == "tools/call":
309
+ tool_name = params.get("name")
310
+ arguments = params.get("arguments", {})
311
+ result = await execute_tool(tool_name, arguments)
312
+ return {"content": [{"type": "text", "text": json.dumps(result, indent=2)}]}
313
+ elif method == "ping":
314
+ return {}
315
+ return {"error": {"code": -32601, "message": f"Method not found: {method}"}}
316
+
317
+
318
+ async def main():
319
+ reader = asyncio.StreamReader()
320
+ protocol = asyncio.StreamReaderProtocol(reader)
321
+ loop = asyncio.get_event_loop()
322
+ await loop.connect_read_pipe(lambda: protocol, sys.stdin)
323
+
324
+ logger.info(f"{TOOL_NAME} MCP server started")
325
+
326
+ while True:
327
+ line = await reader.readline()
328
+ if not line:
329
+ break
330
+
331
+ line_str = line.decode("utf-8").strip()
332
+ if not line_str:
333
+ continue
334
+
335
+ try:
336
+ request = json.loads(line_str)
337
+ response = await handle_request(request)
338
+ response["jsonrpc"] = "2.0"
339
+ response["id"] = request.get("id")
340
+ sys.stdout.write(json.dumps(response) + "\n")
341
+ sys.stdout.flush()
342
+ except json.JSONDecodeError:
343
+ error_resp = {
344
+ "jsonrpc": "2.0",
345
+ "id": None,
346
+ "error": {"code": -32700, "message": "Parse error"}
347
+ }
348
+ sys.stdout.write(json.dumps(error_resp) + "\n")
349
+ sys.stdout.flush()
350
+ except Exception as e:
351
+ logger.exception("Error handling request")
352
+ error_resp = {
353
+ "jsonrpc": "2.0",
354
+ "id": request.get("id") if "request" in dir() else None,
355
+ "error": {"code": -32603, "message": f"Internal error: {str(e)}"}
356
+ }
357
+ sys.stdout.write(json.dumps(error_resp) + "\n")
358
+ sys.stdout.flush()
359
+
360
+
361
+ if __name__ == "__main__":
362
+ asyncio.run(main())