mirror of
https://github.com/zhigang1992/liquid-stacking.git
synced 2026-01-12 17:23:23 +08:00
Merge pull request #35 from alexgo-io/refactor/lqstx-mint-endpoint
refactor: lqstx-mint-endpoint
This commit is contained in:
@@ -229,26 +229,14 @@ epoch = 2.4
|
||||
path = "contracts/deployed/lisa-rebase.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.lisa-rebase-v1-02]
|
||||
path = "contracts/extensions/lisa-rebase.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.rebase-1]
|
||||
path = "contracts/deployed/rebase-1.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.rebase-1-v1-02]
|
||||
path = "contracts/rules/rebase-1.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.operators]
|
||||
path = "contracts/extensions/operators.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.rebase-mock]
|
||||
path = "contracts/mocks/rebase-mock.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.mock-strategy]
|
||||
path = "contracts/mocks/mock-strategy.clar"
|
||||
epoch = 2.4
|
||||
|
||||
@@ -62,7 +62,6 @@ are in the form `(err uint)` and they are unique across all contracts.
|
||||
| li-stx-burn-nft | err-unauthorised | (err u3000) | |
|
||||
| li-stx-mint-nft | err-unauthorised | (err u3000) | |
|
||||
| lisa-rebase | err-unauthorised | (err u3000) | |
|
||||
| lisa-rebase-v1-02 | err-unauthorised | (err u3000) | |
|
||||
| lqstx-mint-endpoint-v1-02 | err-unauthorised | (err u3000) | |
|
||||
| public-pools-strategy-manager | err-unauthorised | (err u3000) | |
|
||||
| token-lisa | err-unauthorised | (err u3000) | |
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
;; SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
(use-trait strategy-trait .strategy-trait.strategy-trait)
|
||||
|
||||
(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))
|
||||
)
|
||||
|
||||
(define-private (sum-strategy-amounts (strategy <strategy-trait>) (accumulator (response uint uint)))
|
||||
(ok (+ (try! (contract-call? strategy get-amount-in-strategy)) (try! accumulator)))
|
||||
)
|
||||
|
||||
(define-public (rebase (strategies (list 20 <strategy-trait>)))
|
||||
(let ((total-stx (- (+ (stx-get-balance .lqstx-vault) (try! (fold sum-strategy-amounts strategies (ok u0)))) (contract-call? .lqstx-mint-endpoint-v1-02 get-mint-requests-pending-amount))))
|
||||
(try! (is-dao-or-extension))
|
||||
(as-contract (try! (contract-call? .token-lqstx set-reserve total-stx)))
|
||||
(ok total-stx)
|
||||
)
|
||||
)
|
||||
@@ -5,6 +5,8 @@
|
||||
;; lqstx-mint-endpoint-v1-02
|
||||
;;
|
||||
|
||||
(use-trait strategy-trait .strategy-trait.strategy-trait)
|
||||
|
||||
;; __IF_MAINNET__
|
||||
(use-trait sip-010-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
|
||||
;; (use-trait sip-010-trait .sip-010-trait.sip-010-trait)
|
||||
@@ -119,10 +121,23 @@
|
||||
|
||||
;; public calls
|
||||
|
||||
(define-public (rebase)
|
||||
(let (
|
||||
(available-stx (stx-get-balance .lqstx-vault))
|
||||
;; __IF_MAINNET__
|
||||
(deployed-stx (unwrap-panic (contract-call? .public-pools-strategy get-amount-in-strategy)))
|
||||
;; (deployed-stx (unwrap-panic (contract-call? .mock-strategy get-amount-in-strategy)))
|
||||
;; __ENDIF__
|
||||
(pending-stx (get-mint-requests-pending-amount))
|
||||
(total-stx (- (+ available-stx deployed-stx) pending-stx)))
|
||||
(try! (contract-call? .token-lqstx set-reserve total-stx))
|
||||
(ok total-stx)))
|
||||
|
||||
;; @dev the requestor stx is held by the contract until mint can be finalized.
|
||||
(define-public (request-mint (amount uint))
|
||||
(let (
|
||||
(let (
|
||||
(sender tx-sender)
|
||||
(rebase-first (try! (rebase)))
|
||||
(cycle (get-request-cycle burn-block-height))
|
||||
(request-details { requested-by: sender, amount: amount, requested-at: cycle, status: PENDING })
|
||||
(request-id (try! (contract-call? .lqstx-mint-registry set-mint-request u0 request-details))))
|
||||
@@ -131,11 +146,13 @@
|
||||
(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? .li-stx-mint-nft mint request-id amount sender))
|
||||
(try! (rebase))
|
||||
(print { type: "mint-request", id: request-id, details: request-details })
|
||||
(ok request-id)))
|
||||
|
||||
(define-public (revoke-mint (request-id uint))
|
||||
(let (
|
||||
(rebase-first (try! (rebase)))
|
||||
(request-details (try! (get-mint-request-or-fail request-id)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-mint-nft request-id)) err-request-finalized-or-revoked)))
|
||||
(try! (is-not-paused-or-fail))
|
||||
@@ -144,24 +161,87 @@
|
||||
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get amount request-details), recipient: recipient }))))
|
||||
(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))))
|
||||
(as-contract (try! (contract-call? .li-stx-mint-nft burn request-id)))
|
||||
(try! (contract-call? .li-stx-mint-nft burn request-id))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (request-burn (amount uint))
|
||||
(let (
|
||||
(sender tx-sender)
|
||||
(rebase-first (try! (rebase)))
|
||||
(cycle (get-request-cycle burn-block-height))
|
||||
(vlqstx-amount (contract-call? .token-vlqstx get-tokens-to-shares amount))
|
||||
(request-details { requested-by: sender, amount: amount, wrapped-amount: vlqstx-amount, requested-at: cycle, status: PENDING })
|
||||
(request-id (try! (contract-call? .lqstx-mint-registry set-burn-request u0 request-details))))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(print { type: "burn-request", id: request-id, details: request-details })
|
||||
(if (>= (stx-get-balance .lqstx-vault) amount)
|
||||
(begin
|
||||
(try! (contract-call? .token-lqstx dao-burn amount sender))
|
||||
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: amount, recipient: sender }))))
|
||||
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))
|
||||
(try! (rebase))
|
||||
(ok {request-id: request-id, status: FINALIZED })
|
||||
)
|
||||
(begin
|
||||
(try! (contract-call? .token-vlqstx mint amount sender))
|
||||
(try! (contract-call? .token-vlqstx transfer vlqstx-amount sender .lqstx-mint-registry none))
|
||||
(try! (contract-call? .li-stx-burn-nft mint request-id amount sender))
|
||||
(try! (rebase))
|
||||
(ok { request-id: request-id, status: PENDING })))))
|
||||
|
||||
(define-public (revoke-burn (request-id uint))
|
||||
(let (
|
||||
(rebase-first (try! (rebase)))
|
||||
(request-details (try! (get-burn-request-or-fail request-id)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-burn-nft request-id)) err-request-finalized-or-revoked))
|
||||
(lqstx-amount (contract-call? .token-vlqstx get-shares-to-tokens (get wrapped-amount request-details))))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(asserts! (is-eq PENDING (get status request-details)) err-request-finalized-or-revoked)
|
||||
(asserts! (is-eq tx-sender recipient) err-unauthorised)
|
||||
(try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) (as-contract tx-sender) .token-vlqstx))
|
||||
(try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) (as-contract tx-sender)))
|
||||
(try! (contract-call? .token-lqstx transfer lqstx-amount (as-contract tx-sender) recipient none))
|
||||
(try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) recipient .token-vlqstx))
|
||||
(try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) recipient))
|
||||
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: REVOKED })))
|
||||
(as-contract (try! (contract-call? .li-stx-burn-nft burn request-id)))
|
||||
(try! (contract-call? .li-stx-burn-nft burn request-id))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-mint (request-id uint))
|
||||
(let (
|
||||
(rebase-first (try! (rebase)))
|
||||
(request-details (try! (get-mint-request-or-fail request-id)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-mint-nft request-id)) err-request-finalized-or-revoked)))
|
||||
(try! (validate-mint-request request-id))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(try! (contract-call? .token-lqstx dao-mint (get amount request-details) recipient))
|
||||
(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? .li-stx-mint-nft burn request-id))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-mint-many (request-ids (list 1000 uint)))
|
||||
(fold check-err (map finalize-mint request-ids) (ok true)))
|
||||
|
||||
(define-public (finalize-burn (request-id uint))
|
||||
(let (
|
||||
(rebase-first (try! (rebase)))
|
||||
(request-details (try! (get-burn-request-or-fail request-id)))
|
||||
(transfer-vlqstx (try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) (as-contract tx-sender) .token-vlqstx)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-burn-nft request-id)) err-request-finalized-or-revoked))
|
||||
(validation-data (try! (validate-burn-request request-id))))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) (as-contract tx-sender)))
|
||||
(try! (contract-call? .token-lqstx dao-burn (get vaulted-amount validation-data) (as-contract tx-sender)))
|
||||
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get vaulted-amount validation-data), recipient: recipient }))))
|
||||
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))
|
||||
(try! (contract-call? .li-stx-burn-nft burn request-id))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-burn-many (request-ids (list 1000 uint)))
|
||||
(fold check-err (map finalize-burn request-ids) (ok true)))
|
||||
|
||||
;; governance calls
|
||||
|
||||
(define-public (set-use-whitelist (new-use bool))
|
||||
@@ -196,66 +276,12 @@
|
||||
|
||||
;; privileged calls
|
||||
|
||||
(define-public (finalize-mint (request-id uint))
|
||||
(let (
|
||||
(request-details (try! (get-mint-request-or-fail request-id)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-mint-nft request-id)) err-request-finalized-or-revoked)))
|
||||
(try! (validate-mint-request request-id))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(try! (is-dao-or-extension))
|
||||
(try! (contract-call? .token-lqstx dao-mint (get amount request-details) recipient))
|
||||
(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? .li-stx-mint-nft burn request-id))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-mint-many (request-ids (list 1000 uint)))
|
||||
(fold check-err (map finalize-mint request-ids) (ok true)))
|
||||
|
||||
(define-public (request-burn (sender principal) (amount uint))
|
||||
(let (
|
||||
(cycle (get-request-cycle burn-block-height))
|
||||
(vlqstx-amount (contract-call? .token-vlqstx get-tokens-to-shares amount))
|
||||
(request-details { requested-by: sender, amount: amount, wrapped-amount: vlqstx-amount, requested-at: cycle, status: PENDING })
|
||||
(request-id (try! (contract-call? .lqstx-mint-registry set-burn-request u0 request-details))))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(try! (is-dao-or-extension))
|
||||
(try! (contract-call? .token-vlqstx mint amount tx-sender))
|
||||
(try! (contract-call? .token-vlqstx transfer vlqstx-amount tx-sender .lqstx-mint-registry none))
|
||||
(print { type: "burn-request", id: request-id, details: request-details })
|
||||
(if (>= (stx-get-balance .lqstx-vault) amount)
|
||||
(begin
|
||||
(try! (contract-call? .lqstx-mint-registry transfer vlqstx-amount (as-contract tx-sender) .token-vlqstx))
|
||||
(try! (contract-call? .token-vlqstx burn vlqstx-amount (as-contract tx-sender)))
|
||||
(try! (contract-call? .token-lqstx dao-burn amount (as-contract tx-sender)))
|
||||
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: vlqstx-amount, recipient: sender }))))
|
||||
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))
|
||||
(ok {request-id: request-id, status: FINALIZED })
|
||||
)
|
||||
(begin
|
||||
(try! (contract-call? .li-stx-burn-nft mint request-id amount sender))
|
||||
(ok { request-id: request-id, status: PENDING })))))
|
||||
|
||||
(define-public (finalize-burn (request-id uint))
|
||||
(let (
|
||||
(request-details (try! (get-burn-request-or-fail request-id)))
|
||||
(transfer-vlqstx (try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) (as-contract tx-sender) .token-vlqstx)))
|
||||
(recipient (unwrap! (unwrap-panic (get-owner-burn-nft request-id)) err-request-finalized-or-revoked))
|
||||
(validation-data (try! (validate-burn-request request-id))))
|
||||
(try! (is-not-paused-or-fail))
|
||||
(try! (is-dao-or-extension))
|
||||
(try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) (as-contract tx-sender)))
|
||||
(try! (contract-call? .token-lqstx dao-burn (get vaulted-amount validation-data) (as-contract tx-sender)))
|
||||
(try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get vaulted-amount validation-data), recipient: recipient }))))
|
||||
(try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))
|
||||
(try! (contract-call? .li-stx-burn-nft burn request-id))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-burn-many (request-ids (list 1000 uint)))
|
||||
(fold check-err (map finalize-burn request-ids) (ok true)))
|
||||
|
||||
;; private calls
|
||||
|
||||
(define-private (sum-strategy-amounts (strategy <strategy-trait>) (accumulator (response uint uint)))
|
||||
(ok (+ (try! (contract-call? strategy get-amount-in-strategy)) (try! accumulator)))
|
||||
)
|
||||
|
||||
(define-private (check-err (result (response bool uint)) (prior (response bool uint)))
|
||||
(match prior
|
||||
ok-value result
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
;; SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
(define-constant PENDING 0x00)
|
||||
(define-constant FINALIZED 0x01)
|
||||
(define-constant REVOKED 0x02)
|
||||
|
||||
(define-public (rebase)
|
||||
(as-contract (contract-call? .lisa-rebase-v1-02 rebase (list .mock-strategy))))
|
||||
|
||||
(define-public (finalize-mint (request-id uint))
|
||||
(begin
|
||||
(try! (rebase))
|
||||
(as-contract (try! (contract-call? .lqstx-mint-endpoint-v1-02 finalize-mint request-id)))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-burn (request-id uint))
|
||||
(begin
|
||||
(try! (rebase))
|
||||
(as-contract (try! (contract-call? .lqstx-mint-endpoint-v1-02 finalize-burn request-id)))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (request-burn (amount uint))
|
||||
(let (
|
||||
(sender tx-sender)
|
||||
(send-token (try! (contract-call? .token-lqstx transfer amount sender (as-contract tx-sender) none)))
|
||||
(request-data (as-contract (try! (contract-call? .lqstx-mint-endpoint-v1-02 request-burn sender amount)))))
|
||||
(match (finalize-burn (get request-id request-data))
|
||||
ok-value (ok { request-id: (get request-id request-data), status: FINALIZED })
|
||||
err-value (ok request-data))))
|
||||
|
||||
(define-public (callback (extension principal) (payload (buff 2048)))
|
||||
(ok true))
|
||||
@@ -6,17 +6,14 @@
|
||||
(define-public (execute (sender principal))
|
||||
(begin
|
||||
(try! (contract-call? .lisa-dao set-extensions (list
|
||||
{extension: .lqstx-mint-endpoint, enabled: false}
|
||||
{extension: .lqstx-mint-endpoint-v1-02, enabled: true}
|
||||
{extension: .lisa-rebase-v1-02, enabled: true}
|
||||
;; __IF_MAINNET__
|
||||
{extension: .rebase-mock, enabled: true}
|
||||
;; {extension: .rebase-1-v1-02, enabled: true}
|
||||
;; __ENDIF__
|
||||
{extension: .rebase-mock, enabled: true}
|
||||
{extension: .mock-strategy-manager, enabled: true}
|
||||
{extension: .lqstx-vault, enabled: true}
|
||||
{extension: .operators, enabled: true}
|
||||
{ extension: .lqstx-mint-endpoint, enabled: false }
|
||||
{ extension: .lqstx-mint-endpoint-v1-02, enabled: true }
|
||||
{ extension: .lqstx-vault, enabled: true }
|
||||
{ extension: .treasury, enabled: true }
|
||||
{ extension: .token-vesting, enabled: true }
|
||||
{ extension: .public-pools-strategy-manager, enabled: true }
|
||||
{ extension: .operators, enabled: true }
|
||||
{ extension: .mock-strategy-manager, enabled: true }
|
||||
)))
|
||||
|
||||
;; Set initial operators
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
;; SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
|
||||
(define-constant PENDING 0x00)
|
||||
(define-constant FINALIZED 0x01)
|
||||
(define-constant REVOKED 0x02)
|
||||
|
||||
(define-public (rebase)
|
||||
(contract-call? .lisa-rebase-v1-02 rebase (list .public-pools-strategy))
|
||||
)
|
||||
|
||||
(define-public (finalize-mint (request-id uint))
|
||||
(begin
|
||||
(try! (rebase))
|
||||
(as-contract (try! (contract-call? .lqstx-mint-endpoint-v1-02 finalize-mint request-id)))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (finalize-burn (request-id uint))
|
||||
(begin
|
||||
(try! (rebase))
|
||||
(as-contract (try! (contract-call? .lqstx-mint-endpoint-v1-02 finalize-burn request-id)))
|
||||
(try! (rebase))
|
||||
(ok true)))
|
||||
|
||||
(define-public (request-burn (amount uint))
|
||||
(let (
|
||||
(sender tx-sender))
|
||||
(try! (contract-call? .token-lqstx transfer amount sender (as-contract tx-sender) none))
|
||||
(as-contract (contract-call? .lqstx-mint-endpoint-v1-02 request-burn sender amount))))
|
||||
@@ -12,50 +12,28 @@
|
||||
{ extension: .treasury, enabled: true }
|
||||
{ extension: .token-vesting, enabled: true }
|
||||
{ extension: .public-pools-strategy-manager, enabled: true }
|
||||
{ extension: .lisa-rebase-v1-02, enabled: true }
|
||||
{ extension: .rebase-1-v1-02, enabled: true }
|
||||
{ extension: .operators, enabled: true }
|
||||
)))
|
||||
|
||||
;; Set initial operators
|
||||
(try! (contract-call? .operators set-operators (list
|
||||
;; three from ALEX
|
||||
{ operator: 'SP3BQ65DRM8DMTYDD5HWMN60EYC0JFS5NC2V5CWW7, enabled: true }
|
||||
{ operator: 'SPHFAXDZVFHMY8YR3P9J7ZCV6N89SBET203ZAY25, enabled: true }
|
||||
{ operator: 'SPSZ26REB731JN8H00TD010S600F4AB4Z8F0JRB7, enabled: true }
|
||||
;; three from Ryder/FAST Pool
|
||||
{ operator: 'SP12BFYTH3NJ6N63KE0S50GHSYV0M91NGQND2B704, enabled: true }
|
||||
{ operator: 'SP1ZPTDQ3801C1AYEZ37NJWNDZ3HM60HC2TCFP228, enabled: true }
|
||||
{ operator: 'SPGAB1P3YV109E22KXFJYM63GK0G21BYX50CQ80B, enabled: true }
|
||||
{operator: tx-sender, enabled: true}
|
||||
{operator: 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM, enabled: true}
|
||||
{operator: 'ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND, enabled: true}
|
||||
{operator: 'ST2REHHS5J3CERCRBEPMGH7921Q6PYKAADT7JP2VB, enabled: true}
|
||||
)))
|
||||
;; Set operator signal threshold, i.e. 4-of-6
|
||||
(try! (contract-call? .operators set-proposal-threshold 4))
|
||||
|
||||
;; Set initial strategy managers, sender is the deployer
|
||||
(try! (contract-call? .public-pools-strategy-manager set-authorised-manager sender true))
|
||||
(try! (contract-call? .operators set-proposal-threshold 2))
|
||||
|
||||
;; Mint max LISA token supply (1bn)
|
||||
(try! (contract-call? .token-lisa dao-mint-many (list
|
||||
{ recipient: .treasury, amount: u1000000000000000 }
|
||||
)))
|
||||
|
||||
;; Enable whitelist
|
||||
(try! (contract-call? .lqstx-mint-endpoint-v1-02 set-use-whitelist false))
|
||||
(try! (contract-call? .lqstx-mint-endpoint-v1-02 set-whitelisted-many
|
||||
(list
|
||||
'SP3BQ65DRM8DMTYDD5HWMN60EYC0JFS5NC2V5CWW7
|
||||
'SP2VZBR9GCVM33BN0WXA05VJP6QV7CJ3Z3SQKJ5HH
|
||||
'SP12BFYTH3NJ6N63KE0S50GHSYV0M91NGQND2B704
|
||||
'SPGAB1P3YV109E22KXFJYM63GK0G21BYX50CQ80B
|
||||
'SPFJVM9Y1A4KJ31T8ZBDESZH36YGPDAZ9WXEFC53
|
||||
)
|
||||
(list
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
)))
|
||||
;; Set initial strategy managers, sender is the deployer
|
||||
(try! (contract-call? .public-pools-strategy-manager set-authorised-manager sender true))
|
||||
(try! (contract-call? .public-pools-strategy-manager set-authorised-manager 'ST2QXSK64YQX3CQPC530K79XWQ98XFAM9W3XKEH3N true))
|
||||
(try! (contract-call? .public-pools-strategy-manager set-authorised-manager 'ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND true))
|
||||
|
||||
(try! (contract-call? .lqstx-mint-endpoint-v1-02 set-paused false))
|
||||
(ok true)
|
||||
)
|
||||
|
||||
@@ -305,6 +305,11 @@ plan:
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/boot.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: commission-trait
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/traits/commission-trait.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: li-stx-burn-nft
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
@@ -320,16 +325,6 @@ plan:
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/deployed/lisa-rebase.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: lqstx-mint-endpoint-v1-02
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/extensions/lqstx-mint-endpoint.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: lisa-rebase-v1-02
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/extensions/lisa-rebase.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: lisa-transfer-proxy
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
@@ -345,6 +340,11 @@ plan:
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/deployed/lqstx-mint-endpoint.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: lqstx-mint-endpoint-v1-02
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/extensions/lqstx-mint-endpoint.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: lqstx-transfer-proxy
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
@@ -368,21 +368,16 @@ plan:
|
||||
epoch: "2.4"
|
||||
- id: 3
|
||||
transactions:
|
||||
- emulated-contract-publish:
|
||||
contract-name: nft-trait
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/traits/nft-trait.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: rebase-1
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/deployed/rebase-1.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: rebase-1-v1-02
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/rules/rebase-1.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: rebase-mock
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
path: contracts/mocks/rebase-mock.clar
|
||||
clarity-version: 2
|
||||
- emulated-contract-publish:
|
||||
contract-name: rebase-strategy-trait-v1-01
|
||||
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"multisig-analyse": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/analyse-multisig-deployment-plan.ts",
|
||||
"get-keys": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/get-secret-pubkeys.ts",
|
||||
"generate-secret": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/generate-secret.ts",
|
||||
"error-codes": "node --no-warnings=ExperimentalWarning --loader ts-node/esm --import=./scripts/logErrors.js ./scripts/error-codes.ts",
|
||||
"error-codes": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/error-codes.ts",
|
||||
"replace:mainnet": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/replace-mainnet-address.ts",
|
||||
"replace:testnet": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/replace-testnet-address.ts",
|
||||
"setup:clarity": "./scripts/clarinet_manager.sh clean && ./scripts/clarinet_manager.sh install",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
import { initSimnet } from '@hirosystems/clarinet-sdk';
|
||||
import { createErrorsTable } from './lib/error-codes.ts';
|
||||
|
||||
const manifestFile = './Clarinet.toml';
|
||||
const simnet = await initSimnet(manifestFile);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { tx } from '@hirosystems/clarinet-sdk';
|
||||
import { IntegerType } from '@stacks/common';
|
||||
import { BufferCV, Cl, ResponseOkCV, UIntCV } from '@stacks/transactions';
|
||||
import { Cl, ResponseOkCV, UIntCV } from '@stacks/transactions';
|
||||
|
||||
export const createClientMockSetup = () => {
|
||||
const accounts = simnet.getAccounts();
|
||||
@@ -9,6 +9,7 @@ export const createClientMockSetup = () => {
|
||||
const bot = accounts.get('wallet_3')!;
|
||||
const manager = accounts.get('wallet_4')!;
|
||||
const operator3 = accounts.get('wallet_5')!;
|
||||
const user2 = accounts.get('wallet_6')!;
|
||||
|
||||
const contracts = {
|
||||
endpoint: 'lqstx-mint-endpoint-v1-02',
|
||||
@@ -17,14 +18,12 @@ export const createClientMockSetup = () => {
|
||||
lqstx: 'token-lqstx',
|
||||
vlqstx: 'token-vlqstx',
|
||||
wstx: 'token-wstx',
|
||||
strategy: 'mock-strategy',
|
||||
rebase: 'lisa-rebase-v1-02',
|
||||
rebase1: 'rebase-mock',
|
||||
strategy: 'public-pools-strategy',
|
||||
amm: 'amm-swap-pool-v1-1',
|
||||
wlqstx: 'token-wlqstx',
|
||||
dao: 'lisa-dao',
|
||||
boot: 'regtest-boot',
|
||||
manager: 'mock-strategy-manager',
|
||||
boot: 'simnet-boot',
|
||||
manager: 'public-pools-strategy-manager',
|
||||
operators: 'operators',
|
||||
proposal: 'mock-proposal',
|
||||
proposal2: 'mock-proposal',
|
||||
@@ -46,13 +45,13 @@ export const createClientMockSetup = () => {
|
||||
simnet.callPublicFn(contracts.endpoint, 'request-mint', [Cl.uint(amount)], user);
|
||||
|
||||
const requestBurn = (amount: IntegerType) =>
|
||||
simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(amount)], user);
|
||||
|
||||
const createPayload = (amount: IntegerType) =>
|
||||
(
|
||||
simnet.callReadOnlyFn(contracts.strategy, 'create-payload', [Cl.uint(amount)], manager)
|
||||
.result as BufferCV
|
||||
).buffer;
|
||||
simnet.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(amount)], user);
|
||||
|
||||
const fundStrategy = (amount: IntegerType) =>
|
||||
simnet.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(amount)])], manager);
|
||||
|
||||
const finalizeMint = (requestId: IntegerType) =>
|
||||
simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(requestId)], bot);
|
||||
|
||||
const getRewardCycle = () => {
|
||||
return (
|
||||
@@ -97,6 +96,13 @@ export const createClientMockSetup = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const goToNextRequestCycle = () => {
|
||||
const cycle = getRequestCycle();
|
||||
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
|
||||
|
||||
simnet.mineEmptyBlocks(blocksToMine);
|
||||
};
|
||||
|
||||
const goToNextCycle = () => {
|
||||
const cycle = getRewardCycle();
|
||||
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
|
||||
@@ -115,14 +121,17 @@ export const createClientMockSetup = () => {
|
||||
prepareTest,
|
||||
requestMint,
|
||||
requestBurn,
|
||||
createPayload,
|
||||
fundStrategy,
|
||||
finalizeMint,
|
||||
getRewardCycle,
|
||||
getRequestCycle,
|
||||
getBlocksToStartOfCycle,
|
||||
goToNextCycle,
|
||||
goToNextRequestCycle,
|
||||
getRequestCutoff,
|
||||
liSTXBalance,
|
||||
user,
|
||||
user2,
|
||||
oracle,
|
||||
bot,
|
||||
manager,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Cl } from '@stacks/transactions';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createClientMockSetup } from './clients/mock-client';
|
||||
|
||||
const { contracts, prepareTest, requestMint, requestBurn, goToNextCycle, liSTXBalance, user, bot } =
|
||||
const { contracts, prepareTest, requestMint, requestBurn, goToNextCycle, liSTXBalance, goToNextRequestCycle, fundStrategy, user, bot } =
|
||||
createClientMockSetup();
|
||||
|
||||
const mintDelay = 14;
|
||||
@@ -37,9 +37,11 @@ describe('LiSTX NFT', () => {
|
||||
response = transferMintNFT(1, bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
// finalize mint
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(100e6).result).toBeOk(Cl.uint(100e6));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
|
||||
// check that bot received liquid stx
|
||||
expect(liSTXBalance(user)).toBeUint(0);
|
||||
@@ -70,9 +72,11 @@ describe('LiSTX NFT', () => {
|
||||
// request and finalize mint
|
||||
response = requestMint(100e6);
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(1e6).result).toBeOk(Cl.uint(1e6));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
|
||||
// request burn
|
||||
@@ -80,7 +84,7 @@ describe('LiSTX NFT', () => {
|
||||
expect(response.result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('01') })
|
||||
);
|
||||
response = requestBurn(40e6);
|
||||
response = requestBurn(39e6);
|
||||
expect(response.result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(2), status: Cl.bufferFromHex('01') })
|
||||
);
|
||||
@@ -97,6 +101,6 @@ describe('LiSTX NFT', () => {
|
||||
|
||||
// check that bot received stx
|
||||
expect(simnet.getAssetsMap().get('STX')?.get(bot)).toBe(100000000000000n);
|
||||
expect(simnet.getAssetsMap().get('STX')?.get(user)).toBe(100000000000000n);
|
||||
expect(simnet.getAssetsMap().get('STX')?.get(user)).toBe(99999999000000n);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,115 +3,38 @@
|
||||
import { tx } from '@hirosystems/clarinet-sdk';
|
||||
import { Cl, TupleCV, UIntCV } from '@stacks/transactions';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createClientMockSetup } from './clients/mock-client';
|
||||
|
||||
const mintDelay = 432;
|
||||
const accounts = simnet.getAccounts();
|
||||
const user = accounts.get('wallet_1')!;
|
||||
const oracle = accounts.get('wallet_2')!;
|
||||
const bot = accounts.get('wallet_3')!;
|
||||
const manager = accounts.get('deployer')!;
|
||||
const operator = accounts.get('wallet_4')!;
|
||||
const user2 = accounts.get('wallet_5')!;
|
||||
|
||||
const contracts = {
|
||||
endpoint: 'lqstx-mint-endpoint-v1-02',
|
||||
registry: 'lqstx-mint-registry',
|
||||
vault: 'lqstx-vault',
|
||||
lqstx: 'token-lqstx',
|
||||
vlqstx: 'token-vlqstx',
|
||||
wstx: 'token-wstx',
|
||||
strategy: 'public-pools-strategy',
|
||||
rebase: 'lisa-rebase-v1-02',
|
||||
rebase1: 'rebase-1-v1-02',
|
||||
amm: 'amm-swap-pool-v1-1',
|
||||
wlqstx: 'token-wlqstx',
|
||||
dao: 'lisa-dao',
|
||||
boot: 'simnet-boot',
|
||||
manager: 'public-pools-strategy-manager',
|
||||
operators: 'operators',
|
||||
proposal: 'mock-proposal',
|
||||
burnNft: 'li-stx-burn-nft',
|
||||
};
|
||||
|
||||
const prepareTest = () =>
|
||||
simnet.mineBlock([
|
||||
tx.callPublicFn(
|
||||
contracts.dao,
|
||||
'construct',
|
||||
[Cl.contractPrincipal(simnet.deployer, contracts.boot)],
|
||||
simnet.deployer
|
||||
),
|
||||
]);
|
||||
|
||||
const getRewardCycle = () => {
|
||||
return (
|
||||
simnet.callReadOnlyFn(
|
||||
contracts.endpoint,
|
||||
'get-reward-cycle',
|
||||
[Cl.uint(simnet.blockHeight)],
|
||||
user
|
||||
).result as UIntCV
|
||||
).value;
|
||||
};
|
||||
|
||||
const getBlocksToStartOfCycle = (cycle: bigint) => {
|
||||
return (
|
||||
Number(
|
||||
(
|
||||
simnet.callReadOnlyFn(
|
||||
contracts.endpoint,
|
||||
'get-first-burn-block-in-reward-cycle',
|
||||
[Cl.uint(cycle)],
|
||||
user
|
||||
).result as UIntCV
|
||||
).value
|
||||
) - simnet.blockHeight
|
||||
);
|
||||
};
|
||||
const goToNextCycle = () => {
|
||||
const cycle = getRewardCycle();
|
||||
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
|
||||
|
||||
simnet.mineEmptyBlocks(blocksToMine);
|
||||
};
|
||||
const { contracts, user, user2, oracle, bot, manager,
|
||||
prepareTest, goToNextCycle, goToNextRequestCycle,
|
||||
requestMint, requestBurn, fundStrategy, finalizeMint } = createClientMockSetup();
|
||||
|
||||
// 1m STX
|
||||
const mintAmount = 1_000_000e6;
|
||||
|
||||
const requestMint = () =>
|
||||
simnet.callPublicFn(contracts.endpoint, 'request-mint', [Cl.uint(mintAmount)], user);
|
||||
|
||||
// lock mintAmount stx and request burn of 1 stx
|
||||
const requestBurn = () =>
|
||||
simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(mintAmount)])], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(1e6)], user),
|
||||
]);
|
||||
const mintDelay = 432;
|
||||
|
||||
describe(contracts.endpoint, () => {
|
||||
it('can request mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
const response = requestMint();
|
||||
const response = requestMint(mintAmount);
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
});
|
||||
|
||||
it('can finalize mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextCycle();
|
||||
|
||||
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
const finaliseErr = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
|
||||
|
||||
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.bool(true));
|
||||
@@ -121,7 +44,7 @@ describe(contracts.endpoint, () => {
|
||||
it('can revoke mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], bot),
|
||||
@@ -133,7 +56,7 @@ describe(contracts.endpoint, () => {
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
@@ -141,17 +64,15 @@ describe(contracts.endpoint, () => {
|
||||
it('can request burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
|
||||
const responses = requestBurn();
|
||||
expect(responses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[2].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(responses[3].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(responses[4].result).toBeOk(
|
||||
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
|
||||
|
||||
expect(requestBurn(mintAmount).result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
});
|
||||
@@ -159,44 +80,40 @@ describe(contracts.endpoint, () => {
|
||||
it('can finalize burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
|
||||
const burnResponses = requestBurn();
|
||||
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(burnResponses[2].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(burnResponses[3].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(burnResponses[4].result).toBeOk(
|
||||
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
|
||||
|
||||
expect(requestBurn(1e6).result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
|
||||
const responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(1e6));
|
||||
expect(responses[1].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(responses[2].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[3].result).toBeErr(Cl.uint(7007));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[2].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
|
||||
it('can revoke burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
|
||||
const burnResponses = requestBurn();
|
||||
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(burnResponses[2].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(burnResponses[3].result).toBeOk(Cl.uint(mintAmount));
|
||||
expect(burnResponses[4].result).toBeOk(
|
||||
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
|
||||
|
||||
expect(requestBurn(mintAmount).result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
|
||||
@@ -204,7 +121,7 @@ describe(contracts.endpoint, () => {
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(1e6));
|
||||
expect(responses[1].result).toBeErr(Cl.uint(3000));
|
||||
@@ -215,7 +132,7 @@ describe(contracts.endpoint, () => {
|
||||
it('can interact with strategies', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
const cycle = (
|
||||
simnet.callReadOnlyFn(
|
||||
@@ -239,7 +156,7 @@ describe(contracts.endpoint, () => {
|
||||
simnet.mineEmptyBlocks(blocksToMine - 100);
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.list([Cl.uint(mintAmount)])], bot),
|
||||
tx.callPublicFn(
|
||||
contracts.manager,
|
||||
@@ -261,15 +178,14 @@ describe(contracts.endpoint, () => {
|
||||
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
|
||||
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(mintAmount)], user),
|
||||
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(1e6)], user),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(mintAmount)], user),
|
||||
tx.callPublicFn(contracts.endpoint, 'request-burn', [Cl.uint(1e6)], user),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], bot),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[1].result).toBeOk(
|
||||
@@ -280,8 +196,7 @@ describe(contracts.endpoint, () => {
|
||||
expect(responses[4].result).toBeErr(Cl.uint(3000)); // not authorized
|
||||
expect(responses[5].result).toBeOk(Cl.uint(1e6)); // refund 1 stx
|
||||
expect(responses[6].result).toBeOk(Cl.uint(0)); // refund 0 stx
|
||||
expect(responses[7].result).toBeOk(Cl.uint(mintAmount)); // rebase mintAmount stx
|
||||
expect(responses[8].result).toBeErr(Cl.uint(7006)); // request pending
|
||||
expect(responses[7].result).toBeErr(Cl.uint(7006)); // request pending
|
||||
|
||||
// refund remaining stx after unlock
|
||||
goToNextCycle();
|
||||
@@ -289,7 +204,7 @@ describe(contracts.endpoint, () => {
|
||||
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(mintAmount - 1e6));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
@@ -313,12 +228,12 @@ describe(contracts.endpoint, () => {
|
||||
goToNextCycle(); // go to the next cycle
|
||||
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
|
||||
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
|
||||
expect(response.result).toBeOk(Cl.uint(0));
|
||||
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(2)], bot);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(2)], bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
|
||||
response = simnet.callPublicFn(
|
||||
@@ -350,7 +265,7 @@ describe(contracts.endpoint, () => {
|
||||
],
|
||||
manager
|
||||
);
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
|
||||
expect(response.result).toBeOk(Cl.uint(100_000_100e6));
|
||||
|
||||
response = simnet.callReadOnlyFn(
|
||||
@@ -375,7 +290,7 @@ describe(contracts.endpoint, () => {
|
||||
response = simnet.transferSTX(1_000_000e6, `${simnet.deployer}.fastpool-member3`, oracle);
|
||||
response = simnet.transferSTX(1_000_000e6, `${simnet.deployer}.fastpool-member4`, oracle);
|
||||
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'rebase', [], oracle);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'rebase', [], oracle);
|
||||
expect(response.result).toBeOk(Cl.uint(104_000_100e6));
|
||||
|
||||
response = simnet.callReadOnlyFn(
|
||||
@@ -398,17 +313,17 @@ describe(contracts.endpoint, () => {
|
||||
it('can set up amm pool', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextCycle(); // go to the next cycle
|
||||
|
||||
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
const finaliseErr = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
|
||||
|
||||
simnet.mineEmptyBlocks(mintDelay + 1); // mint-delay
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(
|
||||
contracts.amm,
|
||||
'create-pool',
|
||||
@@ -432,15 +347,17 @@ describe(contracts.endpoint, () => {
|
||||
let response;
|
||||
|
||||
// request and finalize mint for 1m STX
|
||||
response = requestMint();
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
expect(requestMint(mintAmount).result).toBeOk(Cl.uint(1));
|
||||
|
||||
// request burn
|
||||
requestBurn();
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(mintAmount).result).toBeOk(Cl.uint(mintAmount));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
expect(finalizeMint(1).result).toBeOk(Cl.bool(true));
|
||||
|
||||
expect(requestBurn(1e6).result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
|
||||
// transfer burn of 1 stx
|
||||
response = simnet.callPublicFn(
|
||||
@@ -456,7 +373,7 @@ describe(contracts.endpoint, () => {
|
||||
);
|
||||
|
||||
simnet.callPublicFn(contracts.manager, 'refund-strategy', [Cl.list([Cl.bool(true)])], manager),
|
||||
(response = simnet.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot));
|
||||
(response = simnet.callPublicFn(contracts.endpoint, 'finalize-burn', [Cl.uint(1)], bot));
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
|
||||
// check that bot received stx
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
import { tx } from '@hirosystems/clarinet-sdk';
|
||||
import { Cl, TupleCV } from '@stacks/transactions';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createClientMockSetup } from './clients/mock-client';
|
||||
|
||||
const {
|
||||
contracts,
|
||||
prepareTest,
|
||||
user,
|
||||
oracle,
|
||||
bot,
|
||||
manager,
|
||||
requestMint: requestMintLib,
|
||||
createPayload,
|
||||
goToNextCycle,
|
||||
getRequestCycle,
|
||||
getRewardCycle,
|
||||
getBlocksToStartOfCycle,
|
||||
} = createClientMockSetup();
|
||||
|
||||
const mintDelay = 144;
|
||||
const requestMint = () => requestMintLib(100e6);
|
||||
|
||||
const requestBurn = (payload: Uint8Array) =>
|
||||
simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user),
|
||||
]);
|
||||
|
||||
describe(contracts.endpoint, () => {
|
||||
it('can request mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
const response = requestMint();
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
});
|
||||
|
||||
it('can finalize mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextCycle();
|
||||
|
||||
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
|
||||
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[1].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
|
||||
it('can revoke mint', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-mint', [Cl.uint(1)], user),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(3000));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay); // mint-delay
|
||||
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
|
||||
it('can request burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
const payload = createPayload(100e6);
|
||||
const responses = requestBurn(payload);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[2].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[3].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[4].result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
});
|
||||
|
||||
it('can finalize burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
const payload = createPayload(100e6);
|
||||
const burnResponses = requestBurn(payload);
|
||||
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(burnResponses[2].result).toBeOk(Cl.uint(100e6));
|
||||
expect(burnResponses[3].result).toBeOk(Cl.uint(100e6));
|
||||
expect(burnResponses[4].result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
|
||||
const responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[1].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[2].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[3].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
|
||||
it('can revoke burn', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
const payload = createPayload(100e6);
|
||||
const burnResponses = requestBurn(payload);
|
||||
expect(burnResponses[0].result).toBeOk(Cl.uint(0));
|
||||
expect(burnResponses[1].result).toBeOk(Cl.bool(true));
|
||||
expect(burnResponses[2].result).toBeOk(Cl.uint(100e6));
|
||||
expect(burnResponses[3].result).toBeOk(Cl.uint(100e6));
|
||||
expect(burnResponses[4].result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
|
||||
const responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.endpoint, 'revoke-burn', [Cl.uint(1)], user),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[1].result).toBeErr(Cl.uint(3000));
|
||||
expect(responses[2].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[3].result).toBeErr(Cl.uint(7007));
|
||||
});
|
||||
|
||||
it('can request burn and finalized immediately', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
let response;
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user);
|
||||
expect(response.result).toBeErr(Cl.uint(1)); // not enough funds
|
||||
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
response = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
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);
|
||||
expect(response.result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.buffer(new Uint8Array([1])) })
|
||||
);
|
||||
// no nft minted
|
||||
expect(simnet.callReadOnlyFn(contracts.burnNft, 'get-last-token-id', [], user).result).toBeOk(
|
||||
Cl.uint(0)
|
||||
);
|
||||
});
|
||||
|
||||
it('can interact with strategies', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
const cycle = getRewardCycle();
|
||||
const blocksToMine = getBlocksToStartOfCycle(cycle + 1n);
|
||||
simnet.mineEmptyBlocks(blocksToMine - 100);
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'fund-strategy', [Cl.uint(100e6)], manager),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(7006));
|
||||
expect(responses[1].result).toBeErr(Cl.uint(1000));
|
||||
expect(responses[2].result).toBeOk(Cl.uint(100e6));
|
||||
|
||||
simnet.mineEmptyBlocks(99); // go to the next cycle
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.rebase1, 'request-burn', [Cl.uint(100e6)], user),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], bot),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
|
||||
tx.callPublicFn(contracts.manager, 'refund-strategy', [Cl.uint(100e6)], manager),
|
||||
tx.callPublicFn(contracts.rebase1, 'rebase', [], oracle),
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-burn', [Cl.uint(1)], bot),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[1].result).toBeOk(
|
||||
Cl.tuple({ 'request-id': Cl.uint(1), status: Cl.bufferFromHex('00') })
|
||||
);
|
||||
expect(responses[2].result).toBeErr(Cl.uint(7006));
|
||||
expect(responses[3].result).toBeErr(Cl.uint(1000));
|
||||
expect(responses[4].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[5].result).toBeErr(Cl.uint(1));
|
||||
expect(responses[6].result).toBeOk(Cl.uint(100e6));
|
||||
expect(responses[7].result).toBeOk(Cl.bool(true));
|
||||
});
|
||||
|
||||
it('can set up amm pool', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(requestMint().result).toBeOk(Cl.uint(1));
|
||||
|
||||
goToNextCycle();
|
||||
|
||||
const finaliseErr = simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(finaliseErr.result).toBeErr(Cl.uint(7006));
|
||||
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot),
|
||||
tx.callPublicFn(
|
||||
contracts.amm,
|
||||
'create-pool',
|
||||
[
|
||||
Cl.principal(simnet.deployer + '.' + contracts.wstx),
|
||||
Cl.principal(simnet.deployer + '.' + contracts.wlqstx),
|
||||
Cl.uint(1e8),
|
||||
Cl.principal(user),
|
||||
Cl.uint(1e8),
|
||||
Cl.uint(1e8),
|
||||
],
|
||||
user
|
||||
),
|
||||
]);
|
||||
expect(responses[0].result).toBeOk(Cl.bool(true));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
});
|
||||
|
||||
it('operator extension works', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
let responses = simnet.mineBlock([
|
||||
tx.callPublicFn(
|
||||
contracts.operators,
|
||||
'propose',
|
||||
[Cl.contractPrincipal(simnet.deployer, contracts.proposal)],
|
||||
bot
|
||||
),
|
||||
tx.callPublicFn(
|
||||
contracts.operators,
|
||||
'propose',
|
||||
[Cl.contractPrincipal(simnet.deployer, contracts.proposal)],
|
||||
simnet.deployer
|
||||
),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(1001));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(false));
|
||||
|
||||
responses = simnet.mineBlock([
|
||||
tx.callPublicFn(
|
||||
contracts.operators,
|
||||
'signal',
|
||||
[Cl.contractPrincipal(simnet.deployer, contracts.proposal), Cl.bool(true)],
|
||||
bot
|
||||
),
|
||||
tx.callPublicFn(
|
||||
contracts.operators,
|
||||
'signal',
|
||||
[Cl.contractPrincipal(simnet.deployer, contracts.proposal), Cl.bool(true)],
|
||||
manager
|
||||
),
|
||||
]);
|
||||
expect(responses[0].result).toBeErr(Cl.uint(1001));
|
||||
expect(responses[1].result).toBeOk(Cl.bool(true));
|
||||
});
|
||||
|
||||
it('request cycle respects cutoff', () => {
|
||||
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
|
||||
|
||||
expect(getRequestCycle()).toBe(0n);
|
||||
// cycle length - prepare cycle length - cutoff - blocks for deployment and prepare
|
||||
simnet.mineEmptyBlocks(1050 - 50 - 300 - 6);
|
||||
// we are at the end of request cycle 0
|
||||
expect(simnet.blockHeight).toBe(699);
|
||||
expect(getRequestCycle()).toBe(0n);
|
||||
|
||||
simnet.mineEmptyBlocks(1050); // cycle length
|
||||
// we are at end of request cycle 1
|
||||
expect(simnet.blockHeight).toBe(1749);
|
||||
expect(getRequestCycle()).toBe(1n);
|
||||
|
||||
simnet.mineEmptyBlocks(1);
|
||||
// we are at beginning of request cycle 2
|
||||
// that is 1050 + 1050 - 50 - 100
|
||||
expect(simnet.blockHeight).toBe(1750);
|
||||
expect(getRequestCycle()).toBe(2n);
|
||||
|
||||
const response = requestMint();
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
expect(response.events[0].event).toBe('stx_transfer_event');
|
||||
expect(response.events[1].event).toBe('nft_mint_event');
|
||||
expect(response.events[2].event).toBe('print_event');
|
||||
expect(
|
||||
((response.events[2].data.value as TupleCV).data.details as TupleCV).data['requested-at']
|
||||
).toBeUint(2);
|
||||
});
|
||||
});
|
||||
@@ -2,16 +2,20 @@ import { Cl } from '@stacks/transactions';
|
||||
import { beforeEach, describe, expect } from 'vitest';
|
||||
import { createClientMockSetup } from './clients/mock-client';
|
||||
import { sip10Tests } from './clients/sip10-client.ts';
|
||||
const { goToNextCycle, requestMint, prepareTest, contracts, bot } = createClientMockSetup();
|
||||
const { goToNextCycle, goToNextRequestCycle, fundStrategy, requestMint, prepareTest, contracts, bot } = createClientMockSetup();
|
||||
const mintDelay = 14;
|
||||
|
||||
describe('lisa token', () => {
|
||||
beforeEach(() => {
|
||||
prepareTest().map(r => expect(r.result).toBeOk(Cl.bool(true)));
|
||||
requestMint(100e6);
|
||||
let response = requestMint(100e6);
|
||||
expect(response.result).toBeOk(Cl.uint(1));
|
||||
goToNextRequestCycle();
|
||||
expect(fundStrategy(1e6).result).toBeOk(Cl.uint(1e6));
|
||||
goToNextCycle();
|
||||
simnet.mineEmptyBlocks(mintDelay);
|
||||
simnet.callPublicFn(contracts.rebase1, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
simnet.mineEmptyBlocks(mintDelay + 1);
|
||||
response = simnet.callPublicFn(contracts.endpoint, 'finalize-mint', [Cl.uint(1)], bot);
|
||||
expect(response.result).toBeOk(Cl.bool(true));
|
||||
});
|
||||
|
||||
sip10Tests(contracts.lqstx);
|
||||
|
||||
Reference in New Issue
Block a user