Source Code

(impl-trait .extension-trait.extension-trait)
(impl-trait .proposal-trait.proposal-trait)
(use-trait ft-trait .trait-sip-010.sip-010-trait)
(define-constant ERR-NOT-AUTHORIZED (err u1000))
(define-constant ERR-SCHEDULE-NOT-FOUND (err u1001))
(define-constant ERR-PAUSED (err u1002))
(define-constant ERR-UPDATE-CHECKPOINT-FAILED (err u1003))
(define-constant ERR-TOKEN-MISMATCH (err u1004))
(define-constant ERR-VESTING-NOT-STARTED (err u1005))
(define-constant ERR-INVALID-VESTING-DETAILS (err u1006))
(define-constant ERR-UPDATE-VESTING-FAILED (err u1007))
(define-constant ERR-UPDATE-PRINCIPAL-MAP-FAILED (err u1008))
(define-constant ERR-UPDATE-NFT-MAP-FAILED (err u1009))
(define-constant ERR-ALREADY-MINTED (err u1010))
(define-constant ERR-TREASURY-GRANT-NOT-PAUSED (err u1011))
(define-constant ERR-OWNER-NOT-FOUND (err u1012))
(define-constant ONE_8 u100000000)
(define-constant MAX_UINT u340282366920938463463374607431768211455)
(define-map nft-principal uint principal)
(define-map principal-nft principal uint)
(define-map vestings uint { stx: uint, alex: uint })
(define-map checkpoints uint uint)
(define-data-var paused bool true)
(define-read-only (is-dao-or-extension)
  (ok (asserts! (or (is-eq tx-sender .executor-dao) (contract-call? .executor-dao is-extension contract-caller)) ERR-NOT-AUTHORIZED)))
(define-read-only (get-start-height)
	(contract-call? .treasury-grant get-start-height))
(define-read-only (get-end-height)
	(contract-call? .treasury-grant get-end-height))
(define-read-only (is-paused)
  (var-get paused))
 (define-read-only (get-nft-principal (token-id uint))
    (map-get? nft-principal token-id))
 (define-read-only (get-principal-nft (principal principal))
    (map-get? principal-nft principal))
(define-read-only (get-vesting-or-fail (token-id uint))
    (ok (unwrap! (map-get? vestings token-id) ERR-SCHEDULE-NOT-FOUND)))
(define-read-only (get-checkpoint-or-fail (token-id uint))
    (let (
            (vesting-details (try! (get-vesting-or-fail token-id))))
        (match (map-get? checkpoints token-id)
            some-value (ok some-value)
            (ok (get-start-height)))))
(define-read-only (get-stats (token-id uint))
    (let (
            (vesting-details (try! (get-vesting-or-fail token-id)))
						(vesting-per-block (/ (get alex vesting-details) (- (get-end-height) (get-start-height))))
            (checkpoint (try! (get-checkpoint-or-fail token-id)))
            (new-checkpoint (max (get-start-height) (min (get-end-height) burn-block-height)))
            (vested-amount (* (- new-checkpoint checkpoint) vesting-per-block))
            (claimed-amount (* (- checkpoint (get-start-height)) vesting-per-block)))
        (ok {
					available: vested-amount, claimed: claimed-amount, remaining: (- (get alex vesting-details) vested-amount claimed-amount),
          checkpoint: checkpoint, new-checkpoint: new-checkpoint })))
(define-read-only (get-owner (token-id uint))
    (contract-call? .token-recovery-nft get-owner token-id))
(define-public (pause (new-paused bool))
  (begin
    (try! (is-dao-or-extension))
    (ok (var-set paused new-paused))))
(define-public (callback (sender principal) (payload (buff 2048)))
	(ok true))
(define-public (execute (sender principal))
	(begin
		(try! (contract-call? .executor-dao set-extensions (list { extension: .treasury-grant-v2, enabled: true } )))
		(try! (contract-call? .treasury-grant pause true))		
		(try! (pause false))
		(ok true)))
(define-public (mint-certificate (user principal))
	(let (
			(alread-minted (asserts! (is-none (map-get? principal-nft user)) ERR-ALREADY-MINTED))
			(token-id (try! (contract-call? .token-recovery-nft mint user)))
			(vesting-details (try! (contract-call? .treasury-grant get-vesting-or-fail user)))
			(checkpoint-details (try! (contract-call? .treasury-grant get-checkpoint-or-fail user))))
			(asserts! (contract-call? .treasury-grant is-paused) ERR-TREASURY-GRANT-NOT-PAUSED)
			(asserts! (map-insert principal-nft user token-id) ERR-UPDATE-PRINCIPAL-MAP-FAILED)
			(asserts! (map-insert nft-principal token-id user) ERR-UPDATE-NFT-MAP-FAILED)
			(asserts! (map-insert vestings token-id vesting-details) ERR-UPDATE-VESTING-FAILED)
			(asserts! (map-insert checkpoints token-id checkpoint-details) ERR-UPDATE-CHECKPOINT-FAILED)
			(ok token-id)))
(define-public (claim-stx (token-id uint))
	(let (				
				(vesting-details (try! (get-vesting-or-fail token-id)))
				(updated-details (merge vesting-details { stx: u0 }))
				(owner (unwrap! (unwrap-panic (get-owner token-id)) ERR-OWNER-NOT-FOUND))
				(sender tx-sender))
      (asserts! (not (is-paused)) ERR-PAUSED)
			(asserts! (is-eq sender owner) ERR-NOT-AUTHORIZED)
      (asserts! (> burn-block-height (get-start-height)) ERR-VESTING-NOT-STARTED)				
			(asserts! (map-set vestings token-id updated-details) ERR-UPDATE-VESTING-FAILED)
			(and (> (get stx vesting-details) u0) (as-contract (try! (contract-call? .treasury-grant transfer-fixed .token-wstx-v2 (get stx vesting-details) sender))))
			(print { notification: "claim-stx", payload: { token-id: token-id, owner: sender, claimed: (get stx vesting-details), updated-details: updated-details }})
			(ok true)))
(define-public (claim-alex (token-id uint))
    (let (
            (stats (try! (get-stats token-id)))
						(owner (unwrap! (unwrap-panic (get-owner token-id)) ERR-OWNER-NOT-FOUND))
						(sender tx-sender))
        (asserts! (not (is-paused)) ERR-PAUSED)
				(asserts! (is-eq sender owner) ERR-NOT-AUTHORIZED)
        (asserts! (> burn-block-height (get-start-height)) ERR-VESTING-NOT-STARTED)
        (asserts! (map-set checkpoints token-id (get new-checkpoint stats)) ERR-UPDATE-CHECKPOINT-FAILED)
				(and (> (get available stats) u0) (as-contract (try! (contract-call? .treasury-grant transfer-fixed .token-alex (get available stats) sender))))
        (print { notification: "claim-alex", payload: { token-id: token-id, owner: sender, claimed: (get available stats) }, claimed-so-far: (+ (get available stats) (get claimed stats)), remaining: (get remaining stats) })
        (ok true)))
(define-public (claim (token-id uint))
	(begin 
		(try! (claim-stx token-id))
		(claim-alex token-id)))
(define-public (claim-many (token-ids (list 1000 uint)))
  (ok (map claim token-ids)))
(define-private (mul-down (a uint) (b uint))
    (/ (* a b) ONE_8))
(define-private (div-down (a uint) (b uint))
  (if (is-eq a u0) u0 (/ (* a ONE_8) b)))
(define-private (min (a uint) (b uint))
    (if (<= a b) a b))
(define-private (max (a uint) (b uint))
    (if (>= a b) a b))

Functions (22)

FunctionAccessArgs
is-dao-or-extensionread-only
get-start-heightread-only
get-end-heightread-only
is-pausedread-only
get-nft-principalread-onlytoken-id: uint
get-principal-nftread-onlyprincipal: principal
get-vesting-or-failread-onlytoken-id: uint
get-checkpoint-or-failread-onlytoken-id: uint
get-statsread-onlytoken-id: uint
get-ownerread-onlytoken-id: uint
pausepublicnew-paused: bool
callbackpublicsender: principal, payload: (buff 2048
executepublicsender: principal
mint-certificatepublicuser: principal
claim-stxpublictoken-id: uint
claim-alexpublictoken-id: uint
claimpublictoken-id: uint
claim-manypublictoken-ids: (list 1000 uint
mul-downprivatea: uint, b: uint
div-downprivatea: uint, b: uint
minprivatea: uint, b: uint
maxprivatea: uint, b: uint