website/design/solidity-lab/generated/FairSettlement.explained.md

7 KiB

FairSettlement — plain-language explanation

Generated by the OSS Singularity contract lab for: Synthetic fair settlement example. Synthetic example: placeholder addresses, a digest over the public synthetic artifact, future deadlines. The lab explains signatures; it never requests one from a wallet, deploys anything, or holds funds.

What this contract models

The settlement design note, as a readable state machine. The agreement comes before the work and before any funds move. The actual budget sits with a SEPARATELY AUTHORIZED holder — an escrow instance or named human authority — that reads these records and executes transfers in its own audited system. This contract records states and who declared them; it never holds, receives, or moves value of any kind, and it is deliberately not payable. The Commons never holds funds and never gains custody.

funded → delivered → accepted → released
funded → delivered → disputed → resolved → released | refunded
funded → refunded            (cancellation before delivery)
any waiting state past its deadline → the outcome the agreement already fixed
from the outer deadline on → refund only; no new release can succeed

States, named exactly as the design note names them

State Meaning
none the agreement is recorded, funding not yet declared
funded the agreed budget sits with the separately authorized holder
delivered a delivery receipt links the declared digest to the work
accepted the coordinator accepted exactly the newest revision — the release CONDITION, never the release itself
disputed one of the two parties named the dispute path and its reason
resolved the holder recorded the resolution decided under the agreed dispute rules
released terminal: the settlement went to the contributor
refunded terminal: the settlement went back to the coordinator

Every function and its requested signature

Function Signature you would be asked to sign What it establishes Who may call
recordFunding() a call declaring the budget sits with the holder that funding exists — a declaration about the holder's custody, never a transfer holder only
recordDelivery(uint16 revision) a call naming the next revision number that the contributor recorded revision N referencing the declared digest contributor only
accept(uint16 revision) a call naming the newest revision that acceptance binds exactly that revision before the review deadline — the release condition coordinator only
release() a call executing the release that the holder released the budget after acceptance satisfied its condition — before the outer deadline holder only
openDispute(string calldata reason) a call naming the reason for the dispute that one party opened the agreed dispute path while the work awaits review contributor or coordinator only
resolveDispute(bool releases) a call declaring which way the resolution goes that the holder recorded the resolution inside the dispute window holder only
executeResolution() a call executing the recorded resolution that the holder carried out the resolution: released or refunded, exactly as resolved — a releasing execution only before the outer deadline holder only
applyDisputeFallback() a call taking the agreed fallback that a dispute unresolved past its window ends in the outcome the agreement fixed (refund) — a releasing fallback only before the outer deadline anyone, once the dispute window has passed
refundAfterOuterDeadline() a call taking the refund path that funds unreleased past the outer deadline flow back instead of sitting withheld anyone, once the outer deadline has passed
refundOnCancellation() a call recording the cancellation refund that a cancelled agreement refunds the budget before delivery holder only

Timeouts for unresponsive participants

Every waiting state names a deadline and a defined default outcome:

  • delivery not reviewed by REVIEW_DEADLINE → the dispute path (accept is refused; openDispute and the outer-deadline refund remain possible) — never a silent release
  • dispute unresolved by DISPUTE_DEADLINE → the agreement's fallback outcome (here: refund), executable by anyone via applyDisputeFallback
  • funds unreleased by OUTER_DEADLINE → the refund path via refundAfterOuterDeadline, from every non-terminal state

Refund priority from the outer deadline on — the one precedence rule this machine fixes: the refund window and every release window are disjoint. Exactly from the outer deadline instant itself (inclusive — the moment refundAfterOuterDeadline becomes available, block.timestamp >= OUTER_DEADLINE), every release-minting transition is refused with OuterDeadlinePassed — release, a releasing executeResolution, and a releasing applyDisputeFallback alike. Before the deadline, releases remain possible and the refund is refused (OuterDeadlineNotPassed). At every timestamp exactly one direction can act, so a release can never race the refund for the same state, whichever transaction arrives first. Executions that already end in a refund stay allowed from the deadline on: they cannot compete with the refund outcome they share.

A timeout produces a DEFINED outcome; it never mints authority. The timeout paths are permissionless on purpose: they can only ever reach the outcome the agreement already fixed, so no caller gains control over the settlement.

What can fail, and how each failure is named

  • NotContributor / NotCoordinator / NotHolder — role checks at the decision point: nobody delivers, reviews, or declares custody for someone else.
  • NotParty — only the two parties may open a dispute; outsiders cannot trigger it.
  • WrongState — every transition demands the exact state the design note names; the failure reports the current one.
  • DuplicateRevision — revisions only move forward, one at a time.
  • NotNewestRevision — stale revisions are refused, not silently superseded.
  • DeadlinePassed — acceptance after the review deadline and resolutions after the dispute deadline are refused.
  • DisputeWindowStillOpen — the agreed fallback exists only for a dispute that outlived its window.
  • OuterDeadlineNotPassed — the refund path exists only from the outer deadline instant onward (inclusive).
  • OuterDeadlinePassed — every release path closes exactly from that instant on: once the refund is available, no new release can succeed.

Honest boundaries

This contract holds no funds and defines no payment mechanics. A digest proves which bytes were declared, not quality, authorship or availability. An acceptance record proves a decision, not fairness. The holder's custody is a separate, audited system with its own threat model; this design depends on it and says so. Deployment, testnet exercise, or any wallet interaction requires separate, explicit authorization — nothing here signs or deploys merely because it was generated.