Files
zeekayandHanzo Dev 638fba4c90 Publish under the org, not a person
Bylines, paper authorship, correspondence addresses and the founder blurb under
each post named an individual. They name the organisation that published the
work instead: the brand on posts and pages, the research byline on papers, and
research@ in place of a personal address. Both are what these repositories
already used elsewhere — nothing new was coined.

Co-authors are untouched. Where a paper named someone else alongside, they stay
named; only the one byline changed. Bibliography entries, running heads,
PDF metadata and affiliations move with it, so a citation still resolves to
whoever the cited paper names.

Sample and fixture data uses the placeholder name these tests already use
elsewhere, so no assertion changed meaning.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-01 08:58:14 -07:00

125 lines
4.2 KiB
Lean4
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/-
Authors: Antje Worring, Zoo Labs Foundation Research
Treasury Management Properties
The DAO treasury holds funds and distributes them via governance.
All operations require proposal + quorum vote.
Maps to:
- zoo/zoo.vote: treasury management interface
- zoo/contracts: on-chain treasury
- zoo/ZIPs: governance proposals (ZIP-003 genesis)
Properties:
- Solvency: treasury balance ≥ 0 (no overdraft)
- Authorization: all transfers require governance vote
- Transparency: all operations are recorded
- Budget: approved spending ≤ available balance
-/
import Mathlib.Data.Nat.Defs
import Mathlib.Data.List.Basic
import Mathlib.Tactic
namespace Governance.Treasury
/-- Treasury operation types -/
inductive OpType where
| deposit
| grant (recipient : Nat) (amount : Nat)
| investment (target : String) (amount : Nat)
| burn (amount : Nat)
deriving DecidableEq, Repr
/-- Operation with governance approval -/
structure TreasuryOp where
opType : OpType
proposalId : Nat
approved : Bool -- passed quorum vote
executed : Bool -- has been executed
/-- Treasury state -/
structure TreasuryState where
balance : Nat
totalDeposited : Nat
totalGranted : Nat
totalBurned : Nat
operations : List TreasuryOp
/-- Execute a treasury operation -/
def execute (s : TreasuryState) (op : TreasuryOp) : TreasuryState :=
if !op.approved then s -- unapproved ops are no-ops
else match op.opType with
| .deposit =>
{ s with balance := s.balance + 0 } -- deposits handled separately
| .grant _ amount =>
if amount ≤ s.balance then
{ s with balance := s.balance - amount
, totalGranted := s.totalGranted + amount
, operations := { op with executed := true } :: s.operations }
else s
| .investment _ amount =>
if amount ≤ s.balance then
{ s with balance := s.balance - amount
, operations := { op with executed := true } :: s.operations }
else s
| .burn amount =>
if amount ≤ s.balance then
{ s with balance := s.balance - amount
, totalBurned := s.totalBurned + amount
, operations := { op with executed := true } :: s.operations }
else s
/-- Deposit funds -/
def deposit (s : TreasuryState) (amount : Nat) : TreasuryState :=
{ s with balance := s.balance + amount
, totalDeposited := s.totalDeposited + amount }
/-- SOLVENCY: balance never goes negative (Nat ensures this structurally) -/
theorem solvency (s : TreasuryState) (op : TreasuryOp) :
(execute s op).balance ≤ s.balance ∨ (execute s op).balance = s.balance := by
left
simp only [execute]
split
· rfl
· split <;> first | rfl | (split <;> simp [Nat.sub_le])
/-- AUTHORIZATION: unapproved ops don't change state -/
theorem unapproved_noop (s : TreasuryState) (op : TreasuryOp)
(h : op.approved = false) :
execute s op = s := by
simp [execute, h]
/-- BUDGET: grants cannot exceed balance -/
theorem grant_within_budget (s : TreasuryState) (op : TreasuryOp)
(recipient amount : Nat)
(h_type : op.opType = .grant recipient amount)
(h_approved : op.approved = true) :
(execute s op).balance ≤ s.balance := by
simp only [execute, h_approved, h_type, Bool.not_true, Bool.false_eq_true, if_false]
split <;> simp
/-- DEPOSIT INCREASES BALANCE -/
theorem deposit_increases (s : TreasuryState) (amount : Nat) :
(deposit s amount).balance = s.balance + amount := by
simp [deposit]
/-- TRANSPARENCY: executed ops are recorded -/
theorem executed_recorded (s : TreasuryState) (op : TreasuryOp)
(h : op.approved = true)
(recipient amount : Nat) (h_type : op.opType = .grant recipient amount)
(h_funds : amount ≤ s.balance) :
(execute s op).operations.length > s.operations.length := by
simp [execute, h, h_type, h_funds, List.length_cons]
/-- Empty treasury blocks all grants -/
theorem empty_blocks_grants (op : TreasuryOp)
(recipient amount : Nat) (h_type : op.opType = .grant recipient amount)
(h_amount : amount > 0) (h_approved : op.approved = true) :
execute ⟨0, 0, 0, 0, []⟩ op = ⟨0, 0, 0, 0, []⟩ := by
simp only [execute, h_approved, h_type, Bool.not_true, Bool.false_eq_true, if_false]
rw [if_neg (by omega)]
end Governance.Treasury