Add 3Jane governance context to LLM reports - #343
Merged
Conversation
3Jane timelock calls reach the LLM as opaque data: setConfig names its parameter only by keccak256 hash, and RewardsDistributor allocates JANE without revealing whether a claim mints new supply or moves a balance. A recent 24h-timelock report hedged four separate times over facts that are public getters. - reverse bytes32 arguments against a checked-in table of ProtocolConfig keys and Jane/EmergencyController roles, with the value stored on-chain for config keys - read RewardsDistributor distribution mode, MINTER_ROLE authority, token supply and transferability, claim accounting, root, and the emissions of the preceding epochs so an allocation is judged against recent ones - follow EIP-1967 to the implementation ABI, since ProtocolConfig and MorphoCredit sit behind transparent proxies - fan protocol adapters out from one registry instead of wiring each into the explainer, and make the Protocol Context prompt header generic Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three inline ABI literals were 75 of the module's lines and pushed the resolvers off screen. Move them next to the protocol's existing ABIs and reuse ProtocolConfig.json rather than restating `config(bytes32)`. Loading is lazy and cached: this module sits in the explainer's import chain, so an unreadable file degrades one protocol's context instead of breaking every AI alert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
One alert probes the same target for both shapes it can take, and each probe followed EIP-1967 independently — two identical eth_getStorageAt calls for a setConfig alert. Split the ABI lookup into own-ABI and implementation-ABI halves and memoize both, so the slot is read only when the proxy ABI comes up short and only once per address. A target that is not a proxy still never reads the slot: adapter cost for a setConfig alert drops from 3 round trips to 2, and the distributor path is unchanged at 2 batched requests. Context output is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three consecutive weeks of the identical setEpochEmissions + updateRoot pair scored LOW, MEDIUM, MEDIUM. Emissions move in a ±3% weekly band, so each allocation is unremarkable in series and "sizable" in isolation — the reports had no series to read. - derive how the proposed allocation compares to the epoch before it, and whether the funded epoch is past, current, or future; no extra reads, the history was already fetched - render a capping key beside what it caps, batched into the existing config request: USD3_SUPPLY_CAP next to USD3 totalAssets, which is what separates a routine ceiling raise from one that unblocks deposits DEBT_CAP is deliberately not registered — its denomination against the market's borrow accounting is unconfirmed, and a wrong unit is worse than no comparison. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bytes32arguments toProtocolConfigkeys and Jane / EmergencyController roles, with the value stored on-chain for config keysRewardsDistributordistribution mode,MINTER_ROLEauthority, JANE supply and transferability, claim accounting, and recent epoch emissionsutils/llm/protocol_context.py) instead of wiring each into the explainerMotivation
This 3Jane 24h-timelock report hedged four times over facts that are public getters — "the current
useMintvalue and available token balance are not provided", "the execution path cannot be determined", "whether the distributor is adequately funded", "whether claims can expand JANE supply" — and called 5.56M JANE "substantial in absolute terms" with nothing to compare it against.ProtocolConfigis owned by the 24h timelock and its only setter issetConfig(bytes32,uint256), so every config change currently reaches the LLM as a bare hash — the same failure mode as an unresolved role hash in agrantRolealert.What the LLM now sees for that alert
Two facts the original report could not reach: JANE
totalSupplyequalstotalClaimedexactly, so claims are the only source of supply and epoch 45 would add ~14% to it; andtransferable = false, so minted rewards are not yet liquid.Notes
keccak256(name)derived at import, so the table cannot drift from the names. Hashes outside the table stay unresolved rather than guessed at, and role hashes get no value line since there is nothing to read.ProtocolConfigandMorphoCreditare transparent proxies, and without this the config read came back "not readable".Protocol Contextprompt header was Infinifi-specific ("farm, asset, whitelist") and rendered above 3Jane content; it is now generic. The Infinifi escrow guidance stays inSYSTEM_INSTRUCTIONS.Testing
uv run pytest -q tests/(844 passed, 4 skipped, 5 subtests)tests/test_threejane_context.pyandtests/test_protocol_context.pyuv run ruff check .anduv run ruff format --check .uv run mypy --follow-imports=skip utils/llm/threejane_context.py utils/llm/protocol_context.pyexplain_transaction(LLM call stubbed), plussetConfigon the proxied ProtocolConfig,grantRoleon JANE, and the wrong-protocol / wrong-chain / unknown-hash guards🤖 Generated with Claude Code