tests integrated

This commit is contained in:
fiftyeightandeight
2024-03-04 11:07:09 +08:00
parent e77cb9c8b9
commit 1c8fbbe9f2
29 changed files with 3491 additions and 354 deletions

View File

@@ -1,5 +1,5 @@
{
"name": "btc-bridge",
"name": "liquid-stacking-testing",
"dependencies": {
"alex_v1": {
"commit": "dev",

View File

@@ -20,8 +20,8 @@ epoch = 2.4
path = "contracts/boot.clar"
epoch = 2.4
[contracts.vault]
path = "contracts/vault.clar"
[contracts.lqstx-vault]
path = "contracts/extensions/lqstx-vault.clar"
epoch = 2.4
[contracts.treasury]
@@ -148,6 +148,10 @@ epoch = 2.4
path = "contracts/traits/sip-010-trait.clar"
epoch = 2.4
[contracts.rebase-strategy-trait]
path = "contracts/traits/rebase-strategy-trait.clar"
epoch = 2.4
[contracts.sip-010-transferable-trait]
path = "contracts/traits/sip-010-transferable-trait.clar"
epoch = 2.4
@@ -165,21 +169,25 @@ path = "contracts/extensions/lqstx-mint-endpoint.clar"
epoch = 2.4
[contracts.lqstx-mint-registry]
path = "contracts/extensions/lqstx-mint-registry.clar"
path = "contracts/lqstx-mint-registry.clar"
epoch = 2.4
[contracts.token-lqstx]
path = "contracts/token-lqstx.clar"
epoch = 2.4
[contracts.token-wlqstx]
path = "contracts/token-wlqstx.clar"
[contracts.token-vlqstx]
path = "contracts/token-vlqstx.clar"
epoch = 2.4
[contracts.token-lisa]
path = "contracts/token-lisa.clar"
epoch = 2.4
[contracts.token-wlqstx]
path = "contracts/wrapped-tokens/token-wlqstx.clar"
epoch = 2.4
[contracts.lisa-rebase]
path = "contracts/extensions/lisa-rebase.clar"
epoch = 2.4
@@ -192,6 +200,62 @@ epoch = 2.4
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
[contracts.mock-strategy-manager]
path = "contracts/mocks/mock-strategy-manager.clar"
epoch = 2.4
[contracts.regtest-boot]
path = "contracts/regtest-boot.clar"
epoch = 2.4
[contracts.amm-swap-pool-v1-1]
path = "contracts_modules/alex_v1/pool/amm-swap-pool-v1-1.clar"
depends_on = ["trait-ownable", "trait-sip-010", "token-amm-swap-pool-v1-1"]
[contracts.token-amm-swap-pool-v1-1]
path = "contracts_modules/alex_v1/pool-token/token-amm-swap-pool-v1-1.clar"
depends_on = ["trait-ownable", "trait-semi-fungible", "alex-vault-v1-1"]
[contracts.alex-vault-v1-1]
path = "contracts_modules/alex_v1/alex-vault-v1-1.clar"
depends_on = [
"trait-vault",
"trait-sip-010",
"trait-flash-loan-user",
"trait-ownable",
"trait-semi-fungible"
]
[contracts.trait-vault]
path = "contracts_modules/alex_v1/traits/trait-vault.clar"
depends_on = ["trait-sip-010", "trait-flash-loan-user"]
[contracts.trait-ownable]
path = "contracts_modules/alex_v1/traits/trait-ownable.clar"
depends_on = []
[contracts.trait-flash-loan-user]
path = "contracts_modules/alex_v1/traits/trait-flash-loan-user.clar"
depends_on = ["trait-sip-010"]
[contracts.trait-semi-fungible]
path = "contracts_modules/alex_v1/traits/trait-semi-fungible.clar"
depends_on = []
[contracts.token-wstx]
path = "contracts_modules/alex_v1/wrapped-token/token-wstx.clar"
[contracts.trait-sip-010]
path = "contracts_modules/alex_v1/traits/trait-sip-010.clar"
# [repl.analysis]
# passes = ["check_checker"]
# check_checker = { trusted_sender = false, trusted_caller = false, callee_filter = false }

View File

@@ -2,11 +2,9 @@
(define-public (execute (sender principal))
(begin
;; Enable core contracts
(try! (contract-call? .lisa-dao set-extensions (list
{extension: .lqstx-mint-endpoint, enabled: true}
{extension: .lqstx-mint-registry, enabled: true}
{extension: .vault, enabled: true}
{extension: .lqstx-vault, enabled: true}
{extension: .treasury, enabled: true}
{extension: .fastpool-strategy-manager, enabled: true}
{extension: .lisa-rebase, enabled: true}

View File

@@ -14,14 +14,14 @@
(define-public (fund-strategy (amounts (list 20 uint)))
(begin
(asserts! (is-authorised-manager tx-sender) err-unauthorised)
(contract-call? .vault fund-strategy .fastpool-strategy (unwrap-panic (to-consensus-buff? amounts)))
(contract-call? .lqstx-vault fund-strategy .fastpool-strategy (unwrap-panic (to-consensus-buff? amounts)))
)
)
(define-public (refund-strategy (selection (list 20 bool)))
(begin
(asserts! (is-authorised-manager tx-sender) err-unauthorised)
(contract-call? .vault refund-strategy .fastpool-strategy (unwrap-panic (to-consensus-buff? selection)))
(contract-call? .lqstx-vault refund-strategy .fastpool-strategy (unwrap-panic (to-consensus-buff? selection)))
)
)

View File

@@ -11,9 +11,12 @@
)
(define-public (rebase (strategies (list 20 <strategy-trait>)))
(let ((total-stx (+ (stx-get-balance .vault) (try! (fold sum-strategy-amounts strategies (ok u0))))))
(let ((total-stx (- (+ (stx-get-balance .lqstx-vault) (try! (fold sum-strategy-amounts strategies (ok u0)))) (contract-call? .lqstx-mint-endpoint get-mint-requests-pending-amount))))
(try! (is-dao-or-extension))
(try! (contract-call? .token-lqstx set-reward-multiplier-from-balance total-stx))
(as-contract (try! (contract-call? .token-lqstx set-reserve total-stx)))
(ok total-stx)
)
)
(define-public (callback (extension principal) (payload (buff 2048)))
(ok true))

View File

@@ -1,7 +1,8 @@
;;
;; lqstx-mint-endpoint
;;
(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)
(use-trait rebase-strategy-trait .rebase-strategy-trait.rebase-strategy-trait)
(define-constant err-unauthorised (err u1000))
(define-constant err-paused (err u1001))
@@ -12,7 +13,14 @@
(define-constant FINALIZED 0x01)
(define-constant REVOKED 0x02)
(define-constant max-uint u340282366920938463463374607431768211455)
(define-data-var paused bool true)
(define-data-var mint-delay uint u144) ;; mint available 1 day after cycle starts
;; @dev test only
(define-data-var activation-block uint u0)
(define-data-var reward-cycle-length uint u2016) ;; 2 weeks
;; read-only calls
@@ -31,90 +39,175 @@
(define-read-only (get-burn-request-or-fail (request-id uint))
(contract-call? .lqstx-mint-registry get-burn-request-or-fail request-id))
(define-read-only (get-rewards-paid-upto)
(contract-call? .lqstx-mint-registry get-rewards-paid-upto))
(define-read-only (get-mint-requests-pending-or-default (user principal))
(contract-call? .lqstx-mint-registry get-mint-requests-pending-or-default user))
(define-read-only (get-burn-requests-pending-or-default (user principal))
(contract-call? .lqstx-mint-registry get-burn-requests-pending-or-default user))
(define-read-only (get-mint-requests-pending-amount)
(contract-call? .lqstx-mint-registry get-mint-requests-pending-amount))
(define-read-only (get-mint-request-or-fail-many (request-ids (list 1000 uint)))
(ok (map get-mint-request-or-fail request-ids)))
(define-read-only (get-burn-request-or-fail-many (request-ids (list 1000 uint)))
(ok (map get-burn-request-or-fail request-ids)))
(define-read-only (validate-mint-request (request-id uint))
(let (
(request-details (try! (contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id))))
(asserts! (>= (get-rewards-paid-upto) (get requested-at request-details)) err-request-pending)
(asserts! (is-eq PENDING (get status request-details)) err-request-finalized-or-revoked)
(ok true)))
(request-details (try! (contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id)))
(request-id-idx (unwrap! (index-of? (get-mint-requests-pending-or-default (get requested-by request-details)) request-id) err-request-finalized-or-revoked)))
(asserts! (>= block-height (+ (get-first-stacks-block-in-reward-cycle (+ (get requested-at request-details) u1)) (var-get mint-delay))) err-request-pending)
(ok request-id-idx)))
;; @dev it favours smaller amounts as we do not allow partial burn
(define-read-only (validate-burn-request (request-id uint))
(let (
(request-details (try! (contract-call? .lqstx-mint-registry get-burn-request-or-fail request-id)))
(vaulted-amount (unwrap-panic (contract-call? .token-wlqstx get-shares-to-tokens (get amount request-details))))
(balance (stx-account .vault)))
(asserts! (>= (* (get unlocked balance) u100) vaulted-amount) err-request-pending)
(asserts! (is-eq PENDING (get status request-details)) err-request-finalized-or-revoked)
(ok { vaulted-amount: vaulted-amount, balance: balance })))
(request-id-idx (unwrap! (index-of? (get-burn-requests-pending-or-default (get requested-by request-details)) request-id) err-request-finalized-or-revoked))
(vaulted-amount (contract-call? .token-vlqstx get-shares-to-tokens (get wrapped-amount request-details))))
(asserts! (>= (stx-get-balance .lqstx-vault) vaulted-amount) err-request-pending)
(ok { vaulted-amount: vaulted-amount, request-id-idx: request-id-idx })))
;; @dev test only
(define-read-only (get-reward-cycle (stacks-height uint))
;; (contract-call? 'SP000000000000000000002Q6VF78.pox-3 current-pox-reward-cycle))
(if (>= stacks-height (var-get activation-block))
(some (/ (- stacks-height (var-get activation-block)) (var-get reward-cycle-length)))
none))
;; TODO: re-write based on POX
(define-read-only (get-first-stacks-block-in-reward-cycle (reward-cycle uint))
(+ (var-get activation-block) (* (var-get reward-cycle-length) reward-cycle)))
(define-read-only (get-mint-delay)
(var-get mint-delay))
;; governance calls
(define-public (set-paused (new-paused bool))
(begin
(try! (is-dao-or-extension))
(ok (var-set paused new-paused))))
(define-public (set-mint-delay (new-delay uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set mint-delay new-delay))))
;; @dev test only
(define-public (set-reward-cycle-length (new-reward-cycle-length uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set reward-cycle-length new-reward-cycle-length))))
;; public calls
;; @dev the requestor stx is held by the contract until mint can be finalized.
(define-public (request-mint (amount-in-fixed uint))
(define-public (request-mint (amount uint))
(let (
(cycle (contract-call? 'SP000000000000000000002Q6VF78.pox-3 current-pox-reward-cycle))
(request-details { requested-by: tx-sender, amount: amount-in-fixed, requested-at: cycle, status: PENDING })
(sender tx-sender)
(cycle (unwrap-panic (get-reward-cycle block-height)))
(request-details { requested-by: sender, amount: amount, requested-at: cycle, status: PENDING })
(request-id (as-contract (try! (contract-call? .lqstx-mint-registry set-mint-request u0 request-details)))))
(try! (is-paused-or-fail))
(try! (stx-transfer? (/ amount-in-fixed u100) tx-sender .lqstx-mint-registry))
(print { type: "mint-request", id: request-id, details: request-details})
(try! (stx-transfer? amount sender .lqstx-vault))
(as-contract (try! (contract-call? .lqstx-mint-registry set-mint-requests-pending-amount (+ (get-mint-requests-pending-amount) amount))))
(as-contract (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)))))
(print { type: "mint-request", id: request-id, details: request-details })
(ok request-id)))
(define-public (finalize-mint (request-id uint))
(let (
(request-details (try! (get-mint-request-or-fail request-id))))
(request-details (try! (get-mint-request-or-fail request-id)))
(mint-requests (get-mint-requests-pending-or-default (get requested-by request-details)))
(request-id-idx (try! (validate-mint-request request-id))))
(try! (is-paused-or-fail))
(try! (validate-mint-request request-id))
(as-contract (try! (contract-call? .lqstx-mint-registry stx-transfer (/ (get amount request-details) u100) .vault)))
(as-contract (try! (contract-call? .token-lqstx dao-mint-fixed (get amount request-details) (get requested-by request-details))))
(as-contract (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: FINALIZED })))))
(try! (is-dao-or-extension))
(as-contract (try! (contract-call? .token-lqstx dao-mint (get amount request-details) (get requested-by request-details))))
(as-contract (try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: FINALIZED }))))
(as-contract (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? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx))))
(ok true)))
(define-public (finalize-mint-many (request-ids (list 1000 uint)))
(fold check-err (map finalize-mint request-ids) (ok true)))
(define-public (revoke-mint (request-id uint))
(let (
(request-details (try! (get-mint-request-or-fail request-id))))
(request-details (try! (get-mint-request-or-fail request-id)))
(mint-requests (get-mint-requests-pending-or-default (get requested-by request-details)))
(request-id-idx (unwrap! (index-of? mint-requests request-id) err-request-finalized-or-revoked)))
(try! (is-paused-or-fail))
(asserts! (is-eq tx-sender (get requested-by request-details)) err-unauthorised)
(asserts! (is-eq PENDING (get status request-details)) err-request-finalized-or-revoked)
(as-contract (try! (contract-call? .lqstx-mint-registry stx-transfer (/ (get amount request-details) u100) (get requested-by request-details))))
(as-contract (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: REVOKED })))))
(as-contract (try! (contract-call? .lqstx-vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (get amount request-details), recipient: (get requested-by request-details) })))))
(as-contract (try! (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: REVOKED }))))
(as-contract (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? .lqstx-mint-registry set-mint-requests-pending (get requested-by request-details) (pop mint-requests request-id-idx))))
(ok true)))
(define-public (request-burn (amount-in-fixed uint))
(define-public (request-burn (amount uint) (rebase-trait <rebase-strategy-trait>))
(let (
(sender tx-sender)
;; @dev requested-at not used for burn
(cycle (contract-call? 'SP000000000000000000002Q6VF78.pox-3 current-pox-reward-cycle))
(request-details { requested-by: tx-sender, amount: amount-in-fixed, requested-at: cycle, status: PENDING })
(cycle (unwrap-panic (get-reward-cycle 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 (as-contract (try! (contract-call? .lqstx-mint-registry set-burn-request u0 request-details)))))
(try! (is-paused-or-fail))
(try! (contract-call? .token-wlqstx mint-fixed amount-in-fixed tx-sender))
(try! (contract-call? .token-wlqstx transfer-fixed amount-in-fixed tx-sender .lqstx-mint-registry none))
(print { type: "burn-request", id: request-id, details: request-details })
(ok request-id)))
(try! (contract-call? .token-vlqstx mint amount sender))
(try! (contract-call? .token-vlqstx transfer vlqstx-amount sender .lqstx-mint-registry none))
(as-contract (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)))))
(match (contract-call? rebase-trait finalize-burn request-id)
ok-value (ok { request-id: request-id, status: FINALIZED })
err-value (begin (print { type: "burn-request", id: request-id, details: request-details, finalize-err: err-value }) (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-wlqstx (as-contract (try! (contract-call? .lqstx-mint-registry transfer-fixed (get amount request-details) tx-sender .token-wlqstx))))
(transfer-vlqstx (as-contract (try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) tx-sender .token-vlqstx))))
(burn-requests (get-burn-requests-pending-or-default (get requested-by request-details)))
(validation-data (try! (validate-burn-request request-id))))
(try! (is-paused-or-fail))
(try! (contract-call? .token-wlqstx burn-fixed (get amount request-details) tx-sender))
(try! (contract-call? .token-lqstx dao-burn-fixed (get vaulted-amount validation-data) tx-sender))
(as-contract (try! (contract-call? .vault proxy-call .stx-transfer-proxy (unwrap-panic (to-consensus-buff? { ustx: (/ (get vaulted-amount validation-data) u100), recipient: (get requested-by request-details) })))))
(as-contract (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED })))))
(try! (is-dao-or-extension))
(as-contract (try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) tx-sender)))
(as-contract (try! (contract-call? .token-lqstx dao-burn (get vaulted-amount validation-data) tx-sender)))
(as-contract (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) })))))
(as-contract (try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: FINALIZED }))))
(as-contract (try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests (get request-id-idx validation-data)))))
(ok true)))
(define-public (finalize-burn-many (request-ids (list 1000 uint)))
(fold check-err (map finalize-burn request-ids) (ok true)))
(define-public (revoke-burn (request-id uint))
(let (
(request-details (try! (get-burn-request-or-fail request-id))))
(request-details (try! (get-burn-request-or-fail request-id)))
(burn-requests (get-burn-requests-pending-or-default (get requested-by request-details)))
(request-id-idx (unwrap! (index-of? burn-requests request-id) err-request-finalized-or-revoked))
(lqstx-amount (contract-call? .token-vlqstx get-shares-to-tokens (get wrapped-amount request-details))))
(try! (is-paused-or-fail))
(asserts! (is-eq PENDING (get status request-details)) err-request-finalized-or-revoked)
(asserts! (is-eq tx-sender (get requested-by request-details)) err-unauthorised)
(try! (contract-call? .token-wlqstx burn-fixed (get amount request-details) tx-sender))
(as-contract (contract-call? .token-lqstx transfer-fixed (unwrap-panic (contract-call? .token-wlqstx get-shares-to-tokens (get amount request-details))) tx-sender (get requested-by request-details) none))))
(as-contract (try! (contract-call? .lqstx-mint-registry transfer (get wrapped-amount request-details) tx-sender .token-vlqstx)))
(as-contract (try! (contract-call? .token-vlqstx burn (get wrapped-amount request-details) tx-sender)))
(as-contract (try! (contract-call? .token-lqstx transfer lqstx-amount tx-sender (get requested-by request-details) none)))
(as-contract (try! (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: REVOKED }))))
(as-contract (try! (contract-call? .lqstx-mint-registry set-burn-requests-pending (get requested-by request-details) (pop burn-requests request-id-idx))))
(ok true)))
(define-public (callback (extension principal) (payload (buff 2048)))
(ok true))
(define-private (check-err (result (response bool uint)) (prior (response bool uint)))
(match prior
ok-value result
err-value (err err-value)))
(define-private (pop (target (list 1000 uint)) (idx uint))
(match (slice? target (+ idx u1) (len target))
some-value (unwrap-panic (as-max-len? (concat (unwrap-panic (slice? target u0 idx)) some-value) u1000))
(unwrap-panic (slice? target u0 idx))))

View File

@@ -6,20 +6,21 @@
(define-constant err-unauthorised (err u1000))
(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))
)
(ok (asserts! (or (is-eq tx-sender .lisa-dao) (contract-call? .lisa-dao is-extension contract-caller)) err-unauthorised)))
;; privileged calls
(define-public (fund-strategy (strategy <strategy-trait>) (payload (buff 2048)))
(let ((amount-taken (try! (as-contract (contract-call? strategy execute payload)))))
(begin
(try! (is-dao-or-extension))
(ok amount-taken)
(as-contract (contract-call? strategy execute payload))
)
)
(define-public (refund-strategy (strategy <strategy-trait>) (payload (buff 2048)))
(let ((amount-refunded (try! (as-contract (contract-call? strategy refund payload)))))
(begin
(try! (is-dao-or-extension))
(ok amount-refunded)
(as-contract (contract-call? strategy refund payload))
)
)
@@ -29,3 +30,6 @@
(as-contract (contract-call? proxy proxy-call payload))
)
)
(define-public (callback (extension principal) (payload (buff 2048)))
(ok true))

View File

@@ -2,8 +2,7 @@
;; lqstx-mint-registry
;;
(use-trait sip-010-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-010-extensions-trait .sip-010-extensions-trait.sip-010-extensions-trait)
(use-trait sip-010-trait .sip-010-trait.sip-010-trait)
(define-constant err-unauthorised (err u1000))
(define-constant err-unknown-request-id (err u1008))
@@ -12,26 +11,22 @@
(define-constant FINALIZED 0x01)
(define-constant REVOKED 0x02)
(define-data-var rewards-paid-upto uint u0)
(define-data-var mint-request-nonce uint u0)
(define-data-var burn-request-nonce uint u0)
(define-map mint-requests uint { requested-by: principal, amount: uint, requested-at: uint, status: (buff 1) })
(define-map burn-requests uint { requested-by: principal, amount: uint, requested-at: uint, status: (buff 1) })
(define-map burn-requests uint { requested-by: principal, amount: uint, wrapped-amount: uint, requested-at: uint, status: (buff 1) })
(define-map mint-requests-pending principal (list 1000 uint))
(define-map burn-requests-pending principal (list 1000 uint))
(define-data-var mint-requests-pending-amount uint u0)
;; read-only calls
(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-read-only (get-pending) PENDING)
(define-read-only (get-finalized) FINALIZED)
(define-read-only (get-revoked) REVOKED)
(define-read-only (get-rewards-paid-upto)
(var-get rewards-paid-upto))
(define-read-only (get-mint-request-nonce)
(var-get mint-request-nonce))
@@ -44,39 +39,56 @@
(define-read-only (get-burn-request-or-fail (request-id uint))
(ok (unwrap! (map-get? burn-requests request-id) err-unknown-request-id)))
;; governance calls
(define-read-only (get-mint-requests-pending-or-default (user principal))
(default-to (list ) (map-get? mint-requests-pending user)))
;; @dev this should be called after all strategies paid rewards for the relevant cycle
(define-public (set-rewards-paid-upto (cycle uint) (vault-balance uint))
(begin
(try! (is-dao-or-extension))
(try! (contract-call? .token-lqstx set-reward-multiplier vault-balance))
(ok (var-set rewards-paid-upto cycle))))
(define-read-only (get-burn-requests-pending-or-default (user principal))
(default-to (list ) (map-get? burn-requests-pending user)))
(define-read-only (get-mint-requests-pending-amount)
(var-get mint-requests-pending-amount))
;; governance calls
(define-public (set-mint-request (request-id uint) (details { requested-by: principal, amount: uint, requested-at: uint, status: (buff 1) }))
(let
(
(current-nonce (var-get mint-request-nonce))
(id (if (is-some (map-get? mint-requests request-id)) request-id (begin (var-set mint-request-nonce (+ current-nonce u1)) current-nonce)))
(next-nonce (+ (var-get mint-request-nonce) u1))
(id (if (is-some (map-get? mint-requests request-id)) request-id (begin (var-set mint-request-nonce next-nonce) next-nonce)))
)
(try! (is-dao-or-extension))
(map-set mint-requests id details)
(ok id)))
(define-public (set-burn-request (request-id uint) (details { requested-by: principal, amount: uint, requested-at: uint, status: (buff 1) }))
(define-public (set-burn-request (request-id uint) (details { requested-by: principal, amount: uint, wrapped-amount: uint, requested-at: uint, status: (buff 1) }))
(let
(
(current-nonce (var-get burn-request-nonce))
(id (if (is-some (map-get? burn-requests request-id)) request-id (begin (var-set burn-request-nonce (+ current-nonce u1)) current-nonce)))
(next-nonce (+ (var-get burn-request-nonce) u1))
(id (if (is-some (map-get? burn-requests request-id)) request-id (begin (var-set burn-request-nonce next-nonce) next-nonce)))
)
(try! (is-dao-or-extension))
(map-set burn-requests id details)
(ok id)))
(define-public (transfer-fixed (amount uint) (recipient principal) (token-trait <sip-010-extensions-trait>))
(define-public (set-mint-requests-pending (requested-by principal) (new-list (list 1000 uint)))
(begin
(try! (is-dao-or-extension))
(as-contract (contract-call? token-trait transfer-fixed amount tx-sender recipient none))))
(ok (map-set mint-requests-pending requested-by new-list))))
(define-public (set-burn-requests-pending (requested-by principal) (new-list (list 1000 uint)))
(begin
(try! (is-dao-or-extension))
(ok (map-set burn-requests-pending requested-by new-list))))
(define-public (set-mint-requests-pending-amount (new-amount uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set mint-requests-pending-amount new-amount))))
(define-public (transfer (amount uint) (recipient principal) (token-trait <sip-010-trait>))
(begin
(try! (is-dao-or-extension))
(as-contract (contract-call? token-trait transfer amount tx-sender recipient none))))
(define-public (stx-transfer (amount uint) (recipient principal))
(begin

View File

@@ -0,0 +1,39 @@
(impl-trait .extension-trait.extension-trait)
(define-constant err-unauthorised (err u1000))
(define-map authorised-managers principal bool)
(map-set authorised-managers tx-sender true)
(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-read-only (is-authorised-manager (who principal))
(default-to false (map-get? authorised-managers who))
)
(define-public (fund-strategy (amount uint))
(begin
(asserts! (is-authorised-manager tx-sender) err-unauthorised)
(as-contract (contract-call? .lqstx-vault fund-strategy .mock-strategy (contract-call? .mock-strategy create-payload amount)))
)
)
(define-public (refund-strategy (amount uint))
(begin
(asserts! (is-authorised-manager tx-sender) err-unauthorised)
(as-contract (contract-call? .lqstx-vault refund-strategy .mock-strategy (contract-call? .mock-strategy create-payload amount)))
)
)
(define-public (set-authorised-manager (who principal) (enabled bool))
(begin
(try! (is-dao-or-extension))
(ok (map-set authorised-managers who enabled))
)
)
(define-public (callback (sender principal) (memo (buff 2048)))
(ok true)
)

View File

@@ -0,0 +1,29 @@
(impl-trait .strategy-trait.strategy-trait)
(define-constant err-unauthorised (err u1000))
(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-read-only (create-payload (amount uint))
(unwrap-panic (to-consensus-buff? amount)))
;; governance calls
(define-public (execute (payload (buff 2048)))
(let (
(amount (unwrap-panic (from-consensus-buff? uint payload))))
(try! (is-dao-or-extension))
(try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
(ok amount)))
(define-public (refund (payload (buff 2048)))
(let (
(sender tx-sender)
(amount (unwrap-panic (from-consensus-buff? uint payload))))
(try! (is-dao-or-extension))
(as-contract (try! (stx-transfer? amount tx-sender sender)))
(ok amount)))
(define-read-only (get-amount-in-strategy)
(ok (stx-get-balance (as-contract tx-sender))))

View File

@@ -0,0 +1,19 @@
(define-public (rebase)
(as-contract (contract-call? .lisa-rebase rebase (list .mock-strategy))))
(define-public (finalize-mint (request-id uint))
(begin
(try! (rebase))
(as-contract (try! (contract-call? .lqstx-mint-endpoint 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 finalize-burn request-id)))
(try! (rebase))
(ok true)))
(define-public (callback (extension principal) (payload (buff 2048)))
(ok true))

View File

@@ -3,7 +3,7 @@
(define-constant err-invalid-payload (err u4000))
(define-public (proxy-call (payload (buff 2048)))
(let ((decoded (unwrap! (from-consensus-buff? { amount: uint, recipient: principal, memo: (optional (buff 34)) } payload) err-invalid-payload)))
(let ((decoded (unwrap! (from-consensus-buff? { amount: uint, recipient: principal, memo: (optional (buff 2048)) } payload) err-invalid-payload)))
(contract-call? .token-lisa transfer (get amount decoded) tx-sender (get recipient decoded) (get memo decoded))
)
)

View File

@@ -3,7 +3,7 @@
(define-constant err-invalid-payload (err u4000))
(define-public (proxy-call (payload (buff 2048)))
(let ((decoded (unwrap! (from-consensus-buff? { amount: uint, recipient: principal, memo: (optional (buff 34)) } payload) err-invalid-payload)))
(let ((decoded (unwrap! (from-consensus-buff? { amount: uint, recipient: principal, memo: (optional (buff 2048)) } payload) err-invalid-payload)))
(contract-call? .token-lqstx transfer (get amount decoded) tx-sender (get recipient decoded) (get memo decoded))
)
)

View File

@@ -0,0 +1,19 @@
(impl-trait .proposal-trait.proposal-trait)
(define-public (execute (sender principal))
(begin
(try! (contract-call? .lisa-dao set-extensions (list
{extension: .lqstx-mint-endpoint, enabled: true}
{extension: .lisa-rebase, enabled: true}
{extension: .rebase-mock, enabled: true}
{extension: .mock-strategy-manager, enabled: true}
{extension: .lqstx-vault, enabled: true}
)))
(try! (contract-call? .lqstx-mint-endpoint set-paused false))
(try! (contract-call? .lqstx-mint-endpoint set-reward-cycle-length u200))
(try! (contract-call? .lqstx-mint-endpoint set-mint-delay u14))
(try! (contract-call? .mock-strategy-manager set-authorised-manager 'ST2QXSK64YQX3CQPC530K79XWQ98XFAM9W3XKEH3N true))
(try! (contract-call? .mock-strategy-manager set-authorised-manager 'ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND true))
(ok true)
)
)

View File

@@ -19,7 +19,7 @@
)
(define-read-only (is-vault-caller)
(ok (asserts! (is-eq tx-sender .vault) err-not-vault-caller))
(ok (asserts! (is-eq tx-sender .lqstx-vault) err-not-vault-caller))
)
(define-private (process-strategy (amount uint) (member <pool-member>))

View File

@@ -80,7 +80,7 @@
;; sip010-ft-trait
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 2048))))
(begin
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) err-not-token-owner)
(ft-transfer? lisa amount sender recipient)

View File

@@ -1,19 +1,18 @@
;; lqstx
;;
(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(define-constant err-unauthorised (err u3000))
(define-constant ONE_8 u100000000)
(define-fungible-token lqstx)
(define-constant err-unauthorised (err u3000))
(define-constant err-invalid-amount (err u3001))
(define-data-var token-name (string-ascii 32) "lqstx")
(define-data-var token-symbol (string-ascii 10) "lqstx")
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://cdn.alexlab.co/metadata/token-lqstx.json"))
(define-data-var token-decimals uint u8)
(define-data-var token-decimals uint u6)
(define-data-var reward-multiplier uint ONE_8)
(define-data-var reserve uint u0)
;; governance functions
@@ -25,9 +24,7 @@
(define-public (dao-set-symbol (new-symbol (string-ascii 10)))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-symbol new-symbol))
)
)
(ok (var-set token-symbol new-symbol))))
(define-public (dao-set-decimals (new-decimals uint))
(begin
@@ -39,54 +36,38 @@
(try! (is-dao-or-extension))
(ok (var-set token-uri new-uri))))
(define-public (set-reward-multiplier-from-balance (balance uint))
;; privileged calls
(define-public (set-reserve (new-reserve uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set reward-multiplier (/ balance (ft-get-supply lqstx))))
)
)
(ok (var-set reserve new-reserve))))
(define-public (set-reward-multiplier (new-multiplier uint))
(define-public (add-reserve (increment uint))
(set-reserve (+ (var-get reserve) increment)))
(define-public (remove-reserve (decrement uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set reward-multiplier new-multiplier))
)
)
(define-public (add-reward-multiplier (increment uint))
(set-reward-multiplier (+ (var-get reward-multiplier) increment))
)
(asserts! (<= decrement (var-get reserve)) err-invalid-amount)
(set-reserve (- (var-get reserve) decrement))))
(define-public (dao-mint (amount uint) (recipient principal))
(begin
(try! (is-dao-or-extension))
(ft-mint? lqstx (unwrap-panic (get-tokens-to-shares amount)) recipient)))
(define-public (dao-mint-fixed (amount uint) (recipient principal))
(begin
(try! (is-dao-or-extension))
(ft-mint? lqstx (fixed-to-decimals (unwrap-panic (get-tokens-to-shares amount))) recipient)))
(define-public (dao-burn-fixed (amount uint) (sender principal))
(begin
(try! (is-dao-or-extension))
(ft-burn? lqstx (fixed-to-decimals (unwrap-panic (get-tokens-to-shares amount))) sender)))
(ft-mint? lqstx (get-tokens-to-shares amount) recipient)))
(define-public (dao-burn (amount uint) (sender principal))
(begin
(try! (is-dao-or-extension))
(ft-burn? lqstx (unwrap-panic (get-tokens-to-shares amount)) sender)))
(ft-burn? lqstx (get-tokens-to-shares amount) sender)))
(define-public (dao-burn-fixed-many (senders (list 200 {amount: uint, sender: principal})))
(begin
(try! (is-dao-or-extension))
(ok (map dao-burn-fixed-many-iter senders))))
(define-public (burn-many (senders (list 200 {amount: uint, sender: principal})))
(fold check-err (map dao-burn-many-iter senders) (ok true)))
;; read-only functions
(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))
)
(ok (asserts! (or (is-eq tx-sender .lisa-dao) (contract-call? .lisa-dao is-extension contract-caller)) err-unauthorised)))
(define-read-only (get-name)
(ok (var-get token-name)))
@@ -94,69 +75,52 @@
(define-read-only (get-symbol)
(ok (var-get token-symbol)))
(define-read-only (get-token-uri)
(ok (var-get token-uri)))
(define-read-only (get-decimals)
(ok (var-get token-decimals)))
(define-read-only (get-balance (who principal))
(get-shares-to-tokens (get-shares who)))
(ok (get-shares-to-tokens (unwrap-panic (get-share who)))))
(define-read-only (get-total-supply)
(get-shares-to-tokens (get-total-shares)))
(get-reserve))
(define-read-only (get-token-uri)
(ok (var-get token-uri)))
(define-read-only (get-shares (who principal))
(ft-get-balance lqstx who))
(define-read-only (get-share (who principal))
(ok (ft-get-balance lqstx who)))
(define-read-only (get-total-shares)
(ft-get-supply lqstx))
(ok (ft-get-supply lqstx)))
;; TODO this can be attacked - need to check
(define-read-only (get-tokens-to-shares (amount uint))
(ok (div-down amount (var-get reward-multiplier))))
(if (is-eq (get-reserve) (ok u0))
amount
(/ (* amount (unwrap-panic (get-total-shares))) (unwrap-panic (get-reserve)))))
;; TODO this can be attacked - need to check
(define-read-only (get-shares-to-tokens (shares uint))
(ok (mul-down shares (var-get reward-multiplier))))
(if (is-eq (get-total-shares) (ok u0))
shares
(/ (* shares (unwrap-panic (get-reserve))) (unwrap-panic (get-total-shares)))))
(define-read-only (get-reward-multiplier)
(ok (var-get reward-multiplier)))
(define-read-only (get-total-supply-fixed)
(ok (decimals-to-fixed (unwrap-panic (get-total-supply)))))
(define-read-only (get-balance-fixed (account principal))
(ok (decimals-to-fixed (unwrap-panic (get-balance account)))))
(define-read-only (get-reserve)
(ok (var-get reserve)))
;; public calls
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(transfer-fixed (decimals-to-fixed amount) sender recipient memo))
(define-public (transfer-fixed (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 2048))))
(begin
(asserts! (or (is-eq sender contract-caller) (is-eq sender tx-sender)) err-unauthorised)
(try! (ft-transfer? lqstx (fixed-to-decimals (unwrap-panic (get-tokens-to-shares amount))) sender recipient))
(asserts! (is-eq sender tx-sender) err-unauthorised)
(try! (ft-transfer? lqstx (get-tokens-to-shares amount) sender recipient))
(match memo to-print (print to-print) 0x)
(ok true)))
;; private functions
(define-private (dao-burn-fixed-many-iter (item {amount: uint, sender: principal}))
(dao-burn-fixed (get amount item) (get sender item)))
(define-private (dao-burn-many-iter (item {amount: uint, sender: principal}))
(dao-burn (get amount item) (get sender item)))
(define-private (pow-decimals)
(pow u10 (unwrap-panic (get-decimals))))
(define-private (decimals-to-fixed (amount uint))
(/ (* amount ONE_8) (pow-decimals)))
(define-private (fixed-to-decimals (amount uint))
(/ (* amount (pow-decimals)) ONE_8))
(define-private (mul-down (a uint) (b uint))
(/ (* a b) ONE_8))
(define-private (div-down (a uint) (b uint))
(if (is-eq a u0)
u0
(/ (* a ONE_8) b)))
(define-private (check-err (result (response bool uint)) (prior (response bool uint)))
(match prior ok-value result err-value (err err-value)))

View File

@@ -0,0 +1,97 @@
;; vlqstx
(define-fungible-token vlqstx)
(define-constant err-unauthorised (err u3000))
(define-data-var token-name (string-ascii 32) "vlqstx")
(define-data-var token-symbol (string-ascii 10) "vlqstx")
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://cdn.alexlab.co/metadata/vlqstx.json"))
(define-data-var token-decimals uint u6)
;; governance functions
(define-public (set-name (new-name (string-ascii 32)))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-name new-name))))
(define-public (set-symbol (new-symbol (string-ascii 10)))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-symbol new-symbol))
)
)
(define-public (set-decimals (new-decimals uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-decimals new-decimals))))
(define-public (set-token-uri (new-uri (optional (string-utf8 256))))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-uri new-uri))))
;; public functions
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 2048))))
(begin
(asserts! (is-eq sender tx-sender) err-unauthorised)
(try! (ft-transfer? vlqstx amount sender recipient))
(match memo to-print (print to-print) 0x)
(ok true)))
(define-public (mint (amount uint) (recipient principal))
(begin
(asserts! (is-eq recipient tx-sender) err-unauthorised)
(try! (ft-mint? vlqstx (get-tokens-to-shares amount) recipient))
(contract-call? .token-lqstx transfer amount recipient (as-contract tx-sender) none)))
(define-public (burn (amount uint) (sender principal))
(begin
(asserts! (is-eq sender tx-sender) err-unauthorised)
(as-contract (try! (contract-call? .token-lqstx transfer (get-shares-to-tokens amount) tx-sender sender none)))
(ft-burn? vlqstx amount sender)))
;; read-only functions
(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-read-only (get-name)
(ok (var-get token-name)))
(define-read-only (get-symbol)
(ok (var-get token-symbol)))
(define-read-only (get-token-uri)
(ok (var-get token-uri)))
(define-read-only (get-decimals)
(ok (var-get token-decimals)))
(define-read-only (get-balance (who principal))
(ok (ft-get-balance vlqstx who)))
(define-read-only (get-total-supply)
(ok (ft-get-supply vlqstx)))
(define-read-only (get-share (who principal))
(ok (get-shares-to-tokens (unwrap-panic (get-balance who)))))
(define-read-only (get-total-shares)
(contract-call? .token-lqstx get-balance (as-contract tx-sender)))
(define-read-only (get-tokens-to-shares (amount uint))
(if (is-eq (get-total-supply) (ok u0))
amount
(/ (* amount (unwrap-panic (get-total-supply))) (unwrap-panic (get-total-shares)))))
(define-read-only (get-shares-to-tokens (shares uint))
(if (is-eq (get-total-supply) (ok u0))
shares
(/ (* shares (unwrap-panic (get-total-shares))) (unwrap-panic (get-total-supply)))))
;; private functions

View File

@@ -1,157 +0,0 @@
;; wlqstx
;;
(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(define-constant err-unauthorised (err u3000))
(define-constant one-8 u100000000)
(define-constant base-token .token-lqstx)
(define-fungible-token wlqstx)
(define-data-var token-name (string-ascii 32) "wlqstx")
(define-data-var token-symbol (string-ascii 10) "wlqstx")
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://cdn.alexlab.co/metadata/wlqstx.json"))
(define-data-var token-decimals uint u8)
;; governance functions
(define-public (set-name (new-name (string-ascii 32)))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-name new-name))))
(define-public (set-symbol (new-symbol (string-ascii 10)))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-symbol new-symbol))
)
)
(define-public (set-decimals (new-decimals uint))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-decimals new-decimals))))
(define-public (set-token-uri (new-uri (optional (string-utf8 256))))
(begin
(try! (is-dao-or-extension))
(ok (var-set token-uri new-uri))))
;; public functions
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(transfer-fixed (decimals-to-fixed amount) sender recipient memo))
(define-public (transfer-fixed (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(begin
(asserts! (is-eq sender tx-sender) err-unauthorised)
(try! (ft-transfer? wlqstx (fixed-to-decimals amount) sender recipient))
(match memo to-print (print to-print) 0x)
(ok true)))
(define-public (mint-fixed (amount uint) (recipient principal))
(let
(
(shares (unwrap-panic (get-tokens-to-shares amount)))
)
(asserts! (is-eq recipient tx-sender) err-unauthorised)
(try! (contract-call? .token-lqstx transfer-fixed amount recipient (as-contract tx-sender) none))
(ft-mint? wlqstx (fixed-to-decimals shares) recipient)))
(define-public (mint (amount uint) (recipient principal))
(mint-fixed (decimals-to-fixed amount) recipient))
(define-public (burn-fixed (amount uint) (sender principal))
(let
(
(vaulted-amount (unwrap-panic (get-shares-to-tokens amount)))
)
(asserts! (is-eq sender tx-sender) err-unauthorised)
(try! (ft-burn? wlqstx (fixed-to-decimals amount) sender))
(as-contract (try! (contract-call? .token-lqstx transfer-fixed vaulted-amount tx-sender sender none)))
(ok true)))
(define-public (burn (amount uint) (sender principal))
(burn-fixed (decimals-to-fixed amount) sender))
;; read-only functions
(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-read-only (get-name)
(ok (var-get token-name)))
(define-read-only (get-symbol)
(ok (var-get token-symbol)))
(define-read-only (get-decimals)
(ok (var-get token-decimals)))
(define-read-only (get-balance (who principal))
(ok (ft-get-balance wlqstx who)))
(define-read-only (get-total-supply)
(ok (ft-get-supply wlqstx)))
(define-read-only (get-total-supply-fixed)
(ok (decimals-to-fixed (unwrap-panic (get-total-supply)))))
(define-read-only (get-balance-fixed (account principal))
(ok (decimals-to-fixed (unwrap-panic (get-balance account)))))
(define-read-only (get-token-uri)
(ok (var-get token-uri)))
(define-read-only (get-vaulted-balance-fixed (who principal))
(get-shares-to-tokens (unwrap-panic (get-balance-fixed who))))
(define-read-only (get-total-vaulted-balance-fixed)
(ok (unwrap-panic (contract-call? .token-lqstx get-balance-fixed (as-contract tx-sender)))))
(define-read-only (get-tokens-to-shares (amount uint))
(let
(
(total-supply (unwrap-panic (get-total-supply-fixed)))
)
(ok (if (is-eq total-supply u0)
amount
(div-down (mul-down amount total-supply) (unwrap-panic (get-total-vaulted-balance-fixed)))
))
)
)
(define-read-only (get-shares-to-tokens (shares uint))
(let
(
(total-supply (unwrap-panic (get-total-supply-fixed)))
)
(ok (if (is-eq total-supply u0)
shares
(div-down (mul-down shares (unwrap-panic (get-total-vaulted-balance-fixed))) total-supply)
))
)
)
(define-read-only (get-reward-multiplier)
(contract-call? .token-lqstx get-reward-multiplier))
;; private functions
(define-private (pow-decimals)
(pow u10 (unwrap-panic (get-decimals))))
(define-private (decimals-to-fixed (amount uint))
(/ (* amount one-8) (pow-decimals)))
(define-private (fixed-to-decimals (amount uint))
(/ (* amount (pow-decimals)) one-8))
(define-private (mul-down (a uint) (b uint))
(/ (* a b) one-8))
(define-private (div-down (a uint) (b uint))
(if (is-eq a u0)
u0
(/ (* a one-8) b)))

View File

@@ -0,0 +1,8 @@
(define-trait rebase-strategy-trait
(
(rebase () (response uint uint))
(finalize-mint (uint) (response bool uint))
(finalize-burn (uint) (response bool uint))
)
)

View File

@@ -4,6 +4,6 @@
(burn (uint principal) (response bool uint))
(mint-fixed (uint principal) (response bool uint))
(burn-fixed (uint principal) (response bool uint))
(transfer-fixed (uint principal principal (optional (buff 34))) (response bool uint))
(transfer-fixed (uint principal principal (optional (buff 2048))) (response bool uint))
)
)

View File

@@ -1,7 +1,7 @@
(define-trait sip-010-trait
(
;; Transfer from the caller to a new principal
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
(transfer (uint principal principal (optional (buff 2048))) (response bool uint))
;; the human readable name of the token
(get-name () (response (string-ascii 32) uint))

View File

@@ -1,5 +1,5 @@
(define-trait sip-010-transferable-trait
(
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
(transfer (uint principal principal (optional (buff 2048))) (response bool uint))
)
)

View File

@@ -1,7 +1,7 @@
(define-trait rebase-sip-010-trait
(
;; Transfer from the caller to a new principal
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
(transfer (uint principal principal (optional (buff 2048))) (response bool uint))
;; the human readable name of the token
(get-name () (response (string-ascii 32) uint))
@@ -22,7 +22,7 @@
(get-token-uri () (response (optional (string-utf8 256)) uint))
;; helper functions for 8-digit fixed notation
(transfer-fixed (uint principal principal (optional (buff 34))) (response bool uint))
(transfer-fixed (uint principal principal (optional (buff 2048))) (response bool uint))
(get-balance-fixed (principal) (response uint uint))
(get-total-supply-fixed () (response uint uint))

View File

@@ -0,0 +1,215 @@
(impl-trait .trait-sip-010.sip-010-trait)
(define-fungible-token wlqstx)
(define-data-var token-name (string-ascii 32) "Wrapped lqSTX")
(define-data-var token-symbol (string-ascii 10) "wlqstx")
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://cdn.alexlab.co/metadata/token-wlqstx.json"))
(define-data-var token-decimals uint u8)
(define-data-var contract-owner principal tx-sender)
;; errors
(define-constant ERR-NOT-AUTHORIZED (err u1000))
(define-constant ERR-MINT-FAILED (err u6002))
(define-constant ERR-BURN-FAILED (err u6003))
(define-constant ERR-TRANSFER-FAILED (err u3000))
(define-constant ERR-NOT-SUPPORTED (err u6004))
(define-read-only (get-contract-owner)
(ok (var-get contract-owner))
)
(define-public (set-contract-owner (owner principal))
(begin
(try! (check-is-owner))
(ok (var-set contract-owner owner))
)
)
(define-private (check-is-owner)
(ok (asserts! (is-eq tx-sender (var-get contract-owner)) ERR-NOT-AUTHORIZED))
)
(define-public (set-name (new-name (string-ascii 32)))
(begin
(try! (check-is-owner))
(ok (var-set token-name new-name))
)
)
(define-public (set-symbol (new-symbol (string-ascii 10)))
(begin
(try! (check-is-owner))
(ok (var-set token-symbol new-symbol))
)
)
(define-public (set-decimals (new-decimals uint))
(begin
(try! (check-is-owner))
(ok (var-set token-decimals new-decimals))
)
)
(define-public (set-token-uri (new-uri (optional (string-utf8 256))))
(begin
(try! (check-is-owner))
(ok (var-set token-uri new-uri))
)
)
;; ---------------------------------------------------------
;; SIP-10 Functions
;; ---------------------------------------------------------
;; @desc get-total-supply
;; @returns (response uint)
(define-read-only (get-total-supply)
;; least authority Issue D
ERR-NOT-SUPPORTED
)
;; @desc get-name
;; @returns (response string-utf8)
(define-read-only (get-name)
(ok (var-get token-name))
)
;; @desc get-symbol
;; @returns (response string-utf8)
(define-read-only (get-symbol)
(ok (var-get token-symbol))
)
;; @desc get-decimals
;; @returns (response uint)
(define-read-only (get-decimals)
(ok (var-get token-decimals))
)
(define-private (get-base-decimals)
(contract-call? .token-lqstx get-decimals))
;; @desc get-balance
;; @params account
;; @returns (response uint)
(define-read-only (get-balance (account principal))
(ok (/ (* (unwrap-panic (contract-call? .token-lqstx get-balance account)) (pow-decimals)) (pow u10 (unwrap-panic (get-base-decimals)))))
)
;; @desc get-token-uri
;; @returns (response some string-utf-8)
(define-read-only (get-token-uri)
(ok (var-get token-uri))
)
;; @desc transfer
;; @restricted sender; tx-sender should be sender
;; @params amount
;; @params sender
;; @params recipient
;; @params memo; expiry
;; @returns (response bool uint)/ error
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 2048))))
(begin
(asserts! (is-eq sender tx-sender) ERR-NOT-AUTHORIZED)
(contract-call? .token-lqstx transfer (/ (* amount (pow u10 (unwrap-panic (get-base-decimals)))) (pow-decimals)) sender recipient memo)
)
)
(define-constant ONE_8 u100000000)
;; @desc pow-decimals
;; @returns uint
(define-private (pow-decimals)
(pow u10 (unwrap-panic (get-decimals)))
)
;; @desc fixed-to-decimals
;; @params amount
;; @returns uint
(define-read-only (fixed-to-decimals (amount uint))
(/ (* amount (pow-decimals)) ONE_8)
)
;; @desc decimals-to-fixed
;; @params amount
;; @returns uint
(define-private (decimals-to-fixed (amount uint))
(/ (* amount ONE_8) (pow-decimals))
)
;; @desc get-total-supply-fixed
;; @params token-id
;; @returns (response uint)
(define-read-only (get-total-supply-fixed)
;; least authority Issue D
ERR-NOT-SUPPORTED
)
;; @desc get-balance-fixed
;; @params token-id
;; @params who
;; @returns (response uint)
(define-read-only (get-balance-fixed (account principal))
(ok (decimals-to-fixed (unwrap-panic (get-balance account))))
)
;; @desc transfer-fixed
;; @params token-id
;; @params amount
;; @params sender
;; @params recipient
;; @returns (response bool)
(define-public (transfer-fixed (amount uint) (sender principal) (recipient principal) (memo (optional (buff 2048))))
(transfer (fixed-to-decimals amount) sender recipient memo)
)
(define-public (mint (amount uint) (recipient principal))
ERR-MINT-FAILED
)
(define-public (burn (amount uint) (sender principal))
ERR-BURN-FAILED
)
(define-public (mint-fixed (amount uint) (recipient principal))
(mint (fixed-to-decimals amount) recipient)
)
;; @desc burn-fixed
;; @params token-id
;; @params amount
;; @params sender
;; @returns (response bool)
(define-public (burn-fixed (amount uint) (sender principal))
(burn (fixed-to-decimals amount) sender)
)
;; @desc check-err
;; @params result
;; @params prior
;; @returns (response bool uint)
(define-private (check-err (result (response bool uint)) (prior (response bool uint)))
(match prior
ok-value result
err-value (err err-value)
)
)
(define-private (transfer-from-tuple (recipient { to: principal, amount: uint }))
(ok (unwrap! (transfer-fixed (get amount recipient) tx-sender (get to recipient) none) ERR-TRANSFER-FAILED))
)
(define-public (send-many (recipients (list 200 { to: principal, amount: uint})))
(fold check-err (map transfer-from-tuple recipients) (ok true))
)
(define-read-only (get-reserve-fixed)
(ok (* (unwrap-panic (contract-call? .token-lqstx get-reserve)) u100)))
;; contract initialisation
(set-contract-owner .executor-dao)

View File

@@ -0,0 +1,371 @@
---
id: 0
name: "Simulated deployment, used as a default for `clarinet console`, `clarinet test` and `clarinet check`"
network: simnet
genesis:
wallets:
- name: deployer
address: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
balance: "100000000000000"
- name: faucet
address: STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6
balance: "100000000000000"
- name: wallet_1
address: ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5
balance: "100000000000000"
- name: wallet_2
address: ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG
balance: "100000000000000"
- name: wallet_3
address: ST2JHG361ZXG51QTKY2NQCVBPPRRE2KZB1HR05NNC
balance: "100000000000000"
- name: wallet_4
address: ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND
balance: "100000000000000"
- name: wallet_5
address: ST2REHHS5J3CERCRBEPMGH7921Q6PYKAADT7JP2VB
balance: "100000000000000"
- name: wallet_6
address: ST3AM1A56AK2C1XAFJ4115ZSV26EB49BVQ10MGCS0
balance: "100000000000000"
- name: wallet_7
address: ST3PF13W7Z0RRM42A8VZRVFQ75SV1K26RXEP8YGKJ
balance: "100000000000000"
- name: wallet_8
address: ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP
balance: "100000000000000"
contracts:
- costs
- pox
- pox-2
- pox-3
- pox-4
- lockup
- costs-2
- costs-3
- cost-voting
- bns
plan:
batches:
- id: 0
transactions:
- emulated-contract-publish:
contract-name: sip-010-trait-ft-standard
emulated-sender: SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE
path: /Users/chanahn/githome/liquid-stacking/./.cache/requirements/SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: trait-sip-010
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/traits/trait-sip-010.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: trait-flash-loan-user
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/traits/trait-flash-loan-user.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: trait-semi-fungible
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/traits/trait-semi-fungible.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: alex-vault-v1-1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/alex-vault-v1-1.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: trait-ownable
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/traits/trait-ownable.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: token-amm-swap-pool-v1-1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/pool-token/token-amm-swap-pool-v1-1.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: amm-swap-pool-v1-1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/pool/amm-swap-pool-v1-1.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: token-wstx
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/wrapped-token/token-wstx.clar
clarity-version: 1
- emulated-contract-publish:
contract-name: trait-vault
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts_modules/alex_v1/traits/trait-vault.clar
clarity-version: 1
epoch: "2.1"
- id: 1
transactions:
- emulated-contract-publish:
contract-name: pox-fast-pool-v2
emulated-sender: SP21YTSM60CAY6D011EZVEVNKXVW8FVZE198XEFFP
path: /Users/chanahn/githome/liquid-stacking/./.cache/requirements/SP21YTSM60CAY6D011EZVEVNKXVW8FVZE198XEFFP.pox-fast-pool-v2.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member10
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member11
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member12
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member13
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member14
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member15
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member16
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member17
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member18
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member19
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member2
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member20
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member3
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member4
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member5
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member6
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member7
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member8
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-member9
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-member.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: strategy-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/strategy-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-strategy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/strategies/fastpool/fastpool-strategy.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: extension-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/extension-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: proposal-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/proposal-trait.clar
clarity-version: 2
epoch: "2.4"
- id: 2
transactions:
- emulated-contract-publish:
contract-name: lisa-dao
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/lisa-dao.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: proxy-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/proxy-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lqstx-vault
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/extensions/lqstx-vault.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: fastpool-strategy-manager
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/extensions/fastpool-strategy-manager.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: operators
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/extensions/operators.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: sip-010-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/sip-010-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: token-lisa
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/token-lisa.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: boot
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/boot.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lqstx-mint-registry
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/lqstx-mint-registry.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: rebase-strategy-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/rebase-strategy-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: stx-transfer-proxy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/proxies/stx-transfer-proxy.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: token-lqstx
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/token-lqstx.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: token-vlqstx
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/token-vlqstx.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lqstx-mint-endpoint
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/extensions/lqstx-mint-endpoint.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lisa-rebase
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/extensions/lisa-rebase.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lisa-transfer-proxy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/proxies/lisa-transfer-proxy.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: lqstx-transfer-proxy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/proxies/lqstx-transfer-proxy.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: mock-strategy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/mocks/mock-strategy.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: mock-strategy-manager
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/mocks/mock-strategy-manager.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: rebase-1
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/rules/rebase-1.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: rebase-mock
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/mocks/rebase-mock.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: regtest-boot
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/regtest-boot.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: sip-010-extensions-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/sip-010-extensions-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: sip-010-transferable-trait
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/traits/sip-010-transferable-trait.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: stx-transfer-many-proxy
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/proxies/stx-transfer-many-proxy.clar
clarity-version: 2
epoch: "2.4"
- id: 3
transactions:
- emulated-contract-publish:
contract-name: token-wlqstx
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/wrapped-tokens/token-wlqstx.clar
clarity-version: 2
- emulated-contract-publish:
contract-name: treasury
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
path: /Users/chanahn/githome/liquid-stacking/contracts/treasury.clar
clarity-version: 2
epoch: "2.4"

1893
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,466 @@
import { tx } from '@hirosystems/clarinet-sdk';
import { Cl } from '@stacks/transactions';
import { describe, expect, it } from 'vitest';
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('wallet_4')!;
const contracts = {
endpoint: 'lqstx-mint-endpoint',
registry: 'lqstx-mint-registry',
vault: 'lqstx-vault',
lqstx: 'token-lqstx',
vlqstx: 'token-vlqstx',
wstx: 'token-wstx',
strategy: 'mock-strategy',
rebase: 'lisa-rebase',
rebase1: 'rebase-mock',
amm: 'amm-swap-pool-v1-1',
wlqstx: 'token-wlqstx',
dao: 'lisa-dao',
boot: 'regtest-boot',
manager: 'mock-strategy-manager'
}
const prepareTest = () =>
simnet.mineBlock([
tx.callPublicFn(
contracts.dao,
'construct',
[
Cl.contractPrincipal(simnet.deployer, contracts.boot),
],
simnet.deployer,
),
]);
const requestMint = () =>
simnet.callPublicFn(
contracts.endpoint,
'request-mint',
[Cl.uint(100e6)],
user,
)
const requestBurn = (payload: Buffer) =>
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.endpoint,
'request-burn',
[
Cl.uint(100e6),
Cl.contractPrincipal(simnet.deployer, contracts.rebase1),
],
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));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
const finaliseErr = simnet.callPublicFn(
contracts.rebase1,
'finalize-mint',
[Cl.uint(1)],
bot
);
expect(finaliseErr.result).toBeErr(Cl.uint(1006));
simnet.mineEmptyBlocks(144); // mint-delay
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(1007));
});
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(1000));
expect(responses[1].result).toBeOk(Cl.bool(true));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
simnet.mineEmptyBlocks(144); // mint-delay
responses = simnet.mineBlock([
tx.callPublicFn(
contracts.rebase1,
'finalize-mint',
[Cl.uint(1)],
bot
)
]);
expect(responses[0].result).toBeErr(Cl.uint(1007));
});
it('can request burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
simnet.mineEmptyBlocks(144); // mint-delay
const payload = simnet.callReadOnlyFn(
contracts.strategy,
'create-payload',
[Cl.uint(100e6)],
manager
).result.buffer;
const responses = requestBurn(payload);
expect(responses[0].result).toBeOk(Cl.uint(0));
expect(responses[1].result).toBeOk(Cl.bool(true));
console.log(responses[2].result);
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));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
simnet.mineEmptyBlocks(144); // mint-delay
const payload = simnet.callReadOnlyFn(
contracts.strategy,
'create-payload',
[Cl.uint(100e6)],
manager
).result.buffer;
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(1007));
});
it('can revoke burn', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
simnet.mineEmptyBlocks(144); // mint-delay
const payload = simnet.callReadOnlyFn(
contracts.strategy,
'create-payload',
[Cl.uint(100e6)],
manager
).result.buffer;
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(1000));
expect(responses[2].result).toBeOk(Cl.bool(true));
expect(responses[3].result).toBeErr(Cl.uint(1007));
});
it('can interact with strategies', () => {
prepareTest().map((e: any) => expect(e.result).toBeOk(Cl.bool(true)));
expect(requestMint().result).toBeOk(Cl.uint(1));
const payload = simnet.callReadOnlyFn(
contracts.strategy,
'create-payload',
[Cl.uint(100e6)],
manager
).result.buffer;
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
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(1006));
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(144); // mint-delay
responses = simnet.mineBlock([
tx.callPublicFn(
contracts.rebase1,
'finalize-mint',
[Cl.uint(1)],
bot
),
tx.callPublicFn(
contracts.endpoint,
'request-burn',
[
Cl.uint(100e6),
Cl.contractPrincipal(simnet.deployer, contracts.rebase1),
],
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(1006));
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));
const cycle = simnet.callReadOnlyFn(contracts.endpoint, 'get-reward-cycle', [Cl.uint(simnet.blockHeight)], user).result.value.value;
const blocksToMine = Number(simnet.callReadOnlyFn(contracts.endpoint, 'get-first-stacks-block-in-reward-cycle', [Cl.uint(cycle + 1n)], user).result.value) - simnet.blockHeight;
simnet.mineEmptyBlocks(blocksToMine); // go to the next cycle
const finaliseErr = simnet.callPublicFn(
contracts.rebase1,
'finalize-mint',
[Cl.uint(1)],
bot
);
expect(finaliseErr.result).toBeErr(Cl.uint(1006));
simnet.mineEmptyBlocks(144); // mint-delay
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));
});
});