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