Source Code

;;contract to produce, send, spend spoints 
;;depends on the collection SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club

;;consts
(define-constant ERR-NOT-AUTHORIZED u404)
(define-constant ERR-MAX-SUPPLY-REACHED u405)
(define-constant ERR-ITEM-LIMIT-REACHED u406)
(define-constant ERR-INSUFFICIENT-BALANCE u407)
(define-constant ERR-ITEM-DOES-NOT-EXIST u408)
(define-constant V-TOKEN-MAX-SUPPLY u21000000000000)
(define-constant ITEM-LIMIT u4200000000)
;;data vars
(define-data-var admin principal tx-sender)
(define-data-var supply uint u0)
(define-data-var spent uint u0)
(define-data-var approved-principals (list 1000 principal) (list 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH tx-sender))
(define-data-var shutoff-valve bool false)
(define-data-var removing-address-from-list principal tx-sender)
;;data maps
(define-map balances {item: uint} {balance: uint} )
(define-map lifetime { address: principal } { earnings: uint })

;;collect spoints from subscriber contracts on a spaghettipunk-club nft
(define-public (collect (item uint) (amount uint))
    (let (
        (spoints-supply (unwrap-panic (get-supply)))
        (spoints-spent (unwrap-panic (get-spent)))
        (item-balance (get-balance item))
        (earnings (get-lifetime tx-sender))
    )
        (asserts! (<= (+ (+ spoints-spent spoints-supply) amount) V-TOKEN-MAX-SUPPLY) (err ERR-MAX-SUPPLY-REACHED))
        (asserts! (<= (+ item-balance amount) ITEM-LIMIT) (err ERR-ITEM-LIMIT-REACHED))
        (asserts! (is-eq (unwrap-panic (unwrap-panic (contract-call? 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club get-owner item))) tx-sender) (err ERR-NOT-AUTHORIZED))
        (asserts! (is-some (index-of (var-get approved-principals) contract-caller)) (err ERR-NOT-AUTHORIZED))
        (asserts! (is-eq (var-get shutoff-valve) false) (err ERR-NOT-AUTHORIZED))
        (begin
            (var-set supply (+ spoints-supply amount))
            (map-set balances {item: item} {balance: (+ amount item-balance)})
            (map-set lifetime {address: tx-sender} {earnings: (+ earnings amount)})
            (ok (print { action: "collect spoints", amount: amount})))))
;;send spoints from a spaghettipunk-club nft to another
(define-public (send (item-sender uint) (item-receiver uint) (amount uint)) 
    (let (
        (item-balance-sender (get-balance item-sender))
        (item-balance-receiver (get-balance item-receiver))
        (owner-receiver (unwrap-panic (contract-call? 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club get-owner item-receiver)))
    ) 
        (asserts! (<= (+ item-balance-receiver amount) ITEM-LIMIT) (err ERR-ITEM-LIMIT-REACHED))
        (asserts! (<= amount item-balance-sender) (err ERR-INSUFFICIENT-BALANCE))
        (asserts! (is-eq (unwrap-panic (unwrap-panic (contract-call? 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club get-owner item-sender))) tx-sender) (err ERR-NOT-AUTHORIZED))
        (asserts! (not (is-none (unwrap-panic (contract-call? 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club get-owner item-receiver)))) (err ERR-ITEM-DOES-NOT-EXIST))
        (map-set balances {item: item-sender} {balance: (- item-balance-sender amount)})
        (map-set balances {item: item-receiver} {balance: (+ item-balance-receiver amount)})
        (ok (print { action: "send spoints", amount: amount}))))
;;spend spoints from a spaghettipunk-club nft
(define-public (spend (item uint) (amount uint)) 
    (let (
        (item-balance (get-balance item))   
        (spoints-spent (unwrap-panic (get-spent))) 
        (spoints-supply (unwrap-panic (get-supply)))
        ) 
        (asserts! (<= amount item-balance) (err ERR-INSUFFICIENT-BALANCE))
        (asserts! (<= amount spoints-supply) (err ERR-INSUFFICIENT-BALANCE))
        (asserts! (is-eq (unwrap-panic (unwrap-panic (contract-call? 'SP1C2K603TGWJGKPT2Z3WWHA0ARM66D352385TTWH.spaghettipunk-club get-owner item))) tx-sender) (err ERR-NOT-AUTHORIZED))
        (var-set supply (- spoints-supply amount))
        (var-set spent (+ spoints-spent amount))
        (map-set balances {item: item} {balance: (- item-balance amount)})
        (ok (print { action: "spend spoints", amount: amount}))))
;;enables an address to collect spoints
(define-public (principal-approve (address principal))
    (begin  
        (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
        (ok (var-set approved-principals (unwrap-panic (as-max-len? (append (var-get approved-principals) address) u1000))))
    ))
;;disable an address to collect spoints
(define-public (principal-remove (address principal)) 
    (begin  
        (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
        (var-set removing-address-from-list address)    
        (ok (var-set approved-principals (filter remove-address-from-list (var-get approved-principals))))
    ))
;;stop collecting spoints
(define-public (shutoff (switch bool))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) (err ERR-NOT-AUTHORIZED))
    (ok (var-set shutoff-valve switch))))
;;checks addresses authorized for the issuance of spoints
(define-read-only (get-approved-principals)
    (ok (var-get approved-principals)))
;;controls the number of spoints generated by an address since ever
(define-read-only (get-lifetime (address principal))
    (default-to u0 (get earnings (map-get? lifetime {address: address}))))
;;controls the number of spoints related to a given spaghettipunk-club nft
(define-read-only (get-balance (item uint))
    (default-to u0 (get balance (map-get? balances {item: item}))))
;;checks the total number of circulating spoints 
(define-read-only (get-supply)
    (ok (var-get supply)))
;;checks the total number of spoints spent
(define-read-only (get-spent)
    (ok (var-get spent)))
;;controls the total number of issued spoints i.e. the number of spoints spent + the number of circulating spoints
(define-read-only (get-total-supply)
    (ok (+ (var-get supply) (var-get spent))))

(define-private (remove-address-from-list (address principal))
  (if (is-eq address (var-get removing-address-from-list))
    false
    true
  ))

Functions (13)

FunctionAccessArgs
collectpublicitem: uint, amount: uint
sendpublicitem-sender: uint, item-receiver: uint, amount: uint
spendpublicitem: uint, amount: uint
principal-approvepublicaddress: principal
principal-removepublicaddress: principal
shutoffpublicswitch: bool
get-approved-principalsread-only
get-lifetimeread-onlyaddress: principal
get-balanceread-onlyitem: uint
get-supplyread-only
get-spentread-only
get-total-supplyread-only
remove-address-from-listprivateaddress: principal