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-data-var contract-owner principal tx-sender)

(define-map cftc-reports uint {hash: (buff 32), fraud-type: (string-ascii 50), market: (string-ascii 30), potential-fine: uint, timestamp: uint, status: (string-ascii 20)})
(define-map tipsters principal {verified: bool, reports-filed: uint, rewards-earned: uint})
(define-map monetary-sanctions {report-id: uint, tipster: principal} {sanction-amount: uint, reward-percentage: uint, disbursed: bool})
(define-data-var cftc-report-count uint u0)

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

(define-read-only (get-cftc-report (report-id uint))
  (map-get? cftc-reports report-id))

(define-read-only (get-tipster (tipster-id principal))
  (map-get? tipsters tipster-id))

(define-read-only (get-monetary-sanction (report-id uint) (tipster principal))
  (map-get? monetary-sanctions {report-id: report-id, tipster: tipster}))

(define-public (file-cftc-report (content-hash (buff 32)) (fraud-type (string-ascii 50)) (market (string-ascii 30)) (potential-fine uint))
  (let ((report-id (+ (var-get cftc-report-count) u1))
        (tipster-data (default-to {verified: false, reports-filed: u0, rewards-earned: u0} (map-get? tipsters tx-sender))))
    (map-set cftc-reports report-id {hash: content-hash, fraud-type: fraud-type, market: market, potential-fine: potential-fine, timestamp: stacks-block-height, status: "filed"})
    (map-set tipsters tx-sender (merge tipster-data {reports-filed: (+ (get reports-filed tipster-data) u1)}))
    (var-set cftc-report-count report-id)
    (ok report-id)))

(define-public (verify-tipster (tipster principal))
  (let ((tipster-data (default-to {verified: false, reports-filed: u0, rewards-earned: u0} (map-get? tipsters tipster))))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set tipsters tipster (merge tipster-data {verified: true})))))

(define-public (update-report-status (report-id uint) (new-status (string-ascii 20)))
  (let ((report (unwrap! (map-get? cftc-reports report-id) ERR_NOT_FOUND)))
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (ok (map-set cftc-reports report-id (merge report {status: new-status})))))

(define-public (record-monetary-sanction (report-id uint) (tipster principal) (sanction-amount uint) (reward-percentage uint))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR_UNAUTHORIZED)
    (asserts! (is-some (map-get? cftc-reports report-id)) ERR_NOT_FOUND)
    (asserts! (and (> sanction-amount u0) (<= reward-percentage u30)) ERR_INVALID_PARAMS)
    (ok (map-set monetary-sanctions {report-id: report-id, tipster: tipster} {sanction-amount: sanction-amount, reward-percentage: reward-percentage, disbursed: false}))))

(define-public (disburse-reward (report-id uint))
  (let ((sanction (unwrap! (map-get? monetary-sanctions {report-id: report-id, tipster: tx-sender}) ERR_NOT_FOUND))
        (tipster-data (unwrap! (map-get? tipsters tx-sender) ERR_NOT_FOUND))
        (reward-amount (/ (* (get sanction-amount sanction) (get reward-percentage sanction)) u100)))
    (asserts! (not (get disbursed sanction)) ERR_ALREADY_EXISTS)
    (map-set monetary-sanctions {report-id: report-id, tipster: tx-sender} (merge sanction {disbursed: true}))
    (ok (map-set tipsters tx-sender (merge tipster-data {rewards-earned: (+ (get rewards-earned tipster-data) reward-amount)})))))

(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 (10)

FunctionAccessArgs
get-ownerread-only
get-cftc-reportread-onlyreport-id: uint
get-tipsterread-onlytipster-id: principal
get-monetary-sanctionread-onlyreport-id: uint, tipster: principal
file-cftc-reportpubliccontent-hash: (buff 32
verify-tipsterpublictipster: principal
update-report-statuspublicreport-id: uint, new-status: (string-ascii 20
record-monetary-sanctionpublicreport-id: uint, tipster: principal, sanction-amount: uint, reward-percentage: uint
disburse-rewardpublicreport-id: uint
transfer-ownershippublicnew-owner: principal