From 267f7ca555ffbbae6a184c0fe273e4a01b428828 Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:52:54 +0000 Subject: [PATCH 1/6] Updated with defined variables --- contracts/market-factory.clar | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index ffb0908..08cbc45 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -1,10 +1,15 @@ -;; PredictStack: Simple Base Implementation -;; Basic prediction market factory for Stacks blockchain +;; PredictStack Market Factory Contract +;; This contract is responsible for creating new prediction markets and tracking them ;; Constants (define-constant CONTRACT-OWNER tx-sender) (define-constant ERR-NOT-AUTHORIZED (err u100)) (define-constant ERR-INVALID-PARAMETERS (err u101)) +(define-constant ERR-MARKET-ALREADY-EXISTS (err u102)) +(define-constant ERR-INSUFFICIENT-FUNDS (err u103)) +(define-constant ERR-DEADLINE-PASSED (err u104)) +(define-constant ERR-INVALID-OUTCOMES (err u105)) +(define-constant ERR-MARKET-NOT-FOUND (err u106)) (define-constant MINIMUM-CREATION-FEE u1000000) ;; 1 STX in microSTX ;; Data maps @@ -13,16 +18,29 @@ { creator: principal, question: (string-utf8 256), + description: (string-utf8 1024), outcomes: (list 5 (string-utf8 64)), + outcome-count: uint, resolution-deadline: uint, creation-block: uint, - is-resolved: bool + contract-address: principal, + is-resolved: bool, + status: (string-ascii 20) } ) +;; Creator to markets mapping +(define-map creator-markets + { creator: principal } + { market-ids: (list 100 uint) } +) + ;; Variables (define-data-var last-market-id uint u0) +(define-data-var treasury-address principal CONTRACT-OWNER) (define-data-var creation-fee uint MINIMUM-CREATION-FEE) +(define-data-var is-paused bool false) + ;; Read-only functions From 6dcbf59d6171670b4219d0aac758228d2c8a023a Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:53:25 +0000 Subject: [PATCH 2/6] Added private functions --- contracts/market-factory.clar | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index 08cbc45..c8a73e6 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -41,6 +41,35 @@ (define-data-var creation-fee uint MINIMUM-CREATION-FEE) (define-data-var is-paused bool false) +;; Private functions +(define-private (is-owner) + (is-eq tx-sender CONTRACT-OWNER) +) + +(define-private (add-market-to-creator-list (creator principal) (market-id uint)) + (let + ( + (current-markets (default-to { market-ids: (list) } (map-get? creator-markets { creator: creator }))) + (current-market-list (get market-ids current-markets)) + (new-market-list (unwrap! (as-max-len? (append current-market-list market-id) u100) ERR-INVALID-PARAMETERS)) + ) + (map-set creator-markets { creator: creator } { market-ids: new-market-list }) + (ok true) + ) +) + +(define-private (validate-outcomes (outcomes (list 5 (string-utf8 64)))) + (let + ( + (outcome-count (len outcomes)) + ) + (and + (>= outcome-count u2) ;; Must have at least 2 outcomes + (<= outcome-count u5) ;; Cannot have more than 5 outcomes + ) + ) +) + ;; Read-only functions From 184ab773106014d667efe291541ccf78ea94b872 Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:54:26 +0000 Subject: [PATCH 3/6] Updated and added more read only functions --- contracts/market-factory.clar | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index c8a73e6..0a5d37e 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -70,13 +70,15 @@ ) ) - ;; Read-only functions - (define-read-only (get-market (market-id uint)) (map-get? markets { market-id: market-id }) ) +(define-read-only (get-markets-by-creator (creator principal)) + (map-get? creator-markets { creator: creator }) +) + (define-read-only (get-last-market-id) (var-get last-market-id) ) @@ -85,6 +87,11 @@ (var-get creation-fee) ) +(define-read-only (is-contract-paused) + (var-get is-paused) +) + + ;; Public functions (define-public (create-market From 618105a1ce7909132b82e5106a03662487163bc7 Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:55:29 +0000 Subject: [PATCH 4/6] Updated create market function --- contracts/market-factory.clar | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index 0a5d37e..2064d96 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -94,8 +94,10 @@ ;; Public functions +;; Public functions (define-public (create-market (question (string-utf8 256)) + (description (string-utf8 1024)) (outcomes (list 5 (string-utf8 64))) (resolution-deadline uint)) (let @@ -103,36 +105,48 @@ (new-market-id (+ (var-get last-market-id) u1)) (current-block block-height) (curr-fee (var-get creation-fee)) + (outcome-count (len outcomes)) ) + ;; Check if contract is paused + (asserts! (not (var-get is-paused)) ERR-NOT-AUTHORIZED) + ;; Validate parameters (asserts! (> (len question) u0) ERR-INVALID-PARAMETERS) - (asserts! (>= (len outcomes) u2) ERR-INVALID-PARAMETERS) - (asserts! (> resolution-deadline current-block) ERR-INVALID-PARAMETERS) - + (asserts! (validate-outcomes outcomes) ERR-INVALID-OUTCOMES) + (asserts! (> resolution-deadline current-block) ERR-DEADLINE-PASSED) + ;; Process creation fee - (try! (stx-transfer? curr-fee tx-sender CONTRACT-OWNER)) - + (try! (stx-transfer? curr-fee tx-sender (var-get treasury-address))) + ;; Create market entry (map-set markets { market-id: new-market-id } { creator: tx-sender, question: question, + description: description, outcomes: outcomes, + outcome-count: outcome-count, resolution-deadline: resolution-deadline, creation-block: current-block, - is-resolved: false + contract-address: tx-sender, ;; To be updated later with actual contract address + is-resolved: false, + status: "active" } ) - + + ;; Add market to creator's list + (try! (add-market-to-creator-list tx-sender new-market-id)) + ;; Update last market ID (var-set last-market-id new-market-id) - + ;; Return the new market ID (ok new-market-id) ) ) + ;; Admin functions (define-public (set-creation-fee (new-fee uint)) From 8e1049a59fe2113fdc19925470ee4a2c0cf3f48f Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:56:04 +0000 Subject: [PATCH 5/6] Added more public functions --- contracts/market-factory.clar | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index 2064d96..a0d17a3 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -146,6 +146,63 @@ ) ) +;; Update market contract address +(define-public (update-market-contract-address (market-id uint) (market-contract principal)) + (let + ( + (market (unwrap! (map-get? markets { market-id: market-id }) ERR-MARKET-NOT-FOUND)) + ) + ;; Only allow creator to update contract address + (asserts! (is-eq (get creator market) tx-sender) ERR-NOT-AUTHORIZED) + + ;; Update contract address + (map-set markets + { market-id: market-id } + (merge market { contract-address: market-contract }) + ) + + (ok true) + ) +) + +;; Update market status +(define-public (update-market-status (market-id uint) (new-status (string-ascii 20))) + (let + ( + (market (unwrap! (map-get? markets { market-id: market-id }) ERR-MARKET-NOT-FOUND)) + ) + ;; Only allow owner or creator to update status + (asserts! (or (is-eq (get creator market) tx-sender) (is-owner)) ERR-NOT-AUTHORIZED) + + ;; Update market status + (map-set markets + { market-id: market-id } + (merge market { status: new-status }) + ) + + (ok true) + ) +) + +;; Mark market as resolved +(define-public (mark-market-resolved (market-id uint)) + (let + ( + (market (unwrap! (map-get? markets { market-id: market-id }) ERR-MARKET-NOT-FOUND)) + ) + ;; Verify the caller is authorized (should be the market contract itself) + (asserts! (is-eq (get contract-address market) tx-sender) ERR-NOT-AUTHORIZED) + + ;; Update resolution status + (map-set markets + { market-id: market-id } + (merge market { is-resolved: true, status: "resolved" }) + ) + + (ok true) + ) +) + ;; Admin functions From c8cb999d9bbeae2c26d1f7b57a9abb35ee17ba82 Mon Sep 17 00:00:00 2001 From: Adenike Akande <38114140-1adenikeakande@users.noreply.replit.com> Date: Fri, 28 Feb 2025 22:56:35 +0000 Subject: [PATCH 6/6] Admin functions updated --- contracts/market-factory.clar | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/contracts/market-factory.clar b/contracts/market-factory.clar index a0d17a3..2d19723 100644 --- a/contracts/market-factory.clar +++ b/contracts/market-factory.clar @@ -203,13 +203,27 @@ ) ) - ;; Admin functions +(define-public (set-treasury-address (new-address principal)) + (begin + (asserts! (is-owner) ERR-NOT-AUTHORIZED) + (var-set treasury-address new-address) + (ok true) + ) +) (define-public (set-creation-fee (new-fee uint)) (begin - (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + (asserts! (is-owner) ERR-NOT-AUTHORIZED) (var-set creation-fee new-fee) (ok true) ) ) + +(define-public (pause-contract (paused bool)) + (begin + (asserts! (is-owner) ERR-NOT-AUTHORIZED) + (var-set is-paused paused) + (ok true) + ) +)