(impl-trait .trait-ownable.ownable-trait)
(define-constant err-not-authorised (err u1000))
(define-constant err-already-processed (err u1409))
(define-constant err-invalid-cycle (err u1410))
(define-constant ONE_8 (pow u10 u8))
(define-constant MAX_UINT u340282366920938463463374607431768211455)
(define-data-var contract-owner principal tx-sender)
(define-map approved-contracts principal bool)
(define-map processed-batches { cycle: uint, batch: uint } bool)
(define-map processed-users { cycle: uint, user: principal} bool)
(define-data-var reward-cycle-length uint u1050) ;; number of block-heights per cycle
(define-data-var activation-block uint MAX_UINT)
(define-read-only (get-reward-cycle-length)
(var-get reward-cycle-length)
)
(define-public (set-reward-cycle-length (new-reward-cycle-length uint))
(begin
(try! (check-is-owner))
(ok (var-set reward-cycle-length new-reward-cycle-length))
)
)
(define-read-only (get-activation-block)
(var-get activation-block)
)
(define-public (set-activation-block (new-activation-block uint))
(begin
(try! (check-is-owner))
(ok (var-set activation-block new-activation-block))
)
)
(define-read-only (get-reward-cycle (stacks-height uint))
(let
(
(first-staking-block (get-activation-block))
(rcLen (get-reward-cycle-length))
)
(if (>= stacks-height first-staking-block)
(some (/ (- stacks-height first-staking-block) rcLen))
none
)
)
)
(define-read-only (get-first-stacks-block-in-reward-cycle (reward-cycle uint))
(+ (get-activation-block) (* (get-reward-cycle-length) reward-cycle))
)
(define-read-only (get-contract-owner)
(ok (var-get contract-owner))
)
(define-public (set-contract-owner (owner principal))
(begin
(try! (check-is-owner))
(ok (var-set contract-owner owner))
)
)
(define-private (check-is-owner)
(ok (asserts! (is-eq tx-sender (var-get contract-owner)) err-not-authorised))
)
(define-private (check-is-approved)
(ok (asserts! (default-to false (map-get? approved-contracts tx-sender)) err-not-authorised))
)
(define-public (add-approved-contract (new-approved-contract principal))
(begin
(try! (check-is-owner))
(ok (map-set approved-contracts new-approved-contract true))
)
)
(define-public (set-approved-contract (owner principal) (approved bool))
(begin
(try! (check-is-owner))
(ok (map-set approved-contracts owner approved))
)
)
(define-read-only (is-cycle-batch-processed (cycle uint) (batch uint))
(default-to
false
(map-get? processed-batches { cycle: cycle, batch: batch })
)
)
(define-read-only (is-cycle-user-processed (cycle uint) (user principal))
(default-to
false
(map-get? processed-users { cycle: cycle, user: user })
)
)
(define-public (distribute-db20 (cycle uint) (batch uint) (recipients (list 200 {cycle: uint, recipient: principal, amount: uint})))
(begin
(asserts! (or (is-ok (check-is-owner)) (is-ok (check-is-approved))) err-not-authorised)
(asserts! (not (is-cycle-batch-processed cycle batch)) err-already-processed)
(asserts! (> (unwrap! (get-reward-cycle block-height) err-invalid-cycle) cycle) err-invalid-cycle)
(let
(
(transferred (try! (fold distribute-db20-iter recipients (ok u0))))
)
(map-set processed-batches { cycle: cycle, batch: batch } true)
(ok transferred)
)
)
)
(define-private (distribute-db20-iter (recipient {cycle: uint, recipient: principal, amount: uint}) (prior (response uint uint)))
(begin
(asserts! (not (is-cycle-user-processed (get cycle recipient) (get recipient recipient))) err-already-processed)
(asserts! (> (unwrap! (get-reward-cycle block-height) err-invalid-cycle) (get cycle recipient)) err-invalid-cycle)
(as-contract (try! (contract-call? .brc20-db20 transfer-fixed (get amount recipient) tx-sender (get recipient recipient) none)))
(ok (+ (try! prior) (get amount recipient)))
)
)