Source Code

(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)

;; Define the contract owner
(define-constant contract-owner tx-sender)

;; Define the whitelist
(define-map whitelist principal bool)

;; Define the withdrawal queue with an additional field for token amount
(define-map withdrawal-queue uint {user: principal, share-amount: uint, token-amount: uint, withdrawal-completed: bool})

;; Define the current-withdrawal-request variable
(define-data-var current-withdrawal-request uint u0)


;; Define the total number of withdrawal requests
(define-data-var total-withdrawal-requests uint u0)


;; Define the global total treasury NAV and shares issued
(define-data-var global-total-treasury-nav uint u0)
(define-data-var global-total-shares-issued uint u0)

(define-constant err-owner-only (err u100))
(define-constant err-not-token-owner (err u101))

;; No maximum supply!
(define-fungible-token hust)

;; Define the admin-only function
(define-private (admin-only)
  (if (is-eq tx-sender contract-owner)
    (ok true)
    (err "Only admin can call this function")
  )
)

;; Define the deposit-for-user function

(define-public (deposit-for-user (user principal) (amount uint))
  (begin
    (asserts! (is-some (map-get? whitelist  user)) (err "Not whitelisted"))
    (asserts! (> amount u0) (err "Amount must be greater than zero"))
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (let ((shares (calculate-shares amount)))
       (if (is-ok (ft-mint? hust shares user))
        (begin
          (var-set global-total-shares-issued (+ (var-get global-total-shares-issued) shares))
          (var-set global-total-treasury-nav (+ (var-get global-total-treasury-nav) amount))
          (ok true)
        )
        (err "Failed to mint tokens")
      )
    )
  )
)

;; Define the request-withdrawal function
(define-public (request-withdrawal (share-amount uint))
  (begin
    (asserts! (> share-amount u0) (err "Share amount must be greater than zero"))
    (asserts! (>= (ft-get-balance hust tx-sender) share-amount) (err "Insufficient shares"))
    (unwrap-panic (ft-burn? hust share-amount tx-sender))
    (map-set withdrawal-queue (var-get total-withdrawal-requests) {user: tx-sender, share-amount: share-amount, token-amount: u0, withdrawal-completed: false})
    (var-set total-withdrawal-requests (+ (var-get total-withdrawal-requests) u1))
    (ok true)
  )
)

;; Define the process-withdrawal function
(define-public (process-withdrawal)
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (let ((current-withdrawal (var-get current-withdrawal-request)))
      (let ((current-request (unwrap! (map-get? withdrawal-queue current-withdrawal) (err "no withdrawal found"))))
        (asserts! (not ( get withdrawal-completed current-request )) (err "withdrawal allready completed"))
        (let ((token-amount (calculate-tokens (get share-amount current-request))))
          (map-set withdrawal-queue current-withdrawal {user: (get user current-request), share-amount: (get share-amount current-request), token-amount: token-amount, withdrawal-completed: true})
        )
      )
      (var-set current-withdrawal-request (+ current-withdrawal u1))
    )
    (ok true)
  )
)

;; Define the get-withdrawal function
(define-read-only (get-withdrawal (id uint))
  (match (map-get? withdrawal-queue id)
    entry (ok entry)
    (err "No withdrawal found with this ID")
  )
)

;; Define the calculate-shares function
(define-read-only (calculate-shares (amount uint))
  (if (or (is-eq (var-get global-total-shares-issued) u0) (is-eq (var-get global-total-treasury-nav) u0))
    amount
    (/ (* amount (var-get global-total-shares-issued)) (var-get global-total-treasury-nav))
  )
)

;; Define the calculate-tokens function
(define-read-only (calculate-tokens (share-amount uint))
  (if (is-eq (ft-get-supply hust) u0)
    u0
    (/ (* share-amount (var-get global-total-treasury-nav)) (ft-get-supply hust))
  )
)

;; Define the add-whitelist function
(define-public (add-whitelist (user principal))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (map-set whitelist  user true)
    (ok true)
  )
)

;; Define the remove-whitelist function
(define-public (remove-whitelist (user principal))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (map-delete whitelist user)
    (ok true)
  )
)

;; Define the is-whitelisted function
(define-read-only  (is-whitelisted (user principal))
  (ok (is-some (map-get? whitelist user)))
)

(define-read-only (get-global-total-treasury-nav)
  (ok (var-get global-total-treasury-nav))
)

(define-read-only (get-global-total-shares-issued)
  (ok (var-get global-total-shares-issued))
)

;; Define the set-global-total-treasury-nav function
(define-public (set-global-total-treasury-nav (new-value uint))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (var-set global-total-treasury-nav new-value)
    (ok true)
  )
)

;; Define the increment-global-total-treasury-nav function
(define-public (increment-global-total-treasury-nav (amount uint))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (var-set global-total-treasury-nav (+ (var-get global-total-treasury-nav) amount))
    (ok true)
  )
)

;; Define the set-global-total-shares-issued function
(define-public (set-global-total-shares-issued (amount uint))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (var-set global-total-shares-issued amount)
    (ok true)
  )
)

;; Define the increment-global-total-shares-issued function
(define-public (increment-global-total-shares-issued (amount uint))
  (begin
    (asserts! (is-ok (admin-only)) (err "Only admin can call this function"))
    (var-set global-total-shares-issued (+ (var-get global-total-shares-issued) amount))
    (ok true)
  )
)

;; sip-010 implementation
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
	(begin
		(asserts! (is-eq tx-sender sender) err-not-token-owner)
		(try! (ft-transfer? hust amount sender recipient))
		(match memo to-print (print to-print) 0x)
		(ok true)
	)
)

(define-read-only (get-name)
	(ok "USTB")
)

(define-read-only (get-symbol)
	(ok "USTB")
)

(define-read-only (get-decimals)
	(ok u0)
)

(define-read-only (get-balance (who principal))
	(ok (ft-get-balance hust who))
)

(define-read-only (get-total-supply)
	(ok (ft-get-supply hust))
)

(define-read-only (get-token-uri)
	(ok none)
)

(define-public (mint (amount uint) (recipient principal))
	(begin
		(asserts! (is-eq tx-sender contract-owner) err-owner-only)
		(ft-mint? hust amount recipient)
	)
)

Functions (24)

FunctionAccessArgs
admin-onlyprivate
deposit-for-userpublicuser: principal, amount: uint
request-withdrawalpublicshare-amount: uint
process-withdrawalpublic
get-withdrawalread-onlyid: uint
calculate-sharesread-onlyamount: uint
calculate-tokensread-onlyshare-amount: uint
add-whitelistpublicuser: principal
remove-whitelistpublicuser: principal
is-whitelistedread-onlyuser: principal
get-global-total-treasury-navread-only
get-global-total-shares-issuedread-only
set-global-total-treasury-navpublicnew-value: uint
increment-global-total-treasury-navpublicamount: uint
set-global-total-shares-issuedpublicamount: uint
increment-global-total-shares-issuedpublicamount: uint
transferpublicamount: uint, sender: principal, recipient: principal, memo: (optional (buff 34
get-nameread-only
get-symbolread-only
get-decimalsread-only
get-balanceread-onlywho: principal
get-total-supplyread-only
get-token-uriread-only
mintpublicamount: uint, recipient: principal