election-specific-prediction-market

SP1V95DB4JK47QVPJBXCEN6MT35JK84CQ4CWS15DQ

Source Code

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-market-closed (err u102))
(define-constant err-invalid-outcome (err u103))

(define-map markets
  uint
  {
    election-name: (string-ascii 128),
    outcomes: (list 10 (string-ascii 64)),
    end-block: uint,
    resolved: bool,
    winning-outcome: uint
  })

(define-map positions
  {market-id: uint, user: principal, outcome: uint}
  {shares: uint, avg-price: uint})

(define-map outcome-pools
  {market-id: uint, outcome: uint}
  {total-shares: uint, total-liquidity: uint})

(define-data-var next-market-id uint u0)

(define-read-only (get-market (market-id uint))
  (ok (map-get? markets market-id)))

(define-read-only (get-position (market-id uint) (user principal) (outcome uint))
  (ok (map-get? positions {market-id: market-id, user: user, outcome: outcome})))

(define-read-only (get-outcome-pool (market-id uint) (outcome uint))
  (ok (map-get? outcome-pools {market-id: market-id, outcome: outcome})))

(define-public (create-market (name (string-ascii 128)) (outcomes (list 10 (string-ascii 64))) (duration uint))
  (let ((market-id (var-get next-market-id)))
    (map-set markets market-id
      {election-name: name, outcomes: outcomes, end-block: (+ stacks-block-height duration),
       resolved: false, winning-outcome: u0})
    (var-set next-market-id (+ market-id u1))
    (ok market-id)))

(define-public (buy-shares (market-id uint) (outcome uint) (amount uint) (price uint))
  (let ((market (unwrap! (map-get? markets market-id) err-not-found)))
    (asserts! (< stacks-block-height (get end-block market)) err-market-closed)
    (asserts! (not (get resolved market)) err-market-closed)
    (try! (stx-transfer? (* amount price) tx-sender (as-contract tx-sender)))
    (map-set positions {market-id: market-id, user: tx-sender, outcome: outcome}
      {shares: amount, avg-price: price})
    (ok true)))

(define-public (resolve-market (market-id uint) (winning-outcome uint))
  (let ((market (unwrap! (map-get? markets market-id) err-not-found)))
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (asserts! (>= stacks-block-height (get end-block market)) err-market-closed)
    (ok (map-set markets market-id (merge market {resolved: true, winning-outcome: winning-outcome})))))

(define-public (claim-winnings (market-id uint) (outcome uint))
  (let ((market (unwrap! (map-get? markets market-id) err-not-found))
        (position (unwrap! (map-get? positions {market-id: market-id, user: tx-sender, outcome: outcome}) err-not-found)))
    (asserts! (get resolved market) err-market-closed)
    (asserts! (is-eq (get winning-outcome market) outcome) err-invalid-outcome)
    (try! (as-contract (stx-transfer? (* (get shares position) (get avg-price position)) tx-sender tx-sender)))
    (ok true)))

Functions (7)

FunctionAccessArgs
get-marketread-onlymarket-id: uint
get-positionread-onlymarket-id: uint, user: principal, outcome: uint
get-outcome-poolread-onlymarket-id: uint, outcome: uint
create-marketpublicname: (string-ascii 128
buy-sharespublicmarket-id: uint, outcome: uint, amount: uint, price: uint
resolve-marketpublicmarket-id: uint, winning-outcome: uint
claim-winningspublicmarket-id: uint, outcome: uint