Merge pull request #33 from alexgo-io/feat/error-codes

Feat/error codes
This commit is contained in:
fiftyeightandeight
2024-03-22 06:53:26 +08:00
committed by GitHub
11 changed files with 434 additions and 95 deletions

View File

@@ -15,6 +15,12 @@ contract_id = "SP001SFSMC2ZY76PD4M68P3WGX154XCH7NE3TYMX.pox-pools-1-cycle-v2"
[[project.requirements]] [[project.requirements]]
contract_id = "SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard" contract_id = "SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard"
[[project.requirements]]
contract_id = "SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.commission-trait"
[[project.requirements]]
contract_id = "SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait"
[contracts.lisa-dao] [contracts.lisa-dao]
path = "contracts/lisa-dao.clar" path = "contracts/lisa-dao.clar"
epoch = 2.4 epoch = 2.4
@@ -191,6 +197,14 @@ epoch = 2.4
path = "contracts/aux/lqstx-mint-registry.clar" path = "contracts/aux/lqstx-mint-registry.clar"
epoch = 2.4 epoch = 2.4
[contracts.li-stx-mint-nft]
path = "contracts/aux/li-stx-mint-nft.clar"
epoch = 2.4
[contracts.li-stx-burn-nft]
path = "contracts/aux/li-stx-burn-nft.clar"
epoch = 2.4
[contracts.token-lqstx] [contracts.token-lqstx]
path = "contracts/token-lqstx.clar" path = "contracts/token-lqstx.clar"
epoch = 2.4 epoch = 2.4

View File

@@ -22,6 +22,7 @@ are in the form `(err uint)` and they are unique across all contracts.
| Pool members | 5XXX | Errors related to stacking pool members. | | Pool members | 5XXX | Errors related to stacking pool members. |
| Wrapped token | 6XXX | Errors coming directly from the wrapped token. | | Wrapped token | 6XXX | Errors coming directly from the wrapped token. |
| Mint Endpoint | 7XXX | Errors coming directly from the mint endpoint. | | Mint Endpoint | 7XXX | Errors coming directly from the mint endpoint. |
| NFTs | 8XXX | Errors coming directly from the NFTs. |
| Vesting | 9XXX | Errors coming directly from vesting. | | Vesting | 9XXX | Errors coming directly from vesting. |
| Pools | 4XX/5XX/6XX | Errors coming public stacking pools. | | Pools | 4XX/5XX/6XX | Errors coming public stacking pools. |
| Assets | 1/2/3/4 | Errors coming for native Clarity assets. | | Assets | 1/2/3/4 | Errors coming for native Clarity assets. |
@@ -34,6 +35,7 @@ are in the form `(err uint)` and they are unique across all contracts.
| lisa-dao | err-unauthorised | (err u1000) | | | lisa-dao | err-unauthorised | (err u1000) | |
| lqstx-mint-endpoint | err-unauthorised | (err u1000) | | | lqstx-mint-endpoint | err-unauthorised | (err u1000) | |
| lqstx-mint-endpoint-v1-01 | err-unauthorised | (err u1000) | | | lqstx-mint-endpoint-v1-01 | err-unauthorised | (err u1000) | |
| lqstx-mint-registry | err-unauthorised | (err u1000) | |
| lqstx-vault | err-unauthorised | (err u1000) | | | lqstx-vault | err-unauthorised | (err u1000) | |
| operators | err-unauthorised | (err u1000) | | | operators | err-unauthorised | (err u1000) | |
| token-vesting | err-unauthorised | (err u1000) | | | token-vesting | err-unauthorised | (err u1000) | |
@@ -57,10 +59,11 @@ are in the form `(err uint)` and they are unique across all contracts.
| lqstx-mint-registry | err-unknown-request-id | (err u1008) | | | lqstx-mint-registry | err-unknown-request-id | (err u1008) | |
| public-pools-strategy | err-not-vault-caller | (err u2000) | | | public-pools-strategy | err-not-vault-caller | (err u2000) | |
| public-pools-strategy | err-invalid-payload | (err u2001) | | | public-pools-strategy | err-invalid-payload | (err u2001) | |
| li-stx-burn-nft | err-unauthorised | (err u3000) | |
| li-stx-mint-nft | err-unauthorised | (err u3000) | |
| lisa-rebase | err-unauthorised | (err u3000) | | | lisa-rebase | err-unauthorised | (err u3000) | |
| lisa-rebase-v1-02 | err-unauthorised | (err u3000) | | | lisa-rebase-v1-02 | err-unauthorised | (err u3000) | |
| lqstx-mint-endpoint-v1-02 | err-unauthorised | (err u3000) | | | lqstx-mint-endpoint-v1-02 | err-unauthorised | (err u3000) | |
| lqstx-mint-registry | err-unauthorised | (err u3000) | |
| public-pools-strategy-manager | err-unauthorised | (err u3000) | | | public-pools-strategy-manager | err-unauthorised | (err u3000) | |
| token-lisa | err-unauthorised | (err u3000) | | | token-lisa | err-unauthorised | (err u3000) | |
| token-lqstx | err-unauthorised | (err u3000) | | | token-lqstx | err-unauthorised | (err u3000) | |
@@ -113,6 +116,16 @@ are in the form `(err uint)` and they are unique across all contracts.
| lqstx-mint-endpoint-v1-02 | err-request-pending | (err u7006) | | | lqstx-mint-endpoint-v1-02 | err-request-pending | (err u7006) | |
| lqstx-mint-endpoint-v1-02 | err-request-finalized-or-revoked | (err u7007) | | | lqstx-mint-endpoint-v1-02 | err-request-finalized-or-revoked | (err u7007) | |
| lqstx-mint-endpoint-v1-02 | err-not-whitelisted | (err u7008) | | | lqstx-mint-endpoint-v1-02 | err-not-whitelisted | (err u7008) | |
| li-stx-mint-nft | err-not-authorized | (err u8000) | |
| li-stx-mint-nft | err-listing | (err u8001) | |
| li-stx-mint-nft | err-wrong-commission | (err u8002) | |
| li-stx-mint-nft | err-not-found | (err u8003) | |
| li-stx-mint-nft | err-metadata-frozen | (err u8004) | |
| li-stx-burn-nft | err-not-authorized | (err u8100) | |
| li-stx-burn-nft | err-listing | (err u8101) | |
| li-stx-burn-nft | err-wrong-commission | (err u8102) | |
| li-stx-burn-nft | err-not-found | (err u8103) | |
| li-stx-burn-nft | err-metadata-frozen | (err u8104) | |
| token-vesting | err-caller-not-recipient | (err u9000) | | | token-vesting | err-caller-not-recipient | (err u9000) | |
| token-vesting | err-unknown-vesting-id | (err u9001) | | | token-vesting | err-unknown-vesting-id | (err u9001) | |
| token-vesting | err-event-not-vested | (err u9002) | | | token-vesting | err-event-not-vested | (err u9002) | |

View File

@@ -0,0 +1,136 @@
;; li-stx-burn
;; contractType: public
(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)
(define-non-fungible-token li-stx-burn uint)
;; Constants
(define-constant err-not-authorized (err u8100))
(define-constant err-listing (err u8101))
(define-constant err-wrong-commission (err u8102))
(define-constant err-not-found (err u8103))
(define-constant err-metadata-frozen (err u8104))
(define-constant err-unauthorised (err u3000))
(define-read-only (is-dao-or-extension)
(ok (asserts! (or (is-eq tx-sender .lisa-dao) (contract-call? .lisa-dao is-extension contract-caller)) err-unauthorised))
)
;; Internal variables
(define-data-var last-id uint u0)
(define-data-var ipfs-root (string-ascii 80) "")
(define-data-var metadata-frozen bool false)
(define-public (mint (id uint) (amount uint))
(let ((current-balance (get-balance tx-sender)))
(try! (is-dao-or-extension))
(var-set last-id id)
(map-set token-count tx-sender (+ current-balance u1))
(nft-mint? li-stx-burn id tx-sender)))
(define-public (burn (token-id uint))
(let ((owner (unwrap! (nft-get-owner? li-stx-burn token-id) err-not-found))
(current-balance (get-balance owner)))
(try! (is-dao-or-extension))
(asserts! (is-none (map-get? market token-id)) err-listing)
(try! (nft-burn? li-stx-burn token-id owner))
(map-set token-count owner (- current-balance u1))
(ok true)))
(define-private (is-owner (token-id uint) (user principal))
(is-eq user (unwrap! (nft-get-owner? li-stx-burn token-id) false)))
;; governance calls
(define-public (set-base-uri (new-base-uri (string-ascii 80)))
(begin
(try! (is-dao-or-extension))
(asserts! (not (var-get metadata-frozen)) err-metadata-frozen)
(print { notification: "token-metadata-update", payload: { token-class: "nft", contract-id: (as-contract tx-sender) }})
(var-set ipfs-root new-base-uri)
(ok true)))
(define-public (freeze-metadata)
(begin
(try! (is-dao-or-extension))
(var-set metadata-frozen true)
(ok true)))
;; Non-custodial SIP-009 transfer function
(define-public (transfer (id uint) (sender principal) (recipient principal))
(begin
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) err-not-authorized)
(asserts! (is-none (map-get? market id)) err-listing)
(trnsfr id sender recipient)))
;; read-only functions
(define-read-only (get-owner (token-id uint))
(ok (nft-get-owner? li-stx-burn token-id)))
(define-read-only (get-last-token-id)
(ok (- (var-get last-id) u1)))
(define-read-only (get-token-uri (token-id uint))
(ok (some (concat (concat (var-get ipfs-root) "{id}") ".json"))))
;; Non-custodial marketplace extras
(use-trait commission-trait 'SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.commission-trait.commission)
(define-map token-count principal uint)
(define-map market uint {price: uint, commission: principal, royalty: uint})
(define-read-only (get-balance (account principal))
(default-to u0
(map-get? token-count account)))
(define-private (trnsfr (id uint) (sender principal) (recipient principal))
(match (nft-transfer? li-stx-burn id sender recipient)
success
(let
((sender-balance (get-balance sender))
(recipient-balance (get-balance recipient)))
(map-set token-count
sender
(- sender-balance u1))
(map-set token-count
recipient
(+ recipient-balance u1))
(ok success))
error (err error)))
(define-private (is-sender-owner (id uint))
(let ((owner (unwrap! (nft-get-owner? li-stx-burn id) false)))
(or (is-eq tx-sender owner) (is-eq contract-caller owner))))
(define-read-only (get-listing-in-ustx (id uint))
(map-get? market id))
(define-public (list-in-ustx (id uint) (price uint) (comm-trait <commission-trait>))
(let ((listing {price: price, commission: (contract-of comm-trait), royalty: u0}))
(asserts! (is-sender-owner id) err-not-authorized)
(map-set market id listing)
(print (merge listing {a: "list-in-ustx", id: id}))
(ok true)))
(define-public (unlist-in-ustx (id uint))
(begin
(asserts! (is-sender-owner id) err-not-authorized)
(map-delete market id)
(print {a: "unlist-in-ustx", id: id})
(ok true)))
(define-public (buy-in-ustx (id uint) (comm-trait <commission-trait>))
(let ((owner (unwrap! (nft-get-owner? li-stx-burn id) err-not-found))
(listing (unwrap! (map-get? market id) err-listing))
(price (get price listing))
(royalty (get royalty listing)))
(asserts! (is-eq (contract-of comm-trait) (get commission listing)) err-wrong-commission)
(try! (stx-transfer? price tx-sender owner))
(try! (contract-call? comm-trait pay id price))
(try! (trnsfr id owner tx-sender))
(map-delete market id)
(print {a: "buy-in-ustx", id: id})
(ok true)))

View File

@@ -0,0 +1,136 @@
;; li-stx-mint
;; contractType: public
(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)
(define-non-fungible-token li-stx-mint uint)
;; Constants
(define-constant err-not-authorized (err u8000))
(define-constant err-listing (err u8001))
(define-constant err-wrong-commission (err u8002))
(define-constant err-not-found (err u8003))
(define-constant err-metadata-frozen (err u8004))
(define-constant err-unauthorised (err u3000))
(define-read-only (is-dao-or-extension)
(ok (asserts! (or (is-eq tx-sender .lisa-dao) (contract-call? .lisa-dao is-extension contract-caller)) err-unauthorised))
)
;; Internal variables
(define-data-var last-id uint u0)
(define-data-var ipfs-root (string-ascii 80) "")
(define-data-var metadata-frozen bool false)
(define-public (mint (id uint) (amount uint))
(let ((current-balance (get-balance tx-sender)))
(try! (is-dao-or-extension))
(var-set last-id id)
(map-set token-count tx-sender (+ current-balance u1))
(nft-mint? li-stx-mint id tx-sender)))
(define-public (burn (token-id uint))
(let ((owner (unwrap! (nft-get-owner? li-stx-mint token-id) err-not-found))
(current-balance (get-balance owner)))
(try! (is-dao-or-extension))
(asserts! (is-none (map-get? market token-id)) err-listing)
(try! (nft-burn? li-stx-mint token-id owner))
(map-set token-count owner (- current-balance u1))
(ok true)))
(define-private (is-owner (token-id uint) (user principal))
(is-eq user (unwrap! (nft-get-owner? li-stx-mint token-id) false)))
;; governance calls
(define-public (set-base-uri (new-base-uri (string-ascii 80)))
(begin
(try! (is-dao-or-extension))
(asserts! (not (var-get metadata-frozen)) err-metadata-frozen)
(print { notification: "token-metadata-update", payload: { token-class: "nft", contract-id: (as-contract tx-sender) }})
(var-set ipfs-root new-base-uri)
(ok true)))
(define-public (freeze-metadata)
(begin
(try! (is-dao-or-extension))
(var-set metadata-frozen true)
(ok true)))
;; Non-custodial SIP-009 transfer function
(define-public (transfer (id uint) (sender principal) (recipient principal))
(begin
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) err-not-authorized)
(asserts! (is-none (map-get? market id)) err-listing)
(trnsfr id sender recipient)))
;; read-only functions
(define-read-only (get-owner (token-id uint))
(ok (nft-get-owner? li-stx-mint token-id)))
(define-read-only (get-last-token-id)
(ok (- (var-get last-id) u1)))
(define-read-only (get-token-uri (token-id uint))
(ok (some (concat (concat (var-get ipfs-root) "{id}") ".json"))))
;; Non-custodial marketplace extras
(use-trait commission-trait 'SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.commission-trait.commission)
(define-map token-count principal uint)
(define-map market uint {price: uint, commission: principal, royalty: uint})
(define-read-only (get-balance (account principal))
(default-to u0
(map-get? token-count account)))
(define-private (trnsfr (id uint) (sender principal) (recipient principal))
(match (nft-transfer? li-stx-mint id sender recipient)
success
(let
((sender-balance (get-balance sender))
(recipient-balance (get-balance recipient)))
(map-set token-count
sender
(- sender-balance u1))
(map-set token-count
recipient
(+ recipient-balance u1))
(ok success))
error (err error)))
(define-private (is-sender-owner (id uint))
(let ((owner (unwrap! (nft-get-owner? li-stx-mint id) false)))
(or (is-eq tx-sender owner) (is-eq contract-caller owner))))
(define-read-only (get-listing-in-ustx (id uint))
(map-get? market id))
(define-public (list-in-ustx (id uint) (price uint) (comm-trait <commission-trait>))
(let ((listing {price: price, commission: (contract-of comm-trait), royalty: u0}))
(asserts! (is-sender-owner id) err-not-authorized)
(map-set market id listing)
(print (merge listing {a: "list-in-ustx", id: id}))
(ok true)))
(define-public (unlist-in-ustx (id uint))
(begin
(asserts! (is-sender-owner id) err-not-authorized)
(map-delete market id)
(print {a: "unlist-in-ustx", id: id})
(ok true)))
(define-public (buy-in-ustx (id uint) (comm-trait <commission-trait>))
(let ((owner (unwrap! (nft-get-owner? li-stx-mint id) err-not-found))
(listing (unwrap! (map-get? market id) err-listing))
(price (get price listing))
(royalty (get royalty listing)))
(asserts! (is-eq (contract-of comm-trait) (get commission listing)) err-wrong-commission)
(try! (stx-transfer? price tx-sender owner))
(try! (contract-call? comm-trait pay id price))
(try! (trnsfr id owner tx-sender))
(map-delete market id)
(print {a: "buy-in-ustx", id: id})
(ok true)))

View File

@@ -125,6 +125,7 @@
(try! (stx-transfer? amount sender .lqstx-vault)) (try! (stx-transfer? amount sender .lqstx-vault))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (+ (get-mint-requests-pending-amount) amount))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (+ (get-mint-requests-pending-amount) amount)))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending sender (unwrap-panic (as-max-len? (append (get-mint-requests-pending-or-default sender) request-id) u1000)))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending sender (unwrap-panic (as-max-len? (append (get-mint-requests-pending-or-default sender) request-id) u1000))))
(try! (contract-call? .li-stx-mint-nft mint request-id amount))
(print { type: "mint-request", id: request-id, details: request-details }) (print { type: "mint-request", id: request-id, details: request-details })
(ok request-id))) (ok request-id)))
@@ -140,6 +141,7 @@
(try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: REVOKED }))) (try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: REVOKED })))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (- (get-mint-requests-pending-amount) (get amount request-details)))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (- (get-mint-requests-pending-amount) (get amount request-details))))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx)))
(try! (contract-call? .li-stx-mint-nft burn request-id))
(ok true))) (ok true)))
(define-public (revoke-burn (request-id uint)) (define-public (revoke-burn (request-id uint))
@@ -156,6 +158,7 @@
(try! (contract-call? .token-lqstx transfer lqstx-amount (as-contract tx-sender) (get requested-by request-details) none)) (try! (contract-call? .token-lqstx transfer lqstx-amount (as-contract tx-sender) (get requested-by request-details) none))
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: REVOKED }))) (try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: REVOKED })))
(try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests request-id-idx))) (try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests request-id-idx)))
(try! (contract-call? .li-stx-burn-nft burn request-id))
(ok true))) (ok true)))
;; governance calls ;; governance calls
@@ -203,6 +206,7 @@
(try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: FINALIZED }))) (try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: FINALIZED })))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (- (get-mint-requests-pending-amount) (get amount request-details)))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (- (get-mint-requests-pending-amount) (get amount request-details))))
(try! (contract-call? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx))) (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx)))
(try! (contract-call? .li-stx-mint-nft burn request-id))
(ok true))) (ok true)))
(define-public (finalize-mint-many (request-ids (list 1000 uint))) (define-public (finalize-mint-many (request-ids (list 1000 uint)))
@@ -220,6 +224,7 @@
(try! (contract-call? .token-vlqstx mint amount tx-sender)) (try! (contract-call? .token-vlqstx mint amount tx-sender))
(try! (contract-call? .token-vlqstx transfer vlqstx-amount tx-sender .lqstx-mint-registry none)) (try! (contract-call? .token-vlqstx transfer vlqstx-amount tx-sender .lqstx-mint-registry none))
(try! (contract-call? .lqstx-mint-registry set-burn-requests-pending sender (unwrap-panic (as-max-len? (append (get-burn-requests-pending-or-default sender) request-id) u1000)))) (try! (contract-call? .lqstx-mint-registry set-burn-requests-pending sender (unwrap-panic (as-max-len? (append (get-burn-requests-pending-or-default sender) request-id) u1000))))
(try! (contract-call? .li-stx-burn-nft mint request-id amount))
(print { type: "burn-request", id: request-id, details: request-details }) (print { type: "burn-request", id: request-id, details: request-details })
(ok { request-id: request-id, status: PENDING }))) (ok { request-id: request-id, status: PENDING })))
@@ -236,6 +241,7 @@
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get vaulted-amount validation-data), recipient: (get requested-by request-details) })))) (try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get vaulted-amount validation-data), recipient: (get requested-by request-details) }))))
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED }))) (try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))
(try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests (get request-id-idx validation-data)))) (try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests (get request-id-idx validation-data))))
(try! (contract-call? .li-stx-burn-nft burn request-id))
(ok true))) (ok true)))
(define-public (finalize-burn-many (request-ids (list 1000 uint))) (define-public (finalize-burn-many (request-ids (list 1000 uint)))

View File

@@ -49,6 +49,16 @@ plan:
batches: batches:
- id: 0 - id: 0
transactions: transactions:
- emulated-contract-publish:
contract-name: nft-trait
emulated-sender: SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9
path: "./.cache/requirements/SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.clar"
clarity-version: 1
- emulated-contract-publish:
contract-name: commission-trait
emulated-sender: SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335
path: "./.cache/requirements/SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.commission-trait.clar"
clarity-version: 1
- emulated-contract-publish: - emulated-contract-publish:
contract-name: sip-010-trait-ft-standard contract-name: sip-010-trait-ft-standard
emulated-sender: SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE emulated-sender: SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE
@@ -295,6 +305,16 @@ plan:
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: contracts/boot.clar path: contracts/boot.clar
clarity-version: 2 clarity-version: 2
- emulated-contract-publish:
contract-name: li-stx-burn-nft
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: contracts/aux/li-stx-burn-nft.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: li-stx-mint-nft
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: contracts/aux/li-stx-mint-nft.clar
clarity-version: 2
- emulated-contract-publish: - emulated-contract-publish:
contract-name: lisa-rebase contract-name: lisa-rebase
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
@@ -345,6 +365,9 @@ plan:
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: contracts/mocks/mock-strategy-manager.clar path: contracts/mocks/mock-strategy-manager.clar
clarity-version: 2 clarity-version: 2
epoch: "2.4"
- id: 3
transactions:
- emulated-contract-publish: - emulated-contract-publish:
contract-name: rebase-1 contract-name: rebase-1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
@@ -355,9 +378,6 @@ plan:
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: contracts/rules/rebase-1.clar path: contracts/rules/rebase-1.clar
clarity-version: 2 clarity-version: 2
epoch: "2.4"
- id: 3
transactions:
- emulated-contract-publish: - emulated-contract-publish:
contract-name: rebase-mock contract-name: rebase-mock
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM

View File

@@ -1,92 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1 // SPDX-License-Identifier: BUSL-1.1
import { initSimnet } from '@hirosystems/clarinet-sdk'; import { initSimnet } from '@hirosystems/clarinet-sdk';
import { readFileSync, writeFileSync } from 'fs'; import { createErrorsTable } from './lib/error-codes.ts';
const readmeFile = './README.md';
const manifestFile = './Clarinet.toml'; const manifestFile = './Clarinet.toml';
const constantErrRegex = /^\s*\(define-constant\s+(err-.+?)\s+(\(.+?\))\s*\)(.*?)$/gm;
const errorCodeRegex = /u([0-9]+)/;
const commentRegex = /;;\s*(.+)/;
const readmeErrorsDelineator = '<!--errors-->';
const tableHeader = ['Contract', 'Constant', 'Value', 'Description'];
const simnet = await initSimnet(manifestFile); const simnet = await initSimnet(manifestFile);
export function isTestContract(contractName: string) { createErrorsTable(simnet, false);
return contractName.indexOf('mock') >= 0;
}
function padTableCell(content: string, length: number) {
const repeat = length - content.length + 1;
return repeat > 0 ? ' ' + content + ' '.repeat(repeat) : ' ';
}
function createErrorsTable() {
const errorsSeenCount: { [key: string]: { lastConstantName: string; count: number } } = {};
let readme = readFileSync(readmeFile).toString();
const errorTable: Array<Array<string>> = [];
const longestColumnCells = tableHeader.map(v => v.length);
const compareReadme = process.env.EXTRACT_CHECK && readme;
for (const [contractId, abi] of simnet.getContractsInterfaces()) {
if (isTestContract(contractId)) continue;
console.log(abi);
const source = simnet.getContractSource(contractId);
if (!source) continue;
const errorConstants = source.matchAll(constantErrRegex);
for (const [, errorConstant, errorValue, errorComment] of errorConstants) {
const errorDescription = errorComment?.match(commentRegex)?.[1] || ''; // || '_None_';
if (!errorValue.match(errorCodeRegex))
console.error(`Constant '${errorConstant}' error value is not in form of (err uint)`);
if (!errorsSeenCount[errorValue])
errorsSeenCount[errorValue] = { lastConstantName: errorConstant, count: 1 };
else if (errorsSeenCount[errorValue].lastConstantName !== errorConstant) {
errorsSeenCount[errorValue].lastConstantName = errorConstant;
++errorsSeenCount[errorValue].count;
}
const row = [contractId.split('.')[1], errorConstant, errorValue, errorDescription];
row.map((content, index) => {
if (content.length > longestColumnCells[index]) longestColumnCells[index] = content.length;
});
errorTable.push(row);
}
}
const nonUniqueErrors = Object.entries(errorsSeenCount).filter(([, value]) => value.count > 1);
if (nonUniqueErrors.length > 0) console.log(nonUniqueErrors);
errorTable.sort((a, b) => (a[2] === b[2] ? (a[0] > b[0] ? 1 : -1) : a[2] > b[2] ? 1 : -1)); // string sort
let errors =
'|' +
tableHeader
.map((content, index) => padTableCell(content, longestColumnCells[index]))
.join('|') +
'|\n';
errors += '|' + longestColumnCells.map(length => '-'.repeat(length + 2)).join('|') + '|\n';
errors += errorTable.reduce(
(accumulator, row) =>
accumulator +
'|' +
row.map((content, index) => padTableCell(content, longestColumnCells[index])).join('|') +
'|\n',
''
);
const split = readme.split(readmeErrorsDelineator);
readme = `${split[0]}${readmeErrorsDelineator}\n${errors}${readmeErrorsDelineator}${split[2]}`;
if (compareReadme && compareReadme !== readme) {
throw new Error(
'Generated readme is not equal to readme in current commit (error table mismatch)'
);
}
writeFileSync(readmeFile, readme);
console.log(`Error table written to ${readmeFile}`);
}
console.log('start');
createErrorsTable();

View File

@@ -0,0 +1,86 @@
// SPDX-License-Identifier: BUSL-1.1
import { Simnet } from '@hirosystems/clarinet-sdk';
import { readFileSync, writeFileSync } from 'fs';
const readmeFile = './README.md';
const constantErrRegex = /^\s*\(define-constant\s+(err-.+?)\s+(\(.+?\))\s*\)(.*?)$/gm;
const errorCodeRegex = /u([0-9]+)/;
const commentRegex = /;;\s*(.+)/;
const readmeErrorsDelineator = '<!--errors-->';
const tableHeader = ['Contract', 'Constant', 'Value', 'Description'];
export function isTestContract(contractName: string) {
return contractName.indexOf('mock') >= 0;
}
function padTableCell(content: string, length: number) {
const repeat = length - content.length + 1;
return repeat > 0 ? ' ' + content + ' '.repeat(repeat) : ' ';
}
export function createErrorsTable(simnet: Simnet, extractCheck: boolean) {
const errorsSeenCount: { [key: string]: { lastConstantName: string; count: number } } = {};
let readme = readFileSync(readmeFile).toString();
const errorTable: Array<Array<string>> = [];
const longestColumnCells = tableHeader.map(v => v.length);
const compareReadme = extractCheck && readme;
for (const [contractId] of simnet.getContractsInterfaces()) {
if (isTestContract(contractId)) continue;
const source = simnet.getContractSource(contractId);
if (!source) continue;
const errorConstants = source.matchAll(constantErrRegex);
for (const [, errorConstant, errorValue, errorComment] of errorConstants) {
const errorDescription = errorComment?.match(commentRegex)?.[1] || ''; // || '_None_';
if (!errorValue.match(errorCodeRegex))
console.error(`Constant '${errorConstant}' error value is not in form of (err uint)`);
if (!errorsSeenCount[errorValue])
errorsSeenCount[errorValue] = { lastConstantName: errorConstant, count: 1 };
else if (errorsSeenCount[errorValue].lastConstantName !== errorConstant) {
errorsSeenCount[errorValue].lastConstantName = errorConstant;
++errorsSeenCount[errorValue].count;
}
const row = [contractId.split('.')[1], errorConstant, errorValue, errorDescription];
row.map((content, index) => {
if (content.length > longestColumnCells[index]) longestColumnCells[index] = content.length;
});
errorTable.push(row);
}
}
const nonUniqueErrors = Object.entries(errorsSeenCount).filter(([, value]) => value.count > 1);
if (nonUniqueErrors.length > 0) console.log(nonUniqueErrors);
errorTable.sort((a, b) => (a[2] === b[2] ? (a[0] > b[0] ? 1 : -1) : a[2] > b[2] ? 1 : -1)); // string sort
let errors =
'|' +
tableHeader
.map((content, index) => padTableCell(content, longestColumnCells[index]))
.join('|') +
'|\n';
errors += '|' + longestColumnCells.map(length => '-'.repeat(length + 2)).join('|') + '|\n';
errors += errorTable.reduce(
(accumulator, row) =>
accumulator +
'|' +
row.map((content, index) => padTableCell(content, longestColumnCells[index])).join('|') +
'|\n',
''
);
const split = readme.split(readmeErrorsDelineator);
readme = `${split[0]}${readmeErrorsDelineator}\n${errors}${readmeErrorsDelineator}${split[2]}`;
if (compareReadme && compareReadme !== readme) {
throw new Error(
'Generated readme is not equal to readme in current commit (error table mismatch)'
);
}
writeFileSync(readmeFile, readme);
console.log(`Error table written to ${readmeFile}`);
}

11
tests/errors.test.ts Normal file
View File

@@ -0,0 +1,11 @@
// SPDX-License-Identifier: BUSL-1.1
import { describe, it } from 'vitest';
import { createErrorsTable } from '../scripts/lib/error-codes.ts';
describe('readme', () => {
it('should have the correct error code table', () => {
createErrorsTable(simnet, true);
// should not throw an error
});
});

View File

@@ -250,7 +250,6 @@ describe(contracts.endpoint, () => {
]); ]);
expect(responses[0].result).toBeErr(Cl.uint(7006)); // request pending expect(responses[0].result).toBeErr(Cl.uint(7006)); // request pending
expect(responses[1].result).toBeErr(Cl.uint(3000)); // not authorized expect(responses[1].result).toBeErr(Cl.uint(3000)); // not authorized
responses[2].events.map((e: any) => console.log(e));
expect(responses[2].result).toBeOk(Cl.uint(mintAmount)); // mintAmount stx transferred, mintAmount - 1 stx locked expect(responses[2].result).toBeOk(Cl.uint(mintAmount)); // mintAmount stx transferred, mintAmount - 1 stx locked
const stxAccountFastPoolMember1 = simnet.runSnippet( const stxAccountFastPoolMember1 = simnet.runSnippet(

View File

@@ -254,10 +254,13 @@ describe(contracts.endpoint, () => {
simnet.mineEmptyBlocks(mintDelay); simnet.mineEmptyBlocks(mintDelay);
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot); response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
expect(response.result).toBeOk(Cl.bool(true)); expect(response.result).toBeOk(Cl.bool(true));
expect(response.events[2].event).toBe('nft_burn_event');
response = simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user); response = simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user);
expect(response.result).toBeOk( expect(response.result).toBeOk(
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.buffer(new Uint8Array([1])) }) Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.buffer(new Uint8Array([1])) })
); );
expect(response.events[7].event).toBe('nft_mint_event');
expect(response.events[17].event).toBe('nft_burn_event');
}); });
it('can interact with strategies', () => { it('can interact with strategies', () => {
@@ -395,12 +398,12 @@ describe(contracts.endpoint, () => {
expect(getRequestCycle()).toBe(2n); expect(getRequestCycle()).toBe(2n);
const response = requestMint(); const response = requestMint();
console.log(response.events[1].data);
expect(response.result).toBeOk(Cl.uint(1)); expect(response.result).toBeOk(Cl.uint(1));
expect(response.events[0].event).toBe('stx_transfer_event'); expect(response.events[0].event).toBe('stx_transfer_event');
expect(response.events[1].event).toBe('print_event'); expect(response.events[1].event).toBe('nft_mint_event');
expect(response.events[2].event).toBe('print_event');
expect( expect(
((response.events[1].data.value as TupleCV).data.details as TupleCV).data['requested-at'] ((response.events[2].data.value as TupleCV).data.details as TupleCV).data['requested-at']
).toBeUint(2); ).toBeUint(2);
}); });
}); });