Source Code

;; board.clar
;; Board of Trustees - Passive oversight for Bitzion governance
;;
;; Powers (from Yarvin's essay):
;; - Hire/fire the coordinator
;; - Approve regular tax (ongoing dilution rate)
;; - Approve special tax (one-time dilution)
;; - NO operational decisions, NO per-spend approval
;;
;; The coordinator handles all operational matters including treasury spending

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-trustee (err u101))
(define-constant err-proposal-not-found (err u102))
(define-constant err-already-voted (err u103))
(define-constant err-proposal-executed (err u104))
(define-constant err-threshold-not-met (err u105))
(define-constant err-invalid-proposal-type (err u106))
(define-constant err-no-coordinator (err u107))

;; 16/30 majority required (53%+)
(define-constant approval-threshold u16)
(define-constant board-size u30)

;; Proposal types
(define-constant proposal-type-coordinator u1)
(define-constant proposal-type-regular-tax u2)
(define-constant proposal-type-special-tax u3)

;; State
(define-data-var proposal-nonce uint u0)
(define-data-var coordinator (optional principal) none)
(define-data-var regular-tax-rate uint u50) ;; 0.5% annual (50 basis points)

;; Proposals
(define-map proposals
  uint
  {
    proposer: principal,
    proposal-type: uint,
    target: principal,        ;; For coordinator: new coordinator. For tax: recipient (treasury)
    amount: uint,             ;; For special tax: amount to mint. For regular: new rate
    memo: (optional (buff 256)),
    executed: bool,
    approval-count: uint
  })

;; Votes on proposals
(define-map proposal-votes
  { proposal-id: uint, voter: principal }
  bool)

;; Check if caller is a trustee
(define-private (is-trustee-caller)
  (contract-call? .hyperelection is-trustee tx-sender))

;; Propose new coordinator
(define-public (propose-coordinator (candidate principal))
  (let
    (
      (proposer tx-sender)
      (proposal-id (var-get proposal-nonce))
    )
    (asserts! (is-trustee-caller) err-not-trustee)

    (map-set proposals proposal-id {
      proposer: proposer,
      proposal-type: proposal-type-coordinator,
      target: candidate,
      amount: u0,
      memo: none,
      executed: false,
      approval-count: u1
    })

    ;; Proposer automatically votes yes
    (map-set proposal-votes {proposal-id: proposal-id, voter: proposer} true)
    (var-set proposal-nonce (+ proposal-id u1))

    (print {event: "proposal-coordinator", id: proposal-id, proposer: proposer, candidate: candidate})
    (ok proposal-id)))

;; Propose regular tax rate change (basis points, 100 = 1%)
(define-public (propose-regular-tax (new-rate uint))
  (let
    (
      (proposer tx-sender)
      (proposal-id (var-get proposal-nonce))
    )
    (asserts! (is-trustee-caller) err-not-trustee)

    (map-set proposals proposal-id {
      proposer: proposer,
      proposal-type: proposal-type-regular-tax,
      target: tx-sender, ;; Not used
      amount: new-rate,
      memo: none,
      executed: false,
      approval-count: u1
    })

    (map-set proposal-votes {proposal-id: proposal-id, voter: proposer} true)
    (var-set proposal-nonce (+ proposal-id u1))

    (print {event: "proposal-regular-tax", id: proposal-id, proposer: proposer, rate: new-rate})
    (ok proposal-id)))

;; Propose special tax (one-time dilution)
(define-public (propose-special-tax (amount uint) (memo (optional (buff 256))))
  (let
    (
      (proposer tx-sender)
      (proposal-id (var-get proposal-nonce))
    )
    (asserts! (is-trustee-caller) err-not-trustee)

    (map-set proposals proposal-id {
      proposer: proposer,
      proposal-type: proposal-type-special-tax,
      target: tx-sender, ;; Not used, mints to treasury
      amount: amount,
      memo: memo,
      executed: false,
      approval-count: u1
    })

    (map-set proposal-votes {proposal-id: proposal-id, voter: proposer} true)
    (var-set proposal-nonce (+ proposal-id u1))

    (print {event: "proposal-special-tax", id: proposal-id, proposer: proposer, amount: amount})
    (ok proposal-id)))

;; Vote on any proposal
(define-public (vote (proposal-id uint))
  (let
    (
      (voter tx-sender)
      (proposal (unwrap! (map-get? proposals proposal-id) err-proposal-not-found))
    )
    (asserts! (is-trustee-caller) err-not-trustee)
    (asserts! (is-none (map-get? proposal-votes {proposal-id: proposal-id, voter: voter})) err-already-voted)
    (asserts! (not (get executed proposal)) err-proposal-executed)

    (map-set proposal-votes {proposal-id: proposal-id, voter: voter} true)
    (map-set proposals proposal-id
      (merge proposal {approval-count: (+ (get approval-count proposal) u1)}))

    (print {event: "vote", proposal-id: proposal-id, voter: voter, new-count: (+ (get approval-count proposal) u1)})
    (ok true)))

;; Execute coordinator appointment
(define-public (execute-coordinator (proposal-id uint))
  (let
    (
      (proposal (unwrap! (map-get? proposals proposal-id) err-proposal-not-found))
    )
    (asserts! (is-eq (get proposal-type proposal) proposal-type-coordinator) err-invalid-proposal-type)
    (asserts! (not (get executed proposal)) err-proposal-executed)
    (asserts! (>= (get approval-count proposal) approval-threshold) err-threshold-not-met)

    ;; Mark executed
    (map-set proposals proposal-id (merge proposal {executed: true}))

    ;; Set new coordinator
    (var-set coordinator (some (get target proposal)))

    ;; Update treasury with new coordinator
    (try! (contract-call? .treasury set-coordinator (get target proposal)))

    (print {event: "coordinator-appointed", proposal-id: proposal-id, coordinator: (get target proposal)})
    (ok true)))

;; Execute regular tax rate change
(define-public (execute-regular-tax (proposal-id uint))
  (let
    (
      (proposal (unwrap! (map-get? proposals proposal-id) err-proposal-not-found))
    )
    (asserts! (is-eq (get proposal-type proposal) proposal-type-regular-tax) err-invalid-proposal-type)
    (asserts! (not (get executed proposal)) err-proposal-executed)
    (asserts! (>= (get approval-count proposal) approval-threshold) err-threshold-not-met)

    ;; Mark executed
    (map-set proposals proposal-id (merge proposal {executed: true}))

    ;; Set new rate
    (var-set regular-tax-rate (get amount proposal))

    (print {event: "regular-tax-updated", proposal-id: proposal-id, new-rate: (get amount proposal)})
    (ok true)))

;; Execute special tax (mint tokens to treasury)
(define-public (execute-special-tax (proposal-id uint))
  (let
    (
      (proposal (unwrap! (map-get? proposals proposal-id) err-proposal-not-found))
    )
    (asserts! (is-eq (get proposal-type proposal) proposal-type-special-tax) err-invalid-proposal-type)
    (asserts! (not (get executed proposal)) err-proposal-executed)
    (asserts! (>= (get approval-count proposal) approval-threshold) err-threshold-not-met)

    ;; Mark executed
    (map-set proposals proposal-id (merge proposal {executed: true}))

    ;; Mint tokens to treasury (dilution)
    (try! (contract-call? .treasury board-dilute (get amount proposal)))

    (print {event: "special-tax-executed", proposal-id: proposal-id, amount: (get amount proposal)})
    (ok true)))

;; Read-only functions

(define-read-only (get-coordinator)
  (var-get coordinator))

(define-read-only (get-regular-tax-rate)
  (var-get regular-tax-rate))

(define-read-only (get-proposal (proposal-id uint))
  (map-get? proposals proposal-id))

(define-read-only (get-vote (proposal-id uint) (voter principal))
  (map-get? proposal-votes {proposal-id: proposal-id, voter: voter}))

(define-read-only (get-proposal-nonce)
  (var-get proposal-nonce))

(define-read-only (get-approval-threshold)
  approval-threshold)

(define-read-only (is-proposal-approved (proposal-id uint))
  (match (map-get? proposals proposal-id)
    proposal (>= (get approval-count proposal) approval-threshold)
    false))

(define-read-only (can-execute (proposal-id uint))
  (match (map-get? proposals proposal-id)
    proposal (and
      (>= (get approval-count proposal) approval-threshold)
      (not (get executed proposal)))
    false))

Functions (16)

FunctionAccessArgs
is-trustee-callerprivate
propose-coordinatorpubliccandidate: principal
propose-regular-taxpublicnew-rate: uint
propose-special-taxpublicamount: uint, memo: (optional (buff 256
votepublicproposal-id: uint
execute-coordinatorpublicproposal-id: uint
execute-regular-taxpublicproposal-id: uint
execute-special-taxpublicproposal-id: uint
get-coordinatorread-only
get-regular-tax-rateread-only
get-proposalread-onlyproposal-id: uint
get-voteread-onlyproposal-id: uint, voter: principal
get-proposal-nonceread-only
get-approval-thresholdread-only
is-proposal-approvedread-onlyproposal-id: uint
can-executeread-onlyproposal-id: uint