;; dao-core.clar
;; Core DAO framework - initialization, membership, roles, parameters
;; Clarity 4 / Epoch 3.3
;; -----------------------------------------------
;; Constants
;; -----------------------------------------------
(define-constant CONTRACT-OWNER tx-sender)
(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-ALREADY-INITIALIZED (err u101))
(define-constant ERR-NOT-INITIALIZED (err u102))
(define-constant ERR-ALREADY-MEMBER (err u103))
(define-constant ERR-NOT-MEMBER (err u104))
(define-constant ERR-INVALID-ROLE (err u105))
(define-constant ERR-DAO-PAUSED (err u106))
(define-constant ERR-INVALID-PARAM (err u107))
(define-constant ROLE-ADMIN u1)
(define-constant ROLE-MEMBER u2)
(define-constant ROLE-OBSERVER u3)
;; -----------------------------------------------
;; Data Variables
;; -----------------------------------------------
(define-data-var dao-name (string-ascii 64) "")
(define-data-var dao-initialized bool false)
(define-data-var dao-paused bool false)
(define-data-var dao-version uint u1)
(define-data-var member-count uint u0)
(define-data-var voting-period uint u144)
(define-data-var quorum-threshold uint u20)
(define-data-var pass-threshold uint u51)
(define-data-var upgrade-address (optional principal) none)
;; -----------------------------------------------
;; Data Maps
;; -----------------------------------------------
(define-map members
principal
{
role: uint,
joined-at: uint,
active: bool
}
)
(define-map dao-parameters
(string-ascii 32)
uint
)
;; -----------------------------------------------
;; Private Functions
;; -----------------------------------------------
(define-private (is-admin (caller principal))
(match (map-get? members caller)
member (and (is-eq (get role member) ROLE-ADMIN) (get active member))
false
)
)
(define-private (is-active-member (caller principal))
(match (map-get? members caller)
member (get active member)
false
)
)
;; -----------------------------------------------
;; Public Functions
;; -----------------------------------------------
;; Initialize the DAO with a name and config
(define-public (initialize (name (string-ascii 64)) (voting-len uint) (quorum uint) (pass uint))
(begin
(asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
(asserts! (not (var-get dao-initialized)) ERR-ALREADY-INITIALIZED)
(asserts! (> voting-len u0) ERR-INVALID-PARAM)
(asserts! (<= quorum u100) ERR-INVALID-PARAM)
(asserts! (<= pass u100) ERR-INVALID-PARAM)
(var-set dao-name name)
(var-set voting-period voting-len)
(var-set quorum-threshold quorum)
(var-set pass-threshold pass)
(var-set dao-initialized true)
(map-set members CONTRACT-OWNER
{ role: ROLE-ADMIN, joined-at: tenure-height, active: true })
(var-set member-count u1)
(ok true)
)
)
;; Register a new member with a role
(define-public (register-member (new-member principal) (role uint))
(begin
(asserts! (var-get dao-initialized) ERR-NOT-INITIALIZED)
(asserts! (not (var-get dao-paused)) ERR-DAO-PAUSED)
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(asserts! (is-none (map-get? members new-member)) ERR-ALREADY-MEMBER)
(asserts! (or (is-eq role ROLE-ADMIN)
(is-eq role ROLE-MEMBER)
(is-eq role ROLE-OBSERVER)) ERR-INVALID-ROLE)
(map-set members new-member
{ role: role, joined-at: tenure-height, active: true })
(var-set member-count (+ (var-get member-count) u1))
(ok true)
)
)
;; Update a member role
(define-public (update-role (member principal) (new-role uint))
(begin
(asserts! (var-get dao-initialized) ERR-NOT-INITIALIZED)
(asserts! (not (var-get dao-paused)) ERR-DAO-PAUSED)
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(asserts! (or (is-eq new-role ROLE-ADMIN)
(is-eq new-role ROLE-MEMBER)
(is-eq new-role ROLE-OBSERVER)) ERR-INVALID-ROLE)
(match (map-get? members member)
existing (begin
(map-set members member (merge existing { role: new-role }))
(ok true)
)
ERR-NOT-MEMBER
)
)
)
;; Remove a member (deactivate)
(define-public (remove-member (member principal))
(begin
(asserts! (var-get dao-initialized) ERR-NOT-INITIALIZED)
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(match (map-get? members member)
existing (begin
(map-set members member (merge existing { active: false }))
(var-set member-count (- (var-get member-count) u1))
(ok true)
)
ERR-NOT-MEMBER
)
)
)
;; Pause the DAO
(define-public (pause-dao)
(begin
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(var-set dao-paused true)
(ok true)
)
)
;; Unpause the DAO
(define-public (unpause-dao)
(begin
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(var-set dao-paused false)
(ok true)
)
)
;; Set upgrade address for future migration
(define-public (set-upgrade-address (new-address principal))
(begin
(asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
(var-set upgrade-address (some new-address))
(var-set dao-version (+ (var-get dao-version) u1))
(ok true)
)
)
;; Update a named DAO parameter
(define-public (set-parameter (param-name (string-ascii 32)) (value uint))
(begin
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(asserts! (not (var-get dao-paused)) ERR-DAO-PAUSED)
(map-set dao-parameters param-name value)
(ok true)
)
)
;; Update voting period directly
(define-public (set-voting-period (new-period uint))
(begin
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(asserts! (> new-period u0) ERR-INVALID-PARAM)
(var-set voting-period new-period)
(ok true)
)
)
;; Update quorum threshold directly
(define-public (set-quorum (new-quorum uint))
(begin
(asserts! (is-admin tx-sender) ERR-NOT-AUTHORIZED)
(asserts! (<= new-quorum u100) ERR-INVALID-PARAM)
(var-set quorum-threshold new-quorum)
(ok true)
)
)
;; -----------------------------------------------
;; Read-Only Functions
;; -----------------------------------------------
(define-read-only (get-dao-info)
{
name: (var-get dao-name),
initialized: (var-get dao-initialized),
paused: (var-get dao-paused),
version: (var-get dao-version),
member-count: (var-get member-count),
voting-period: (var-get voting-period),
quorum: (var-get quorum-threshold),
pass-threshold: (var-get pass-threshold)
}
)
(define-read-only (get-member-info (member principal))
(map-get? members member)
)
(define-read-only (is-dao-member (who principal))
(is-active-member who)
)
(define-read-only (get-parameter (param-name (string-ascii 32)))
(map-get? dao-parameters param-name)
)
(define-read-only (get-upgrade-address)
(var-get upgrade-address)
)