;; USDCx 代币
;;
;; 此合约为可替代代币合约实现了 SIP-010 trait。
;;
;; 此合约使用基于角色的访问控制系统来管理协议权限。
;; 有三种角色:
;;
;; - `governance`:允许更新协议合约并添加/移除角色
;; - `mint`:允许铸造和销毁代币
;; - `pause`:允许暂停和恢复协议
;;
(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
;; `tx-sender` 或 `contract-caller` 试图移动其不拥有的代币。
(define-constant ERR_NOT_OWNER (err u4))
;; `contract-caller` 试图使用其未被授权使用的函数。
(define-constant ERR_UNAUTHORIZED (err u400))
;; 协议已暂停。
(define-constant ERR_PAUSED (err u401))
(define-fungible-token usdcx-token)
(define-data-var token-name (string-ascii 32) "USDCx")
(define-data-var token-symbol (string-ascii 10) "USDCx")
;; 代币元数据的 SIP-16 URI
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://ipfs.io/ipfs/bafkreifkhq47bgrlq2z2qgtps65eawgp6xsqkwldz57y2bjpefgo5zvza4"))
(define-constant token-decimals u6)
;; 允许更新协议合约
(define-constant governance-role 0x00)
;; 允许铸造和销毁代币
(define-constant mint-role 0x01)
;; 允许暂停和恢复协议
(define-constant pause-role 0x02)
;; 允许协议被暂停
(define-data-var paused bool false)
;; 活跃协议合约的映射(按角色)
(define-map active-protocol-contracts
{
caller: principal,
role: (buff 1),
}
bool
)
;; 合约 .usdcx-v1 自动具有 `mint` 角色
(map-set active-protocol-contracts {
caller: .usdcx-v1,
role: mint-role,
}
true
)
;; 默认将合约部署者设为具有 `governance` 角色
(map-set active-protocol-contracts {
caller: tx-sender,
role: governance-role,
}
true
)
;; SIP-010 函数
(define-public (transfer
(amount uint)
(sender principal)
(recipient principal)
(memo (optional (buff 34)))
)
(begin
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender))
ERR_NOT_OWNER
)
(try! (ft-transfer? usdcx-token amount sender recipient))
(match memo
to-print (print to-print)
0x
)
(ok true)
)
)
(define-read-only (get-name)
(ok (var-get token-name))
)
(define-read-only (get-symbol)
(ok (var-get token-symbol))
)
(define-read-only (get-decimals)
(ok token-decimals)
)
(define-read-only (get-balance (who principal))
(ok (ft-get-balance usdcx-token who))
)
(define-read-only (get-balance-available (who principal))
(ok (ft-get-balance usdcx-token who))
)
(define-read-only (get-balance-locked (who principal))
(ok (ft-get-balance usdcx-token who))
)
(define-read-only (get-total-supply)
(ok (ft-get-supply usdcx-token))
)
(define-read-only (get-token-uri)
(ok (var-get token-uri))
)
;; 协议调用者验证
;; 检查 contract-caller 是否为协议合约
(define-read-only (is-protocol-caller
(contract-flag (buff 1))
(contract principal)
)
(validate-protocol-caller contract-flag contract)
)
;; 验证给定主体是否为协议合约
(define-read-only (validate-protocol-caller
(contract-flag (buff 1))
(contract principal)
)
(begin
;; 检查调用者是否具有所需角色
(asserts!
(default-to false
(map-get? active-protocol-contracts {
caller: contract,
role: contract-flag,
})
)
ERR_UNAUTHORIZED
)
(ok true)
)
)
;; 协议暂停功能
(define-read-only (is-protocol-paused)
(var-get paused)
)
;; 验证协议未被暂停
(define-read-only (validate-protocol-active)
(ok (asserts! (not (is-protocol-paused)) ERR_PAUSED))
)
;; --- 协议函数
;; 将代币从一个账户转移到另一个账户。
;; 只有 `mint` 角色被允许调用此函数。
(define-public (protocol-transfer
(amount uint)
(sender principal)
(recipient principal)
)
(begin
;; #[filter(amount, sender, recipient)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller mint-role contract-caller))
(ft-transfer? usdcx-token amount sender recipient)
)
)
;; 向账户铸造代币。
;; 只有 `mint` 角色被允许调用此函数。
(define-public (protocol-mint
(amount uint)
(recipient principal)
)
(begin
;; #[filter(amount, recipient)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller mint-role contract-caller))
(ft-mint? usdcx-token amount recipient)
)
)
;; 从账户销毁代币。
;; 只有 `mint` 角色被允许调用此函数。
(define-public (protocol-burn
(amount uint)
(owner principal)
)
(begin
;; #[filter(amount, owner)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller mint-role contract-caller))
(ft-burn? usdcx-token amount owner)
)
)
;; 设置代币的名称。
;; 只有 `governance` 角色被允许调用此函数。
(define-public (protocol-set-name (new-name (string-ascii 32)))
(begin
;; #[filter(new-name)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller governance-role contract-caller))
(ok (var-set token-name new-name))
)
)
;; 设置代币的符号。
;; 只有 `governance` 角色被允许调用此函数。
(define-public (protocol-set-symbol (new-symbol (string-ascii 10)))
(begin
;; #[filter(new-symbol)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller governance-role contract-caller))
(ok (var-set token-symbol new-symbol))
)
)
;; 设置代币元数据的 SIP-16 URI。
;; 只有 `governance` 角色被允许调用此函数。
(define-public (protocol-set-token-uri (new-uri (optional (string-utf8 256))))
(begin
;; #[filter(new-uri)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller governance-role contract-caller))
(ok (var-set token-uri new-uri))
)
)
;; 用于向多个接收者铸造代币的辅助函数。
;; 只有 `mint` 角色被允许调用此函数。
(define-private (protocol-mint-many-iter (item {
amount: uint,
recipient: principal,
}))
;; #[allow(unchecked_data)]
(ft-mint? usdcx-token (get amount item) (get recipient item))
)
;; 向多个接收者铸造代币。
;; 只有 `mint` 角色被允许调用此函数。
(define-public (protocol-mint-many (recipients (list 200 {
amount: uint,
recipient: principal,
})))
(begin
;; #[filter(recipients)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller mint-role contract-caller))
(ok (map protocol-mint-many-iter recipients))
)
)
;; 设置活跃的协议调用者。
;; 只有 `governance` 角色被允许调用此函数。
(define-public (set-active-protocol-caller
(caller principal)
(role (buff 1))
(enabled bool)
)
(begin
;; #[filter(caller, role, enabled)]
(try! (validate-protocol-active))
(try! (validate-protocol-caller governance-role contract-caller))
(map-set active-protocol-contracts {
caller: caller,
role: role,
}
enabled
)
(ok true)
)
)
;; 暂停协议。
;; 只有 `pause` 角色被允许调用此函数。
(define-public (pause)
(begin
(try! (validate-protocol-caller pause-role contract-caller))
(print {
topic: "pause",
paused: true,
caller: contract-caller,
})
(ok (var-set paused true))
)
)
;; 取消暂停协议。
;; 只有 `pause` 角色被允许调用此函数。
(define-public (unpause)
(begin
(try! (validate-protocol-caller pause-role contract-caller))
(print {
topic: "pause",
paused: false,
caller: contract-caller,
})
(ok (var-set paused false))
)
)