v0.1.0 — first beta release
Pre-releasePoint it at any on-chain address. It reconstructs what that address depends on. No protocol whitelist, no ABI, no signature database.
Selectors are recovered from deployed bytecode, called with no arguments, addresses decoded from the shape of the return, and followed — which is why a Morpho market's params struct and a Curve pool's Vyper dispatch come out of the same code path.
This is beta, and experimental by nature. It works, and every number in the README is verified against a live crawl at a pinned block — but output shape, metric definitions and the API can change before 1.0. Treat a graph as evidence to check, not as an oracle.
Try it
git clone https://github.com/linstan1/edg && cd edg && uv sync
export EDG_RPC_URL_ETHEREUM=https://your-rpc-endpoint
uv run python -m edg.discovery.run 0xdd0f28e19C1780eb6396170735D45153D261490dOr install from the tag: uv pip install "git+https://github.com/linstan1/edg@v0.1.0"
It is not a Morpho tool
Same binary, same code path, no adapter — Aave V3 Pool 200 nodes / 235 edges, EigenLayer StrategyManager 65 / 153, Curve 3pool 18 / 19, Uniswap V3 12 / 17, Lido stETH 4 / 3, ENS registry 2 / 1, WETH 1 / 0. WETH returning one node and no edges is the correct answer: none of its eleven selectors returns an address.
scripts/regen_assets.py re-crawls every one of those and fails if a count has drifted, so the README cannot quietly stop being true.
What it refuses to do
A graph that hides its own gaps is worse than no graph, because it looks most authoritative exactly where it is weakest. So: a transport failure is never recorded as "the contract does not implement that"; a node the crawl stopped short of is a frontier, never a leaf; completeness is scored over every contract and only positive evidence of probing counts. The crawl below scores 94.6% over 168 contracts — a number under 100 with a worklist attached is the intended output.
Highlights of this release
- Ontology-free discovery, plus a generic sweep that re-probes every contract a protocol extractor already claimed — recognition describes what it found, it never decides what gets found
- Flow completeness (
edg.flowness), carried inmeta.flowso the CLI, the API and the viewer all quote the same number - React Flow viewer built around the degradation flags, with a chain selector and block-explorer links
- Multi-chain: a chain with no configured endpoint is refused rather than crawled against another chain's node
- Fixes for proxy resolution (Aave reported one node with a lending protocol behind it), Vyper dispatch (Curve reported one node), and EVM faults misread as transport failures (the ENS registry crawl died outright)
Full detail, including the bug behind each change: CHANGELOG.md
Contributions welcome
The most valuable report is a root address whose graph is confidently wrong — a dependency missed, an edge invented, a frontier presented as a terminal. Every read is block-pinned, so anything reproducible can be diagnosed exactly. Contracts whose dispatch this crawler cannot read (diamonds, computed jump tables, unusual proxies) are just as useful.