Source Code

;; Corgi Soldiers are 3x more effective in battle

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

(define-constant corgi-soliders u3)
(define-constant contract (as-contract tx-sender))
(define-constant deployer tx-sender)

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

;; Storage
(define-map bids {bidder: principal, epoch: uint} {price: uint})
(define-map highest-bidder uint principal)
(define-map highest-bid uint uint)
(define-map bid-count uint uint)
(define-map prize-claimed uint bool)

;; --- 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))
)

;; Create a new bid
(define-public (bid (new-price uint))
    (let
    (
        ;; if bidder has already bid, add the new bid to the existing one
        (existing-bid (default-to u0 (get price (map-get? bids {bidder: tx-sender, epoch: (get-current-epoch)}))))
        (updated-bid (+ new-price existing-bid))
    )

    (map-set highest-bidder (get-current-epoch)
        (if
        (> updated-bid (default-to u0 (map-get? highest-bid (get-current-epoch))))
        tx-sender
        (default-to deployer (map-get? highest-bidder (get-current-epoch)))
        )
    )

    (map-set highest-bid (get-current-epoch)
        (if
        (> updated-bid (default-to u0 (map-get? highest-bid (get-current-epoch))))
        updated-bid
        (default-to u0 (map-get? highest-bid (get-current-epoch)))
        )
    )

    (map-set bids {bidder: tx-sender, epoch: (get-current-epoch)} {price: updated-bid})
    (map-set bid-count (get-current-epoch) (+ (default-to u0 (map-get? bid-count (get-current-epoch))) u1))
    (print {
        notification: "updated-bid",
        payload: {
        bidder: tx-sender,
        price: updated-bid,
        bid-count: (map-get? bid-count (get-current-epoch)),
        }
    })
    (ok (map-get? bid-count (get-current-epoch)))
    )
)

;; Get highest bid
(define-read-only (get-highest-bid (epoch uint))
    (map-get? highest-bid epoch)
)

;; Get higest bidder
(define-read-only (get-highest-bidder (epoch uint))
    (map-get? highest-bidder epoch)
)

;; Get latest bid of
(define-read-only (get-latest-bid-of (bidder principal) (epoch uint))
    (default-to u0 (get price (map-get? bids {bidder: bidder, epoch: epoch})))
)

;; Get winner: if max-bid-count
(define-read-only (get-winner (epoch uint))
    (default-to deployer (map-get? highest-bidder epoch))
)

;; 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))
)

;; Increment the epoch if an epoch has passed
(define-private (try-reset-epoch)
    (if (epoch-passed)
        (let (
            (last-epoch (var-get current-epoch))
        )
            (var-set current-epoch (+ last-epoch u1))
            (var-set last-reset-block block-height)
            (print {
                notification: "epoch-reset",
                payload: {
                    epoch: (var-get current-epoch),
                    last-epoch: last-epoch,
                    last-reset-block: (var-get last-reset-block),
                    block-height: block-height,
                    winner: (get-winner last-epoch),
                    highest-bid: (get-highest-bid last-epoch),
                }
            })
            true
        )
        false
    )
)

(define-public (battle (creature-id uint))
    (let
        (
            (tapped-out (unwrap-panic (contract-call? .creatures-kit tap creature-id)))
            (ENERGY (get ENERGY tapped-out))
            (bid-amount (* ENERGY (get-factor)))
            (TOKENS (if (is-eq creature-id corgi-soliders) (* bid-amount u3) bid-amount))
            (original-sender tx-sender)
            (is-reset (try-reset-epoch))
        )
        (if is-reset
            (try! (as-contract (contract-call? .fuji-apples transfer (var-get supply-per-epoch) contract (get-winner (- (get-current-epoch) u1)) none)))
            false
        )
        (bid TOKENS)
    )
)

(define-read-only (get-claimable-amount (creature-id uint))
    (var-get supply-per-epoch)
)

;; 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-per-epoch)
    (var-get supply-per-epoch)
)

(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))
    )
)

Functions (21)

FunctionAccessArgs
is-dao-or-extensionprivate
is-authorizedread-only
bidpublicnew-price: uint
get-highest-bidread-onlyepoch: uint
get-highest-bidderread-onlyepoch: uint
get-latest-bid-ofread-onlybidder: principal, epoch: uint
get-winnerread-onlyepoch: uint
epoch-passedprivate
try-reset-epochprivate
battlepubliccreature-id: uint
get-claimable-amountread-onlycreature-id: uint
get-factorread-only
get-blocks-per-epochread-only
get-per-epochread-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