Branch data Line data Source code
1 : : ;; Title: BME00 Governance Token
2 : : ;; Synopsis:
3 : : ;; This extension defines the governance token of BigMarket DAO.
4 : : ;; Description:
5 : : ;; The governance token is a simple SIP010-compliant fungible token
6 : : ;; with some added functions to make it easier to manage by
7 : : ;; BigMarket DAO proposals and extensions.
8 : : ;; The operations vesting schedule and recipients can be updated (see current-key and
9 : : ;; set-core-team-vesting) up till the first claim. If more recipients are added they
10 : : ;; allocation is proportionally diluted.
11 : :
12 : : (impl-trait .governance-token-trait.governance-token-trait)
13 : : (impl-trait 'SP2AKWJYC7BNY18W1XXKPGP0YVEK63QJG4793Z2D4.sip-010-trait-ft-standard.sip-010-trait)
14 : : (impl-trait 'SP3JP0N1ZXGASRJ0F7QAHWFPGTVK9T2XNXDB908Z.extension-trait.extension-trait)
15 : :
16 : : (define-fungible-token bmg-token u100000000000000) ;; 100M
17 : : (define-fungible-token bmg-token-locked)
18 : :
19 : : (define-constant core-team-max-vesting u1500000000000) ;; 15% of total supply (10,000,000 BIG)
20 : : (define-constant SCALE u1000000)
21 : :
22 : : (define-constant err-unauthorised (err u3000))
23 : : (define-constant err-not-token-owner (err u3001))
24 : : (define-constant err-not-core-team (err u3002))
25 : : (define-constant err-no-vesting-schedule (err u3003))
26 : : (define-constant err-nothing-to-claim (err u3004))
27 : : (define-constant err-core-vesting-limit (err u3005))
28 : : (define-constant err-cliff-not-reached (err u3006))
29 : : (define-constant err-recipients-are-locked (err u3007))
30 : : (define-constant err-transfers-blocked (err u3008))
31 : :
32 : : (define-data-var token-name (string-ascii 32) "BigMarket Governance Token")
33 : : (define-data-var token-symbol (string-ascii 10) "BIG")
34 : : (define-data-var token-uri (optional (string-utf8 256)) none)
35 : : (define-data-var token-decimals uint u6)
36 : : (define-data-var core-team-size uint u0)
37 : :
38 : : (define-data-var token-price uint u100000)
39 : : (define-data-var transfers-active bool false)
40 : :
41 : : (define-map core-team-vesting-tracker principal uint) ;; Tracks vested amount per recipient
42 : :
43 : : ;; ---- Vesting Storage ----
44 : : (define-data-var claim-made bool false)
45 : : (define-data-var current-key uint u0)
46 : : (define-map core-team-vesting {current-key: uint, recipient: principal}
47 : : {total-amount: uint, start-block: uint, duration: uint, claimed: uint}
48 : : )
49 : :
50 : : ;; --- Authorisation check
51 : :
52 : 289 : (define-public (is-dao-or-extension)
53 [ + ][ + + ]: 686 : (ok (asserts! (or (is-eq tx-sender .bigmarket-dao) (contract-call? .bigmarket-dao is-extension contract-caller)) err-unauthorised))
54 : : )
55 : :
56 : : ;; ---- Vesting Methods ----
57 : :
58 : : ;; --- Vesting logic and sale
59 : 0 : (define-public (set-transfers-active (new-transfers-active bool))
60 : 0 : (begin
61 : 0 : (try! (is-dao-or-extension))
62 : 0 : (var-set transfers-active new-transfers-active)
63 : 0 : (ok true)
64 : : )
65 : : )
66 : 0 : (define-read-only (get-transfers-active) (var-get transfers-active))
67 : :
68 : 0 : (define-public (set-token-price (new-token-price uint))
69 : 0 : (begin
70 : 0 : (try! (is-dao-or-extension))
71 : 0 : (var-set token-price new-token-price)
72 : 0 : (ok true)
73 : : )
74 : : )
75 : :
76 : 289 : (define-public (set-core-team-vesting (core-team (list 200 {recipient: principal, start-block: uint, duration: uint})))
77 : 292 : (begin
78 : 292 : (try! (is-dao-or-extension))
79 [ + ]: 291 : (asserts! (not (var-get claim-made)) err-recipients-are-locked)
80 : 290 : (var-set current-key (+ u1 (var-get current-key)))
81 : 290 : (var-set core-team-size (len core-team))
82 : 290 : (as-contract (fold set-core-team-vesting-iter core-team (ok true)))
83 : : )
84 : : )
85 : 289 : (define-private (set-core-team-vesting-iter (item {recipient: principal, start-block: uint, duration: uint}) (previous-result (response bool uint)))
86 : 1448 : (begin
87 : 1448 : (try! previous-result)
88 : 1448 : (let (
89 : 1448 : (amount-scaled (/ (* core-team-max-vesting SCALE) (var-get core-team-size)))
90 : 1448 : (amount (/ amount-scaled SCALE))
91 : : )
92 : 1448 : (map-set core-team-vesting {current-key: (var-get current-key), recipient: (get recipient item)}
93 : 1448 : {total-amount: amount, start-block: (get start-block item), duration: (get duration item), claimed: u0})
94 : 1448 : (map-set core-team-vesting-tracker (get recipient item) amount)
95 : 1448 : (print {event: "set-core-team-vesting", amount: amount, start-block: (get start-block item), duration: (get duration item), current-key: (var-get current-key)})
96 : 1448 : (ok true)
97 : : )
98 : : )
99 : : )
100 : :
101 : 4 : (define-public (core-claim)
102 : 7 : (let
103 : : (
104 : 7 : (vesting (unwrap! (map-get? core-team-vesting {current-key: (var-get current-key), recipient: tx-sender}) err-no-vesting-schedule))
105 : 7 : (current-block burn-block-height)
106 : 7 : (start-block (get start-block vesting))
107 : 7 : (duration (get duration vesting))
108 : 7 : (total-amount (get total-amount vesting))
109 : 7 : (claimed (get claimed vesting))
110 [ + - ]: 7 : (elapsed (if (> current-block start-block) (- current-block start-block) u0))
111 : 7 : (vested-scaled (if (> elapsed duration)
112 [ + ]: 3 : (* total-amount SCALE)
113 [ + ]: 4 : (/ (* (* total-amount elapsed) SCALE) duration)))
114 : 7 : (vested (/ vested-scaled SCALE))
115 : 7 : (claimable (- vested claimed))
116 : 7 : (midpoint (+ start-block (/ duration u2)))
117 : : )
118 : :
119 [ + ]: 7 : (asserts! (> burn-block-height midpoint) err-cliff-not-reached)
120 [ + ]: 6 : (asserts! (> claimable u0) err-nothing-to-claim)
121 : 5 : (try! (as-contract (ft-mint? bmg-token claimable tx-sender)))
122 : :
123 : 5 : (map-set core-team-vesting {current-key: (var-get current-key), recipient: tx-sender}
124 : 5 : (merge vesting {claimed: (+ claimed claimable)}))
125 : 5 : (var-set claim-made true)
126 : 5 : (print {event: "core-claim", claimed: claimed, recipient: tx-sender, claimable: claimable, elapsed: elapsed, vested: vested})
127 : 5 : (ok claimable)
128 : : )
129 : : )
130 : :
131 : 7 : (define-read-only (get-vesting-schedule (who principal))
132 : 14 : (map-get? core-team-vesting {current-key: (var-get current-key), recipient: who})
133 : : )
134 : :
135 : : ;; --- Internal DAO functions
136 : :
137 : : ;; governance-token-trait
138 : :
139 : 0 : (define-public (bmg-transfer (amount uint) (sender principal) (recipient principal))
140 : 0 : (begin
141 : 0 : (try! (is-dao-or-extension))
142 : 0 : (ft-transfer? bmg-token amount sender recipient)
143 : : )
144 : : )
145 : :
146 : 37 : (define-public (bmg-lock (amount uint) (owner principal))
147 : 64 : (begin
148 : 64 : (try! (is-dao-or-extension))
149 : 64 : (try! (ft-burn? bmg-token amount owner))
150 : 63 : (ft-mint? bmg-token-locked amount owner)
151 : : )
152 : : )
153 : :
154 : 0 : (define-public (bmg-unlock (amount uint) (owner principal))
155 : 0 : (begin
156 : 0 : (try! (is-dao-or-extension))
157 : 0 : (try! (ft-burn? bmg-token-locked amount owner))
158 : 0 : (ft-mint? bmg-token amount owner)
159 : : )
160 : : )
161 : :
162 : 3 : (define-public (bmg-mint (amount uint) (recipient principal))
163 : 9 : (begin
164 : 9 : (try! (is-dao-or-extension))
165 : 9 : (ft-mint? bmg-token amount recipient)
166 : : )
167 : : )
168 : :
169 : 1 : (define-public (bmg-burn (amount uint) (owner principal))
170 : 1 : (begin
171 : 1 : (try! (is-dao-or-extension))
172 : 1 : (ft-burn? bmg-token amount owner)
173 : :
174 : : )
175 : : )
176 : :
177 : : ;; Other
178 : :
179 : 0 : (define-public (set-name (new-name (string-ascii 32)))
180 : 0 : (begin
181 : 0 : (try! (is-dao-or-extension))
182 : 0 : (ok (var-set token-name new-name))
183 : : )
184 : : )
185 : :
186 : 0 : (define-public (set-symbol (new-symbol (string-ascii 10)))
187 : 0 : (begin
188 : 0 : (try! (is-dao-or-extension))
189 : 0 : (ok (var-set token-symbol new-symbol))
190 : : )
191 : : )
192 : :
193 : 0 : (define-public (set-decimals (new-decimals uint))
194 : 0 : (begin
195 : 0 : (try! (is-dao-or-extension))
196 : 0 : (ok (var-set token-decimals new-decimals))
197 : : )
198 : : )
199 : :
200 : 0 : (define-public (set-token-uri (new-uri (optional (string-utf8 256))))
201 : 0 : (begin
202 : 0 : (try! (is-dao-or-extension))
203 : 0 : (ok (var-set token-uri new-uri))
204 : : )
205 : : )
206 : :
207 : 289 : (define-private (bmg-mint-many-iter (item {amount: uint, recipient: principal}))
208 : 1445 : (ft-mint? bmg-token (get amount item) (get recipient item))
209 : : )
210 : :
211 : 289 : (define-public (bmg-mint-many (recipients (list 200 {amount: uint, recipient: principal})))
212 : 289 : (begin
213 : 289 : (try! (is-dao-or-extension))
214 : 289 : (ok (map bmg-mint-many-iter recipients))
215 : : )
216 : : )
217 : :
218 : : ;; --- Public functions
219 : :
220 : : ;; sip-010-trait
221 : :
222 : 6 : (define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
223 : 31 : (begin
224 [ - ][ + - ]: 31 : (asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) err-not-token-owner)
225 [ - ][ + + ]: 31 : (asserts! (or (var-get transfers-active) (unwrap! (is-dao-or-extension) err-unauthorised)) err-transfers-blocked)
226 : 31 : (ft-transfer? bmg-token amount sender recipient)
227 : : )
228 : : )
229 : :
230 : 0 : (define-read-only (get-name)
231 : 0 : (ok (var-get token-name))
232 : : )
233 : :
234 : 0 : (define-read-only (get-symbol)
235 : 0 : (ok (var-get token-symbol))
236 : : )
237 : :
238 : 0 : (define-read-only (get-decimals)
239 : 0 : (ok (var-get token-decimals))
240 : : )
241 : :
242 : 1 : (define-read-only (get-balance (who principal))
243 : 1 : (ok (+ (ft-get-balance bmg-token who) (ft-get-balance bmg-token-locked who)))
244 : : )
245 : :
246 : 0 : (define-read-only (get-total-supply)
247 : 0 : (ok (+ (ft-get-supply bmg-token) (ft-get-supply bmg-token-locked)))
248 : : )
249 : :
250 : 0 : (define-read-only (get-token-uri)
251 : 0 : (ok (var-get token-uri))
252 : : )
253 : :
254 : : ;; governance-token-trait
255 : :
256 : 0 : (define-read-only (bmg-get-balance (who principal))
257 : 0 : (get-balance who)
258 : : )
259 : :
260 : 0 : (define-read-only (bmg-has-percentage-balance (who principal) (factor uint))
261 : 0 : (ok (>= (* (unwrap-panic (get-balance who)) factor) (* (unwrap-panic (get-total-supply)) u1000)))
262 : : )
263 : :
264 : 0 : (define-read-only (bmg-get-locked (owner principal))
265 : 0 : (ok (ft-get-balance bmg-token-locked owner))
266 : : )
267 : :
268 : : ;; --- Extension callback
269 : :
270 : 0 : (define-public (callback (sender principal) (memo (buff 34)))
271 : 0 : (ok true)
272 : : )
|