Source Code

;; Referral System Contract
;; Track and reward referrals

(define-constant err-self-referral (err u100))
(define-constant err-already-referred (err u101))

(define-data-var referral-reward uint u1000000)

(define-map referrals
    principal
    {
        referrer: (optional principal),
        referral-count: uint,
        total-earned: uint,
        registration-block: uint
    }
)

(define-map referral-codes (string-ascii 20) principal)

(define-public (register-with-referral (referrer-code (optional (string-ascii 20))))
    (begin
        (asserts! (is-none (map-get? referrals tx-sender)) err-already-referred)

        (match referrer-code
            code
            (match (map-get? referral-codes code)
                referrer
                (begin
                    (asserts! (not (is-eq tx-sender referrer)) err-self-referral)
                    (map-set referrals tx-sender {
                        referrer: (some referrer),
                        referral-count: u0,
                        total-earned: u0,
                        registration-block: block-height
                    })
                    (try! (reward-referrer referrer))
                    (ok (some referrer))
                )
                (ok none)
            )
            (begin
                (map-set referrals tx-sender {
                    referrer: none,
                    referral-count: u0,
                    total-earned: u0,
                    registration-block: block-height
                })
                (ok none)
            )
        )
    )
)

(define-public (create-referral-code (code (string-ascii 20)))
    (begin
        (asserts! (is-none (map-get? referral-codes code)) err-already-referred)
        (map-set referral-codes code tx-sender)
        (ok true)
    )
)

(define-private (reward-referrer (referrer principal))
    (let (
        (referrer-data (unwrap-panic (map-get? referrals referrer)))
    )
        (try! (as-contract
            (stx-transfer? (var-get referral-reward) tx-sender referrer)))

        (map-set referrals referrer {
            referrer: (get referrer referrer-data),
            referral-count: (+ (get referral-count referrer-data) u1),
            total-earned: (+ (get total-earned referrer-data) (var-get referral-reward)),
            registration-block: (get registration-block referrer-data)
        })

        (ok true)
    )
)

(define-read-only (get-referral-stats (user principal))
    (map-get? referrals user)
)

(define-read-only (resolve-code (code (string-ascii 20)))
    (map-get? referral-codes code)
)

(define-read-only (get-referrer (user principal))
    (match (map-get? referrals user)
        data (get referrer data)
        none
    )
)

Functions (6)

FunctionAccessArgs
register-with-referralpublicreferrer-code: (optional (string-ascii 20
create-referral-codepubliccode: (string-ascii 20
reward-referrerprivatereferrer: principal
get-referral-statsread-onlyuser: principal
resolve-coderead-onlycode: (string-ascii 20
get-referrerread-onlyuser: principal