Source Code

;; === Error Constants ===
(define-constant ERR-NOT-AUTHORIZED u401)
(define-constant ERR-NOT-APPROVED u402)
(define-constant ERR-ALREADY-APPROVED u403)
(define-constant ERR-REFERRALS-PAUSED u404)
(define-constant ERR-NO-REWARD u405)
(define-constant ERR-MISSING-SPC-ID u406)
(define-constant ERR-REFERRAL-NOT-FOUND u407)
(define-constant ERR-SENDER-IS-REFERRAL u408)

;; === Admin and State Variables ===
(define-data-var admin principal tx-sender)
(define-data-var paused bool false)
(define-data-var approved-contracts (list 100 principal) (list ))
(define-data-var removing-contract principal tx-sender)

;; === Referral Rewards ===
(define-map referral-reward principal uint)
(define-map referral-bonus principal { reward: uint, expiration: uint })
(define-data-var spoint-referral-bonus uint u0)

;; === Helper Functions ===
(define-private (remove-contract-from-list (address principal))
  (not (is-eq address (var-get removing-contract))))

;; === Read-Only Functions ===
(define-read-only (get-admin)
  (var-get admin))

(define-read-only (get-spoint-referral-bonus-reward)
  (var-get spoint-referral-bonus))

(define-read-only (get-referral-reward (col principal))
  (default-to u0 (map-get? referral-reward col)))

(define-read-only (get-referral-reward-bonus (col principal))
  (let ((entry (default-to {expiration: u0, reward: u0} (map-get? referral-bonus col))))
    (if (<= tenure-height (get expiration entry))
        (get reward entry)
        u0)))

(define-read-only (get-tenure-height) tenure-height)

(define-read-only (get-contract-info)
  {
    contract-balance: (stx-get-balance (as-contract tx-sender)),
    admin: (var-get admin),
    paused: (var-get paused)
  })

(define-read-only (is-approved-contract (addr principal))
  (ok (is-some (index-of (var-get approved-contracts) addr))))

(define-read-only (get-approved-contracts)
  (ok (var-get approved-contracts)))

(define-read-only (get-total-reward (col principal))
  (+ (get-referral-reward col) (get-referral-reward-bonus col)))

;; === Public Functions ===
(define-public (set-spoint-referral-bonus-reward (bonus uint))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (var-set spoint-referral-bonus bonus)
    (ok true)))

(define-public (deposit (amount uint))
  (begin
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    (ok true)))

(define-public (admin-withdraw)
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (let ((balance (as-contract (stx-get-balance tx-sender))))
      (as-contract 
        (stx-transfer? balance tx-sender (var-get admin))))))

(define-public (set-referral-reward (col principal) (reward uint))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (map-set referral-reward col reward)
    (ok true)))

(define-public (set-referral-bonus-reward (col principal) (bonus uint) (expiration uint))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (map-set referral-bonus col { reward: bonus, expiration: expiration })
    (ok true)))

(define-public (approve-contract-address (addr principal))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (asserts! (is-none (index-of (var-get approved-contracts) addr)) (err ERR-ALREADY-APPROVED))
    (ok (var-set approved-contracts
      (unwrap-panic (as-max-len? (append (var-get approved-contracts) addr) u100))))))

(define-public (remove-approved-contract-address (addr principal))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (var-set removing-contract addr)
    (ok (var-set approved-contracts (filter remove-contract-from-list (var-get approved-contracts))))))

(define-public (set-referrals-paused (pause bool))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (var-set paused pause)
    (ok true)))

(define-public (handout-referral-reward 
  (referral-code (string-ascii 30)) 
  (col principal)
  (qty uint)
  (spc_id (optional uint))
)
  (begin
    (asserts! (not (var-get paused)) (err ERR-REFERRALS-PAUSED))
    (asserts! (is-some (index-of (var-get approved-contracts) contract-caller)) (err ERR-NOT-APPROVED))
    (let (
      (some-ref-addr (unwrap! (contract-call? .spaghettipunk-referral-codes get-referral-address referral-code) (err ERR-REFERRAL-NOT-FOUND)))
      (base (get-referral-reward col))
      (bonus (get-referral-reward-bonus col))
      (spoint-bonus (var-get spoint-referral-bonus))
      (total-reward (* qty (+ base bonus)))
    )
      (asserts! (not (is-eq some-ref-addr tx-sender)) (err ERR-SENDER-IS-REFERRAL))
      (asserts! (> total-reward u0) (err ERR-NO-REWARD))
      (try! (as-contract (stx-transfer? total-reward (as-contract tx-sender) some-ref-addr)))
      (if (and (> spoint-bonus u0) (is-some spc_id))
        (try! (contract-call? 'SP217FZ8AZYTGPKMERWZ6FYRAK4ZZ6YHMJ7XQXGEV.spoints collect (unwrap! spc_id (err ERR-MISSING-SPC-ID)) (* spoint-bonus qty)))
        true)
      (ok true))))

;; Change admin (only current admin can do this)
(define-public (change-admin (new-admin principal))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (var-set admin new-admin)
    (ok true)))

Functions (20)

FunctionAccessArgs
remove-contract-from-listprivateaddress: principal
get-adminread-only
get-spoint-referral-bonus-rewardread-only
get-referral-rewardread-onlycol: principal
get-referral-reward-bonusread-onlycol: principal
get-tenure-heightread-only
get-contract-inforead-only
is-approved-contractread-onlyaddr: principal
get-approved-contractsread-only
get-total-rewardread-onlycol: principal
set-spoint-referral-bonus-rewardpublicbonus: uint
depositpublicamount: uint
admin-withdrawpublic
set-referral-rewardpubliccol: principal, reward: uint
set-referral-bonus-rewardpubliccol: principal, bonus: uint, expiration: uint
approve-contract-addresspublicaddr: principal
remove-approved-contract-addresspublicaddr: principal
set-referrals-pausedpublicpause: bool
handout-referral-rewardpublicreferral-code: (string-ascii 30
change-adminpublicnew-admin: principal