Branch data Line data Source code
1 : : ;; Title: BME006 Treasury
2 : : ;; Synopsis:
3 : : ;; A treasury that can manage STX, SIP009, SIP010, and SIP013 tokens.
4 : : ;; Description:
5 : : ;; An extension contract that is meant to hold tokens on behalf of the
6 : : ;; DAO. It can hold and transfer STX, SIP009, SIP010, and SIP013 tokens.
7 : : ;; They can be deposited by simply transferring them to the contract.
8 : : ;; Any extension or executing proposal can trigger transfers.
9 : : ;; Technically, the ExecutorDAO core can hold and transfer tokens
10 : : ;; directly. The treasury extension merely adds a bit of separation.
11 : :
12 : : (impl-trait 'SP3JP0N1ZXGASRJ0F7QAHWFPGTVK9T2XNXDB908Z.extension-trait.extension-trait)
13 : : (use-trait prediction-market-trait .prediction-market-trait.prediction-market-trait)
14 : : (use-trait ft-velar-token 'SP2AKWJYC7BNY18W1XXKPGP0YVEK63QJG4793Z2D4.sip-010-trait-ft-standard.sip-010-trait)
15 : :
16 : : (define-constant err-unauthorised (err u3000))
17 : : (define-constant err-invalid-amount (err u3001))
18 : :
19 : : (define-constant share-fee-to 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-share-fee-to)
20 : : (define-constant SCALE u1000000)
21 : :
22 : : ;; --- Transferable traits
23 : : (define-data-var slippage-bips uint u500) ;; default 5%
24 : :
25 : 0 : (define-public (set-slippage-bips (bips uint))
26 : 0 : (begin
27 : 0 : (try! (is-dao-or-extension))
28 [ - ][ - - ]: 0 : (asserts! (and (>= bips u1) (<= bips u3000)) err-invalid-amount) ;; 0.01%..30% bounds
29 : 0 : (var-set slippage-bips bips)
30 : 0 : (ok true)
31 : : )
32 : : )
33 : :
34 : : (define-trait sip009-transferable
35 : : (
36 : : (transfer (uint principal principal) (response bool uint))
37 : : )
38 : : )
39 : :
40 : : (define-trait sip010-transferable
41 : : (
42 : : (transfer (uint principal principal (optional (buff 34))) (response bool uint))
43 : : )
44 : : )
45 : :
46 : : (define-trait sip013-transferable
47 : : (
48 : : (transfer (uint uint principal principal) (response bool uint))
49 : : (transfer-memo (uint uint principal principal (buff 34)) (response bool uint))
50 : : )
51 : : )
52 : :
53 : : (define-trait sip013-transferable-many
54 : : (
55 : : (transfer-many ((list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal})) (response bool uint))
56 : : (transfer-many-memo ((list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal, memo: (buff 34)})) (response bool uint))
57 : : )
58 : : )
59 : :
60 : : ;; --- Authorisation check
61 : :
62 : 8 : (define-public (is-dao-or-extension)
63 [ + ][ + + ]: 34 : (ok (asserts! (or (is-eq tx-sender .bigmarket-dao) (contract-call? .bigmarket-dao is-extension contract-caller)) err-unauthorised))
64 : : )
65 : :
66 : : ;; --- Internal DAO functions
67 : :
68 : 0 : (define-public (swap-tokens
69 : : (token0 <ft-velar-token>) (token1 <ft-velar-token>)
70 : : (token-in <ft-velar-token>) (token-out <ft-velar-token>)
71 : : (amount uint)
72 : : )
73 : 0 : (let ((bips (var-get slippage-bips))
74 : 0 : (min-amount-scaled (/ (* (* amount (- u10000 bips)) SCALE) u10000))
75 : 0 : (min-amount (/ min-amount-scaled SCALE))
76 : : )
77 : 0 : (try! (is-dao-or-extension))
78 [ - ]: 0 : (asserts! (> amount u0) err-invalid-amount)
79 [ - ]: 0 : (asserts! (> amount min-amount) err-invalid-amount)
80 : 0 : (try! (as-contract (contract-call? .univ2-router swap-exact-tokens-for-tokens
81 : 0 : u0 token0 token1 token-in token-out share-fee-to amount min-amount)))
82 : 0 : (print {event:"swap-tokens", amount:amount, min-amount:min-amount})
83 : 0 : (ok true)
84 : : )
85 : : )
86 : : ;;entrypoint to pass slippage per trade
87 : 0 : (define-public (swap-tokens-with-slippage
88 : : (token0 <ft-velar-token>) (token1 <ft-velar-token>)
89 : : (token-in <ft-velar-token>) (token-out <ft-velar-token>)
90 : : (amount uint) (slip-bips uint)
91 : : )
92 : 0 : (let (
93 : 0 : (min-amount-scaaled (/ (* (* amount (- u10000 slip-bips)) SCALE) u10000))
94 : 0 : (min-amount (/ min-amount-scaaled SCALE))
95 : : )
96 : 0 : (try! (is-dao-or-extension))
97 [ - ][ - - ]: 0 : (asserts! (and (>= slip-bips u1) (<= slip-bips u3000)) err-invalid-amount)
98 [ - ]: 0 : (asserts! (> amount u0) err-invalid-amount)
99 [ - ]: 0 : (asserts! (> amount min-amount) err-invalid-amount)
100 : 0 : (try! (as-contract (contract-call? .univ2-router swap-exact-tokens-for-tokens
101 : 0 : u0 token0 token1 token-in token-out share-fee-to amount min-amount)))
102 : 0 : (print {event:"swap-tokens", amount:amount, min-amount:min-amount, slip-bips:slip-bips})
103 : 0 : (ok true)
104 : : )
105 : : )
106 : :
107 : :
108 : : ;; STX
109 : 1 : (define-public (stx-transfer (amount uint) (recipient principal) (memo (optional (buff 34))))
110 : 2 : (begin
111 : 2 : (try! (is-dao-or-extension))
112 [ - + ]: 2 : (match memo to-print (print to-print) 0x)
113 : 2 : (as-contract (stx-transfer? amount tx-sender recipient))
114 : : )
115 : : )
116 : :
117 : 0 : (define-public (stx-transfer-many (transfers (list 200 {amount: uint, recipient: principal, memo: (optional (buff 34))})))
118 : 0 : (begin
119 : 0 : (try! (is-dao-or-extension))
120 : 0 : (as-contract (fold stx-transfer-many-iter transfers (ok true)))
121 : : )
122 : : )
123 : :
124 : : ;; SIP009
125 : :
126 : 0 : (define-public (sip009-transfer (token-id uint) (recipient principal) (asset <sip009-transferable>))
127 : 0 : (begin
128 : 0 : (try! (is-dao-or-extension))
129 : 0 : (as-contract (contract-call? asset transfer token-id tx-sender recipient))
130 : : )
131 : : )
132 : :
133 : 0 : (define-public (sip009-transfer-many (data (list 200 {token-id: uint, recipient: principal})) (asset <sip009-transferable>))
134 : 0 : (begin
135 : 0 : (as-contract (fold sip009-transfer-many-iter data asset))
136 : 0 : (ok true)
137 : : )
138 : : )
139 : :
140 : : ;; SIP010
141 : :
142 : 7 : (define-public (sip010-transfer (amount uint) (recipient principal) (memo (optional (buff 34))) (asset <sip010-transferable>))
143 : 32 : (begin
144 : 32 : (try! (is-dao-or-extension))
145 : 31 : (as-contract (contract-call? asset transfer amount tx-sender recipient memo))
146 : : )
147 : : )
148 : :
149 : 0 : (define-public (sip010-transfer-many (data (list 200 {amount: uint, recipient: principal, memo: (optional (buff 34))})) (asset <sip010-transferable>))
150 : 0 : (begin
151 : 0 : (as-contract (fold sip010-transfer-many-iter data asset))
152 : 0 : (ok true)
153 : : )
154 : : )
155 : :
156 : : ;; SIP013
157 : :
158 : 0 : (define-public (sip013-transfer (token-id uint) (amount uint) (recipient principal) (memo (optional (buff 34))) (asset <sip013-transferable>))
159 : 0 : (begin
160 : 0 : (try! (is-dao-or-extension))
161 : 0 : (as-contract (match memo memo-buff
162 [ - ]: 0 : (contract-call? asset transfer-memo token-id amount tx-sender recipient memo-buff)
163 [ - ]: 0 : (contract-call? asset transfer token-id amount tx-sender recipient)
164 : : ))
165 : : )
166 : : )
167 : :
168 : 0 : (define-public (sip013-transfer-many (transfers (list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal})) (asset <sip013-transferable-many>))
169 : 0 : (begin
170 : 0 : (try! (is-dao-or-extension))
171 : 0 : (as-contract (contract-call? asset transfer-many transfers))
172 : : )
173 : : )
174 : :
175 : 0 : (define-public (sip013-transfer-many-memo (transfers (list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal, memo: (buff 34)})) (asset <sip013-transferable-many>))
176 : 0 : (begin
177 : 0 : (try! (is-dao-or-extension))
178 : 0 : (as-contract (contract-call? asset transfer-many-memo transfers))
179 : : )
180 : : )
181 : :
182 : : ;; --- Iterator functions
183 : :
184 : 0 : (define-private (stx-transfer-many-iter (data {amount: uint, recipient: principal, memo: (optional (buff 34))}) (previous-result (response bool uint)))
185 : 0 : (begin
186 : 0 : (try! previous-result)
187 [ - - ]: 0 : (match (get memo data) to-print (print to-print) 0x)
188 : 0 : (stx-transfer? (get amount data) tx-sender (get recipient data))
189 : : )
190 : : )
191 : :
192 : 0 : (define-private (sip009-transfer-many-iter (data {token-id: uint, recipient: principal}) (asset <sip009-transferable>))
193 : 0 : (begin
194 : 0 : (unwrap-panic (contract-call? asset transfer (get token-id data) tx-sender (get recipient data)))
195 : 0 : asset
196 : : )
197 : : )
198 : :
199 : 0 : (define-private (sip010-transfer-many-iter (data {amount: uint, recipient: principal, memo: (optional (buff 34))}) (asset <sip010-transferable>))
200 : 0 : (begin
201 : 0 : (unwrap-panic (contract-call? asset transfer (get amount data) tx-sender (get recipient data) (get memo data)))
202 : 0 : asset
203 : : )
204 : : )
205 : :
206 : : ;; --- Extension callback
207 : :
208 : 0 : (define-public (callback (sender principal) (memo (buff 34)))
209 : 0 : (ok true)
210 : : )
211 : :
212 : 3 : (define-public (claim-for-dao (market <prediction-market-trait>) (market-id uint) (token <ft-velar-token>))
213 : 3 : (begin
214 : 3 : (as-contract
215 : 3 : (contract-call? market claim-winnings market-id token)
216 : : )
217 : : )
218 : : )
|