Source Code

(define-constant ERR_UNAUTHORIZED (err u100))
(define-constant ERR_NOT_FOUND (err u101))
(define-constant ERR_ALREADY_EXISTS (err u102))
(define-constant ERR_INVALID_PARAMS (err u103))

(define-data-var contract-owner principal tx-sender)

(define-map curated-tokens uint {token-contract: principal, symbol: (string-ascii 10), curator: principal, rating: uint, category: (string-ascii 50), curated-at: uint, active: bool})
(define-map curators principal {curator-name: (string-ascii 100), reputation: uint, tokens-curated: uint, verified: bool})
(define-map curator-votes {token-id: uint, curator: principal} {vote: bool, weight: uint, voted-at: uint})
(define-map token-metrics {token-id: uint, metric-type: (string-ascii 30)} uint)
(define-data-var token-count uint u0)

(define-read-only (get-owner) (var-get contract-owner))

(define-read-only (get-curated-token (token-id uint))
  (map-get? curated-tokens token-id))

(define-read-only (get-curator (curator-id principal))
  (map-get? curators curator-id))

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

(define-read-only (get-token-metric (token-id uint) (metric-type (string-ascii 30)))
  (map-get? token-metrics {token-id: token-id, metric-type: metric-type}))

(define-public (register-curator (curator-name (string-ascii 100)))
  (begin
    (asserts! (is-none (map-get? curators tx-sender)) ERR_ALREADY_EXISTS)
    (ok (map-set curators tx-sender {curator-name: curator-name, reputation: u50, tokens-curated: u0, verified: false}))))

(define-public (verify-curator (curator principal))
  (let ((curator-data (unwrap! (map-get? curators curator) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set curators curator (merge curator-data {verified: true})))))

(define-public (curate-token (token-contract principal) (symbol (string-ascii 10)) (rating uint) (category (string-ascii 50)))
  (let ((token-id (+ (var-get token-count) u1))
        (curator-data (unwrap! (map-get? curators tx-sender) ERR_UNAUTHORIZED)))
    (asserts! (get verified curator-data) ERR_UNAUTHORIZED)
    (asserts! (<= rating u100) ERR_INVALID_PARAMS)
    (map-set curated-tokens token-id {token-contract: token-contract, symbol: symbol, curator: tx-sender, rating: rating, category: category, curated-at: stacks-block-height, active: true})
    (map-set curators tx-sender (merge curator-data {tokens-curated: (+ (get tokens-curated curator-data) u1)}))
    (var-set token-count token-id)
    (ok token-id)))

(define-public (vote-on-token (token-id uint) (vote bool) (weight uint))
  (let ((curator-data (unwrap! (map-get? curators tx-sender) ERR_UNAUTHORIZED))
        (token (unwrap! (map-get? curated-tokens token-id) ERR_NOT_FOUND)))
    (asserts! (get verified curator-data) ERR_UNAUTHORIZED)
    (asserts! (get active token) ERR_INVALID_PARAMS)
    (asserts! (is-none (map-get? curator-votes {token-id: token-id, curator: tx-sender})) ERR_ALREADY_EXISTS)
    (asserts! (<= weight u10) ERR_INVALID_PARAMS)
    (ok (map-set curator-votes {token-id: token-id, curator: tx-sender} {vote: vote, weight: weight, voted-at: stacks-block-height}))))

(define-public (update-token-rating (token-id uint) (new-rating uint))
  (let ((token (unwrap! (map-get? curated-tokens token-id) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (get curator token)) ERR_UNAUTHORIZED)
    (asserts! (<= new-rating u100) ERR_INVALID_PARAMS)
    (ok (map-set curated-tokens token-id (merge token {rating: new-rating})))))

(define-public (record-metric (token-id uint) (metric-type (string-ascii 30)) (value uint))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (asserts! (is-some (map-get? curated-tokens token-id)) ERR_NOT_FOUND)
    (ok (map-set token-metrics {token-id: token-id, metric-type: metric-type} value))))

(define-public (update-curator-reputation (curator principal) (new-reputation uint))
  (let ((curator-data (unwrap! (map-get? curators curator) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (asserts! (<= new-reputation u100) ERR_INVALID_PARAMS)
    (ok (map-set curators curator (merge curator-data {reputation: new-reputation})))))

(define-public (delist-token (token-id uint))
  (let ((token (unwrap! (map-get? curated-tokens token-id) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set curated-tokens token-id (merge token {active: false})))))

(define-public (transfer-ownership (new-owner principal))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (var-set contract-owner new-owner))))

Functions (14)

FunctionAccessArgs
get-ownerread-only
get-curated-tokenread-onlytoken-id: uint
get-curatorread-onlycurator-id: principal
get-curator-voteread-onlytoken-id: uint, curator: principal
get-token-metricread-onlytoken-id: uint, metric-type: (string-ascii 30
register-curatorpubliccurator-name: (string-ascii 100
verify-curatorpubliccurator: principal
curate-tokenpublictoken-contract: principal, symbol: (string-ascii 10
vote-on-tokenpublictoken-id: uint, vote: bool, weight: uint
update-token-ratingpublictoken-id: uint, new-rating: uint
record-metricpublictoken-id: uint, metric-type: (string-ascii 30
update-curator-reputationpubliccurator: principal, new-reputation: uint
delist-tokenpublictoken-id: uint
transfer-ownershippublicnew-owner: principal