Source Code

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

;; === 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-map total-rewards (string-ascii 30) { total: uint, recipient: principal })
(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-spoint-referral-bonus)
  (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 (<= stacks-block-height (get expiration entry))
        (get reward entry)
        u0)))

(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 (code (string-ascii 30)))
  (let ((entry (default-to { total: u0, recipient: tx-sender } (map-get? total-rewards code))))
    (get total entry)))

;; === Public Functions ===
(define-public (set-spoint-referral-bonus (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 (stx-get-balance (as-contract tx-sender))))
      (as-contract 
        (stx-transfer? balance (as-contract tx-sender) tx-sender)))))

(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 (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) tx-sender)) (err ERR-NOT-APPROVED))
    (let (
      (some-ref-addr (unwrap! (contract-call? .modern-amethyst-albatross 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)))
      (existing (map-get? total-rewards referral-code))
    )
      (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? .spoints collect (unwrap! spc_id (err ERR-MISSING-SPC-ID)) (* spoint-bonus qty)))
        true)
      (map-set total-rewards referral-code {
        total: (+ total-reward (if (is-some existing) (get total (unwrap! existing (err ERR-NO-EXISTING-RECORD))) u0)),
        recipient: some-ref-addr
      })
      (print { action: "handout-referral-reward", code: referral-code, address: some-ref-addr, reward: total-reward })
      (ok true))))

Functions (17)

FunctionAccessArgs
remove-contract-from-listprivateaddress: principal
get-spoint-referral-bonusread-only
get-referral-rewardread-onlycol: principal
get-referral-reward-bonusread-onlycol: principal
get-contract-inforead-only
is-approved-contractread-onlyaddr: principal
get-approved-contractsread-only
get-total-rewardread-onlycode: (string-ascii 30
set-spoint-referral-bonuspublicbonus: uint
depositpublicamount: uint
admin-withdrawpublic
set-referral-rewardpubliccol: principal, reward: uint
set-referral-bonuspubliccol: 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