docs(PolicyRegistry): document activation gating contract#157
Conversation
Add an Activation section to the PolicyRegistry reference spelling out the dispatcher's activation contract: - view entry points (isAuthorized, policyExists, policyAdmin, pendingPolicyAdmin) are always callable, regardless of activation state; - mutating entry points are gated and revert FeatureNotActivated while the feature is inactive; - selector/ABI error classification is independent of activation state, so UnknownFunctionSelector and ABI-decode errors are preserved even when the feature is inactive (the gate is reached only after a call resolves to a known mutator with well-formed args). Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
Interface Coverage✅ All interface functions have test coverage. |
📊 Forge Coverage (
|
| File | Lines | Stmts | Branches | Funcs |
|---|---|---|---|---|
| 🟢 B20FactoryLib.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockActivationRegistry.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockActivationRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Asset.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟡 MockB20Factory.sol | 98.96% | 99.10% | 100.00% | 100.00% |
| 🟢 MockB20Stablecoin.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Storage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockPolicyRegistry.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockPolicyRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| Total | 99.86% | 99.88% | 100.00% | 100.00% |
Full report: download artifact. To browse locally: make coverage (runs forge coverage + genhtml + opens the HTML report).
✅ Fork tests: all 610 passedbase/base is fully in sync with the base-std spec. |
|
|
||
| Keeping the views ungated means consumers — B20 tokens running `isAuthorized` on transfer, off-chain indexers reading membership and admin state — observe identical behavior whether or not the feature is active. Calling a gated mutator while the feature is inactive reverts with `FeatureNotActivated`. | ||
|
|
||
| > **Error classification is independent of activation state.** The dispatcher recognizes the selector and decodes arguments *before* it applies the activation gate. An unrecognized selector reverts `UnknownFunctionSelector` and malformed calldata reverts with an ABI-decode error whether the feature is active or not — the activation gate is reached only once a call has been resolved to a known mutating function with well-formed arguments. Clients, tests, and cross-environment simulations can therefore distinguish "feature inactive" from "bad call" reliably, and a given malformed call produces the same error on both sides of an activation boundary. |
There was a problem hiding this comment.
This is a bit hard for me to understand which means our customers probably will as well. Is there a way we can dumb it down or be more concise without losing important information?
There was a problem hiding this comment.
Maybe we could also flag this with "For auditors:" if we are going to dump this. Maybe this just deserves to be in base/base though
There was a problem hiding this comment.
Dropped the dense block. Kept the builder-facing contract (reads always callable, writes gated with FeatureNotActivated while inactive) and removed the selector/ABI error-classification detail.
There was a problem hiding this comment.
Agree it's auditor-oriented — removed it here rather than tagging "For auditors:". Will follow up separately with the team on capturing the error-semantics detail in base/base.
Address review feedback: - table of views/mutators -> two plain bullet lists - code-format `PolicyRegistry` to match `ActivationRegistry` - drop the dense error-classification blockquote; the selector/ABI error-semantics detail is auditor-oriented and is better placed in base/base. Keep the builder-facing contract: reads always callable, writes gated with FeatureNotActivated while inactive. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
What
Adds an Activation section to
docs/PolicyRegistry/README.mddocumenting the precompile dispatcher's activation contract — previously undocumented in the reference.Contract documented
isAuthorized,policyExists,policyAdmin,pendingPolicyAdmin) are always callable, regardless of activation state. Consumers (B20 transfer-time auth checks, off-chain indexers) see identical view behavior whether or not the feature is active.FeatureNotActivated.UnknownFunctionSelectorand ABI-decode errors are preserved even while the feature is inactive. A malformed call produces the same error on both sides of an activation boundary.Scope
Docs only — no interface or behavior change. Captures the intended dispatcher contract so the reference spec, tests, and cross-environment simulations agree on behavior near activation boundaries.