Source Code

;; title: TesseractVault
;; version:
;; summary:
;; description:

;; Constants
(define-constant CONTRACT-OWNER tx-sender)
(define-constant TOKEN-NAME "OluolaVote Token")
(define-constant TOKEN-SYMBOL "OVOTE")
(define-constant TOKEN-DECIMALS u6)

;; Error codes
(define-constant ERR-NOT-AUTHORIZED (err u401))
(define-constant ERR-INSUFFICIENT-BALANCE (err u402))
(define-constant ERR-INVALID-AMOUNT (err u403))
(define-constant ERR-TRANSFER-FAILED (err u404))
(define-constant ERR-MINT-FAILED (err u405))
(define-constant ERR-BURN-FAILED (err u406))

;; Data variables
(define-data-var token-uri (optional (string-utf8 256)) none)
(define-data-var total-supply uint u0)

;; Data maps
(define-map balances principal uint)
(define-map allowances { owner: principal, spender: principal } uint)

;; Token holder tracking with Clarity 4 timestamps
(define-map token-holders
    { holder: principal }
    {
        balance: uint,
        first-received: uint,                ;; Clarity 4: Unix timestamp
        last-updated: uint                   ;; Clarity 4: Unix timestamp
    }
)

;; SIP-010 Functions

(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
    (begin
        (asserts! (is-eq tx-sender sender) ERR-NOT-AUTHORIZED)
        (asserts! (> amount u0) ERR-INVALID-AMOUNT)

        (let
            (
                (sender-balance (default-to u0 (map-get? balances sender)))
            )
            (asserts! (>= sender-balance amount) ERR-INSUFFICIENT-BALANCE)

            (map-set balances sender (- sender-balance amount))
            (map-set balances recipient (+ (default-to u0 (map-get? balances recipient)) amount))

            ;; Update token holder tracking
            (map-set token-holders
                { holder: recipient }
                {
                    balance: (+ (default-to u0 (map-get? balances recipient)) amount),
                    first-received: (match (map-get? token-holders { holder: recipient })
                        holder-info (get first-received holder-info)
                        stacks-block-time
                    ),
                    last-updated: stacks-block-time          ;; Clarity 4: Unix timestamp
                }
            )

            (print {
                event: "token-transfer",
                sender: sender,
                recipient: recipient,
                amount: amount,
                memo: memo,
                timestamp: stacks-block-time
            })
            (ok true)
        )
    )
)

(define-read-only (get-name)
    (ok TOKEN-NAME)
)

(define-read-only (get-symbol)
    (ok TOKEN-SYMBOL)
)

(define-read-only (get-decimals)
    (ok TOKEN-DECIMALS)
)

(define-read-only (get-balance (account principal))
    (ok (default-to u0 (map-get? balances account)))
)

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

(define-read-only (get-token-uri)
    (ok (var-get token-uri))
)

;; Governance-specific functions

;; Mint new tokens (only contract owner)
(define-public (mint (amount uint) (recipient principal))
    (begin
        (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
        (asserts! (> amount u0) ERR-INVALID-AMOUNT)

        (map-set balances recipient (+ (default-to u0 (map-get? balances recipient)) amount))
        (var-set total-supply (+ (var-get total-supply) amount))

        ;; Update token holder tracking
        (map-set token-holders
            { holder: recipient }
            {
                balance: (+ (default-to u0 (map-get? balances recipient)) amount),
                first-received: (match (map-get? token-holders { holder: recipient })
                    holder-info (get first-received holder-info)
                    stacks-block-time
                ),
                last-updated: stacks-block-time              ;; Clarity 4: Unix timestamp
            }
        )

        (print {
            event: "token-minted",
            recipient: recipient,
            amount: amount,
            timestamp: stacks-block-time
        })
        (ok true)
    )
)

;; Burn tokens from sender's balance
(define-public (burn (amount uint))
    (let
        (
            (sender-balance (default-to u0 (map-get? balances tx-sender)))
        )
        (asserts! (> amount u0) ERR-INVALID-AMOUNT)
        (asserts! (>= sender-balance amount) ERR-INSUFFICIENT-BALANCE)

        (map-set balances tx-sender (- sender-balance amount))
        (var-set total-supply (- (var-get total-supply) amount))

        ;; Update token holder tracking
        (map-set token-holders
            { holder: tx-sender }
            {
                balance: (- sender-balance amount),
                first-received: (match (map-get? token-holders { holder: tx-sender })
                    holder-info (get first-received holder-info)
                    stacks-block-time
                ),
                last-updated: stacks-block-time              ;; Clarity 4: Unix timestamp
            }
        )

        (print {
            event: "token-burned",
            holder: tx-sender,
            amount: amount,
            timestamp: stacks-block-time
        })
        (ok true)
    )
)

;; Get voting power (same as balance for this implementation)
(define-read-only (get-voting-power (account principal))
    (ok (default-to u0 (map-get? balances account)))
)

;; Get token holder information
(define-read-only (get-holder-info (holder principal))
    (ok (map-get? token-holders { holder: holder }))
)

;; Set token URI (only contract owner)
(define-public (set-token-uri (new-uri (string-utf8 256)))
    (begin
        (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
        (var-set token-uri (some new-uri))
        (ok true)
    )
)

Functions (12)

FunctionAccessArgs
transferpublicamount: uint, sender: principal, recipient: principal, memo: (optional (buff 34
get-nameread-only
get-symbolread-only
get-decimalsread-only
get-balanceread-onlyaccount: principal
get-total-supplyread-only
get-token-uriread-only
mintpublicamount: uint, recipient: principal
burnpublicamount: uint
get-voting-powerread-onlyaccount: principal
get-holder-inforead-onlyholder: principal
set-token-uripublicnew-uri: (string-utf8 256