mirror of
https://github.com/zhigang1992/liquid-stacking.git
synced 2026-01-12 17:23:23 +08:00
Merge pull request #8 from alexgo-io/treasury-token-operators
Add treasury, LISA token, operators extension
This commit is contained in:
@@ -24,6 +24,10 @@ epoch = 2.4
|
||||
path = "contracts/vault.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.treasury]
|
||||
path = "contracts/treasury.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.strategy-trait]
|
||||
path = "contracts/traits/strategy-trait.clar"
|
||||
epoch = 2.4
|
||||
@@ -48,6 +52,14 @@ epoch = 2.4
|
||||
path = "contracts/proxies/stx-transfer-many-proxy.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.lqstx-transfer-proxy]
|
||||
path = "contracts/proxies/lqstx-transfer-proxy.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.lisa-transfer-proxy]
|
||||
path = "contracts/proxies/lisa-transfer-proxy.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.fastpool-strategy]
|
||||
path = "contracts/strategies/fastpool/fastpool-strategy.clar"
|
||||
epoch = 2.4
|
||||
@@ -132,6 +144,14 @@ epoch = 2.4
|
||||
path = "contracts/strategies/fastpool/fastpool-member.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.sip-010-trait]
|
||||
path = "contracts/traits/sip-010-trait.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.sip-010-transferable-trait]
|
||||
path = "contracts/traits/sip-010-transferable-trait.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.sip-010-extensions-trait]
|
||||
path = "contracts/traits/sip-010-extensions-trait.clar"
|
||||
epoch = 2.4
|
||||
@@ -156,6 +176,10 @@ epoch = 2.4
|
||||
path = "contracts/token-wlqstx.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.token-lisa]
|
||||
path = "contracts/token-lisa.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.lisa-rebase]
|
||||
path = "contracts/extensions/lisa-rebase.clar"
|
||||
epoch = 2.4
|
||||
@@ -164,6 +188,10 @@ epoch = 2.4
|
||||
path = "contracts/rules/rebase-1.clar"
|
||||
epoch = 2.4
|
||||
|
||||
[contracts.operators]
|
||||
path = "contracts/extensions/operators.clar"
|
||||
epoch = 2.4
|
||||
|
||||
# [repl.analysis]
|
||||
# passes = ["check_checker"]
|
||||
# check_checker = { trusted_sender = false, trusted_caller = false, callee_filter = false }
|
||||
|
||||
@@ -2,12 +2,33 @@
|
||||
|
||||
(define-public (execute (sender principal))
|
||||
(begin
|
||||
;; Enable core contracts
|
||||
(try! (contract-call? .lisa-dao set-extensions (list
|
||||
{extension: .deposit-stx, enabled: true}
|
||||
{extension: .lqstx-mint-endpoint, enabled: true}
|
||||
{extension: .lqstx-mint-registry, enabled: true}
|
||||
{extension: .vault, enabled: true}
|
||||
{extension: .treasury, enabled: true}
|
||||
{extension: .fastpool-strategy-manager, enabled: true}
|
||||
{extension: .lisa-rebase, enabled: true}
|
||||
{extension: .rebase-1, enabled: true}
|
||||
{extension: .operators, enabled: true}
|
||||
)))
|
||||
|
||||
;; Set initial operators
|
||||
(try! (contract-call? .operators set-operators (list
|
||||
{operator: tx-sender, enabled: true}
|
||||
{operator: 'ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5, enabled: true}
|
||||
{operator: 'ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG, enabled: true}
|
||||
)))
|
||||
;; Set operator signal threshold
|
||||
(try! (contract-call? .operators set-proposal-threshold 2))
|
||||
|
||||
;; Set initial Fastpool strategy managers
|
||||
(try! (contract-call? .fastpool-strategy-manager set-authorised-manager tx-sender true))
|
||||
|
||||
;; Mint initial LISA token supply
|
||||
(try! (contract-call? .token-lisa dao-mint-many (list
|
||||
{recipient: .treasury, amount: u100000000000000}
|
||||
)))
|
||||
(ok true)
|
||||
)
|
||||
|
||||
96
contracts/extensions/operators.clar
Normal file
96
contracts/extensions/operators.clar
Normal file
@@ -0,0 +1,96 @@
|
||||
(use-trait proposal-trait .proposal-trait.proposal-trait)
|
||||
|
||||
(define-constant err-unauthorised (err u1000))
|
||||
(define-constant err-not-operator (err u1001))
|
||||
(define-constant err-already-signalled (err u1002))
|
||||
(define-constant err-proposal-expired (err u1003))
|
||||
(define-constant err-unknown-proposal (err u1004))
|
||||
(define-constant err-reused-proposal (err u1005))
|
||||
|
||||
(define-constant proposal-validity-period u144)
|
||||
|
||||
(define-data-var proposal-threshold int 1)
|
||||
(define-data-var operators-update-height uint block-height)
|
||||
|
||||
(define-map operators principal bool)
|
||||
(define-map proposals principal { proposed-at: uint, signals: int, executed: bool })
|
||||
(define-map proposal-signals { proposal: principal, operator: principal } uint)
|
||||
|
||||
(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-operator)
|
||||
(ok (asserts! (default-to false (map-get? operators tx-sender)) err-not-operator))
|
||||
)
|
||||
|
||||
(define-private (set-operator (entry {operator: principal, enabled: bool}))
|
||||
(map-set operators (get operator entry) (get enabled entry))
|
||||
)
|
||||
|
||||
;; operators
|
||||
|
||||
(define-private (check-validity (proposed-at uint))
|
||||
(and
|
||||
(< block-height (+ proposed-at proposal-validity-period))
|
||||
(< (var-get operators-update-height) proposed-at)
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (signal (proposal <proposal-trait>) (for bool))
|
||||
(let (
|
||||
(proposal-principal (contract-of proposal))
|
||||
(proposal-data (unwrap! (map-get? proposals proposal-principal) err-unknown-proposal))
|
||||
(proposal-height (get proposed-at proposal-data))
|
||||
(signals (+ (get signals proposal-data) (if for 1 -1)))
|
||||
(threshold-met (>= signals (var-get proposal-threshold)))
|
||||
)
|
||||
(try! (is-operator))
|
||||
(asserts! (check-validity proposal-height) err-proposal-expired)
|
||||
(asserts! (<
|
||||
;; operator can signal again on a proposal that was resubmitted
|
||||
(default-to u0 (map-get? proposal-signals { proposal: proposal-principal, operator: tx-sender }))
|
||||
proposal-height)
|
||||
err-already-signalled
|
||||
)
|
||||
(map-set proposal-signals { proposal: proposal-principal, operator: tx-sender } block-height)
|
||||
(map-set proposals proposal-principal (merge proposal-data {signals: signals, executed: threshold-met}))
|
||||
(if threshold-met
|
||||
(contract-call? .lisa-dao execute proposal tx-sender)
|
||||
(ok false)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (propose (proposal <proposal-trait>))
|
||||
(let ((proposal-principal (contract-of proposal)))
|
||||
(try! (is-operator))
|
||||
(asserts! (match (map-get? proposals proposal-principal)
|
||||
;; proposal can be resubmitted if it was not executed and it expired
|
||||
data (not (or (get executed data) (check-validity (get proposed-at data))))
|
||||
true)
|
||||
err-reused-proposal
|
||||
)
|
||||
(map-set proposals proposal-principal { proposed-at: block-height, signals: 0, executed: false })
|
||||
(signal proposal true)
|
||||
)
|
||||
)
|
||||
|
||||
;; DAO
|
||||
|
||||
(define-public (set-operators (entries (list 20 {operator: principal, enabled: bool})))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(var-set operators-update-height block-height)
|
||||
(ok (map set-operator entries))
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (set-proposal-threshold (threshold int))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(asserts! (> threshold 0) err-unauthorised)
|
||||
(var-set operators-update-height block-height)
|
||||
(ok (var-set proposal-threshold threshold))
|
||||
)
|
||||
)
|
||||
9
contracts/proxies/lisa-transfer-proxy.clar
Normal file
9
contracts/proxies/lisa-transfer-proxy.clar
Normal file
@@ -0,0 +1,9 @@
|
||||
(impl-trait .proxy-trait.proxy-trait)
|
||||
|
||||
(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)))
|
||||
(contract-call? .token-lisa transfer (get amount decoded) tx-sender (get recipient decoded) (get memo decoded))
|
||||
)
|
||||
)
|
||||
9
contracts/proxies/lqstx-transfer-proxy.clar
Normal file
9
contracts/proxies/lqstx-transfer-proxy.clar
Normal file
@@ -0,0 +1,9 @@
|
||||
(impl-trait .proxy-trait.proxy-trait)
|
||||
|
||||
(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)))
|
||||
(contract-call? .token-lqstx transfer (get amount decoded) tx-sender (get recipient decoded) (get memo decoded))
|
||||
)
|
||||
)
|
||||
122
contracts/token-lisa.clar
Normal file
122
contracts/token-lisa.clar
Normal file
@@ -0,0 +1,122 @@
|
||||
(impl-trait .sip-010-trait.sip-010-trait)
|
||||
|
||||
(define-constant err-unauthorised (err u3000))
|
||||
(define-constant err-not-token-owner (err u4))
|
||||
|
||||
(define-fungible-token lisa)
|
||||
|
||||
(define-data-var token-name (string-ascii 32) "LISA")
|
||||
(define-data-var token-symbol (string-ascii 10) "LISA")
|
||||
(define-data-var token-uri (optional (string-utf8 256)) none)
|
||||
(define-data-var token-decimals uint u6)
|
||||
|
||||
(define-public (is-dao-or-extension)
|
||||
(ok (asserts! (or (is-eq tx-sender .lisa-dao) (contract-call? .lisa-dao is-extension contract-caller)) err-unauthorised))
|
||||
)
|
||||
|
||||
(define-public (dao-transfer (amount uint) (sender principal) (recipient principal))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(ft-transfer? lisa amount sender recipient)
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (dao-mint (amount uint) (recipient principal))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(ft-mint? lisa amount recipient)
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (dao-burn (amount uint) (owner principal))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(ft-burn? lisa amount owner)
|
||||
)
|
||||
)
|
||||
|
||||
;; Other
|
||||
|
||||
(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))
|
||||
)
|
||||
)
|
||||
|
||||
(define-private (dao-mint-many-iter (item {amount: uint, recipient: principal}))
|
||||
(ft-mint? lisa (get amount item) (get recipient item))
|
||||
)
|
||||
|
||||
(define-public (dao-mint-many (recipients (list 200 {amount: uint, recipient: principal})))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(ok (map dao-mint-many-iter recipients))
|
||||
)
|
||||
)
|
||||
|
||||
;; --- Public functions
|
||||
|
||||
;; sip010-ft-trait
|
||||
|
||||
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
|
||||
(begin
|
||||
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) err-not-token-owner)
|
||||
(ft-transfer? lisa amount sender recipient)
|
||||
)
|
||||
)
|
||||
|
||||
(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 lisa who))
|
||||
)
|
||||
|
||||
(define-read-only (get-total-supply)
|
||||
(ok (ft-get-supply lisa))
|
||||
)
|
||||
|
||||
(define-read-only (get-token-uri)
|
||||
(ok (var-get token-uri))
|
||||
)
|
||||
|
||||
;; governance-token-trait
|
||||
|
||||
(define-read-only (dao-get-balance (who principal))
|
||||
(get-balance who)
|
||||
)
|
||||
|
||||
(define-read-only (dao-has-percentage-balance (who principal) (factor uint))
|
||||
(ok (>= (* (unwrap-panic (get-balance who)) factor) (* (unwrap-panic (get-total-supply)) u1000)))
|
||||
)
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
(define-public (transfer-fixed (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
|
||||
(begin
|
||||
(asserts! (is-eq sender tx-sender) err-unauthorised)
|
||||
(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))
|
||||
(match memo to-print (print to-print) 0x)
|
||||
(ok true)))
|
||||
|
||||
24
contracts/traits/sip-010-trait.clar
Normal file
24
contracts/traits/sip-010-trait.clar
Normal file
@@ -0,0 +1,24 @@
|
||||
(define-trait sip-010-trait
|
||||
(
|
||||
;; Transfer from the caller to a new principal
|
||||
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
|
||||
|
||||
;; the human readable name of the token
|
||||
(get-name () (response (string-ascii 32) uint))
|
||||
|
||||
;; the ticker symbol, or empty if none
|
||||
(get-symbol () (response (string-ascii 32) uint))
|
||||
|
||||
;; the number of decimals used, e.g. 6 would mean 1_000_000 represents 1 token
|
||||
(get-decimals () (response uint uint))
|
||||
|
||||
;; the balance of the passed principal
|
||||
(get-balance (principal) (response uint uint))
|
||||
|
||||
;; the current total supply (which does not need to be a constant)
|
||||
(get-total-supply () (response uint uint))
|
||||
|
||||
;; an optional URI that represents metadata of this token
|
||||
(get-token-uri () (response (optional (string-utf8 256)) uint))
|
||||
)
|
||||
)
|
||||
5
contracts/traits/sip-010-transferable-trait.clar
Normal file
5
contracts/traits/sip-010-transferable-trait.clar
Normal file
@@ -0,0 +1,5 @@
|
||||
(define-trait sip-010-transferable-trait
|
||||
(
|
||||
(transfer (uint principal principal (optional (buff 34))) (response bool uint))
|
||||
)
|
||||
)
|
||||
32
contracts/treasury.clar
Normal file
32
contracts/treasury.clar
Normal file
@@ -0,0 +1,32 @@
|
||||
(use-trait proxy-trait .proxy-trait.proxy-trait)
|
||||
(use-trait sip-010-transferable-trait .sip-010-transferable-trait.sip-010-transferable-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-public (stx-transfer (amount uint) (recipient principal) (memo (optional (buff 34))))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(as-contract (match memo
|
||||
to-print (stx-transfer-memo? amount tx-sender recipient to-print)
|
||||
(stx-transfer? amount tx-sender recipient)
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (sip010-transfer (amount uint) (recipient principal) (memo (optional (buff 34))) (sip010 <sip-010-transferable-trait>))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(contract-call? sip010 transfer amount (as-contract tx-sender) recipient memo)
|
||||
)
|
||||
)
|
||||
|
||||
(define-public (proxy-call (proxy <proxy-trait>) (payload (buff 2048)))
|
||||
(begin
|
||||
(try! (is-dao-or-extension))
|
||||
(as-contract (contract-call? proxy proxy-call payload))
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user