Source Code

;; title: aibtc-dao
;; version: 1.0.0
;; summary: An ExecutorDAO implementation for aibtcdev

;; traits
;;

(impl-trait 'SPW8QZNWKZGVHX012HCBJVJVPS94PXFG578P53TM.aibtc-base-dao-trait.aibtc-base-dao)
(use-trait proposal-trait 'SPW8QZNWKZGVHX012HCBJVJVPS94PXFG578P53TM.aibtc-dao-traits.proposal)
(use-trait extension-trait 'SPW8QZNWKZGVHX012HCBJVJVPS94PXFG578P53TM.aibtc-dao-traits.extension)

;; constants
;;

(define-constant ERR_UNAUTHORIZED (err u1200))
(define-constant ERR_ALREADY_EXECUTED (err u1201))
(define-constant ERR_INVALID_EXTENSION (err u1202))
(define-constant ERR_NO_EMPTY_LISTS (err u1203))
(define-constant ERR_DAO_ALREADY_CONSTRUCTED (err u1204))

;; data vars
;;

;; used for initial construction, set to contract itself after
(define-data-var executive principal tx-sender)
(define-data-var constructed bool false)

;; data maps
;;

;; tracks block height of executed proposals
(define-map ExecutedProposals
  principal
  uint
)
;; tracks enabled status of extensions
(define-map Extensions
  principal
  bool
)

;; public functions
;;

;; initial construction of the DAO
(define-public (construct (proposal <proposal-trait>))
  (let ((sender tx-sender))
    (asserts! (not (var-get constructed)) ERR_DAO_ALREADY_CONSTRUCTED)
    (asserts! (is-eq sender (var-get executive)) ERR_UNAUTHORIZED)
    (var-set constructed true)
    (var-set executive (as-contract tx-sender))
    (print {
      notification: "fake-base-dao/construct",
      payload: {
        proposal: (contract-of proposal),
        sender: sender,
      },
    })
    (as-contract (execute proposal sender))
  )
)

;; execute Clarity code in a proposal
(define-public (execute
    (proposal <proposal-trait>)
    (sender principal)
  )
  (begin
    (try! (is-self-or-extension))
    (asserts!
      (map-insert ExecutedProposals (contract-of proposal) stacks-block-height)
      ERR_ALREADY_EXECUTED
    )
    (print {
      notification: "fake-base-dao/execute",
      payload: {
        proposal: proposal,
        sender: sender,
      },
    })
    (as-contract (contract-call? proposal execute sender))
  )
)

;; add an extension or update the status of an existing one
(define-public (set-extension
    (extension principal)
    (enabled bool)
  )
  (begin
    (try! (is-self-or-extension))
    (print {
      notification: "fake-base-dao/set-extension",
      payload: {
        enabled: enabled,
        extension: extension,
      },
    })
    (ok (map-set Extensions extension enabled))
  )
)

;; add multiple extensions or update the status of existing ones
(define-public (set-extensions (extensionList (list 200 {
  extension: principal,
  enabled: bool,
})))
  (begin
    (try! (is-self-or-extension))
    (asserts! (> (len extensionList) u0) ERR_NO_EMPTY_LISTS)
    (ok (map set-extensions-iter extensionList))
  )
)

;; request a callback from an extension
(define-public (request-extension-callback
    (extension <extension-trait>)
    (memo (buff 34))
  )
  (let ((sender tx-sender))
    (asserts! (is-extension contract-caller) ERR_INVALID_EXTENSION)
    (asserts! (is-eq contract-caller (contract-of extension))
      ERR_INVALID_EXTENSION
    )
    (print {
      notification: "fake-base-dao/request-extension-callback",
      payload: {
        extension: extension,
        memo: memo,
        sender: sender,
      },
    })
    (as-contract (contract-call? extension callback sender memo))
  )
)

;; read only functions
;;

(define-read-only (is-constructed)
  (var-get constructed)
)

(define-read-only (is-extension (extension principal))
  (default-to false (map-get? Extensions extension))
)

(define-read-only (executed-at (proposal <proposal-trait>))
  (map-get? ExecutedProposals (contract-of proposal))
)

;; private functions
;;

;; authorization check
(define-private (is-self-or-extension)
  (ok (asserts!
    (or (is-eq tx-sender (as-contract tx-sender)) (is-extension contract-caller))
    ERR_UNAUTHORIZED
  ))
)

;; set-extensions helper function
(define-private (set-extensions-iter (item {
  extension: principal,
  enabled: bool,
}))
  (begin
    (print {
      notification: "fake-base-dao/set-extension",
      payload: {
        enabled: (get enabled item),
        extension: (get extension item),
      },
    })
    (map-set Extensions (get extension item) (get enabled item))
  )
)

Functions (8)

FunctionAccessArgs
constructpublicproposal: <proposal-trait>
set-extensionspublicextensionList: (list 200 { extension: principal, enabled: bool, }
request-extension-callbackpublicextension: <extension-trait>, memo: (buff 34
is-constructedread-only
is-extensionread-onlyextension: principal
executed-atread-onlyproposal: <proposal-trait>
is-self-or-extensionprivate
set-extensions-iterprivateitem: { extension: principal, enabled: bool, }