Merge pull request #8 from alexgo-io/treasury-token-operators

Add treasury, LISA token, operators extension
This commit is contained in:
fiftyeightandeight
2024-03-04 10:06:37 +08:00
committed by GitHub
10 changed files with 348 additions and 2 deletions

View File

@@ -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 }

View File

@@ -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)
)

View 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))
)
)

View 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))
)
)

View 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
View 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)))
)

View File

@@ -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)))

View 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))
)
)

View 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
View 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))
)
)