white-labeled-stablecoin-issurance

SP1V95DB4JK47QVPJBXCEN6MT35JK84CQ4CWS15DQ

Source Code

(define-constant ERR_UNAUTHORIZED (err u100))
(define-constant ERR_NOT_FOUND (err u101))
(define-constant ERR_ALREADY_EXISTS (err u102))
(define-constant ERR_INVALID_PARAMS (err u103))
(define-constant ERR_INSUFFICIENT_BALANCE (err u104))

(define-data-var contract-owner principal tx-sender)

(define-map stablecoin-issuers principal {issuer-name: (string-ascii 100), licensed: bool, total-issued: uint, collateral-ratio: uint, active: bool})
(define-map token-balances {issuer: principal, holder: principal} uint)
(define-map reserve-assets {issuer: principal, asset-type: (string-ascii 30)} {amount: uint, last-updated: uint})
(define-map compliance-records {issuer: principal, period: uint} {audited: bool, compliant: bool, audit-hash: (buff 32)})

(define-read-only (get-owner) (var-get contract-owner))

(define-read-only (get-issuer (issuer-id principal))
  (map-get? stablecoin-issuers issuer-id))

(define-read-only (get-balance (issuer principal) (holder principal))
  (default-to u0 (map-get? token-balances {issuer: issuer, holder: holder})))

(define-read-only (get-reserve (issuer principal) (asset-type (string-ascii 30)))
  (map-get? reserve-assets {issuer: issuer, asset-type: asset-type}))

(define-read-only (get-compliance (issuer principal) (period uint))
  (map-get? compliance-records {issuer: issuer, period: period}))

(define-public (register-issuer (issuer-name (string-ascii 100)) (collateral-ratio uint))
  (begin
    (asserts! (is-none (map-get? stablecoin-issuers tx-sender)) ERR_ALREADY_EXISTS)
    (asserts! (>= collateral-ratio u100) ERR_INVALID_PARAMS)
    (ok (map-set stablecoin-issuers tx-sender {issuer-name: issuer-name, licensed: false, total-issued: u0, collateral-ratio: collateral-ratio, active: true}))))

(define-public (license-issuer (issuer principal))
  (let ((issuer-data (unwrap! (map-get? stablecoin-issuers issuer) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set stablecoin-issuers issuer (merge issuer-data {licensed: true})))))

(define-public (mint-stablecoin (amount uint) (recipient principal))
  (let ((issuer-data (unwrap! (map-get? stablecoin-issuers tx-sender) ERR_UNAUTHORIZED))
        (current-balance (get-balance tx-sender recipient)))
    (asserts! (get licensed issuer-data) ERR_UNAUTHORIZED)
    (asserts! (get active issuer-data) ERR_UNAUTHORIZED)
    (asserts! (> amount u0) ERR_INVALID_PARAMS)
    (map-set token-balances {issuer: tx-sender, holder: recipient} (+ current-balance amount))
    (ok (map-set stablecoin-issuers tx-sender (merge issuer-data {total-issued: (+ (get total-issued issuer-data) amount)})))))

(define-public (burn-stablecoin (issuer principal) (amount uint))
  (let ((issuer-data (unwrap! (map-get? stablecoin-issuers issuer) ERR_NOT_FOUND))
        (current-balance (get-balance issuer tx-sender)))
    (asserts! (>= current-balance amount) ERR_INSUFFICIENT_BALANCE)
    (asserts! (> amount u0) ERR_INVALID_PARAMS)
    (map-set token-balances {issuer: issuer, holder: tx-sender} (- current-balance amount))
    (ok (map-set stablecoin-issuers issuer (merge issuer-data {total-issued: (- (get total-issued issuer-data) amount)})))))

(define-public (transfer-stablecoin (issuer principal) (amount uint) (recipient principal))
  (let ((sender-balance (get-balance issuer tx-sender))
        (recipient-balance (get-balance issuer recipient)))
    (asserts! (>= sender-balance amount) ERR_INSUFFICIENT_BALANCE)
    (asserts! (> amount u0) ERR_INVALID_PARAMS)
    (map-set token-balances {issuer: issuer, holder: tx-sender} (- sender-balance amount))
    (ok (map-set token-balances {issuer: issuer, holder: recipient} (+ recipient-balance amount)))))

(define-public (deposit-reserve (asset-type (string-ascii 30)) (amount uint))
  (let ((reserve (default-to {amount: u0, last-updated: u0} (map-get? reserve-assets {issuer: tx-sender, asset-type: asset-type}))))
    (asserts! (is-some (map-get? stablecoin-issuers tx-sender)) ERR_UNAUTHORIZED)
    (asserts! (> amount u0) ERR_INVALID_PARAMS)
    (ok (map-set reserve-assets {issuer: tx-sender, asset-type: asset-type} {amount: (+ (get amount reserve) amount), last-updated: stacks-block-height}))))

(define-public (record-compliance (period uint) (audit-hash (buff 32)) (compliant bool))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set compliance-records {issuer: tx-sender, period: period} {audited: true, compliant: compliant, audit-hash: audit-hash}))))

(define-public (deactivate-issuer (issuer principal))
  (let ((issuer-data (unwrap! (map-get? stablecoin-issuers issuer) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set stablecoin-issuers issuer (merge issuer-data {active: false})))))

(define-public (transfer-ownership (new-owner principal))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (var-set contract-owner new-owner))))

Functions (14)

FunctionAccessArgs
get-ownerread-only
get-issuerread-onlyissuer-id: principal
get-balanceread-onlyissuer: principal, holder: principal
get-reserveread-onlyissuer: principal, asset-type: (string-ascii 30
get-complianceread-onlyissuer: principal, period: uint
register-issuerpublicissuer-name: (string-ascii 100
license-issuerpublicissuer: principal
mint-stablecoinpublicamount: uint, recipient: principal
burn-stablecoinpublicissuer: principal, amount: uint
transfer-stablecoinpublicissuer: principal, amount: uint, recipient: principal
deposit-reservepublicasset-type: (string-ascii 30
record-compliancepublicperiod: uint, audit-hash: (buff 32
deactivate-issuerpublicissuer: principal
transfer-ownershippublicnew-owner: principal