Source Code

;; clarity-version: 2
(define-constant contract-owner tx-sender)
(define-constant err-unauthorized (err u100))
(define-constant err-not-found (err u101))
(define-constant err-invalid-score (err u102))

(define-data-var total-researchers uint u0)

(define-map researcher-profiles
    { researcher: principal }
    {
        total-submissions: uint,
        accepted-submissions: uint,
        rejected-submissions: uint,
        total-earned: uint,
        reputation-score: uint,
        joined-at: uint,
        is-verified: bool
    }
)

(define-read-only (get-researcher-profile (researcher principal))
    (map-get? researcher-profiles { researcher: researcher })
)

(define-read-only (get-reputation-score (researcher principal))
    (match (map-get? researcher-profiles { researcher: researcher })
        profile (ok (get reputation-score profile))
        err-not-found
    )
)

(define-public (register-researcher)
    (let
        (
            (existing (map-get? researcher-profiles { researcher: tx-sender }))
        )
        (asserts! (is-none existing) err-unauthorized)
        (map-set researcher-profiles
            { researcher: tx-sender }
            {
                total-submissions: u0,
                accepted-submissions: u0,
                rejected-submissions: u0,
                total-earned: u0,
                reputation-score: u50,
                joined-at: block-height,
                is-verified: false
            }
        )
        (var-set total-researchers (+ (var-get total-researchers) u1))
        (ok true)
    )
)

(define-public (update-reputation-on-acceptance 
    (researcher principal) 
    (reward uint) 
    (severity (string-ascii 8))
)
    (let
        (
            (profile (unwrap! (map-get? researcher-profiles { researcher: researcher }) err-not-found))
            (score-boost (severity-to-score-boost severity))
            (new-score (+ (get reputation-score profile) score-boost))
        )
        (asserts! (is-eq contract-caller contract-owner) err-unauthorized)
        (map-set researcher-profiles
            { researcher: researcher }
            (merge profile {
                total-submissions: (+ (get total-submissions profile) u1),
                accepted-submissions: (+ (get accepted-submissions profile) u1),
                total-earned: (+ (get total-earned profile) reward),
                reputation-score: (if (> new-score u100) u100 new-score)
            })
        )
        (ok new-score)
    )
)

(define-public (update-reputation-on-rejection (researcher principal))
    (let
        (
            (profile (unwrap! (map-get? researcher-profiles { researcher: researcher }) err-not-found))
            (new-score (if (>= (get reputation-score profile) u5) 
                (- (get reputation-score profile) u5)
                u0
            ))
        )
        (asserts! (is-eq contract-caller contract-owner) err-unauthorized)
        (map-set researcher-profiles
            { researcher: researcher }
            (merge profile {
                total-submissions: (+ (get total-submissions profile) u1),
                rejected-submissions: (+ (get rejected-submissions profile) u1),
                reputation-score: new-score
            })
        )
        (ok new-score)
    )
)

(define-private (severity-to-score-boost (severity (string-ascii 8)))
    (if (is-eq severity "critical")
        u20
        (if (is-eq severity "high")
            u15
            (if (is-eq severity "medium")
                u10
                u5
            )
        )
    )
)

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

(define-read-only (calculate-success-rate (researcher principal))
    (match (map-get? researcher-profiles { researcher: researcher })
        profile
        (let
            (
                (total (get total-submissions profile))
                (accepted (get accepted-submissions profile))
            )
            (if (> total u0)
                (ok (/ (* accepted u100) total))
                (ok u0)
            )
        )
        err-not-found
    )
)

Functions (8)

FunctionAccessArgs
get-researcher-profileread-onlyresearcher: principal
get-reputation-scoreread-onlyresearcher: principal
register-researcherpublic
update-reputation-on-acceptancepublicresearcher: principal, reward: uint, severity: (string-ascii 8
update-reputation-on-rejectionpublicresearcher: principal
severity-to-score-boostprivateseverity: (string-ascii 8
get-total-researchersread-only
calculate-success-rateread-onlyresearcher: principal