Source Code

;; DAO Treasury Contract
;; Manages funds and executes transfers authorized by governance

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u300))
(define-constant err-not-authorized (err u301))
(define-constant err-insufficient-balance (err u302))
(define-constant err-invalid-amount (err u303))
(define-constant err-proposal-not-executed (err u304))
(define-constant err-transfer-failed (err u305))

;; Data variables
(define-data-var proposal-system-contract principal .proposal-system)
(define-data-var total-deposited uint u0)
(define-data-var total-withdrawn uint u0)
(define-data-var treasury-balance uint u0)

;; Data maps
(define-map authorized-proposals uint bool)
(define-map spending-history 
    uint 
    { 
        recipient: principal, 
        amount: uint, 
        timestamp: uint,
        proposal-id: uint,
        description: (string-utf8 200)
    }
)
(define-data-var spending-count uint u0)

;; Deposit funds into treasury
(define-public (deposit-funds (amount uint))
    (begin
        (asserts! (> amount u0) err-invalid-amount)
        (var-set total-deposited (+ (var-get total-deposited) amount))
        (var-set treasury-balance (+ (var-get treasury-balance) amount))
        (print { 
            event: "funds-deposited", 
            depositor: tx-sender, 
            amount: amount,
            new-balance: (var-get treasury-balance)
        })
        (ok true)
    )
)

;; Withdraw funds (only through governance)
(define-public (withdraw-funds (amount uint) (recipient principal) (proposal-id uint) (description (string-utf8 200)))
    (let (
        (spending-id (+ (var-get spending-count) u1))
    )
        (asserts! (> amount u0) err-invalid-amount)
        (asserts! (is-authorized-proposal proposal-id) err-not-authorized)
        (asserts! (>= (var-get treasury-balance) amount) err-insufficient-balance)
        
        (var-set total-withdrawn (+ (var-get total-withdrawn) amount))
        (var-set treasury-balance (- (var-get treasury-balance) amount))
        (map-set spending-history spending-id {
            recipient: recipient,
            amount: amount,
            timestamp: stacks-block-height,
            proposal-id: proposal-id,
            description: description
        })
        (var-set spending-count spending-id)
        
        (print { 
            event: "funds-withdrawn", 
            recipient: recipient, 
            amount: amount,
            proposal-id: proposal-id,
            spending-id: spending-id
        })
        (ok spending-id)
    )
)

;; Execute transfer approved by governance
(define-public (execute-transfer (recipient principal) (amount uint) (proposal-id uint) (description (string-utf8 200)))
    (begin
        ;; Verify proposal is executed in the proposal system
        (asserts! (is-proposal-executed proposal-id) err-proposal-not-executed)
        
        ;; Authorize and execute withdrawal
        (map-set authorized-proposals proposal-id true)
        (withdraw-funds amount recipient proposal-id description)
    )
)

;; Authorize a proposal (only proposal system can call)
(define-public (authorize-proposal (proposal-id uint))
    (begin
        (asserts! (is-eq contract-caller (var-get proposal-system-contract)) err-not-authorized)
        (map-set authorized-proposals proposal-id true)
        (print { event: "proposal-authorized", proposal-id: proposal-id })
        (ok true)
    )
)

;; Emergency withdrawal (only owner, for security)
(define-public (emergency-withdraw (amount uint) (recipient principal))
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (asserts! (> amount u0) err-invalid-amount)
        (asserts! (>= (var-get treasury-balance) amount) err-insufficient-balance)
        
        (var-set total-withdrawn (+ (var-get total-withdrawn) amount))
        (var-set treasury-balance (- (var-get treasury-balance) amount))
        
        (print { 
            event: "emergency-withdrawal", 
            recipient: recipient, 
            amount: amount 
        })
        (ok true)
    )
)

;; Update proposal system contract (only owner)
(define-public (set-proposal-system (new-contract principal))
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (var-set proposal-system-contract new-contract)
        (print { event: "proposal-system-updated", new-contract: new-contract })
        (ok true)
    )
)

;; Read-only functions

(define-read-only (get-balance)
    (var-get treasury-balance)
)

(define-read-only (get-total-deposited)
    (ok (var-get total-deposited))
)

(define-read-only (get-total-withdrawn)
    (ok (var-get total-withdrawn))
)

(define-read-only (is-authorized-proposal (proposal-id uint))
    (default-to false (map-get? authorized-proposals proposal-id))
)

(define-read-only (get-spending-history (spending-id uint))
    (ok (map-get? spending-history spending-id))
)

(define-read-only (get-spending-count)
    (ok (var-get spending-count))
)

(define-read-only (get-proposal-system-contract)
    (ok (var-get proposal-system-contract))
)

;; Helper function to check if proposal is executed
(define-private (is-proposal-executed (proposal-id uint))
    ;; This would interact with proposal-system contract
    ;; For now, we'll use a simplified check
    (is-authorized-proposal proposal-id)
)

;; Treasury statistics
(define-read-only (get-treasury-stats)
    (ok {
        current-balance: (var-get treasury-balance),
        total-deposited: (var-get total-deposited),
        total-withdrawn: (var-get total-withdrawn),
        spending-count: (var-get spending-count)
    })
)

Functions (15)

FunctionAccessArgs
deposit-fundspublicamount: uint
withdraw-fundspublicamount: uint, recipient: principal, proposal-id: uint, description: (string-utf8 200
execute-transferpublicrecipient: principal, amount: uint, proposal-id: uint, description: (string-utf8 200
authorize-proposalpublicproposal-id: uint
emergency-withdrawpublicamount: uint, recipient: principal
set-proposal-systempublicnew-contract: principal
get-balanceread-only
get-total-depositedread-only
get-total-withdrawnread-only
is-authorized-proposalread-onlyproposal-id: uint
get-spending-historyread-onlyspending-id: uint
get-spending-countread-only
get-proposal-system-contractread-only
is-proposal-executedprivateproposal-id: uint
get-treasury-statsread-only