Disputes & Bonds (Flags, Cases, Grace, Refunds, Community Notes)
Status: Concept for v0 / v0.1 Last updated: YYYY‑MM‑DD
1) Purpose & Scope
The Disputes & Bonds module handles:
Flags (paid requests for review),
Case lifecycle (open → resolve),
Time‑based grace for author publish bonds,
Refund/forfeit rules for flags and bonds,
Community Notes (DAO‑approved context labels).
ELI5: If readers think something is wrong, they pay a small deposit to raise a hand. If the DAO agrees and takes action, those readers get their money back and the author’s publish deposit can be taken (within ~10 days). If the DAO does nothing, the readers’ deposits are kept by the protocol, and the author gets their deposit back after ~10 days.
Out of scope: recording a wallet’s single action (that’s Actions) and article publication itself (that’s ArticlesRegistry).
2) Responsibilities & Non‑Goals
Responsibilities
Escrow flag deposits; open cases at threshold.
Resolve cases; process refunds/forfeits.
Enforce time‑based grace for publish bond refunds/slashing.
Store and expose Community Notes (IPFS CIDs).
Non‑Goals
Voting, downvotes, upvotes (Actions module).
Search, ranking, indexing (CIN node).
DAO voting mechanics (handled by the governance process off‑chain/on‑chain, but Disputes enforces the final decision via authorized roles).
3) External Dependencies
CRUMBS (ERC‑20) — currency for flags/bonds.
ArticlesRegistry — authoritative record of
cidexistence and publish timestamp (createdAt) and author address.Actions — enforces single‑action rule and routes
flag(...)into Disputes.Vault — destination for unrefunded flag fees and slashed bonds.
Config (DAO‑timelocked) — parameters & percentages.
4) Parameters (DAO‑timelocked defaults)
FLAG_FEEF = 25 CRUMBSFLAGS_TO_OPENK = 3GRACE_SECONDS≈ 10 days (time‑based; not block‑based)PUBLISH_BONDB = 100 CRUMBS
Economic rules (as finalized):
Downvotes (Dislike/DownVote): 100% to Vault.
Upvotes: 20% of counted part to Vault; 80% of counted + 100% of tips to Author.
Flags:
If DAO action taken → flaggers refunded F.
If no action → flags forfeit to Vault.
Publish bond:
If DAO action taken within grace → bond slashed to Vault.
If no upheld action during grace → bond refundable to Author after grace.
If action is taken after grace, flags still refunded, but bond cannot be slashed (already refundable/returned).
5) Data Model & State
Notes
One open case per CID at a time. Additional flags while a case is open are added to that case.
After resolution, a new case can open later if fresh flags reach threshold again (rare; allowed).
6) Flows
6.1 Publish (handled via ArticlesRegistry; bond recorded here)
ArticlesRegistry.publish(cid, ...)requires B CRUMBS; Actions/Registry callsDisputes._onPublish(cid, author, createdAt)to record:bondOf[cid] = { amount: B, publishTime: createdAt, refunded: false, slashed: false }.
6.2 Flag (called from Actions.flag)
Verify
cidis published and caller hasn’t acted (Actions enforces).Pull F CRUMBS from caller into Disputes escrow.
If
openCaseOf[cid] == 0:Create new case with
CaseStatus.Open, pushFlagInfo, setopenedAt = now.If total flags in case ≥ K, emit
DisputeOpened.
Else:
Append flag to existing Open case.
If flags cross threshold and case was not announced, emit
DisputeOpened.
Emit
Flagged(cid, flagger, noteCid?).
Single‑action: the wallet’s action ledger is in Actions; Flags here assume Actions already consumed that slot.
6.3 Resolve (DAO‑authorized)
resolveDispute(caseId, actionTaken, noteCids[])
Preconditions:
cases[caseId].status == Open.Set
cases[caseId].status = Resolved,resolvedAt = now,resolution = actionTaken ? ActionTaken : NoAction.Store Community Notes (
noteCids[]) in the case (append).If ActionTaken:
For each flag in case: mark refundable; do not pull from Vault; refunds go from escrow (see 6.4).
If
now <= bondOf[cid].publishTime + GRACE_SECONDSand bond is not refunded/slashed:Slash bond: transfer B to Vault; mark
slashed = true.
Else (grace elapsed): bond remains refundable; no slashing.
If NoAction:
Transfer all flag escrow for this case to Vault (flaggers will not be refunded).
Emit
DisputeResolved(caseId, actionTaken, noteCids).
6.4 Flag refunds (pull‑based)
claimFlagRefund(caseId) — callable by each flagger if and only if:
cases[caseId].status == Resolved && cases[caseId].resolution == ActionTaken, andThe caller appears in
flags[]andrefunded == false.
On success:
Transfer F to caller; set
refunded = true; emitFlagRefunded(caseId, caller, F).
6.5 Author bond refund (pull‑or‑anyone‑trigger)
autoRefundBond(cid) — callable by anyone if and only if:
now >= bondOf[cid].publishTime + GRACE_SECONDS, andNo ActionTaken resolution exists within grace for this
cid, andBond not already
refundedorslashed.
On success:
Transfer B to the Author of the
cid; markrefunded = true; emitBondRefunded(cid, author, B).
Edge: If ActionTaken happens after grace, the bond may already be refunded or eligible; Disputes must not attempt slashing after grace.
7) Interfaces & Events (Solidity Sketch)
Access control:
flag(...)— only callable by Actions module (prevents bypassing single‑action rule).resolveDispute(...)— onlyDAO (e.g., governed timelocked executor / council multisig).autoRefundBondandclaimFlagRefund— public, with guards.
8) Community Notes
Notes are IPFS CIDs (immutable), approved on resolution.
UIs display notes prominently with the dispute label.
CIN nodes index note CIDs alongside article docs so clients can fetch summarized context.
Categories (recommendation for UI, not enforced on‑chain):
Misleading / Missing Context
Plagiarism / Copyright
Harmful / Illegal in Jurisdiction
Malware / Phishing
Other (free text in note file)
9) Security & Invariants
Escrow conservation: For each case, the sum of all flag deposits ends either in refunds (ActionTaken) or Vault (NoAction). No stranded CRUMBS.
Bond finality: A bond is exclusively refunded or slashed or still escrowed; never double‑spent.
Grace correctness: Slashing is only allowed if
now ≤ publishTime + GRACE_SECONDS.Reentrancy‑safe:
nonReentrantonresolveDispute, refunds, and bond transfers; CEI pattern.Auth boundaries: Only Actions can add flags; only DAO can resolve.
Time source:
block.timestampis the clock; avoid assumptions about block cadence.
10) Testing Checklist
Unit
Flag escrow: amounts recorded; thresholds open cases; events emitted.
Resolve(ActionTaken): flag refunds claimable; no Vault transfer of flags; bond slashing within grace; no slashing after grace.
Resolve(NoAction): flag escrow transferred to Vault; no refunds; bond auto‑refundable after grace.
autoRefundBond: succeeds after grace; fails before; idempotent via state flags.Single‑action integration: bypass attempts rejected via onlyActions (mock Actions).
Property/Fuzz
Conservation:
sum(flags) = sum(refunds)(ActionTaken) or= transferToVault(NoAction).Bond state never double‑finalizes.
Random interleavings of flags/resolve/refund maintain invariants.
Integration
With Actions:
flag()path, single‑action consumption.With ArticlesRegistry: publish time and author address consistent.
With Vault: balances match expectations (flags/no action, bonds/slash).
11) Read‑Model for UIs & Indexers
Per CID: current open caseId (if any), case status, flag count, openedAt, notes.
Author view: bond status (
escrowed | refunded | slashed), grace deadline timestamp.Flagger view: list of cases where wallet flagged, and whether refund is claimable.
CIN nodes should mirror case metadata to power:
“Under Review” ribbons,
“Action Taken” labels + notes,
Countdown to grace expiry for authors.
12) Performance & Gas Notes
One open case per CID keeps state small.
Flags stored densely; consider cap or pagination for extremely popular disputes (UI can compress).
Refunds are pull‑based to avoid looping transfers on resolve (gas‑safe and reentrancy‑safe).
13) Acceptance Criteria
Flags open cases at K; DAO resolutions process funds as specified.
Bonds are slashed only within
GRACE_SECONDS; otherwise refundable after grace.UIs can query complete case status and notes.
No double refunds, no stuck funds, all events emitted.
14) Changelog
v1: Initial Disputes & Bonds spec with time‑based grace, escrowed flags, refunds/forfeits, slashing rules, and Community Notes.
Last updated