Source Code

;; Blacksmiths produce 10x times more iron ingots than other creature types in the iron forge

(define-constant err-unauthorized (err u401))

(define-constant blacksmiths u2)
(define-constant contract tx-sender)

(define-data-var factor uint u1)
(define-data-var blocks-per-epoch uint u100)
(define-data-var supply-per-epoch uint u100000000)
(define-data-var iron-supply-remaining uint u100000000)
(define-data-var last-reset-block uint u0)
(define-data-var current-epoch uint u0)

;; --- Authorization check
(define-private (is-dao-or-extension)
    (or (is-eq tx-sender 'SP2D5BGGJ956A635JG7CJQ59FTRFRB0893514EZPJ.dungeon-master) (contract-call? 'SP2D5BGGJ956A635JG7CJQ59FTRFRB0893514EZPJ.dungeon-master is-extension contract-caller))
)

(define-read-only (is-authorized)
    (ok (asserts! (is-dao-or-extension) err-unauthorized))
)

;; Helper function to check if an epoch has passed
(define-private (epoch-passed)
    (> (- block-height (var-get last-reset-block)) (var-get blocks-per-epoch))
)

;; Reset the epoch supply if an epoch has passed
(define-private (try-reset-epoch-supply)
    (if (epoch-passed)
        (begin
            (var-set iron-supply-remaining (var-get supply-per-epoch))
            (var-set current-epoch (+ (var-get current-epoch) u1))
            (var-set last-reset-block block-height)
            true
        )
        false
    )
)

;; Only a limited amount of iron ingots can be created per epoch
(define-public (forge (creature-id uint))
    (let
        (
            (tapped-out (unwrap-panic (contract-call? .creatures-energy tap creature-id)))
            (ENERGY (get ENERGY tapped-out))
            (ingot-amount (* ENERGY (get-factor)))
            (CLAIM (if (is-eq creature-id blacksmiths) (* ingot-amount u10) ingot-amount))
            (original-sender tx-sender)
            (is-reset (try-reset-epoch-supply))
            (supply-remaining (get-iron-supply-remaining))
            (TOKENS (if (> CLAIM supply-remaining) supply-remaining CLAIM))
        )
        (var-set iron-supply-remaining (- supply-remaining TOKENS))
        (as-contract (contract-call? .iron-ingots transfer TOKENS tx-sender original-sender none))
    )
)

(define-read-only (get-claimable-amount (creature-id uint))
    (let
        (
            (untapped-energy (unwrap-panic (contract-call? .creatures-energy get-untapped-amount creature-id tx-sender)))
            (ingot-amount (* untapped-energy (get-factor)))
            (tokens-amount (if (is-eq creature-id blacksmiths) (* ingot-amount u10) ingot-amount))
            (supply-remaining (get-iron-supply-remaining))
        )
        (if (> tokens-amount supply-remaining) supply-remaining tokens-amount)
    )
)

;; Getters
(define-read-only (get-factor)
    (var-get factor)
)

(define-read-only (get-blocks-per-epoch)
    (var-get blocks-per-epoch)
)

(define-read-only (get-supply-per-epoch)
    (var-get supply-per-epoch)
)

(define-read-only (get-iron-supply-remaining)
    (var-get iron-supply-remaining)
)

(define-read-only (get-last-reset-block)
    (var-get last-reset-block)
)

(define-read-only (get-current-epoch)
    (var-get current-epoch)
)

;; Setters
(define-public (set-factor (new-factor uint))
    (begin
        (try! (is-authorized))
        (ok (var-set factor new-factor))
    )
)

(define-public (set-blocks-per-epoch (new-blocks-per-epoch uint))
    (begin
        (try! (is-authorized))
        (ok (var-set blocks-per-epoch new-blocks-per-epoch))
    )
)

(define-public (set-supply-per-epoch (new-supply-per-epoch uint))
    (begin
        (try! (is-authorized))
        (ok (var-set supply-per-epoch new-supply-per-epoch))
    )
)

;; Utility functions

(define-read-only (get-blocks-until-next-epoch)
    (let
        (
            (blocks-since-last-reset (- block-height (var-get last-reset-block)))
            (blocks-in-current-epoch (mod blocks-since-last-reset (var-get blocks-per-epoch)))
        )
        (- (var-get blocks-per-epoch) blocks-in-current-epoch)
    )
)

(define-read-only (get-epoch-progress)
    (let
        (
            (blocks-since-last-reset (- block-height (var-get last-reset-block)))
            (blocks-in-current-epoch (mod blocks-since-last-reset (var-get blocks-per-epoch)))
        )
        (/ (* blocks-in-current-epoch u100) (var-get blocks-per-epoch))
    )
)

(define-read-only (get-supply-utilization)
    (let
        (
            (supply-remaining (var-get iron-supply-remaining))
            (total-supply (var-get supply-per-epoch))
        )
        (- u100 (/ (* supply-remaining u100) total-supply))
    )
)

Functions (18)

FunctionAccessArgs
is-dao-or-extensionprivate
is-authorizedread-only
epoch-passedprivate
try-reset-epoch-supplyprivate
forgepubliccreature-id: uint
get-claimable-amountread-onlycreature-id: uint
get-factorread-only
get-blocks-per-epochread-only
get-supply-per-epochread-only
get-iron-supply-remainingread-only
get-last-reset-blockread-only
get-current-epochread-only
set-factorpublicnew-factor: uint
set-blocks-per-epochpublicnew-blocks-per-epoch: uint
set-supply-per-epochpublicnew-supply-per-epoch: uint
get-blocks-until-next-epochread-only
get-epoch-progressread-only
get-supply-utilizationread-only