Source Code

(define-non-fungible-token future-rewards-nft uint)

(define-constant ERR-NOT-AUTHORIZED (err u401))
(define-constant ERR-NOT-FOUND (err u404))

(define-data-var token-id-nonce uint u0)

(define-map token-reward-allocation
    uint
    {
        total-allocation: uint,
        claimed-amount: uint,
        beneficiary: principal
    }
)

(define-map historical-owners
    {token-id: uint, owner: principal}
    uint
)

(define-read-only (get-last-token-id)
    (ok (var-get token-id-nonce))
)

(define-read-only (get-owner (token-id uint))
    (ok (nft-get-owner? future-rewards-nft token-id))
)

(define-read-only (get-reward-allocation (token-id uint))
    (ok (map-get? token-reward-allocation token-id))
)

(define-read-only (get-claimable-amount (token-id uint))
    (match (map-get? token-reward-allocation token-id)
        allocation (ok (- (get total-allocation allocation) (get claimed-amount allocation)))
        ERR-NOT-FOUND
    )
)

(define-read-only (get-historical-ownership (token-id uint) (owner principal))
    (ok (default-to u0 (map-get? historical-owners {token-id: token-id, owner: owner})))
)

(define-public (mint (total-allocation uint) (beneficiary principal))
    (let
        (
            (new-id (+ (var-get token-id-nonce) u1))
        )
        (try! (nft-mint? future-rewards-nft new-id tx-sender))
        (map-set token-reward-allocation new-id {
            total-allocation: total-allocation,
            claimed-amount: u0,
            beneficiary: beneficiary
        })
        (map-set historical-owners {token-id: new-id, owner: tx-sender} stacks-block-time)
        (var-set token-id-nonce new-id)
        (ok new-id)
    )
)

(define-public (transfer (token-id uint) (sender principal) (recipient principal))
    (begin
        (asserts! (is-eq tx-sender sender) ERR-NOT-AUTHORIZED)
        (map-set historical-owners {token-id: token-id, owner: recipient} stacks-block-time)
        (nft-transfer? future-rewards-nft token-id sender recipient)
    )
)

(define-public (claim-rewards (token-id uint))
    (let
        (
            (allocation (unwrap! (map-get? token-reward-allocation token-id) ERR-NOT-FOUND))
            (claimable (- (get total-allocation allocation) (get claimed-amount allocation)))
        )
        (asserts! (is-eq tx-sender (get beneficiary allocation)) ERR-NOT-AUTHORIZED)
        (map-set token-reward-allocation token-id (merge allocation {
            claimed-amount: (get total-allocation allocation)
        }))
        (ok claimable)
    )
)

(define-public (set-beneficiary (token-id uint) (new-beneficiary principal))
    (let
        (
            (owner (unwrap! (nft-get-owner? future-rewards-nft token-id) ERR-NOT-FOUND))
            (allocation (unwrap! (map-get? token-reward-allocation token-id) ERR-NOT-FOUND))
        )
        (asserts! (is-eq tx-sender owner) ERR-NOT-AUTHORIZED)
        (ok (map-set token-reward-allocation token-id (merge allocation {beneficiary: new-beneficiary})))
    )
)

(define-read-only (get-contract-hash)
    (contract-hash? .future-rewards-nft)
)

Functions (10)

FunctionAccessArgs
get-last-token-idread-only
get-ownerread-onlytoken-id: uint
get-reward-allocationread-onlytoken-id: uint
get-claimable-amountread-onlytoken-id: uint
get-historical-ownershipread-onlytoken-id: uint, owner: principal
mintpublictotal-allocation: uint, beneficiary: principal
transferpublictoken-id: uint, sender: principal, recipient: principal
claim-rewardspublictoken-id: uint
set-beneficiarypublictoken-id: uint, new-beneficiary: principal
get-contract-hashread-only