Source Code

;; ===============================
;; StacksOne Reputation Engine
;; NO BLOCK HEIGHT VERSION
;; ===============================

(define-constant CONTRACT-OWNER tx-sender)

(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-USER-NOT-FOUND (err u101))
(define-constant ERR-INVALID-AMOUNT (err u102))

;; ===============================
;; DATA MAPS
;; ===============================

(define-map user-reputation
  principal
  {
    score: uint,
    multiplier: uint
  }
)

(define-map admins
  principal
  bool
)

;; ===============================
;; INTERNAL CHECKS
;; ===============================

(define-private (is-admin (user principal))
  (or
    (is-eq user CONTRACT-OWNER)
    (default-to false (map-get? admins user))
  )
)

(define-private (assert-admin)
  (if (is-admin tx-sender)
      (ok true)
      ERR-NOT-AUTHORIZED
  )
)

;; ===============================
;; READ
;; ===============================

(define-read-only (get-user (user principal))
  (map-get? user-reputation user)
)

;; ===============================
;; PUBLIC
;; ===============================

(define-public (add-admin (new-admin principal))
  (begin
    (try! (assert-admin))
    (map-set admins new-admin true)
    (ok true)
  )
)

(define-public (init-user (user principal))
  (begin
    (map-set user-reputation user {
      score: u0,
      multiplier: u1
    })
    (ok true)
  )
)

(define-public (increase-score (user principal) (amount uint))
  (begin
    (try! (assert-admin))

    (if (is-eq amount u0)
        ERR-INVALID-AMOUNT
        (match (map-get? user-reputation user)
          user-data
            (let (
                  (new-score (+ (get score user-data) amount))
                  (new-multiplier (+ u1 (/ new-score u100)))
                 )
              (map-set user-reputation user {
                score: new-score,
                multiplier: new-multiplier
              })
              (ok true)
            )
          ERR-USER-NOT-FOUND
        )
    )
  )
)

(define-public (decay (user principal))
  (match (map-get? user-reputation user)
    user-data
      (let (
            (score (get score user-data))
            (decayed (/ score u20))
           )
        (map-set user-reputation user {
          score: (- score decayed),
          multiplier: (get multiplier user-data)
        })
        (ok true)
      )
    ERR-USER-NOT-FOUND
  )
)

Functions (7)

FunctionAccessArgs
is-adminprivateuser: principal
assert-adminprivate
get-userread-onlyuser: principal
add-adminpublicnew-admin: principal
init-userpublicuser: principal
increase-scorepublicuser: principal, amount: uint
decaypublicuser: principal