web3skill 0.1.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.
- package/LICENSE +21 -0
- package/README.md +127 -0
- package/dist/archives/web3-audit-orchestrator.skill +0 -0
- package/dist/archives/web3-audit-reporting.skill +0 -0
- package/dist/archives/web3-fuzzing-and-invariants.skill +0 -0
- package/dist/archives/web3-native-operator.skill +0 -0
- package/dist/archives/web3-repo-heuristics.skill +0 -0
- package/dist/archives/web3-research-and-market-intel.skill +0 -0
- package/dist/archives/web3-risk-gate.skill +0 -0
- package/dist/archives/web3-service-orchestrator.skill +0 -0
- package/dist/archives/web3-static-analysis-runner.skill +0 -0
- package/dist/archives/web3-trace-and-state-analysis.skill +0 -0
- package/dist/archives/web3-transaction-simulator.skill +0 -0
- package/dist/archives/web3-wallet-operator.skill +0 -0
- package/dist/manifest.json +170 -0
- package/dist/skills/web3-audit-orchestrator/SKILL.md +79 -0
- package/dist/skills/web3-audit-orchestrator/references/ADAPTER_CONSUMPTION_MAP.md +15 -0
- package/dist/skills/web3-audit-orchestrator/references/OUTPUT_TEMPLATE.md +52 -0
- package/dist/skills/web3-audit-orchestrator/references/REVIEW_STATE_MACHINE.md +25 -0
- package/dist/skills/web3-audit-orchestrator/scripts/render_audit_review.py +95 -0
- package/dist/skills/web3-audit-reporting/SKILL.md +77 -0
- package/dist/skills/web3-audit-reporting/references/FINDING_TEMPLATE.md +54 -0
- package/dist/skills/web3-audit-reporting/references/REPORT_TEMPLATE.md +58 -0
- package/dist/skills/web3-audit-reporting/references/RETEST_TEMPLATE.md +35 -0
- package/dist/skills/web3-audit-reporting/references/SEVERITY_RUBRIC.md +75 -0
- package/dist/skills/web3-fuzzing-and-invariants/SKILL.md +68 -0
- package/dist/skills/web3-fuzzing-and-invariants/references/ADAPTER_CONSUMPTION_MAP.md +14 -0
- package/dist/skills/web3-fuzzing-and-invariants/references/OUTPUT_TEMPLATE.md +40 -0
- package/dist/skills/web3-fuzzing-and-invariants/references/READINESS_AND_FAILURES.md +25 -0
- package/dist/skills/web3-fuzzing-and-invariants/scripts/render_fuzz_summary.py +64 -0
- package/dist/skills/web3-native-operator/SKILL.md +218 -0
- package/dist/skills/web3-native-operator/references/EXECUTION_BUNDLE_TEMPLATE.md +47 -0
- package/dist/skills/web3-native-operator/references/OPERATOR_BUNDLE_TEMPLATE.md +39 -0
- package/dist/skills/web3-native-operator/references/POSTTRADE_FOLLOWUP_BUNDLE_TEMPLATE.md +35 -0
- package/dist/skills/web3-native-operator/references/POSTTRADE_WATCH_TEMPLATE.md +34 -0
- package/dist/skills/web3-native-operator/references/PRETRADE_PACKET_TEMPLATE.md +34 -0
- package/dist/skills/web3-native-operator/references/ROUTE_RECIPES.md +140 -0
- package/dist/skills/web3-native-operator/references/ROUTING_STATE_MACHINE.md +73 -0
- package/dist/skills/web3-native-operator/references/WATCH_CRON_REQUEST_TEMPLATE.md +26 -0
- package/dist/skills/web3-native-operator/references/WATCH_FOLLOWUP_BUNDLE_TEMPLATE.md +35 -0
- package/dist/skills/web3-native-operator/references/WATCH_HEARTBEAT_TEMPLATE.md +31 -0
- package/dist/skills/web3-native-operator/scripts/apply_followup_bundle_to_heartbeat.py +118 -0
- package/dist/skills/web3-native-operator/scripts/render_execution_bundle.py +259 -0
- package/dist/skills/web3-native-operator/scripts/render_operator_bundle.py +800 -0
- package/dist/skills/web3-native-operator/scripts/render_posttrade_followup_bundle.py +118 -0
- package/dist/skills/web3-native-operator/scripts/render_posttrade_watch_status.py +125 -0
- package/dist/skills/web3-native-operator/scripts/render_pretrade_packet.py +205 -0
- package/dist/skills/web3-native-operator/scripts/render_watch_cron_request.py +88 -0
- package/dist/skills/web3-native-operator/scripts/render_watch_followup_bundle.py +118 -0
- package/dist/skills/web3-native-operator/scripts/render_watch_heartbeat.py +52 -0
- package/dist/skills/web3-repo-heuristics/SKILL.md +37 -0
- package/dist/skills/web3-repo-heuristics/references/FOUNDRY.md +49 -0
- package/dist/skills/web3-repo-heuristics/references/HARDHAT.md +47 -0
- package/dist/skills/web3-repo-heuristics/references/VYPER.md +26 -0
- package/dist/skills/web3-research-and-market-intel/SKILL.md +138 -0
- package/dist/skills/web3-research-and-market-intel/references/ADAPTER_CONSUMPTION_MAP.md +66 -0
- package/dist/skills/web3-research-and-market-intel/references/EVIDENCE_QUALITY.md +27 -0
- package/dist/skills/web3-research-and-market-intel/references/OUTPUT_TEMPLATE.md +37 -0
- package/dist/skills/web3-research-and-market-intel/references/PORTFOLIO_STATUS_TEMPLATE.md +51 -0
- package/dist/skills/web3-research-and-market-intel/references/WATCH_STATUS_TEMPLATE.md +39 -0
- package/dist/skills/web3-research-and-market-intel/scripts/render_portfolio_status.py +85 -0
- package/dist/skills/web3-research-and-market-intel/scripts/render_research_brief.py +58 -0
- package/dist/skills/web3-research-and-market-intel/scripts/render_watch_status.py +70 -0
- package/dist/skills/web3-risk-gate/SKILL.md +100 -0
- package/dist/skills/web3-risk-gate/references/OUTPUT_TEMPLATE.md +72 -0
- package/dist/skills/web3-risk-gate/references/SIGNAL_TAXONOMY.md +34 -0
- package/dist/skills/web3-risk-gate/scripts/merge_risk_gate_blocks.py +189 -0
- package/dist/skills/web3-service-orchestrator/SKILL.md +34 -0
- package/dist/skills/web3-static-analysis-runner/SKILL.md +76 -0
- package/dist/skills/web3-static-analysis-runner/references/ADAPTER_CONSUMPTION_MAP.md +13 -0
- package/dist/skills/web3-static-analysis-runner/references/OUTPUT_TEMPLATE.md +45 -0
- package/dist/skills/web3-static-analysis-runner/references/TRIAGE_BUCKETS.md +16 -0
- package/dist/skills/web3-static-analysis-runner/scripts/render_static_analysis_summary.py +64 -0
- package/dist/skills/web3-trace-and-state-analysis/SKILL.md +74 -0
- package/dist/skills/web3-trace-and-state-analysis/references/ADAPTER_CONSUMPTION_MAP.md +27 -0
- package/dist/skills/web3-trace-and-state-analysis/references/OUTPUT_TEMPLATE.md +63 -0
- package/dist/skills/web3-trace-and-state-analysis/references/TRACE_BACKEND_PREFLIGHT.md +47 -0
- package/dist/skills/web3-trace-and-state-analysis/scripts/render_trace_summary.py +99 -0
- package/dist/skills/web3-transaction-simulator/SKILL.md +83 -0
- package/dist/skills/web3-transaction-simulator/references/OUTPUT_TEMPLATE.md +86 -0
- package/dist/skills/web3-transaction-simulator/references/STATUS_AND_FAILURES.md +49 -0
- package/dist/skills/web3-transaction-simulator/scripts/merge_simulation_blocks.py +198 -0
- package/dist/skills/web3-wallet-operator/SKILL.md +52 -0
- package/dist/skills/web3-wallet-operator/references/ACTION_RECIPES.md +56 -0
- package/dist/skills/web3-wallet-operator/references/OUTPUT_TEMPLATE.md +43 -0
- package/dist/skills/web3-wallet-operator/scripts/render_wallet_operation_plan.py +101 -0
- package/index.js +50 -0
- package/package.json +36 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Static Analysis Triage Buckets
|
|
2
|
+
|
|
3
|
+
Normalize static-analysis output into these buckets:
|
|
4
|
+
|
|
5
|
+
- `confirmed-finding`
|
|
6
|
+
- root cause validated with exploit relevance or direct code proof
|
|
7
|
+
- `review-needed`
|
|
8
|
+
- plausible issue that still needs human validation or environment support
|
|
9
|
+
- `false-positive`
|
|
10
|
+
- tool hit does not survive code review or context check
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
- Deduplicate by root cause, not by scanner line count.
|
|
15
|
+
- A single root cause can have evidence from multiple scanners.
|
|
16
|
+
- If scanners cannot run because the repo will not build or the environment is missing, put that in blockers instead of inventing triage.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Render a stable Web3 static-analysis summary block."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
12
|
+
parser = argparse.ArgumentParser(description="Render a Web3 static-analysis summary block.")
|
|
13
|
+
parser.add_argument("--scope", required=True)
|
|
14
|
+
parser.add_argument("--status", choices=("complete", "partial", "blocked"), default="partial")
|
|
15
|
+
parser.add_argument("--scanner", action="append", default=[])
|
|
16
|
+
parser.add_argument("--raw-hit-count", type=int, default=0)
|
|
17
|
+
parser.add_argument("--root-cause", action="append", default=[])
|
|
18
|
+
parser.add_argument("--confirmed-count", type=int, default=0)
|
|
19
|
+
parser.add_argument("--review-needed-count", type=int, default=0)
|
|
20
|
+
parser.add_argument("--false-positive-count", type=int, default=0)
|
|
21
|
+
parser.add_argument("--blocker", action="append", default=[])
|
|
22
|
+
parser.add_argument("--next-step", action="append", default=[])
|
|
23
|
+
parser.add_argument("--evidence", action="append", default=[])
|
|
24
|
+
return parser
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def parse_evidence(entries: list[str]) -> list[dict[str, str]]:
|
|
28
|
+
parsed = []
|
|
29
|
+
for entry in entries:
|
|
30
|
+
adapter, sep, detail = entry.partition(":")
|
|
31
|
+
if sep:
|
|
32
|
+
parsed.append({"adapter": adapter.strip(), "detail": detail.strip()})
|
|
33
|
+
else:
|
|
34
|
+
parsed.append({"adapter": "unknown", "detail": entry})
|
|
35
|
+
return parsed
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def main() -> int:
|
|
39
|
+
args = build_parser().parse_args()
|
|
40
|
+
payload = {
|
|
41
|
+
"static_analysis_summary": {
|
|
42
|
+
"version": 1,
|
|
43
|
+
"status": args.status,
|
|
44
|
+
"scope": args.scope,
|
|
45
|
+
"scanners_run": args.scanner,
|
|
46
|
+
"raw_hit_count": args.raw_hit_count,
|
|
47
|
+
"deduped_root_causes": args.root_cause,
|
|
48
|
+
"escalation_counts": {
|
|
49
|
+
"confirmed_finding": args.confirmed_count,
|
|
50
|
+
"review_needed": args.review_needed_count,
|
|
51
|
+
"false_positive": args.false_positive_count,
|
|
52
|
+
},
|
|
53
|
+
"blockers": args.blocker,
|
|
54
|
+
"next_steps": args.next_step,
|
|
55
|
+
"evidence": parse_evidence(args.evidence),
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
json.dump(payload, sys.stdout, ensure_ascii=False, indent=2)
|
|
59
|
+
sys.stdout.write("\n")
|
|
60
|
+
return 0
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == "__main__":
|
|
64
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web3-trace-and-state-analysis
|
|
3
|
+
description: Trace and state analysis layer for transaction inspection, trace_call style reasoning, proxy/delegatecall analysis, and storage/state deltas. Use for tx hashes, suspicious calls, archive-node analysis, and call-path debugging.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Web3 Trace And State Analysis
|
|
7
|
+
|
|
8
|
+
Use this skill for transaction tracing, forward call inspection, proxy path analysis, and state-change attribution.
|
|
9
|
+
|
|
10
|
+
## Required Components
|
|
11
|
+
|
|
12
|
+
- Read `evm-mcp-playbook` for live chain access and backend setup.
|
|
13
|
+
- Prefer these Web3 profile adapters when applicable:
|
|
14
|
+
- `behavioral-state-analysis`
|
|
15
|
+
- `entry-point-analyzer`
|
|
16
|
+
- `etherscan`
|
|
17
|
+
|
|
18
|
+
Use [references/ADAPTER_CONSUMPTION_MAP.md](references/ADAPTER_CONSUMPTION_MAP.md)
|
|
19
|
+
to normalize adapter evidence into a stable trace/state summary.
|
|
20
|
+
Use [references/TRACE_BACKEND_PREFLIGHT.md](references/TRACE_BACKEND_PREFLIGHT.md)
|
|
21
|
+
before claiming trace coverage or readiness.
|
|
22
|
+
Use [references/OUTPUT_TEMPLATE.md](references/OUTPUT_TEMPLATE.md) and
|
|
23
|
+
[scripts/render_trace_summary.py](scripts/render_trace_summary.py) when a downstream
|
|
24
|
+
skill needs stable machine-consumable output.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. Name chain, backend class, and block context.
|
|
29
|
+
2. Determine whether this is:
|
|
30
|
+
- historical tx analysis
|
|
31
|
+
- forward-looking call analysis
|
|
32
|
+
- repo-assisted state analysis
|
|
33
|
+
3. Use live reads or tracing backend to inspect call path, logs, code, and storage.
|
|
34
|
+
4. If repo code is available, use `entry-point-analyzer` to map state-changing entry points.
|
|
35
|
+
5. Use `behavioral-state-analysis` to explain risk, invariants, and exploit relevance.
|
|
36
|
+
|
|
37
|
+
## Reusable Output Contract
|
|
38
|
+
|
|
39
|
+
Always emit both:
|
|
40
|
+
|
|
41
|
+
1. A short trace/state explanation for the user
|
|
42
|
+
2. A normalized `trace_summary` block for downstream operator or audit flows
|
|
43
|
+
|
|
44
|
+
The normalized block must preserve:
|
|
45
|
+
|
|
46
|
+
- `status`
|
|
47
|
+
- `subject`
|
|
48
|
+
- chain, block, and backend readiness
|
|
49
|
+
- call chain edges
|
|
50
|
+
- state changes
|
|
51
|
+
- risk notes and unknowns
|
|
52
|
+
- exact evidence source per observation
|
|
53
|
+
|
|
54
|
+
## Output Schema
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Context:
|
|
58
|
+
- chain / block / backend
|
|
59
|
+
Call Chain:
|
|
60
|
+
- caller -> callee -> delegatecall / external call path
|
|
61
|
+
State Changes:
|
|
62
|
+
- key storage or balance changes
|
|
63
|
+
Risk Notes:
|
|
64
|
+
- privilege transition, token flow, upgrade path, invariant break
|
|
65
|
+
Unknowns:
|
|
66
|
+
- missing trace support, missing source, ambiguous state slot
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Guardrails
|
|
70
|
+
|
|
71
|
+
- If the backend does not expose trace methods, say so clearly and fall back to code/storage/call-only analysis.
|
|
72
|
+
- Distinguish historical traces from forward simulation.
|
|
73
|
+
- Never claim a full state diff when only logs or receipts were inspected.
|
|
74
|
+
- If backend readiness is partial or missing, reflect that in the normalized block instead of hiding the gap.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Trace Adapter Consumption Map
|
|
2
|
+
|
|
3
|
+
- `behavioral-state-analysis` -> risk notes, invariant context, exploit relevance
|
|
4
|
+
- `entry-point-analyzer` -> entrypoints, privilege boundaries, state-changing surface
|
|
5
|
+
- `etherscan` -> ABI, verified source, proxy implementation, tx/account evidence
|
|
6
|
+
|
|
7
|
+
Normalize into:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
trace_summary:
|
|
11
|
+
status: COMPLETE | PARTIAL | UNAVAILABLE
|
|
12
|
+
subject: historical-tx | forward-call | repo-assisted
|
|
13
|
+
backend:
|
|
14
|
+
class: archive-rpc | debug-trace-rpc | explorer-plus-abi | repo-assisted | mixed
|
|
15
|
+
readiness: ready | partial | missing
|
|
16
|
+
call_chain:
|
|
17
|
+
- caller -> callee
|
|
18
|
+
state_changes:
|
|
19
|
+
- concrete storage or balance delta
|
|
20
|
+
risk_notes:
|
|
21
|
+
- privilege / flow / invariant interpretation
|
|
22
|
+
unknowns:
|
|
23
|
+
- remaining ambiguity
|
|
24
|
+
evidence:
|
|
25
|
+
- adapter: name
|
|
26
|
+
detail: exact supporting hit
|
|
27
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Web3 Trace Output Template
|
|
2
|
+
|
|
3
|
+
Always emit:
|
|
4
|
+
|
|
5
|
+
1. A short human-readable trace/state summary
|
|
6
|
+
2. A normalized block
|
|
7
|
+
|
|
8
|
+
```yaml
|
|
9
|
+
trace_summary:
|
|
10
|
+
version: 1
|
|
11
|
+
status: PARTIAL
|
|
12
|
+
subject: historical-tx
|
|
13
|
+
chain: base
|
|
14
|
+
block: 28765432
|
|
15
|
+
backend:
|
|
16
|
+
class: mixed
|
|
17
|
+
readiness: partial
|
|
18
|
+
methods:
|
|
19
|
+
- eth_getTransactionReceipt
|
|
20
|
+
- getsourcecode
|
|
21
|
+
scope:
|
|
22
|
+
tx_hash: 0xabc
|
|
23
|
+
from: 0xcaller
|
|
24
|
+
to: 0xrouter
|
|
25
|
+
function: swapExactTokensForTokens
|
|
26
|
+
call_chain:
|
|
27
|
+
- 0xcaller -> 0xrouter
|
|
28
|
+
- 0xrouter -> 0xpair
|
|
29
|
+
state_changes:
|
|
30
|
+
- balance[tokenOut][receiver] increases
|
|
31
|
+
- allowance[tokenIn][router] decreases
|
|
32
|
+
risk_notes:
|
|
33
|
+
- proxy implementation resolved through explorer metadata only
|
|
34
|
+
unknowns:
|
|
35
|
+
- no internal trace for delegatecall branch
|
|
36
|
+
next_steps:
|
|
37
|
+
- rerun on a trace-capable archive backend
|
|
38
|
+
follow_up_skills:
|
|
39
|
+
- web3-native-operator
|
|
40
|
+
evidence:
|
|
41
|
+
- adapter: etherscan
|
|
42
|
+
detail: proxy implementation and verified ABI fetched
|
|
43
|
+
- adapter: entry-point-analyzer
|
|
44
|
+
detail: router path touches external callback surface
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Required Fields
|
|
48
|
+
|
|
49
|
+
- `status`: `COMPLETE | PARTIAL | UNAVAILABLE`
|
|
50
|
+
- `subject`: `historical-tx | forward-call | repo-assisted`
|
|
51
|
+
- `chain`
|
|
52
|
+
- `backend`
|
|
53
|
+
- `call_chain`
|
|
54
|
+
- `state_changes`
|
|
55
|
+
- `risk_notes`
|
|
56
|
+
- `unknowns`
|
|
57
|
+
- `evidence`
|
|
58
|
+
|
|
59
|
+
## Notes
|
|
60
|
+
|
|
61
|
+
- Use empty lists instead of dropping list fields.
|
|
62
|
+
- `status = UNAVAILABLE` still requires concrete `unknowns` and a next step.
|
|
63
|
+
- Do not promote inferred state changes to confirmed ones without supporting evidence.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Trace Backend Preflight
|
|
2
|
+
|
|
3
|
+
Use this checklist before claiming trace coverage.
|
|
4
|
+
|
|
5
|
+
## Backend Classes
|
|
6
|
+
|
|
7
|
+
- `archive-rpc`
|
|
8
|
+
- historical state reads and archive storage available
|
|
9
|
+
- `debug-trace-rpc`
|
|
10
|
+
- `trace_call`, `debug_traceCall`, `debug_traceTransaction`, or equivalent available
|
|
11
|
+
- `explorer-plus-abi`
|
|
12
|
+
- verified source, ABI, receipts, token transfers, and proxy metadata available
|
|
13
|
+
- `repo-assisted`
|
|
14
|
+
- local source code available for entry-point and storage interpretation
|
|
15
|
+
- `mixed`
|
|
16
|
+
- more than one backend class combined
|
|
17
|
+
|
|
18
|
+
## Readiness
|
|
19
|
+
|
|
20
|
+
- `ready`
|
|
21
|
+
- trace methods or equivalent archive capability confirmed
|
|
22
|
+
- enough data to attribute internal calls or state deltas with confidence
|
|
23
|
+
- `partial`
|
|
24
|
+
- receipts, logs, explorer metadata, or repo analysis available
|
|
25
|
+
- but full internal call path or precise state diff is incomplete
|
|
26
|
+
- `missing`
|
|
27
|
+
- no trace-capable backend and no credible fallback evidence
|
|
28
|
+
|
|
29
|
+
## Minimum Preflight Questions
|
|
30
|
+
|
|
31
|
+
1. Which chain and block context are in scope?
|
|
32
|
+
2. Is this a historical tx, forward-looking call, or repo-assisted path analysis?
|
|
33
|
+
3. Does the backend expose trace methods or only explorer/receipt data?
|
|
34
|
+
4. Is verified source or local source available?
|
|
35
|
+
5. Can balances, storage, or proxy implementation slots be cross-checked?
|
|
36
|
+
|
|
37
|
+
## Status Mapping
|
|
38
|
+
|
|
39
|
+
- `ready` -> `trace_summary.status = COMPLETE`
|
|
40
|
+
- `partial` -> `trace_summary.status = PARTIAL`
|
|
41
|
+
- `missing` -> `trace_summary.status = UNAVAILABLE`
|
|
42
|
+
|
|
43
|
+
## Guardrails
|
|
44
|
+
|
|
45
|
+
- Do not report `COMPLETE` if you only inspected receipts or logs.
|
|
46
|
+
- If proxy resolution or storage attribution is inferred from source without live validation, keep readiness at `partial`.
|
|
47
|
+
- If the action is safety-critical and readiness is not `ready`, tell the operator to keep the flow in investigate mode.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Render a stable Web3 trace summary block from normalized backend evidence."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
12
|
+
parser = argparse.ArgumentParser(description="Render a Web3 trace summary block.")
|
|
13
|
+
parser.add_argument(
|
|
14
|
+
"--subject",
|
|
15
|
+
choices=("historical-tx", "forward-call", "repo-assisted"),
|
|
16
|
+
required=True,
|
|
17
|
+
)
|
|
18
|
+
parser.add_argument("--chain", required=True)
|
|
19
|
+
parser.add_argument("--block", default="latest")
|
|
20
|
+
parser.add_argument(
|
|
21
|
+
"--backend-class",
|
|
22
|
+
choices=("archive-rpc", "debug-trace-rpc", "explorer-plus-abi", "repo-assisted", "mixed"),
|
|
23
|
+
required=True,
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--backend-readiness",
|
|
27
|
+
choices=("ready", "partial", "missing"),
|
|
28
|
+
required=True,
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument("--method", action="append", default=[])
|
|
31
|
+
parser.add_argument("--tx-hash", default="")
|
|
32
|
+
parser.add_argument("--from-address", default="")
|
|
33
|
+
parser.add_argument("--to-address", default="")
|
|
34
|
+
parser.add_argument("--function", default="")
|
|
35
|
+
parser.add_argument("--call-edge", action="append", default=[])
|
|
36
|
+
parser.add_argument("--state-change", action="append", default=[])
|
|
37
|
+
parser.add_argument("--risk-note", action="append", default=[])
|
|
38
|
+
parser.add_argument("--unknown", action="append", default=[])
|
|
39
|
+
parser.add_argument("--next-step", action="append", default=[])
|
|
40
|
+
parser.add_argument("--follow-up-skill", action="append", default=[])
|
|
41
|
+
parser.add_argument("--evidence", action="append", default=[])
|
|
42
|
+
return parser
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def choose_status(readiness: str) -> str:
|
|
46
|
+
if readiness == "ready":
|
|
47
|
+
return "COMPLETE"
|
|
48
|
+
if readiness == "partial":
|
|
49
|
+
return "PARTIAL"
|
|
50
|
+
return "UNAVAILABLE"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def parse_evidence(entries: list[str]) -> list[dict[str, str]]:
|
|
54
|
+
parsed = []
|
|
55
|
+
for entry in entries:
|
|
56
|
+
adapter, sep, detail = entry.partition(":")
|
|
57
|
+
if not sep:
|
|
58
|
+
parsed.append({"adapter": "unknown", "detail": entry})
|
|
59
|
+
continue
|
|
60
|
+
parsed.append({"adapter": adapter.strip(), "detail": detail.strip()})
|
|
61
|
+
return parsed
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def main() -> int:
|
|
65
|
+
args = build_parser().parse_args()
|
|
66
|
+
payload = {
|
|
67
|
+
"trace_summary": {
|
|
68
|
+
"version": 1,
|
|
69
|
+
"status": choose_status(args.backend_readiness),
|
|
70
|
+
"subject": args.subject,
|
|
71
|
+
"chain": args.chain,
|
|
72
|
+
"block": args.block,
|
|
73
|
+
"backend": {
|
|
74
|
+
"class": args.backend_class,
|
|
75
|
+
"readiness": args.backend_readiness,
|
|
76
|
+
"methods": args.method,
|
|
77
|
+
},
|
|
78
|
+
"scope": {
|
|
79
|
+
"tx_hash": args.tx_hash,
|
|
80
|
+
"from": args.from_address,
|
|
81
|
+
"to": args.to_address,
|
|
82
|
+
"function": args.function,
|
|
83
|
+
},
|
|
84
|
+
"call_chain": args.call_edge,
|
|
85
|
+
"state_changes": args.state_change,
|
|
86
|
+
"risk_notes": args.risk_note,
|
|
87
|
+
"unknowns": args.unknown,
|
|
88
|
+
"next_steps": args.next_step,
|
|
89
|
+
"follow_up_skills": args.follow_up_skill,
|
|
90
|
+
"evidence": parse_evidence(args.evidence),
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
json.dump(payload, sys.stdout, ensure_ascii=False, indent=2)
|
|
94
|
+
sys.stdout.write("\n")
|
|
95
|
+
return 0
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if __name__ == "__main__":
|
|
99
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web3-transaction-simulator
|
|
3
|
+
description: Pre-execution simulation layer for swaps, approvals, transfers, and liquidity actions. Use after risk gating and before any chain write. It combines venue planners with live read checks and returns a normalized go/no-go summary.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Web3 Transaction Simulator
|
|
7
|
+
|
|
8
|
+
Use this skill after `web3-risk-gate` and before any chain write.
|
|
9
|
+
|
|
10
|
+
## Required Adapters
|
|
11
|
+
|
|
12
|
+
Load the adapter that matches the action:
|
|
13
|
+
|
|
14
|
+
- `swap-planner`
|
|
15
|
+
- `liquidity-planner`
|
|
16
|
+
- `token-swap`
|
|
17
|
+
- `hyperliquid`
|
|
18
|
+
|
|
19
|
+
For live balances, allowance, code, or call checks, also read `evm-mcp-playbook`.
|
|
20
|
+
For gas-sensitive routing or timing, use `gas-tracker`.
|
|
21
|
+
When consuming adapter output, prefer each adapter's `references/SIMULATION_NORMALIZATION.md`
|
|
22
|
+
or mode-specific template so route and failure labels remain stable.
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
1. Collect chain, input/output asset, amount, slippage, receiver, and deadline.
|
|
27
|
+
2. Use the venue planner to get a route, quote, or execution plan.
|
|
28
|
+
3. Use live reads to verify balance, allowance, target code, and basic preconditions.
|
|
29
|
+
4. Normalize the result before any execution step.
|
|
30
|
+
|
|
31
|
+
## Reusable Output Contract
|
|
32
|
+
|
|
33
|
+
Always emit both:
|
|
34
|
+
|
|
35
|
+
1. A short human-readable simulation summary
|
|
36
|
+
2. A normalized block that downstream execution or routing skills can reuse
|
|
37
|
+
|
|
38
|
+
Use [references/OUTPUT_TEMPLATE.md](references/OUTPUT_TEMPLATE.md) for the exact scaffold.
|
|
39
|
+
Use [references/STATUS_AND_FAILURES.md](references/STATUS_AND_FAILURES.md) when classifying
|
|
40
|
+
`PASS`, `WARN`, `FAIL`, or `NO_SIMULATION`.
|
|
41
|
+
When deterministic merge behavior is needed, use
|
|
42
|
+
[scripts/merge_simulation_blocks.py](scripts/merge_simulation_blocks.py)
|
|
43
|
+
to combine multiple adapter-produced `simulation` blocks into one conservative result.
|
|
44
|
+
|
|
45
|
+
The minimum fields are:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Simulation: PASS | WARN | FAIL | NO_SIMULATION
|
|
49
|
+
Action:
|
|
50
|
+
- transfer | approve | swap | liquidity | perp-order
|
|
51
|
+
Venue:
|
|
52
|
+
- uniswap | hyperliquid | token-swap | unknown
|
|
53
|
+
Preconditions:
|
|
54
|
+
- balance / allowance / route assumptions
|
|
55
|
+
Expected Result:
|
|
56
|
+
- quoted output or expected state change
|
|
57
|
+
Failure Modes:
|
|
58
|
+
- revert reason, liquidity risk, unsupported path, missing backend
|
|
59
|
+
Readiness:
|
|
60
|
+
- ready | needs-confirmation | blocked
|
|
61
|
+
Next Step:
|
|
62
|
+
- proceed | adjust params | stop
|
|
63
|
+
Evidence:
|
|
64
|
+
- quote source or simulation backend
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The normalized block must preserve:
|
|
68
|
+
|
|
69
|
+
- simulation status
|
|
70
|
+
- action type and venue
|
|
71
|
+
- route assumptions
|
|
72
|
+
- readiness and blockers
|
|
73
|
+
- exact failure classification
|
|
74
|
+
- next step and evidence source
|
|
75
|
+
|
|
76
|
+
## Guardrails
|
|
77
|
+
|
|
78
|
+
- Never execute from this skill. Stop at plan, quote, or simulation summary.
|
|
79
|
+
- If the target token is not yet risk-gated, send the flow back to `web3-risk-gate`.
|
|
80
|
+
- If no reliable quote or call simulation exists, return `NO_SIMULATION`.
|
|
81
|
+
- Separate quote quality from token safety. A good quote does not imply a safe token.
|
|
82
|
+
- Distinguish missing simulation infrastructure from an actual transaction failure.
|
|
83
|
+
- If the route is available but preconditions are not met, return `WARN` or `FAIL`, not `NO_SIMULATION`.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Web3 Transaction Simulator Output Template
|
|
2
|
+
|
|
3
|
+
Always emit two sections in this order.
|
|
4
|
+
|
|
5
|
+
## 1. Human Summary
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Simulation: WARN
|
|
9
|
+
Action:
|
|
10
|
+
- swap
|
|
11
|
+
Venue:
|
|
12
|
+
- uniswap
|
|
13
|
+
Preconditions:
|
|
14
|
+
- Wallet balance is sufficient
|
|
15
|
+
- Allowance is missing for router 0x...
|
|
16
|
+
- Quote assumes 0.5% slippage and current pool reserves
|
|
17
|
+
Expected Result:
|
|
18
|
+
- Estimated output: 1,243.11 TOKEN
|
|
19
|
+
- Expected state change: approve router, then swap exact input
|
|
20
|
+
Failure Modes:
|
|
21
|
+
- Approval missing
|
|
22
|
+
- Quote may degrade if liquidity moves before execution
|
|
23
|
+
Readiness:
|
|
24
|
+
- needs-confirmation
|
|
25
|
+
Next Step:
|
|
26
|
+
- set allowance or use permit path
|
|
27
|
+
- rerun simulation after allowance is available
|
|
28
|
+
Evidence:
|
|
29
|
+
- swap-planner quote at current route
|
|
30
|
+
- evm-mcp-playbook allowance read
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 2. Normalized Block
|
|
34
|
+
|
|
35
|
+
Use this exact field layout. Omit empty optional arrays, but do not rename fields.
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
simulation:
|
|
39
|
+
version: 1
|
|
40
|
+
status: WARN
|
|
41
|
+
action: swap
|
|
42
|
+
venue: uniswap
|
|
43
|
+
chain: ethereum
|
|
44
|
+
readiness: needs-confirmation
|
|
45
|
+
route:
|
|
46
|
+
input_token: "0x..."
|
|
47
|
+
output_token: "0x..."
|
|
48
|
+
amount_in: "1.0 ETH"
|
|
49
|
+
slippage_bps: 50
|
|
50
|
+
preconditions:
|
|
51
|
+
- type: balance-ok
|
|
52
|
+
source: evm-mcp-playbook
|
|
53
|
+
detail: wallet balance covers amount and gas
|
|
54
|
+
- type: allowance-missing
|
|
55
|
+
source: evm-mcp-playbook
|
|
56
|
+
detail: router has no allowance
|
|
57
|
+
expected_result:
|
|
58
|
+
quoted_out: "1243.11 TOKEN"
|
|
59
|
+
state_change: approve then swap
|
|
60
|
+
failure_modes:
|
|
61
|
+
- type: missing-allowance
|
|
62
|
+
severity: medium
|
|
63
|
+
source: evm-mcp-playbook
|
|
64
|
+
detail: swap would revert without prior approval
|
|
65
|
+
- type: quote-drift
|
|
66
|
+
severity: low
|
|
67
|
+
source: swap-planner
|
|
68
|
+
detail: output depends on live liquidity at execution time
|
|
69
|
+
next_step:
|
|
70
|
+
- adjust params
|
|
71
|
+
- rerun simulation
|
|
72
|
+
evidence:
|
|
73
|
+
- adapter: swap-planner
|
|
74
|
+
signal: route quote
|
|
75
|
+
exact_hit: best path at current reserves
|
|
76
|
+
- adapter: evm-mcp-playbook
|
|
77
|
+
signal: allowance read
|
|
78
|
+
exact_hit: allowance is zero
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Notes
|
|
82
|
+
|
|
83
|
+
- `status` is mandatory and must be one of `PASS`, `WARN`, `FAIL`, `NO_SIMULATION`.
|
|
84
|
+
- `readiness` is mandatory and must be one of `ready`, `needs-confirmation`, `blocked`.
|
|
85
|
+
- `NO_SIMULATION` is for missing or unreliable simulation capability, not for normal transaction reverts.
|
|
86
|
+
- `failure_modes` should distinguish hard blockers from parameter issues.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Web3 Transaction Simulator Status And Failure Rules
|
|
2
|
+
|
|
3
|
+
Use these stable classifications.
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
- `PASS`
|
|
8
|
+
- A reliable quote or simulation exists.
|
|
9
|
+
- Preconditions are satisfied.
|
|
10
|
+
- No material blocker is detected.
|
|
11
|
+
|
|
12
|
+
- `WARN`
|
|
13
|
+
- A route or simulation exists, but some precondition or parameter still needs user action.
|
|
14
|
+
- Example: missing allowance, slippage too loose, thin liquidity, permit path not confirmed.
|
|
15
|
+
|
|
16
|
+
- `FAIL`
|
|
17
|
+
- A reliable simulation predicts revert, unacceptable loss, or clearly unsafe execution.
|
|
18
|
+
- Example: insufficient balance, guaranteed revert, route unavailable for requested size.
|
|
19
|
+
|
|
20
|
+
- `NO_SIMULATION`
|
|
21
|
+
- The system cannot obtain a trustworthy simulation or quote.
|
|
22
|
+
- Example: unsupported venue backend, missing archive / tenderly backend, planner unavailable.
|
|
23
|
+
|
|
24
|
+
## Readiness
|
|
25
|
+
|
|
26
|
+
- `ready`
|
|
27
|
+
- User could proceed after confirmation.
|
|
28
|
+
- `needs-confirmation`
|
|
29
|
+
- Parameters or preconditions still need fixing or confirming.
|
|
30
|
+
- `blocked`
|
|
31
|
+
- Execution should not proceed.
|
|
32
|
+
|
|
33
|
+
## Failure Type Labels
|
|
34
|
+
|
|
35
|
+
- `missing-allowance`
|
|
36
|
+
- `insufficient-balance`
|
|
37
|
+
- `unsupported-route`
|
|
38
|
+
- `quote-drift`
|
|
39
|
+
- `liquidity-too-thin`
|
|
40
|
+
- `gas-too-high`
|
|
41
|
+
- `revert-predicted`
|
|
42
|
+
- `backend-unavailable`
|
|
43
|
+
- `venue-unreachable`
|
|
44
|
+
|
|
45
|
+
## Mapping Rules
|
|
46
|
+
|
|
47
|
+
- If backend access is the main problem, prefer `NO_SIMULATION` with a failure type like `backend-unavailable`.
|
|
48
|
+
- If backend works and predicts revert, use `FAIL`, not `NO_SIMULATION`.
|
|
49
|
+
- If the only issue is user-adjustable and execution may still succeed later, prefer `WARN`.
|