diff --git a/clarity/Clarinet.toml b/clarity/Clarinet.toml index c726c95e..7ea6233d 100644 --- a/clarity/Clarinet.toml +++ b/clarity/Clarinet.toml @@ -50,8 +50,8 @@ contract_id = "SP3951VNPC55BMS9RCF6SKRZP4K3Q2PQ2RSM1DD1V.fast" contract_id = "SPPK49DG7WR1J5D50GZ4W7DYYWM5MAXSX0ZA9VEJ.FrodoSaylorKeanuPepe10Inu-token-v69" [[project.requirements]] contract_id = "SP3WPNAEBYMX06RQNNYTH5PTJ1FRGX5A13ZZMZ01D.dogwifhat-token" -[[project.requirements]] -contract_id = "SP3R4MHK99JAAM0N3T0CBZRZVSVQFG1N75DQ08JSD.Wsbtc" +# [[project.requirements]] +# contract_id = "SP3R4MHK99JAAM0N3T0CBZRZVSVQFG1N75DQ08JSD.Wsbtc" [[project.requirements]] contract_id = "SP3SJSNPJXXHY7RJM48ZT6G1BXYZADAC5YAXZA3ZC.ODINToken" [[project.requirements]] @@ -1586,7 +1586,7 @@ depends_on = ["trait-ownable", "trait-sip-010"] # [contracts.token-ssl-wsbtc-08JSD] # path = "contracts/wrapped-token/token-ssl-wsbtc-08JSD.clar" -# depends_on = [ "trait-ownable", "trait-sip-010" ] +# depends_on = [ ] # clarity_version = 2 # epoch = 2.4 diff --git a/clarity/contracts/token/brc20-tx20.clar b/clarity/contracts/token/brc20-tx20.clar new file mode 100644 index 00000000..abea94cd --- /dev/null +++ b/clarity/contracts/token/brc20-tx20.clar @@ -0,0 +1,229 @@ +(define-constant ERR-NOT-AUTHORIZED (err u1000)) + +(define-constant ONE_8 u100000000) + +;; -- token implementation + +(define-fungible-token brc20-tx20) + +(define-data-var contract-owner principal tx-sender) +(define-data-var token-name (string-ascii 32) "TX20 (BRC20)") +(define-data-var token-symbol (string-ascii 32) "TX20") +(define-data-var token-uri (optional (string-utf8 256)) (some u"https://cdn.alexlab.co/metadata/brc20-tx20.json")) + +(define-data-var token-decimals uint u8) + +(define-map approved-contracts principal bool) + +;; read-only calls + +(define-read-only (get-contract-owner) + (ok (var-get contract-owner)) +) + +(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 (var-get token-decimals)) +) + +(define-read-only (get-balance (who principal)) + (ok (ft-get-balance brc20-tx20 who)) +) + +(define-read-only (get-total-supply) + (ok (ft-get-supply brc20-tx20)) +) + +(define-read-only (get-token-uri) + (ok (var-get token-uri)) +) + +;; @desc fixed-to-decimals +;; @params amount +;; @returns uint +(define-read-only (fixed-to-decimals (amount uint)) + (/ (* amount (pow-decimals)) ONE_8) +) + +;; @desc get-total-supply-fixed +;; @params token-id +;; @returns (response uint) +(define-read-only (get-total-supply-fixed) + (ok (decimals-to-fixed (unwrap-panic (get-total-supply)))) +) + +;; @desc get-balance-fixed +;; @params token-id +;; @params who +;; @returns (response uint) +(define-read-only (get-balance-fixed (account principal)) + (ok (decimals-to-fixed (unwrap-panic (get-balance account)))) +) + +;; governance calls + +(define-public (set-contract-owner (owner principal)) + (begin + (try! (check-is-owner)) + (ok (var-set contract-owner owner)) + ) +) + +(define-public (set-name (new-name (string-ascii 32))) + (begin + (try! (check-is-owner)) + (ok (var-set token-name new-name)) + ) +) + +(define-public (set-symbol (new-symbol (string-ascii 10))) + (begin + (try! (check-is-owner)) + (ok (var-set token-symbol new-symbol)) + ) +) + +(define-public (set-decimals (new-decimals uint)) + (begin + (try! (check-is-owner)) + (ok (var-set token-decimals new-decimals)) + ) +) + +(define-public (set-token-uri (new-uri (optional (string-utf8 256)))) + (begin + (try! (check-is-owner)) + (ok (var-set token-uri new-uri)) + ) +) + +(define-public (add-approved-contract (new-approved-contract principal)) + (begin + (try! (check-is-owner)) + (ok (map-set approved-contracts new-approved-contract true)) + ) +) + +(define-public (set-approved-contract (owner principal) (approved bool)) + (begin + (try! (check-is-owner)) + (ok (map-set approved-contracts owner approved)) + ) +) + +;; priviliged calls + +;; @desc mint +;; @restricted ContractOwner/Approved Contract +;; @params token-id +;; @params amount +;; @params recipient +;; @returns (response bool) +(define-public (mint (amount uint) (recipient principal)) + (begin + (asserts! (or (is-ok (check-is-approved)) (is-ok (check-is-owner))) ERR-NOT-AUTHORIZED) + (ft-mint? brc20-tx20 amount recipient) + ) +) + +;; @desc burn +;; @restricted ContractOwner/Approved Contract +;; @params token-id +;; @params amount +;; @params sender +;; @returns (response bool) +(define-public (burn (amount uint) (sender principal)) + (begin + (asserts! (or (is-ok (check-is-approved)) (is-ok (check-is-owner))) ERR-NOT-AUTHORIZED) + (ft-burn? brc20-tx20 amount sender) + ) +) + +;; @desc mint-fixed +;; @params token-id +;; @params amount +;; @params recipient +;; @returns (response bool) +(define-public (mint-fixed (amount uint) (recipient principal)) + (mint (fixed-to-decimals amount) recipient) +) + +;; @desc burn-fixed +;; @params token-id +;; @params amount +;; @params sender +;; @returns (response bool) +(define-public (burn-fixed (amount uint) (sender principal)) + (burn (fixed-to-decimals amount) sender) +) + +(define-public (mint-fixed-many (recipients (list 200 { amount: uint, to: principal}))) + (fold mint-many-iter recipients (ok true)) +) + +;; public calls + +(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34)))) + (begin + (asserts! (is-eq sender tx-sender) ERR-NOT-AUTHORIZED) + (try! (ft-transfer? brc20-tx20 amount sender recipient)) + (match memo to-print (print to-print) 0x) + (ok true) + ) +) + +;; @desc transfer-fixed +;; @params token-id +;; @params amount +;; @params sender +;; @params recipient +;; @returns (response bool) +(define-public (transfer-fixed (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34)))) + (transfer (fixed-to-decimals amount) sender recipient memo) +) + +(define-public (transfer-fixed-many (recipients (list 200 { amount: uint, to: principal}))) + (fold transfer-many-iter recipients (ok true)) +) + +;; private calls + +(define-private (check-is-owner) + (ok (asserts! (is-eq tx-sender (var-get contract-owner)) ERR-NOT-AUTHORIZED)) +) + +(define-private (check-is-approved) + (ok (asserts! (default-to false (map-get? approved-contracts tx-sender)) ERR-NOT-AUTHORIZED)) +) + +;; @desc decimals-to-fixed +;; @params amount +;; @returns uint +(define-private (decimals-to-fixed (amount uint)) + (/ (* amount ONE_8) (pow-decimals)) +) + +;; @desc pow-decimals +;; @returns uint +(define-private (pow-decimals) + (pow u10 (unwrap-panic (get-decimals))) +) + +(define-private (mint-many-iter (recipient { amount: uint, to: principal }) (previous-response (response bool uint))) + (match previous-response prev-ok (mint-fixed (get amount recipient) (get to recipient)) prev-err previous-response) +) + +(define-private (transfer-many-iter (recipient { amount: uint, to: principal }) (previous-response (response bool uint))) + (match previous-response prev-ok (transfer-fixed (get amount recipient) tx-sender (get to recipient) none) prev-err previous-response) +) + +;; contract initialisation +(contract-call? .alex-vault-v1-1 set-approved-token .brc20-tx20 true) +;; (set-contract-owner .executor-dao)