Governance ZIP — Changelog & Implementation Notes
Companion post for DRAFT Governance ZIP v2 for Comment (kept separate to stay within forum post limits): the pre-merge implementation checklist, then the changelog (newest first).
Required pre-merge updates (Reference Implementation checklist)
-
Fork-height activation for both heights; nothing conditioned on an on-chain spork object.
-
Bridge/Liquidity admin changes removed from the governance PR — the migration is its own PR.
-
Pillar-owner-only proposing; open-action cap.
-
Propose-time allowlist, emergency-flag, and zero-address validation.
-
Legacy spork-path removal at the fork.
-
Deposit escrow: exact amount, no setter, refund/donate settlement.
-
Type-1E: absolute conditions, immediate execution, early-reject, expiry.
-
Per-round
ActivePillarSnapshot, never read live. -
Type-2 direct write: codec not dispatchable; round-0 immediate, ratchet delayed;
ExecutableAt; no send on approval. -
networkAdministratorwith fallback; deterministicGetNetworkAdministrator(). -
Automated readiness signaling (§11.3a) with measurement tooling.
-
GetPillarVotes,GetNetworkAdministrator, Type-2MultisigRecordInfoinlining. -
No Multisig-contract changes beyond its own ZIP’s activation gate; independent review confirms nothing else rides along.
-
Migration PR: implement the §6.3 disposition table with table-driven tests for every row (incl.
Fund/BurnZnnre-gating, redefined BridgeEmergency, LiquidityEmergencyunresolvable, guardian-less surviving callers); deprecated-field assertions (never read post-height, zeroed on first write, pre-height bytes decode identically); plasma check inReceiveBlock;Haltaccepts TSS from a non-admin; end-to-end threshold-signed admin call;GovernanceAddressretained for replay only, no other non-test consumer. -
Open as upstream PRs.
Changelog
v2.2 — hard-fork activation for the Multisig; readiness criterion specified (2026-07-27).
-
The Multisig ZIP activates by hard fork (
MultisigForkHeight), not byMultisigSpork. Both contracts are now enabled by hard fork; the heights are independent, schedulable in either order, and MAY coincide — a single shared-height fork is the preferred deployment when release timing allows. This removes the governance-first activation ordering, the two-Type-1-action spork dance for the multisig, and the extra placeholder-replacement release it required. It costs one small change to PR #72 (the activation gate swaps from the dormant spork check to a fork-height check — see Multisig ZIP v1.2). The two-action implemented-spork release protocol is retained in §6.1 as the normative procedure for all future governance-activated sporks, where the consensus-safety lesson still applies. -
Readiness signaling fully specified (§11.3a/3b). Pillars signal via automated once-per-epoch zero-amount blocks from the producer address carrying a feature marker — consensus-neutral under pre-fork rules, attributable via the Pillar registry, measurable by anyone. The momentum
Versionfield is explicitly ruled out (the verifier pins it exactly pre-fork). The below-threshold path is now explicit: after a suggested 90-day campaign, the height MAY be scheduled anyway with ≥90 days’ lead — the criterion is pacing guidance, never an adoption veto. -
Editorial: comparative references to the superseded v1 draft were moved out of the specification body and into this changelog. For the record, relative to v1: the
GovernanceForkHeight == MultisigForkHeighthard coupling was dropped (now optional rather than required); the requirement that the multisig’sChangeSignerSetacceptGovernanceContractas a caller was withdrawn as infeasible and weaker (Type-2 becameSetNetworkAdministrator); the propose-time rejection ofDestination == MultisigContractbecame moot whenMultisigContractleft the destination set; and the Type-2 payload changed from a raw signer list (no on-chain object to inspect) to an address with a queryable live policy.
v2.1 — adversarial-review fixes (2026-07-26). Addresses the findings of the independent adversarial audit (2026-07-26-codex-adversarial-review.md):
-
CRITICAL-1: the
MultisigSporkactivation sequence now specifies two Type-1 actions with a mandatory real-SporkId binary release betweenCreateSporkandActivateSpork(§2); collapsing them terminates every upgraded node at enforcement (os.Exit(2)on an active unimplemented spork). -
CRITICAL-2: Liquidity
FundandBurnZnn— gated today on the unreachable legacy spork signer and therefore already stranded — are re-gated tonetworkAdminin the migration (§6.3). -
CRITICAL-3:
Emergencysemantics defined: BridgeEmergencyis retained, redefined asnetworkAdmin-gated TSS-clear + halt (no administrator zeroing, no guardian predicate); LiquidityEmergencyis removed as redundant withSetIsHalted(§6.3). -
CRITICAL-4: persisted composite storage (
bridgeInfo,liquidityInfo,securityInfo) keeps its ABI codec unchanged; deprecated fields are ignored by consensus logic and zeroed on first post-height write — “removal” is from authorization/dispatch/RPC, never from the storage encoding (§6.3). -
HIGH-2: the guardian-count predicate is removed from
CheckSecurityInitializedpost-height so surviving callers (SetTokenTuple,SetAllowKeygen,ChangeTssECDSAPubKey,Emergency) don’t brick;AdministratorDelayis explicitly deprecated (all consumers removed). -
HIGH-3: the claim that a round-0 Type-2 vote “outruns” the TSS time challenge is corrected to a race with mandatory monitoring — the challenge floor is one epoch (~24h) and the protocol guarantees no vote latency.
-
MEDIUM-1/2/3: Type-2 approval-vs-effect semantics unambiguous (internal write in whichever
ExecuteActionperforms it; ratchet rounds separate approval and effect by 72h by design); “three heights” corrected to two hard forks plus a spork, strayMultisigForkHeightreference removed; runtime vs scheduling prerequisites distinguished in §2. -
LOW-1/3: threshold-floor figures stated per track (Type-2 ~21.8%, Type-1 ~26.4%, asymptotic); proposal input validation fully specified (30/240-byte limits, exact URL regex).
-
§6.3 now carries the complete privileged-method disposition table (Bridge 16 admin-aware methods, Liquidity 10), replacing the enumerate-it-later requirement.
v2 — networkAdmin (2026-07-26). Incorporates the multisig-implementation review and the plasma/GovernanceAddress finding:
-
Type-2 redefined:
SetNetworkAdministratoronGovernanceContract, replacingChangeSignerSetonMultisigContract. The v1 action was infeasible against the actual Multisig implementation (go-zenon#72): the method isChangePolicy, it operates only on its own sender, the account verifier hard-rejects blocks lacking threshold signatures (which a contract-send cannot carry), andLockedis monotonic. It was also the weaker design: rotation recovers only from compromised signers, while repointing recovers from a compromised, locked, or abandoned admin. Type-2 now writes governance storage directly (no contract-send), exempting it from the non-atomic-execution caveat. Thresholds, ratchet schedule, periods, and the 72h ratchet-round delay are unchanged. -
The Multisig contract is untouched. v1’s requirement that it accept
GovernanceContractas an authorized caller is withdrawn. The multisig manages only its own signing policy; its power as admin derives entirely from other contracts honoring its address. -
Single
networkAdminreplaces all per-contract admin state. NewnetworkAdministratorgovernance variable withInitialNetworkAdministratorfallback (hardcoded to the community Multisig, published and verified per the new §11.5 gate). At a new third height, Bridge and Liquidity dropAdministrator, guardians,ChangeAdministrator/ProposeAdministrator/NominateGuardians, andInitialBridgeAdministrator; admin-gated methods checkGetNetworkAdministrator(). Fund-equivalent time challenges (ChangeTssECDSAPubKey) andHaltMethod’s dual admin/TSS path are retained. Bridge/Liquidity RPC keeps theadministratorfield, populated from governance. -
Plasma parameters become admin-set, resolving the
GovernanceAddresstrap. ZIP-3’sSetVariableswas gated on a placeholder user address whose planned repoint to the governance contract would have made the setter permanently unreachable (no action type can targetPlasmaContract). Instead, plasma joins the migration:SetVariableschecksGetNetworkAdministrator()(inReceiveBlock— send-side validation has no state access), the placeholder is retired, and the current single-keyholder backdoor closes. Boundary made explicit: the governance contract setsnetworkAdminand nothing else; it has no path, direct or indirect, to plasma variables. -
Same-height coupling removed. Merge order between the two implementations is unconstrained; the Multisig ZIP activates via
MultisigSpork(expected: Type-1 actions per the §2 release protocol, the first production use of this machinery; genesis pre-activation on new networks), andAdminMigrationForkHeightrequires governance active,MultisigSporkactive, and the §11.5 publication gate (address,(creatorPubKey, nonce)for offline recomputation, signer identities,locked == false,pending == null). The v1 propose-time rejection ofDestination == MultisigContractis obsolete — it is no longer a destination at all. -
No callable setter.
SetNetworkAdministratorexists only as the Type-2 payload codec and is absent from the dispatch table; the vote is the only write path. Explicitly not the BridgeChangeAdministratorpattern, under which a captured admin could transfer authority without a vote. -
Type-2 target validation: reject only the zero address (
ErrInvalidNetworkAdministrator); noIsMultisigAddressrequirement — the type check is false assurance (a 2-of-2 held by one person passes) and forecloses future embedded-contract admins. In its place, a hard RPC requirement: Type-2 action views MUST inline the proposed address’sMultisigRecordInfo, defending the new pending-policy bait-and-switch and locked-target considerations. NewGetNetworkAdministratorRPC with the same inlining. -
New security material: malicious admin repointing (replacing malicious signer rotation), admin control of plasma parameters, an emergency admin-replacement runbook (creator-must-be-a-signer constraint, round-0 fast path, exposure-window bounds), migration completeness, and the orchestrator administrator-mode retirement documented under Backward Compatibility.
-
New constants
AdminMigrationForkHeight,InitialNetworkAdministrator,ErrInvalidNetworkAdministrator; theGovernanceForkHeight == MultisigForkHeightconstraint is removed.
v1 revisions (retained for history). Incorporates community review: the Multisig dependency is pinned (shared fork height, normative interface); a Type-1E emergency spork track is added (7 days, Yes from >66% of all active Pillars); the Type-2 ratchet floor rises >25% → >33% with a 72h delay on ratchet-round rotations; NoDecision now refunds the deposit; per-round Pillar snapshots, re-vote semantics, a 2-open-actions cap, and a measurable fork-height readiness signal are specified; and signer-set legitimacy is assigned to the Pillar vote rather than a nomination filter.
v1 — fixed deposit. The proposal deposit is a fixed protocol constant of 100 ZNN for all action types. SetProposalDeposit, the [10, 1,000] ZNN bounds, the Type-2 pricing exemption, and the GetProposalDeposit RPC are removed. Rationale: Pillar-only proposing plus the 2-open-actions cap already bound spam, so the adjustment lever added attack surface (deposit-as-censorship, and the only Multisig-to-governance authorization edge) without benefit; the deposit can now change only by Pillar-approved protocol upgrade.