Source Code

(use-trait reserve-trait .reserve-trait-v1.reserve-trait)

(define-constant ERR_SHUTDOWN u39001)
(define-constant ERR_WITHDRAW_NOT_NFT_OWNER u39002)
(define-constant ERR_WITHDRAW_NFT_DOES_NOT_EXIST u39003)
(define-constant ERR_GET_OWNER u39004)
(define-constant ERR_WITHDRAW_ALREADY_USED u39005)

(define-map withdrawals-by-nft uint bool)

(define-read-only (get-withdrawal-status (nft-id uint))
  (default-to false (map-get? withdrawals-by-nft nft-id))
)

(define-public (withdraw (reserve-contract <reserve-trait>) (nft-id uint))
  (let (
    (receiver tx-sender)
    
    (withdrawal-status (get-withdrawal-status nft-id))
    (withdrawal-entry (contract-call? .stacking-dao-core-v1 get-withdrawals-by-nft nft-id))  
    (nft-owner (unwrap! (contract-call? .ststx-withdraw-nft get-owner nft-id) (err ERR_GET_OWNER)))
    (stx-to-receive (get stx-amount withdrawal-entry))
  )
    (asserts! (not withdrawal-status) (err ERR_WITHDRAW_ALREADY_USED))
    (try! (contract-call? .dao check-is-enabled))
    (try! (contract-call? .dao check-is-protocol (contract-of reserve-contract)))
    (asserts! (is-some nft-owner) (err ERR_WITHDRAW_NFT_DOES_NOT_EXIST))
    (asserts! (is-eq (unwrap! nft-owner (err ERR_GET_OWNER)) tx-sender) (err ERR_WITHDRAW_NOT_NFT_OWNER))

    ;; STX to user, burn stSTX
    (try! (as-contract (contract-call? reserve-contract request-stx-for-withdrawal stx-to-receive receiver)))
    (try! (as-contract (contract-call? .ststx-token burn-for-protocol (get ststx-amount withdrawal-entry) (as-contract .stacking-dao-core-v1))))
    (try! (as-contract (contract-call? .ststx-withdraw-nft burn-for-protocol nft-id)))

    ;; Mark NFT as used for withdrawal
    (map-set withdrawals-by-nft nft-id true)

    (print { action: "withdraw", data: { stacker: tx-sender, amount: (get ststx-amount withdrawal-entry), block-height: block-height } })
    (ok stx-to-receive)
  )
)

Functions (2)

FunctionAccessArgs
get-withdrawal-statusread-onlynft-id: uint
withdrawpublicreserve-contract: <reserve-trait>, nft-id: uint