Skip to content

Start DIN-DAO #23

Description

@umeradl

Branch: feat/din-dao
Assignee: @robertocarlous
Roadmap ref: P3-5.1 (DAO governance hooks) · ROADMAP Discussion §1 · Developer/issues/decentralized-governance.md

Long-running issue. DIN does not need a live DAO today: devnet 1.0 is released; devnet 2.0, devnet 3.0, testnet 1.0, and testnet 2.0 are still ahead. DAO governance is expected to activate devnet 3.0 onwards, with binding on-chain governance hardening through the testnets. This issue tracks the whole effort — design first, contracts behind feat/din-dao, staged activation later. Detailed task files under Developer/tasks/ will follow per stage.

Goal

Design and implement the DIN-DAO: the contract layer that progressively replaces the centralized DIN-Representative admin key (owner() / daoAdmin) with multisig, timelocked, and eventually token-vote-driven governance over the platform contracts (DinCoordinator, DinValidatorStake, DINModelRegistry, and the PR #13 ProxyAdmin).

Contracts live in foundry/src/ (suggested: foundry/src/dao/). Design and documentation are first-class deliverables, not afterthoughts.

What already exists in the repo (survey result)

There is substantial conceptual design but no contract-level architecture and no governance code:

  • Developer/issues/decentralized-governance.md — the main prior design work. Defines governance domains (parameter / policy / operational / treasury / upgrade), a proposal lifecycle (draft → discussion → creation → vote → queue → timelock → execute), per-category thresholds, and a layered architecture (voting power / proposal / voting / timelock / emergency). Key decisions already taken there: no raw quadratic voting; voting power from staked or locked DIN at a snapshot, not free balances; timelocked execution; narrow, expiring emergency powers.
  • Documentation/dindao.md — operational doc for the current, centralized "DIN DAO" (the DIN-Representative running dincli dindao ...). This is the admin surface the DAO must eventually own.
  • Developer/ROADMAP.md Discussion §1 + P3-5.1 — DAO hooks land in P3 as onlyOwner parameter setters with a documented path to multisig/DAO; DAO is deliberately not scheduled ahead of slashing/staking/testnet readiness.
  • Developer/issues/tokenomics.md §7 — token policy (issuance rate, treasury withdrawal, fees) flagged as centralized; recommends timelocked rate changes and moving owner powers to DAO execution.
  • Developer/issues/staking-mechanism.md — future governance-only confiscation path for permanently blacklisted stake (must execute via accepted DAO proposal, not interim admin).
  • Developer/issues/indexer.md — governance contracts should be designed events-first; proposal lists, voter histories, and dashboards belong in the indexer, not in on-chain enumeration.
  • hardhat/contracts/DINModelRegistry.sol setDAOAdmin — already documented as the "multisig / timelock migration path". PR Feature/platform upgradeable #13 converts this to Ownable two-step ownership, which is exactly the handle the DAO takes over.
  • OpenZeppelin governance primitives (Governor, TimelockController, Votes) are already vendored at foundry/lib/openzeppelin-contracts/contracts/governance/ — no new dependency needed.

Conclusion: no DIN-DAO architecture is built. The production-grade design below is proposed as the baseline for this issue; challenge it in the design doc where you disagree.

Reference implementation: DAOFLcode

https://github.com/umermajeedkhu/DAOFLcode/tree/main/contracts is a prior DAO-for-federated-learning prototype worth mining for patterns, not for code:

  • MultiSigC.sol — multisig with selector-typed proposals (bytes4 selector => ContractCallType with per-type configuration, open-proposal caps per approver, and an explicit NotExist → Open → Executable → Closed/Executed proposal state machine). The typed-proposal idea maps directly onto DIN's per-category thresholds.
  • DAOC.sol / DAOFLC.sol — membership-NFT (ERC-721) based DAO with GI-aware proposals (proposal ↔ global-iteration mapping).
  • Caveats: Solidity 0.8.7 / OZ 4.x era (Counters, string reverts), hand-rolled Ownable, no timelock, no snapshot voting, no delegation. Treat it as a pattern reference; the DIN implementation should be built on the vendored OZ 5.x governance stack, custom errors, and the repo's conventions (solc 0.8.28, via_ir, NatSpec per P3-6.3b).

Proposed architecture (production-grade baseline)

Progressive decentralization in four stages. Each stage is independently shippable and matches a network milestone.

Stage A — Multisig (build now, shadow-operate in devnet 2.0)

DinMultisig.sol — an N-of-M multisig with typed proposals (DAOFLcode MultiSigC pattern, modernized):

  • proposal = target + calldata + category; confirm / revoke / execute; explicit state machine
  • per-category confirmation thresholds (e.g. 2-of-3 for fee changes, 3-of-3 for treasury/upgrades)
  • events for every transition (indexer-first, per Developer/issues/indexer.md)
  • Document the tradeoff vs. adopting Gnosis Safe on OP Sepolia in the design doc. Writing our own keeps the devnet self-contained and auditable in-tree; Safe is the battle-tested choice for mainnet treasury later. Both paths must be covered in the doc even if we build our own first.

Stage B — Timelock owns the platform (devnet 3.0 activation target)

DinTimelock.sol — thin instantiation of OZ TimelockController:

  • becomes owner() of DinCoordinator, DinValidatorStake, DINModelRegistry, and the PR Feature/platform upgradeable #13 ProxyAdmin (upgrade governance)
  • DinMultisig holds PROPOSER_ROLE + CANCELLER_ROLE; EXECUTOR_ROLE open or multisig-gated (document choice)
  • minimum delay per risk class: short for bounded parameter changes, long for upgrades/treasury (two timelock instances or per-operation salt conventions — document the chosen mechanism)
  • This stage is the smallest meaningful decentralization step (Phase 1 of decentralized-governance.md): every admin action becomes visible on-chain before it executes, with a cancellation window.

Stage C — Token-vote governance (testnet 1.0 → 2.0)

  • DinGovernanceStaking.sol (working name stDIN) — voting power source. Locks DIN, mints non-transferable, checkpointed voting power implementing OZ IVotes (delegation + snapshot at proposal creation). This enforces the two standing decisions: no free-balance voting, no raw quadratic voting. Whether validator stake in DinValidatorStake also counts (hybrid) is an open design question — answer it in the design doc with the economic rationale.
  • DinGovernor.sol — OZ Governor + GovernorSettings + GovernorCountingSimple + GovernorVotes + GovernorVotesQuorumFraction + GovernorTimelockControl, executing through DinTimelock. Proposal threshold, voting delay, voting period, quorum fraction all governance-settable.
  • Per-category thresholds (simple majority for parameters; supermajority + longer delay for treasury/upgrades): OZ Governor is single-track, so document and pick one of — (a) two governor instances routed to two timelocks, (b) a category registry checked in propose(), or (c) start single-track and split later. The multisig retains CANCELLER_ROLE as a safety brake during this transition.

Stage D — Emergency layer (with Stage C)

DinGuardian.sol — narrow, expiring emergency authority:

  • scope limited to protective actions only: disable a model, deauthorize a slasher, pause a dangerous flow
  • every emergency action expires unless ratified by normal governance within a fixed window; restorative actions (re-enable, unblacklist) always go through normal governance
  • guardian role held by the multisig, revocable by governance

Explicit non-goals (for this issue)

  • No quadratic voting (see decentralized-governance.md — signaling-only, if ever, and off-chain)
  • No task-level governance — task contracts stay model-owner-driven
  • No on-chain proposal browsing/enumeration helpers — dashboards come from the indexer (P4-IDX work)
  • No mainnet treasury custody decisions yet — Safe-vs-own-multisig is documented, not committed

Integration points to design around

  • PR Feature/platform upgradeable #13 upgradeable contracts: ProxyAdmin ownership is the upgrade-governance handle; storage layout rules (__gap, append-only) apply to any upgradeable DAO contract.
  • P3-5.1/5.2/5.3 (token utility, emission, fees): their onlyOwner setters are the DAO's future surface — no signature changes needed if they follow the plain-setter convention; flag any that don't.
  • dincli dindao: current direct admin calls eventually become propose → queue → execute flows. CLI work is out of scope here, but the design doc must specify the command mapping so the SDK/daemon issues (start DIN-SDK #20, start DIN daemon #21) can plan for it.
  • Slashing/dispute work (P3-4.x): dispute resolution and blacklist appeal flows will name the DAO as final arbiter — coordinate interfaces with Umer's slashing spec.

Deliverables

  • Design doc Documentation/technical/din-dao/README.md: architecture, stage rollout mapped to network milestones (devnet 2.0 / 3.0, testnet 1.0 / 2.0), category-threshold table, voting-power model decision (locked vs. hybrid with stake), Safe-vs-own-multisig tradeoff, answers to the open questions in Developer/issues/decentralized-governance.md
  • Contracts in foundry/src/dao/: DinMultisig.sol, DinTimelock.sol, DinGovernanceStaking.sol, DinGovernor.sol, DinGuardian.sol + interfaces (solc 0.8.28, custom errors, NatSpec, events-first)
  • Foundry tests in foundry/test/dao/: full proposal lifecycle e2e (propose → vote → queue → execute against a real platform-contract call), timelock delay enforcement, quorum/threshold edges, delegation checkpoints, multisig confirm/revoke/execute, guardian action expiry + ratification; fuzz/invariant tests (voting power conservation, nothing executes before its delay) per P3-6.3b conventions
  • Ownership-transfer runbook: exact ordered steps to move owner()/daoAdmin of each platform contract to the timelock, with rollback notes (extends Documentation/dindao.md §5)
  • Update Developer/issues/decentralized-governance.md with decisions made (keep it as the rationale record; the new design doc is the spec)

Suggested sequencing

  1. Design doc first — get the stage boundaries and voting-power decision reviewed before writing Solidity
  2. DinMultisig + DinTimelock + tests (Stage A/B is the bulk of near-term value)
  3. DinGovernanceStaking + DinGovernor + DinGuardian (Stage C/D — can trail by weeks; nothing activates before devnet 3.0)

No hard deadline: nothing in P3 blocks on this, and P3-5.x setter work should not wait for it. The design doc, however, is worth landing early so the P3-5.x contracts expose the right governance surface.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions