(define-constant O tx-sender)
(define-constant E1 (err u900))
(define-constant E2 (err u901))
(define-constant E3 (err u902))
(define-data-var current-epoch uint u0)
(define-data-var epoch-reward uint u10000000)
(define-map epoch-data uint {total-shares: uint, reward: uint, finalized: bool})
(define-map user-shares {epoch: uint, user: principal} uint)
(define-map user-claimed {epoch: uint, user: principal} bool)
(define-public (set-epoch-reward (r uint))
(begin (asserts! (is-eq tx-sender O) E1) (ok (var-set epoch-reward r))))
(define-public (add-shares (epoch uint) (user principal) (shares uint))
(begin (asserts! (is-eq tx-sender O) E1)
(let ((cur (default-to u0 (map-get? user-shares {epoch: epoch, user: user})))
(ed (default-to {total-shares: u0, reward: (var-get epoch-reward), finalized: false}
(map-get? epoch-data epoch))))
(map-set user-shares {epoch: epoch, user: user} (+ cur shares))
(ok (map-set epoch-data epoch
(merge ed {total-shares: (+ (get total-shares ed) shares)}))))))
(define-public (finalize-epoch (epoch uint))
(begin (asserts! (is-eq tx-sender O) E1)
(let ((ed (unwrap! (map-get? epoch-data epoch) E2)))
(ok (map-set epoch-data epoch (merge ed {finalized: true}))))))
(define-read-only (get-epoch (epoch uint)) (map-get? epoch-data epoch))
(define-read-only (get-user-shares (epoch uint) (user principal))
(default-to u0 (map-get? user-shares {epoch: epoch, user: user})))
(define-read-only (get-current-epoch) (var-get current-epoch))