interoperable-security-token

SP1V95DB4JK47QVPJBXCEN6MT35JK84CQ4CWS15DQ

Source Code

(define-fungible-token interoperable-security-token)

(define-data-var total-supply uint u0)

(define-map balances {account: principal, partition-id: uint} uint)
(define-map locked-balances {account: principal, partition-id: uint} {amount: uint, release-time: uint})
(define-map transfer-restrictions {partition-id: uint} bool)
(define-map frozen-addresses principal bool)

(define-constant contract-owner tx-sender)
(define-constant err-not-owner (err u100))
(define-constant err-frozen (err u101))
(define-constant err-restricted (err u102))
(define-constant err-insufficient-balance (err u103))
(define-constant err-locked (err u104))

(define-read-only (get-balance (account principal) (partition-id uint))
  (default-to u0 (map-get? balances {account: account, partition-id: partition-id})))

(define-read-only (transferable-balance (account principal) (partition-id uint))
  (let ((total (get-balance account partition-id))
        (locked-info (map-get? locked-balances {account: account, partition-id: partition-id})))
    (match locked-info
      info (if (>= stacks-block-time (get release-time info))
             total
             (- total (get amount info)))
      total)))

(define-read-only (locked-balance-of (account principal) (partition-id uint))
  (match (map-get? locked-balances {account: account, partition-id: partition-id})
    info (if (< stacks-block-time (get release-time info))
           (get amount info)
           u0)
    u0))

(define-read-only (can-transfer (from principal) (to principal) (partition-id uint) (amount uint))
  (and (not (is-frozen from))
       (not (is-frozen to))
       (not (is-restricted partition-id))
       (>= (transferable-balance from partition-id) amount)))

(define-read-only (is-frozen (account principal))
  (default-to false (map-get? frozen-addresses account)))

(define-read-only (is-restricted (partition-id uint))
  (default-to false (map-get? transfer-restrictions {partition-id: partition-id})))

(define-public (mint (account principal) (partition-id uint) (amount uint))
  (let ((current-balance (get-balance account partition-id)))
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (try! (ft-mint? interoperable-security-token amount account))
    (map-set balances {account: account, partition-id: partition-id} (+ current-balance amount))
    (var-set total-supply (+ (var-get total-supply) amount))
    (ok true)))

(define-public (transfer (amount uint) (sender principal) (recipient principal) (partition-id uint))
  (let ((sender-balance (get-balance sender partition-id))
        (recipient-balance (get-balance recipient partition-id)))
    (asserts! (is-eq tx-sender sender) err-not-owner)
    (asserts! (can-transfer sender recipient partition-id amount) err-restricted)
    (asserts! (>= (transferable-balance sender partition-id) amount) err-locked)
    (try! (ft-transfer? interoperable-security-token amount sender recipient))
    (map-set balances {account: sender, partition-id: partition-id} (- sender-balance amount))
    (map-set balances {account: recipient, partition-id: partition-id} (+ recipient-balance amount))
    (ok true)))

(define-public (lock-tokens (account principal) (partition-id uint) (amount uint) (release-time uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (map-set locked-balances {account: account, partition-id: partition-id} 
      {amount: amount, release-time: release-time})
    (ok true)))

(define-public (restrict-transfer (partition-id uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (map-set transfer-restrictions {partition-id: partition-id} true)
    (ok true)))

(define-public (remove-restriction (partition-id uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (map-set transfer-restrictions {partition-id: partition-id} false)
    (ok true)))

(define-public (freeze-address (account principal))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (map-set frozen-addresses account true)
    (ok true)))

(define-public (unfreeze-address (account principal))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (map-set frozen-addresses account false)
    (ok true)))

(define-public (forced-transfer (from principal) (to principal) (partition-id uint) (amount uint))
  (let ((from-balance (get-balance from partition-id))
        (to-balance (get-balance to partition-id)))
    (asserts! (is-eq tx-sender contract-owner) err-not-owner)
    (try! (ft-transfer? interoperable-security-token amount from to))
    (map-set balances {account: from, partition-id: partition-id} (- from-balance amount))
    (map-set balances {account: to, partition-id: partition-id} (+ to-balance amount))
    (ok true)))

(define-read-only (get-total-supply)
  (ok (var-get total-supply)))

(define-read-only (get-contract-hash)
  (contract-hash? .interoperable-security-token))

(define-read-only (get-block-time)
  stacks-block-time)

Functions (17)

FunctionAccessArgs
get-balanceread-onlyaccount: principal, partition-id: uint
transferable-balanceread-onlyaccount: principal, partition-id: uint
locked-balance-ofread-onlyaccount: principal, partition-id: uint
can-transferread-onlyfrom: principal, to: principal, partition-id: uint, amount: uint
is-frozenread-onlyaccount: principal
is-restrictedread-onlypartition-id: uint
mintpublicaccount: principal, partition-id: uint, amount: uint
transferpublicamount: uint, sender: principal, recipient: principal, partition-id: uint
lock-tokenspublicaccount: principal, partition-id: uint, amount: uint, release-time: uint
restrict-transferpublicpartition-id: uint
remove-restrictionpublicpartition-id: uint
freeze-addresspublicaccount: principal
unfreeze-addresspublicaccount: principal
forced-transferpublicfrom: principal, to: principal, partition-id: uint, amount: uint
get-total-supplyread-only
get-contract-hashread-only
get-block-timeread-only