Smart Contract
FiatToken
A.b19436aae4d94622.FiatToken
1import Crypto
2import FungibleToken from 0xf233dcee88fe0abe
3import OnChainMultiSig from 0x220c1b4155f86f2f
4
5pub contract FiatToken: FungibleToken {
6
7 // ------- FiatToken Events -------
8
9 // Admin events
10 pub event AdminCreated(resourceId: UInt64)
11 pub event AdminChanged(address: Address, resourceId: UInt64)
12
13 // Owner events
14 pub event OwnerCreated(resourceId: UInt64)
15 pub event OwnerChanged(address: Address, resourceId: UInt64)
16
17 // MasterMinter events
18 pub event MasterMinterCreated(resourceId: UInt64)
19 pub event MasterMinterChanged(address: Address, resourceId: UInt64)
20
21 // Pauser events
22 pub event Paused()
23 pub event Unpaused()
24 pub event PauserCreated(resourceId: UInt64)
25 pub event PauserChanged(address: Address, resourceId: UInt64)
26
27 // Blocklister events
28 pub event Blocklisted(resourceId: UInt64)
29 pub event Unblocklisted(resourceId: UInt64)
30 pub event BlocklisterCreated(resourceId: UInt64)
31 pub event BlocklisterChanged(address: Address, resourceId: UInt64)
32
33 // FiatToken.Vault events
34 pub event NewVault(resourceId: UInt64)
35 pub event DestroyVault(resourceId: UInt64)
36 pub event FiatTokenWithdrawn(amount: UFix64, from: UInt64)
37 pub event FiatTokenDeposited(amount: UFix64, to: UInt64)
38
39 // Minting events
40 pub event MinterCreated(resourceId: UInt64)
41 pub event MinterControllerCreated(resourceId: UInt64)
42 pub event Mint(minter: UInt64, amount: UFix64)
43 pub event Burn(minter: UInt64, amount: UFix64)
44 pub event MinterConfigured(controller: UInt64, minter: UInt64, allowance: UFix64)
45 pub event MinterRemoved(controller: UInt64, minter: UInt64)
46 pub event ControllerConfigured(controller: UInt64, minter: UInt64)
47 pub event ControllerRemoved(controller: UInt64)
48
49
50 // ------- FungibleToken Events -------
51
52 pub event TokensInitialized(initialSupply: UFix64)
53 pub event TokensWithdrawn(amount: UFix64, from: Address?)
54 pub event TokensDeposited(amount: UFix64, to: Address?)
55
56
57 // ------- FiatToken Paths -------
58
59 pub let VaultStoragePath: StoragePath
60 pub let VaultBalancePubPath: PublicPath
61 pub let VaultUUIDPubPath: PublicPath
62 pub let VaultReceiverPubPath: PublicPath
63
64 pub let BlocklistExecutorStoragePath: StoragePath
65
66 pub let BlocklisterStoragePath: StoragePath
67 pub let BlocklisterCapReceiverPubPath: PublicPath
68 pub let BlocklisterUUIDPubPath: PublicPath
69 pub let BlocklisterPubSigner: PublicPath
70
71 pub let PauseExecutorStoragePath: StoragePath
72
73 pub let PauserStoragePath: StoragePath
74 pub let PauserCapReceiverPubPath: PublicPath
75 pub let PauserUUIDPubPath: PublicPath
76 pub let PauserPubSigner: PublicPath
77
78 pub let AdminExecutorStoragePath: StoragePath
79
80 pub let AdminStoragePath: StoragePath
81 pub let AdminCapReceiverPubPath: PublicPath
82 pub let AdminUUIDPubPath: PublicPath
83 pub let AdminPubSigner: PublicPath
84
85 pub let OwnerExecutorStoragePath: StoragePath
86
87 pub let OwnerStoragePath: StoragePath
88 pub let OwnerCapReceiverPubPath: PublicPath
89 pub let OwnerUUIDPubPath: PublicPath
90 pub let OwnerPubSigner: PublicPath
91
92 pub let MasterMinterExecutorStoragePath: StoragePath
93
94 pub let MasterMinterStoragePath: StoragePath
95 pub let MasterMinterCapReceiverPubPath: PublicPath
96 pub let MasterMinterUUIDPubPath: PublicPath
97 pub let MasterMinterPubSigner: PublicPath
98
99 pub let MinterControllerStoragePath: StoragePath
100 pub let MinterControllerUUIDPubPath: PublicPath
101 pub let MinterControllerPubSigner: PublicPath
102
103 pub let MinterStoragePath: StoragePath
104 pub let MinterUUIDPubPath: PublicPath
105
106
107 // ------- FiatToken States / Variables -------
108
109 pub let name: String
110 pub var version: String
111 // Set to true if the contract is paused
112 pub var paused: Bool
113 // The token total supply
114 pub var totalSupply: UFix64
115 // Blocked resources dictionary {resourceId: Block Height}
116 access(contract) let blocklist: {UInt64: UInt64}
117 // Managed minters dictionary {MinterController: Minter}
118 access(contract) let managedMinters: {UInt64: UInt64}
119 // Minter allowance dictionary {Minter: Allowance}
120 access(contract) let minterAllowances: { UInt64: UFix64}
121
122
123 // ------- FiatToken Interfaces -------
124
125 pub resource interface ResourceId {
126 pub fun UUID(): UInt64
127 }
128
129 pub resource interface AdminCapReceiver {
130 pub fun setAdminCap(cap: Capability<&AdminExecutor>)
131 }
132
133 pub resource interface OwnerCapReceiver {
134 pub fun setOwnerCap(cap: Capability<&OwnerExecutor>)
135 }
136
137 pub resource interface MasterMinterCapReceiver {
138 pub fun setMasterMinterCap(cap: Capability<&MasterMinterExecutor>)
139 }
140
141 pub resource interface BlocklisterCapReceiver {
142 pub fun setBlocklistCap(cap: Capability<&BlocklistExecutor>)
143 }
144
145 pub resource interface PauseCapReceiver {
146 pub fun setPauseCap(cap: Capability<&PauseExecutor>)
147 }
148
149
150 // ------- Path linking -------
151
152 access(contract) fun linkAdminExec(_ newPrivPath: PrivatePath): Capability<&AdminExecutor> {
153 return self.account.link<&AdminExecutor>(newPrivPath, target: FiatToken.AdminExecutorStoragePath)
154 ?? panic("could not create new AdminExecutor capability link")
155 }
156
157 access(contract) fun linkOwnerExec(_ newPrivPath: PrivatePath): Capability<&OwnerExecutor> {
158 return self.account.link<&OwnerExecutor>(newPrivPath, target: FiatToken.OwnerExecutorStoragePath)
159 ?? panic("could not create new OwnerExecutor capability link")
160 }
161
162 access(contract) fun linkMasterMinterExec(_ newPrivPath: PrivatePath): Capability<&MasterMinterExecutor> {
163 return self.account.link<&MasterMinterExecutor>(newPrivPath, target: FiatToken.MasterMinterExecutorStoragePath)
164 ?? panic("could not create new MasterMinterExecutor capability link")
165 }
166
167 access(contract) fun linkBlocklistExec(_ newPrivPath: PrivatePath): Capability<&FiatToken.BlocklistExecutor> {
168 return self.account.link<&BlocklistExecutor>(newPrivPath, target: FiatToken.BlocklistExecutorStoragePath)
169 ?? panic("could not create new BlocklistExecutor capability link")
170 }
171
172 access(contract) fun linkPauserExec(_ newPrivPath: PrivatePath): Capability<&FiatToken.PauseExecutor> {
173 return self.account.link<&FiatToken.PauseExecutor>(newPrivPath, target: FiatToken.PauseExecutorStoragePath)
174 ?? panic("could not create new PauseExecutor capability link")
175 }
176
177 // ------- Path unlinking -------
178
179 access(contract) fun unlinkPriv(_ privPath: PrivatePath) {
180 self.account.unlink(privPath)
181 }
182
183
184 // ------- FiatToken Resources -------
185
186 pub resource Vault:
187 ResourceId,
188 FungibleToken.Provider,
189 FungibleToken.Receiver,
190 FungibleToken.Balance {
191
192 pub var balance: UFix64
193
194 pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
195 pre {
196 !FiatToken.paused: "FiatToken contract paused"
197 FiatToken.blocklist[self.uuid] == nil: "Vault Blocklisted"
198 }
199 self.balance = self.balance - amount
200 emit FiatTokenWithdrawn(amount: amount, from: self.uuid)
201 emit TokensWithdrawn(amount: amount, from: self.owner?.address)
202 return <-create Vault(balance: amount)
203 }
204
205 pub fun deposit(from: @FungibleToken.Vault) {
206 pre {
207 !FiatToken.paused: "FiatToken contract paused"
208 FiatToken.blocklist[from.uuid] == nil: "Receiving Vault Blocklisted"
209 FiatToken.blocklist[self.uuid] == nil: "Vault Blocklisted"
210 }
211 let vault <- from as! @FiatToken.Vault
212 self.balance = self.balance + vault.balance
213 emit FiatTokenDeposited(amount: vault.balance, to: self.uuid)
214 emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
215 vault.balance = 0.0
216 destroy vault
217 }
218
219 pub fun UUID(): UInt64 {
220 return self.uuid
221 }
222
223 access(contract) fun burn() {
224 pre {
225 self.balance > 0.0: "Cannot burn USDC Vault with zero balance"
226 }
227 FiatToken.totalSupply = FiatToken.totalSupply - self.balance
228 self.balance = 0.0
229 }
230
231 destroy() {
232 pre {
233 self.balance == 0.0: "Cannot destroy USDC Vault with non-zero balance"
234 }
235 emit DestroyVault(resourceId: self.uuid)
236 }
237
238 init(balance: UFix64) {
239 self.balance = balance
240 }
241
242 }
243
244 pub resource AdminExecutor {
245
246 access(self) var currentCapPath: PrivatePath?
247
248 pub fun upgradeContract(name: String, code: [UInt8], version: String) {
249 FiatToken.upgradeContract(name: name, code: code, version: version)
250 }
251
252 pub fun changeAdmin(to: Address, newPath: PrivatePath) {
253 let newCap = FiatToken.linkAdminExec(newPath)
254 let receiver = getAccount(to)
255 .getCapability<&Admin{AdminCapReceiver}>(FiatToken.AdminCapReceiverPubPath)
256 .borrow() ?? panic("could not borrow AdminCapReceiver capability")
257 let idRef = getAccount(to)
258 .getCapability<&Admin{ResourceId}>(FiatToken.AdminUUIDPubPath)
259 .borrow() ?? panic("could not borrow Admin ResourceId capability")
260 receiver.setAdminCap(cap: newCap)
261 if self.currentCapPath != nil {
262 FiatToken.unlinkPriv(self.currentCapPath!)
263 }
264 self.currentCapPath = newPath
265 emit AdminChanged(address: to, resourceId: idRef.UUID())
266 }
267
268 init () {
269 self.currentCapPath = nil
270 }
271
272 }
273
274 pub resource Admin: OnChainMultiSig.PublicSigner, ResourceId, AdminCapReceiver {
275
276 access(self) let multiSigManager: @OnChainMultiSig.Manager
277 access(self) var adminExecutorCapability: Capability<&AdminExecutor>?
278
279 pub fun setAdminCap(cap: Capability<&AdminExecutor>) {
280 pre {
281 self.adminExecutorCapability == nil: "Capability has already been set"
282 cap.borrow() != nil: "Invalid capability"
283 }
284 self.adminExecutorCapability = cap
285 }
286
287 // ------- OnChainMultiSig.PublicSigner interfaces -------
288
289 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
290 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <-payload, publicKey: publicKey, sig: sig)
291 }
292
293 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
294 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
295 }
296
297 pub fun executeTx(txIndex: UInt64): @AnyResource? {
298 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
299 switch p.method {
300 case "configureKey":
301 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
302 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
303 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
304 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
305 case "removeKey":
306 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
307 self.multiSigManager.removeKeys(pks: [pubKey])
308 case "removePayload":
309 let txIndex = p.getArg(i: 0)! as? UInt64 ?? panic ("cannot downcast txIndex")
310 let payloadToRemove <- self.multiSigManager.removePayload(txIndex: txIndex)
311 destroy(payloadToRemove)
312 case "upgradeContract":
313 let name = p.getArg(i: 0)! as? String ?? panic ("cannot downcast contract name")
314 let code = p.getArg(i: 1)! as? String ?? panic ("cannot downcast contract code")
315 let version = p.getArg(i: 2)! as? String ?? panic ("cannot downcast contract version")
316 let executor = self.adminExecutorCapability!.borrow() ?? panic("cannot borrow AdminExecutor capability")
317 executor.upgradeContract(name: name, code: code.decodeHex(), version: version)
318 case "changeAdmin":
319 let to = p.getArg(i: 0)! as? Address ?? panic("cannot downcast receiver address")
320 let path = p.getArg(i: 1)! as? PrivatePath ?? panic("cannot downcast new link path")
321 let executor = self.adminExecutorCapability!.borrow() ?? panic("cannot borrow AdminExecutor capability")
322 executor.changeAdmin(to: to, newPath: path)
323 default:
324 panic("Unknown transaction method")
325 }
326 destroy (p)
327 return nil
328 }
329
330 pub fun UUID(): UInt64 {
331 return self.uuid
332 }
333
334 pub fun getTxIndex(): UInt64 {
335 return self.multiSigManager.txIndex
336 }
337
338 pub fun getSignerKeys(): [String] {
339 return self.multiSigManager.getSignerKeys()
340 }
341
342 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
343 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
344 }
345
346 destroy() {
347 destroy self.multiSigManager
348 }
349
350 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
351 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
352 self.adminExecutorCapability = nil
353 }
354
355 }
356
357 pub resource OwnerExecutor {
358
359 access(self) var ownerCapPath: PrivatePath?
360 access(self) var masterMinterCapPath: PrivatePath?
361 access(self) var blocklisterCapPath: PrivatePath?
362 access(self) var pauserCapPath: PrivatePath?
363
364 pub fun reassignOwner(to: Address, newPath: PrivatePath) {
365 let newCap = FiatToken.linkOwnerExec(newPath)
366 let receiver = getAccount(to)
367 .getCapability<&Owner{OwnerCapReceiver}>(FiatToken.OwnerCapReceiverPubPath)
368 .borrow() ?? panic("could not borrow the OwnerCapReceiver capability")
369 let idRef = getAccount(to)
370 .getCapability<&Owner{ResourceId}>(FiatToken.OwnerUUIDPubPath)
371 .borrow() ?? panic("could not borrow the Owner ResourceId capability")
372 receiver.setOwnerCap(cap: newCap)
373 if self.ownerCapPath != nil {
374 FiatToken.unlinkPriv(self.ownerCapPath!)
375 }
376 self.ownerCapPath = newPath
377 emit OwnerChanged(address: to, resourceId: idRef.UUID())
378 }
379
380 pub fun reassignMasterMinter(to: Address, newPath: PrivatePath) {
381 let newCap = FiatToken.linkMasterMinterExec(newPath)
382 let receiver = getAccount(to)
383 .getCapability<&MasterMinter{MasterMinterCapReceiver}>(FiatToken.MasterMinterCapReceiverPubPath)
384 .borrow() ?? panic("could not borrow the MasterMinterCapReceiver capability")
385 let idRef = getAccount(to)
386 .getCapability<&MasterMinter{ResourceId}>(FiatToken.MasterMinterUUIDPubPath)
387 .borrow() ?? panic("could not borrow the MasterMinter ResourceId capability")
388 receiver.setMasterMinterCap(cap: newCap)
389 if self.masterMinterCapPath != nil {
390 FiatToken.unlinkPriv(self.masterMinterCapPath!)
391 }
392 self.masterMinterCapPath = newPath
393 emit MasterMinterChanged(address: to, resourceId: idRef.UUID())
394 }
395
396 pub fun reassignBlocklister(to: Address, newPath: PrivatePath) {
397 let newCap = FiatToken.linkBlocklistExec(newPath)
398 let receiver = getAccount(to)
399 .getCapability<&Blocklister{BlocklisterCapReceiver}>(FiatToken.BlocklisterCapReceiverPubPath)
400 .borrow() ?? panic("could not borrow the BlocklisterCapReceiver capability ")
401 let idRef = getAccount(to)
402 .getCapability<&Blocklister{ResourceId}>(FiatToken.BlocklisterUUIDPubPath)
403 .borrow() ?? panic("could not borrow the Blocklister ResourceId capability")
404 receiver.setBlocklistCap(cap: newCap)
405 if self.blocklisterCapPath != nil {
406 FiatToken.unlinkPriv(self.blocklisterCapPath!)
407 }
408 self.blocklisterCapPath = newPath
409 emit BlocklisterChanged(address: to, resourceId: idRef.UUID())
410 }
411
412 pub fun reassignPauser(to: Address, newPath: PrivatePath) {
413 let newCap = FiatToken.linkPauserExec(newPath)
414 let receiver = getAccount(to)
415 .getCapability<&Pauser{PauseCapReceiver}>(FiatToken.PauserCapReceiverPubPath)
416 .borrow() ?? panic("could not borrow the PauseCapReceiver capability")
417 let idRef = getAccount(to)
418 .getCapability<&Pauser{ResourceId}>(FiatToken.PauserUUIDPubPath)
419 .borrow() ?? panic("could not borrow the Pauser ResourceId capability")
420 receiver.setPauseCap(cap: newCap)
421 if self.pauserCapPath != nil {
422 FiatToken.unlinkPriv(self.pauserCapPath!)
423 }
424 self.pauserCapPath = newPath
425 emit PauserChanged(address: to, resourceId: idRef.UUID())
426 }
427
428 init() {
429 self.ownerCapPath = nil
430 self.masterMinterCapPath = nil
431 self.blocklisterCapPath = nil
432 self.pauserCapPath = nil
433 }
434
435 }
436
437 pub resource Owner: OnChainMultiSig.PublicSigner, ResourceId, OwnerCapReceiver {
438
439 access(self) let multiSigManager: @OnChainMultiSig.Manager
440 access(self) var ownerExecutorCapability: Capability<&OwnerExecutor>?
441
442 pub fun setOwnerCap(cap: Capability<&OwnerExecutor>) {
443 pre {
444 self.ownerExecutorCapability == nil: "Capability has already been set"
445 cap.borrow() != nil: "Invalid capability"
446 }
447 self.ownerExecutorCapability = cap
448 }
449
450 // ------- OnChainMultiSig.PublicSigner interfaces -------
451
452 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
453 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <-payload, publicKey: publicKey, sig: sig)
454 }
455
456 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
457 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
458 }
459
460 pub fun executeTx(txIndex: UInt64): @AnyResource? {
461 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
462 switch p.method {
463 case "configureKey":
464 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
465 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
466 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
467 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
468 case "removeKey":
469 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
470 self.multiSigManager.removeKeys(pks: [pubKey])
471 case "reassignOwner":
472 let to = p.getArg(i: 0)! as? Address ?? panic("cannot downcast receiver address")
473 let path = p.getArg(i: 1)! as? PrivatePath ?? panic("cannot downcast new link path")
474 let executor = self.ownerExecutorCapability!.borrow() ?? panic("cannot borrow OwnerExecutor capability")
475 executor.reassignOwner(to: to, newPath: path)
476 case "reassignMasterMinter":
477 let to = p.getArg(i: 0)! as? Address ?? panic("cannot downcast receiver address")
478 let path = p.getArg(i: 1)! as? PrivatePath ?? panic("cannot downcast new link path")
479 let executor = self.ownerExecutorCapability!.borrow() ?? panic("cannot borrow OwnerExecutor capability")
480 executor.reassignMasterMinter(to: to, newPath: path)
481 case "reassignBlocklister":
482 let to = p.getArg(i: 0)! as? Address ?? panic("cannot downcast receiver address")
483 let path = p.getArg(i: 1)! as? PrivatePath ?? panic("cannot downcast new link path")
484 let executor = self.ownerExecutorCapability!.borrow() ?? panic("cannot borrow OwnerExecutor capability")
485 executor.reassignBlocklister(to: to, newPath: path)
486 case "reassignPauser":
487 let to = p.getArg(i: 0)! as? Address ?? panic("cannot downcast receiver address")
488 let path = p.getArg(i: 1)! as? PrivatePath ?? panic("cannot downcast new link path")
489 let executor = self.ownerExecutorCapability!.borrow() ?? panic("cannot borrow OwnerExecutor capability")
490 executor.reassignPauser(to: to, newPath: path)
491 default:
492 panic("Unknown transaction method")
493 }
494 destroy (p)
495 return nil
496 }
497
498 pub fun UUID(): UInt64 {
499 return self.uuid
500 }
501
502 pub fun getTxIndex(): UInt64 {
503 return self.multiSigManager.txIndex
504 }
505
506 pub fun getSignerKeys(): [String] {
507 return self.multiSigManager.getSignerKeys()
508 }
509 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
510 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
511 }
512
513 destroy() {
514 destroy self.multiSigManager
515 }
516
517 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
518 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
519 self.ownerExecutorCapability = nil
520 }
521 }
522
523 pub resource MasterMinterExecutor {
524
525 pub fun configureMinterController(minter: UInt64, minterController: UInt64) {
526 // Overwrite the minter if the MinterController is already configured (a MinterController can only control 1 minter)
527 FiatToken.managedMinters.insert(key: minterController, minter)
528 emit ControllerConfigured(controller: minterController, minter: minter)
529 }
530
531 pub fun removeMinterController(minterController: UInt64){
532 pre {
533 FiatToken.managedMinters.containsKey(minterController): "cannot remove unknown MinterController"
534 }
535 FiatToken.managedMinters.remove(key: minterController)
536 emit ControllerRemoved(controller: minterController)
537 }
538 }
539
540 pub resource MasterMinter: ResourceId, OnChainMultiSig.PublicSigner, MasterMinterCapReceiver {
541
542 access(self) let multiSigManager: @OnChainMultiSig.Manager
543 access(self) var masterMinterExecutorCapability: Capability<&MasterMinterExecutor>?
544
545 pub fun setMasterMinterCap(cap: Capability<&MasterMinterExecutor>) {
546 pre {
547 self.masterMinterExecutorCapability == nil: "Capability has already been set"
548 cap.borrow() != nil: "Invalid capability"
549 }
550 self.masterMinterExecutorCapability = cap
551 }
552
553 // ------- OnChainMultiSig.PublicSigner interfaces -------
554
555 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
556 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <-payload, publicKey: publicKey, sig: sig)
557 }
558
559 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
560 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
561 }
562
563 pub fun executeTx(txIndex: UInt64): @AnyResource? {
564 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
565 switch p.method {
566 case "configureKey":
567 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
568 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
569 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
570 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
571 case "removeKey":
572 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
573 self.multiSigManager.removeKeys(pks: [pubKey])
574 case "configureMinterController":
575 let m = p.getArg(i: 0)! as? UInt64 ?? panic ("cannot downcast minter id")
576 let mc = p.getArg(i: 1)! as? UInt64 ?? panic ("cannot downcast MinterController id")
577 let executor = self.masterMinterExecutorCapability!.borrow() ?? panic("cannot borrow MasterMinterExecutor capability")
578 executor.configureMinterController(minter: m, minterController: mc)
579 case "removeMinterController":
580 let mc = p.getArg(i: 0)! as? UInt64 ?? panic ("cannot downcast MinterController id")
581 let executor = self.masterMinterExecutorCapability!.borrow() ?? panic("cannot borrow MasterMinterExecutor capability")
582 executor.removeMinterController(minterController: mc)
583 default:
584 panic("Unknown transaction method")
585 }
586 destroy (p)
587 return nil
588 }
589
590 pub fun UUID(): UInt64 {
591 return self.uuid
592 }
593
594 pub fun getTxIndex(): UInt64 {
595 return self.multiSigManager.txIndex
596 }
597
598 pub fun getSignerKeys(): [String] {
599 return self.multiSigManager.getSignerKeys()
600 }
601 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
602 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
603 }
604
605 destroy() {
606 destroy self.multiSigManager
607 }
608
609 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
610 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
611 self.masterMinterExecutorCapability = nil
612 }
613 }
614
615 pub resource MinterController: ResourceId, OnChainMultiSig.PublicSigner {
616
617 access(self) let multiSigManager: @OnChainMultiSig.Manager
618
619 pub fun UUID(): UInt64 {
620 return self.uuid
621 }
622
623 pub fun configureMinterAllowance(allowance: UFix64) {
624 let managedMinter = FiatToken.managedMinters[self.uuid] ?? panic("MinterController does not manage any minters")
625 FiatToken.minterAllowances[managedMinter] = allowance
626 emit MinterConfigured(controller: self.uuid, minter: managedMinter, allowance: allowance)
627 }
628
629 pub fun increaseMinterAllowance(increment: UFix64) {
630 let managedMinter = FiatToken.managedMinters[self.uuid] ?? panic("MinterController does not manage any minters")
631 let allowance = FiatToken.minterAllowances[managedMinter] ?? 0.0
632 let newAllowance = allowance.saturatingAdd(increment)
633 self.configureMinterAllowance(allowance: newAllowance)
634 }
635
636 pub fun decreaseMinterAllowance(decrement: UFix64) {
637 let managedMinter = FiatToken.managedMinters[self.uuid] ?? panic("MinterController does not manage any minters")
638 let allowance = FiatToken.minterAllowances[managedMinter] ?? panic("Cannot decrease nil MinterAllowance")
639 let newAllowance = allowance!.saturatingSubtract(decrement)
640 self.configureMinterAllowance(allowance: newAllowance)
641 }
642
643 pub fun removeMinter() {
644 let managedMinter = FiatToken.managedMinters[self.uuid] ?? panic("MinterController does not manage any minters")
645 assert(FiatToken.minterAllowances.containsKey(managedMinter), message: "cannot remove unknown Minter")
646 FiatToken.minterAllowances.remove(key: managedMinter)
647 emit MinterRemoved(controller: self.uuid, minter: managedMinter)
648 }
649
650 // ------- OnChainMultiSig.PublicSigner interfaces -------
651
652 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
653 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <-payload, publicKey: publicKey, sig: sig)
654 }
655
656 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
657 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
658 }
659
660 pub fun executeTx(txIndex: UInt64): @AnyResource? {
661 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
662 switch p.method {
663 case "configureKey":
664 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
665 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
666 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
667 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
668 case "removeKey":
669 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
670 self.multiSigManager.removeKeys(pks: [pubKey])
671 case "configureMinterAllowance":
672 let allowance = p.getArg(i: 0)! as? UFix64 ?? panic ("cannot downcast allowance amount")
673 self.configureMinterAllowance(allowance: allowance)
674 case "increaseMinterAllowance":
675 let increment = p.getArg(i: 0)! as? UFix64 ?? panic ("cannot downcast increment amount")
676 self.increaseMinterAllowance(increment: increment)
677 case "decreaseMinterAllowance":
678 let decrement = p.getArg(i: 0)! as? UFix64 ?? panic ("cannot downcast decrement amount")
679 self.decreaseMinterAllowance(decrement: decrement)
680 case "removeMinter":
681 self.removeMinter()
682 default:
683 panic("Unknown transaction method")
684 }
685 destroy (p)
686 return nil
687 }
688
689 pub fun getTxIndex(): UInt64 {
690 return self.multiSigManager.txIndex
691 }
692
693 pub fun getSignerKeys(): [String] {
694 return self.multiSigManager.getSignerKeys()
695 }
696
697 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
698 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
699 }
700
701 destroy() {
702 destroy self.multiSigManager
703 }
704
705 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
706 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
707 }
708 }
709
710 pub resource Minter: ResourceId {
711
712 pub fun mint(amount: UFix64): @FungibleToken.Vault{
713 pre {
714 !FiatToken.paused: "FiatToken contract paused"
715 FiatToken.blocklist[self.uuid] == nil: "Minter Blocklisted"
716 FiatToken.minterAllowances.containsKey(self.uuid): "minter does not have allowance set"
717 }
718 let mintAllowance = FiatToken.minterAllowances[self.uuid]!
719 assert(mintAllowance >= amount, message: "insufficient mint allowance")
720 FiatToken.minterAllowances.insert(key: self.uuid, mintAllowance - amount)
721 let newTotalSupply = FiatToken.totalSupply + amount
722 FiatToken.totalSupply = newTotalSupply
723
724 emit Mint(minter: self.uuid, amount: amount)
725 return <-create Vault(balance: amount)
726 }
727
728 pub fun burn(vault: @FungibleToken.Vault) {
729 pre {
730 !FiatToken.paused: "FiatToken contract paused"
731 FiatToken.blocklist[self.uuid] == nil: "Minter Blocklisted"
732 FiatToken.minterAllowances.containsKey(self.uuid): "minter is not configured"
733 }
734 let toBurn <- vault as! @FiatToken.Vault
735 let amount = toBurn.balance
736
737 assert(FiatToken.totalSupply >= amount, message: "burning more than total supply")
738
739 // This function updates FiatToken.totalSupply and sets the Vault's value to 0.0
740 toBurn.burn()
741 // Destroys the now empty Vault
742 destroy toBurn
743 emit Burn(minter: self.uuid, amount: amount)
744 }
745
746 pub fun UUID(): UInt64 {
747 return self.uuid
748 }
749 }
750
751 pub resource BlocklistExecutor {
752
753 pub fun blocklist(resourceId: UInt64){
754 let block = getCurrentBlock()
755 FiatToken.blocklist.insert(key: resourceId, block.height)
756 emit Blocklisted(resourceId: resourceId)
757 }
758
759 pub fun unblocklist(resourceId: UInt64){
760 FiatToken.blocklist.remove(key: resourceId)
761 emit Unblocklisted(resourceId: resourceId)
762 }
763 }
764
765 pub resource Blocklister: ResourceId, BlocklisterCapReceiver, OnChainMultiSig.PublicSigner {
766
767 access(self) var blocklistCap: Capability<&BlocklistExecutor>?
768 access(self) let multiSigManager: @OnChainMultiSig.Manager
769
770 pub fun blocklist(resourceId: UInt64){
771 post {
772 FiatToken.blocklist.containsKey(resourceId): "Resource not blocklisted"
773 }
774 self.blocklistCap!.borrow()!.blocklist(resourceId: resourceId)
775 }
776
777 pub fun unblocklist(resourceId: UInt64){
778 post {
779 !FiatToken.blocklist.containsKey(resourceId): "Resource still on blocklist"
780 }
781 self.blocklistCap!.borrow()!.unblocklist(resourceId: resourceId)
782 }
783
784 pub fun setBlocklistCap(cap: Capability<&BlocklistExecutor>){
785 pre {
786 self.blocklistCap == nil: "Capability has already been set"
787 cap.borrow() != nil: "Invalid BlocklistCap capability"
788 }
789 self.blocklistCap = cap
790 }
791
792 // ------- OnChainMultiSig.PublicSigner interfaces -------
793
794 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
795 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <- payload, publicKey: publicKey, sig: sig)
796 }
797
798 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
799 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
800 }
801
802 pub fun executeTx(txIndex: UInt64): @AnyResource? {
803 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
804 switch p.method {
805 case "configureKey":
806 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
807 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
808 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
809 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
810 case "removeKey":
811 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
812 self.multiSigManager.removeKeys(pks: [pubKey])
813 case "blocklist":
814 let resourceId = p.getArg(i: 0)! as? UInt64 ?? panic ("cannot downcast resourceId")
815 self.blocklist(resourceId: resourceId)
816 case "unblocklist":
817 let resourceId = p.getArg(i: 0)! as? UInt64 ?? panic ("cannot downcast resourceId")
818 self.unblocklist(resourceId: resourceId)
819 default:
820 panic("Unknown transaction method")
821 }
822 destroy(p)
823 return nil
824 }
825
826 pub fun UUID(): UInt64 {
827 return self.uuid
828 }
829
830 pub fun getTxIndex(): UInt64 {
831 return self.multiSigManager.txIndex
832 }
833
834 pub fun getSignerKeys(): [String] {
835 return self.multiSigManager.getSignerKeys()
836 }
837 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
838 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
839 }
840
841 destroy() {
842 destroy self.multiSigManager
843 }
844
845 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
846 self.blocklistCap = nil
847 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
848 }
849 }
850
851 pub resource PauseExecutor {
852
853 pub fun pause() {
854 FiatToken.paused = true
855 emit Paused()
856 }
857
858 pub fun unpause() {
859 FiatToken.paused = false
860 emit Unpaused()
861 }
862 }
863
864 pub resource Pauser: ResourceId, PauseCapReceiver, OnChainMultiSig.PublicSigner {
865
866 access(self) var pauseCap: Capability<&PauseExecutor>?
867 access(self) let multiSigManager: @OnChainMultiSig.Manager
868
869 pub fun setPauseCap(cap: Capability<&PauseExecutor>) {
870 pre {
871 self.pauseCap == nil: "Capability has already been set"
872 cap.borrow() != nil: "Invalid PauseCap capability"
873 }
874 self.pauseCap = cap
875 }
876
877 pub fun pause(){
878 let cap = self.pauseCap!.borrow()!
879 cap.pause()
880 }
881
882 pub fun unpause(){
883 let cap = self.pauseCap!.borrow()!
884 cap.unpause()
885 }
886
887 // ------- OnChainMultiSig.PublicSigner interfaces -------
888
889 pub fun addNewPayload(payload: @OnChainMultiSig.PayloadDetails, publicKey: String, sig: [UInt8]) {
890 self.multiSigManager.addNewPayload(resourceId: self.uuid, payload: <- payload, publicKey: publicKey, sig: sig)
891 }
892
893 pub fun addPayloadSignature (txIndex: UInt64, publicKey: String, sig: [UInt8]) {
894 self.multiSigManager.addPayloadSignature(resourceId: self.uuid, txIndex: txIndex, publicKey: publicKey, sig: sig)
895 }
896
897 pub fun executeTx(txIndex: UInt64): @AnyResource? {
898 let p <- self.multiSigManager.readyForExecution(txIndex: txIndex) ?? panic ("no ready transaction payload at given txIndex")
899 switch p.method {
900 case "configureKey":
901 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
902 let weight = p.getArg(i: 1)! as? UFix64 ?? panic ("cannot downcast weight")
903 let sa = p.getArg(i: 2)! as? UInt8 ?? panic ("cannot downcast sig algo")
904 self.multiSigManager.configureKeys(pks: [pubKey], kws: [weight], sa: [sa])
905 case "removeKey":
906 let pubKey = p.getArg(i: 0)! as? String ?? panic ("cannot downcast public key")
907 self.multiSigManager.removeKeys(pks: [pubKey])
908 case "pause":
909 self.pause()
910 case "unpause":
911 self.unpause()
912 default:
913 panic("Unknown transaction method")
914 }
915 destroy(p)
916 return nil
917 }
918
919 pub fun UUID(): UInt64 {
920 return self.uuid
921 }
922
923 pub fun getTxIndex(): UInt64 {
924 return self.multiSigManager.txIndex
925 }
926
927 pub fun getSignerKeys(): [String] {
928 return self.multiSigManager.getSignerKeys()
929 }
930
931 pub fun getSignerKeyAttr(publicKey: String): OnChainMultiSig.PubKeyAttr? {
932 return self.multiSigManager.getSignerKeyAttr(publicKey: publicKey)
933 }
934
935 destroy() {
936 destroy self.multiSigManager
937 }
938
939 init(pk: [String], pka: [OnChainMultiSig.PubKeyAttr]) {
940 self.pauseCap = nil
941 self.multiSigManager <- OnChainMultiSig.createMultiSigManager(publicKeys: pk, pubKeyAttrs: pka)
942 }
943 }
944
945 // ------- FiatToken functions -------
946
947 pub fun createEmptyVault(): @Vault {
948 let r <-create Vault(balance: 0.0)
949 emit NewVault(resourceId: r.uuid)
950 return <-r
951 }
952
953 pub fun createNewAdmin(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @Admin{
954 let admin <-create Admin(pk: publicKeys, pka: pubKeyAttrs)
955 emit AdminCreated(resourceId: admin.uuid)
956 return <- admin
957 }
958
959 pub fun createNewOwner(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @Owner{
960 let owner <-create Owner(pk: publicKeys, pka: pubKeyAttrs)
961 emit OwnerCreated(resourceId: owner.uuid)
962 return <- owner
963 }
964
965 pub fun createNewPauser(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @Pauser{
966 let pauser <-create Pauser(pk: publicKeys, pka: pubKeyAttrs)
967 emit PauserCreated(resourceId: pauser.uuid)
968 return <- pauser
969 }
970
971 pub fun createNewMasterMinter(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @MasterMinter{
972 let masterMinter <- create MasterMinter(pk: publicKeys, pka: pubKeyAttrs)
973 emit MasterMinterCreated(resourceId: masterMinter.uuid)
974 return <- masterMinter
975 }
976
977 pub fun createNewMinterController(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @MinterController{
978 let minterController <- create MinterController(pk: publicKeys, pka: pubKeyAttrs)
979 emit MinterControllerCreated(resourceId: minterController.uuid)
980 return <- minterController
981 }
982
983 pub fun createNewMinter(): @Minter{
984 let minter <- create Minter()
985 emit MinterCreated(resourceId: minter.uuid)
986 return <- minter
987 }
988
989 pub fun createNewBlocklister(publicKeys: [String], pubKeyAttrs: [OnChainMultiSig.PubKeyAttr]): @Blocklister{
990 let blocklister <-create Blocklister(pk: publicKeys, pka: pubKeyAttrs)
991 emit BlocklisterCreated(resourceId: blocklister.uuid)
992 return <-blocklister
993 }
994
995 pub fun getBlocklist(resourceId: UInt64): UInt64?{
996 return FiatToken.blocklist[resourceId]
997 }
998
999 pub fun getManagedMinter(resourceId: UInt64): UInt64?{
1000 return FiatToken.managedMinters[resourceId]
1001 }
1002
1003 pub fun getMinterAllowance(resourceId: UInt64): UFix64?{
1004 return FiatToken.minterAllowances[resourceId]
1005 }
1006
1007 access(self) fun upgradeContract( name: String, code: [UInt8], version: String,) {
1008 self.account.contracts.update__experimental(name: name, code: code)
1009 self.version = version
1010 }
1011
1012 // ------- FiatToken Initializer -------
1013 init(
1014 contractAccount: AuthAccount,
1015 VaultStoragePath: StoragePath,
1016 VaultBalancePubPath: PublicPath,
1017 VaultUUIDPubPath: PublicPath,
1018 VaultReceiverPubPath: PublicPath,
1019 BlocklistExecutorStoragePath: StoragePath,
1020 BlocklisterStoragePath: StoragePath,
1021 BlocklisterCapReceiverPubPath: PublicPath,
1022 BlocklisterUUIDPubPath: PublicPath,
1023 BlocklisterPubSigner: PublicPath,
1024 PauseExecutorStoragePath: StoragePath,
1025 PauserStoragePath: StoragePath,
1026 PauserCapReceiverPubPath: PublicPath,
1027 PauserUUIDPubPath: PublicPath,
1028 PauserPubSigner: PublicPath,
1029 AdminExecutorStoragePath: StoragePath,
1030 AdminStoragePath: StoragePath,
1031 AdminCapReceiverPubPath: PublicPath,
1032 AdminUUIDPubPath: PublicPath,
1033 AdminPubSigner: PublicPath,
1034 OwnerExecutorStoragePath: StoragePath,
1035 OwnerStoragePath: StoragePath,
1036 OwnerCapReceiverPubPath: PublicPath,
1037 OwnerUUIDPubPath: PublicPath,
1038 OwnerPubSigner: PublicPath,
1039 MasterMinterExecutorStoragePath: StoragePath,
1040 MasterMinterStoragePath: StoragePath,
1041 MasterMinterCapReceiverPubPath: PublicPath,
1042 MasterMinterPubSigner: PublicPath,
1043 MasterMinterUUIDPubPath: PublicPath,
1044 MinterControllerStoragePath: StoragePath,
1045 MinterControllerUUIDPubPath: PublicPath,
1046 MinterControllerPubSigner: PublicPath,
1047 MinterStoragePath: StoragePath,
1048 MinterUUIDPubPath: PublicPath,
1049 initialAdminCapabilityPrivPath: PrivatePath,
1050 initialOwnerCapabilityPrivPath: PrivatePath,
1051 initialMasterMinterCapabilityPrivPath: PrivatePath,
1052 initialPauserCapabilityPrivPath: PrivatePath,
1053 initialBlocklisterCapabilityPrivPath: PrivatePath,
1054 tokenName: String,
1055 version: String,
1056 initTotalSupply: UFix64,
1057 initPaused: Bool,
1058 adminPubKeys: [String],
1059 adminPubKeysWeights: [UFix64],
1060 adminPubKeysAlgos: [UInt8],
1061 ownerPubKeys: [String],
1062 ownerPubKeysWeights: [UFix64],
1063 ownerPubKeysAlgos: [UInt8],
1064 masterMinterPubKeys: [String],
1065 masterMinterPubKeysWeights: [UFix64],
1066 masterMinterPubKeysAlgos: [UInt8],
1067 blocklisterPubKeys: [String],
1068 blocklisterPubKeysWeights: [UFix64],
1069 blocklisterPubKeysAlgos: [UInt8],
1070 pauserPubKeys: [String],
1071 pauserPubKeysWeights: [UFix64],
1072 pauserPubKeysAlgos: [UInt8],
1073 ) {
1074
1075 // Validate the keys
1076 assert(adminPubKeys.length == adminPubKeysWeights.length, message: "Admin pub keys length and weights mismatched")
1077 assert(ownerPubKeys.length == ownerPubKeysWeights.length, message: "Owner pub keys length and weights mismatched")
1078 assert(masterMinterPubKeys.length == masterMinterPubKeysWeights.length, message: "MasterMinter pub keys length and weights mismatched")
1079 assert(blocklisterPubKeys.length == blocklisterPubKeysWeights.length, message: "Blocklister pub keys length and weights mismatched")
1080 assert(pauserPubKeys.length == pauserPubKeysWeights.length, message: "Pauser pub keys length and weights mismatched")
1081
1082 // Set the State
1083 self.name = tokenName
1084 self.version = version
1085 self.paused = initPaused
1086 self.totalSupply = initTotalSupply
1087 self.blocklist = {}
1088 self.minterAllowances = {}
1089 self.managedMinters = {}
1090
1091 self.VaultStoragePath = VaultStoragePath
1092 self.VaultBalancePubPath = VaultBalancePubPath
1093 self.VaultUUIDPubPath = VaultUUIDPubPath
1094 self.VaultReceiverPubPath = VaultReceiverPubPath
1095
1096 self.BlocklistExecutorStoragePath = BlocklistExecutorStoragePath
1097
1098 self.BlocklisterStoragePath = BlocklisterStoragePath
1099 self.BlocklisterCapReceiverPubPath = BlocklisterCapReceiverPubPath
1100 self.BlocklisterUUIDPubPath = BlocklisterUUIDPubPath
1101 self.BlocklisterPubSigner = BlocklisterPubSigner
1102
1103 self.PauseExecutorStoragePath = PauseExecutorStoragePath
1104
1105 self.PauserStoragePath = PauserStoragePath
1106 self.PauserCapReceiverPubPath = PauserCapReceiverPubPath
1107 self.PauserUUIDPubPath = PauserUUIDPubPath
1108 self.PauserPubSigner = PauserPubSigner
1109
1110 self.AdminExecutorStoragePath = AdminExecutorStoragePath
1111
1112 self.AdminStoragePath = AdminStoragePath
1113 self.AdminCapReceiverPubPath = AdminCapReceiverPubPath
1114 self.AdminUUIDPubPath = AdminUUIDPubPath
1115 self.AdminPubSigner = AdminPubSigner
1116
1117 self.OwnerExecutorStoragePath = OwnerExecutorStoragePath
1118
1119 self.OwnerStoragePath = OwnerStoragePath
1120 self.OwnerCapReceiverPubPath = OwnerCapReceiverPubPath
1121 self.OwnerUUIDPubPath = OwnerUUIDPubPath
1122 self.OwnerPubSigner = OwnerPubSigner
1123
1124 self.MasterMinterExecutorStoragePath = MasterMinterExecutorStoragePath
1125
1126 self.MasterMinterStoragePath = MasterMinterStoragePath
1127 self.MasterMinterCapReceiverPubPath = MasterMinterCapReceiverPubPath
1128 self.MasterMinterPubSigner = MasterMinterPubSigner
1129 self.MasterMinterUUIDPubPath = MasterMinterUUIDPubPath
1130
1131 self.MinterControllerStoragePath = MinterControllerStoragePath
1132 self.MinterControllerUUIDPubPath = MinterControllerUUIDPubPath
1133 self.MinterControllerPubSigner = MinterControllerPubSigner
1134
1135 self.MinterStoragePath = MinterStoragePath
1136 self.MinterUUIDPubPath = MinterUUIDPubPath
1137
1138 // Create admin accounts
1139 let adminAccount = AuthAccount(payer: contractAccount)
1140 let ownerAccount = AuthAccount(payer: contractAccount)
1141 let masterMinterAccount = AuthAccount(payer: contractAccount)
1142 let blocklisterAccount = AuthAccount(payer: contractAccount)
1143 let pauserAccount = AuthAccount(payer: contractAccount)
1144
1145 // Create the Executors
1146 contractAccount.save(<- create AdminExecutor(), to: self.AdminExecutorStoragePath)
1147 contractAccount.save(<- create OwnerExecutor(), to: self.OwnerExecutorStoragePath)
1148 contractAccount.save(<- create MasterMinterExecutor(), to: self.MasterMinterExecutorStoragePath)
1149 contractAccount.save(<- create BlocklistExecutor(), to: self.BlocklistExecutorStoragePath)
1150 contractAccount.save(<- create PauseExecutor(), to: self.PauseExecutorStoragePath)
1151
1152 // Setup the Admin
1153 var pubKeyAttrs: [OnChainMultiSig.PubKeyAttr] = []
1154 var i = 0
1155 while i < adminPubKeys.length {
1156 let pka = OnChainMultiSig.PubKeyAttr(sa: adminPubKeysAlgos[i], w: adminPubKeysWeights[i])
1157 pubKeyAttrs.append(pka)
1158 let key = PublicKey(
1159 publicKey: adminPubKeys[i].decodeHex(),
1160 signatureAlgorithm: SignatureAlgorithm(rawValue: adminPubKeysAlgos[i]) ?? panic ("Invalid signature algo")
1161 )
1162 adminAccount.keys.add(
1163 publicKey: key,
1164 hashAlgorithm: HashAlgorithm.SHA3_256,
1165 weight: adminPubKeysWeights[i]
1166 )
1167 i = i + 1
1168 }
1169 adminAccount.save(<- self.createNewAdmin(publicKeys: adminPubKeys, pubKeyAttrs: pubKeyAttrs), to: self.AdminStoragePath)
1170 adminAccount.link<&Admin{OnChainMultiSig.PublicSigner}>(self.AdminPubSigner, target: self.AdminStoragePath)
1171 adminAccount.link<&Admin{ResourceId}>(self.AdminUUIDPubPath, target: self.AdminStoragePath)
1172 adminAccount.link<&Admin{AdminCapReceiver}>(self.AdminCapReceiverPubPath, target: self.AdminStoragePath)
1173
1174 // Setup the Owner
1175 pubKeyAttrs = []
1176 i = 0
1177 while i < ownerPubKeys.length {
1178 let pka = OnChainMultiSig.PubKeyAttr(sa: ownerPubKeysAlgos[i], w: ownerPubKeysWeights[i])
1179 pubKeyAttrs.append(pka)
1180 let key = PublicKey(
1181 publicKey: ownerPubKeys[i].decodeHex(),
1182 signatureAlgorithm: SignatureAlgorithm(rawValue: ownerPubKeysAlgos[i]) ?? panic ("Invalid signature algo")
1183 )
1184 ownerAccount.keys.add(
1185 publicKey: key,
1186 hashAlgorithm: HashAlgorithm.SHA3_256,
1187 weight: ownerPubKeysWeights[i]
1188 )
1189 i = i + 1
1190 }
1191 ownerAccount.save(<- self.createNewOwner(publicKeys: ownerPubKeys, pubKeyAttrs: pubKeyAttrs), to: self.OwnerStoragePath)
1192 ownerAccount.link<&Owner{OnChainMultiSig.PublicSigner}>(self.OwnerPubSigner, target: self.OwnerStoragePath)
1193 ownerAccount.link<&Owner{ResourceId}>(self.OwnerUUIDPubPath, target: self.OwnerStoragePath)
1194 ownerAccount.link<&Owner{OwnerCapReceiver}>(self.OwnerCapReceiverPubPath, target: self.OwnerStoragePath)
1195
1196 // Setup the MasterMinter
1197 pubKeyAttrs = []
1198 i = 0
1199 while i < masterMinterPubKeys.length {
1200 let pka = OnChainMultiSig.PubKeyAttr(sa: masterMinterPubKeysAlgos[i], w: masterMinterPubKeysWeights[i])
1201 pubKeyAttrs.append(pka)
1202 let key = PublicKey(
1203 publicKey: masterMinterPubKeys[i].decodeHex(),
1204 signatureAlgorithm: SignatureAlgorithm(rawValue: masterMinterPubKeysAlgos[i]) ?? panic ("Invalid signature algo")
1205 )
1206 masterMinterAccount.keys.add(
1207 publicKey: key,
1208 hashAlgorithm: HashAlgorithm.SHA3_256,
1209 weight: masterMinterPubKeysWeights[i]
1210 )
1211 i = i + 1
1212 }
1213 masterMinterAccount.save(<- self.createNewMasterMinter(publicKeys: masterMinterPubKeys, pubKeyAttrs: pubKeyAttrs), to: self.MasterMinterStoragePath)
1214 masterMinterAccount.link<&MasterMinter{OnChainMultiSig.PublicSigner}>(self.MasterMinterPubSigner, target: self.MasterMinterStoragePath)
1215 masterMinterAccount.link<&MasterMinter{ResourceId}>(self.MasterMinterUUIDPubPath, target: self.MasterMinterStoragePath)
1216 masterMinterAccount.link<&MasterMinter{MasterMinterCapReceiver}>(self.MasterMinterCapReceiverPubPath, target: self.MasterMinterStoragePath)
1217
1218 // Setup the Blocklister
1219 pubKeyAttrs = []
1220 i = 0
1221 while i < blocklisterPubKeys.length {
1222 let pka = OnChainMultiSig.PubKeyAttr(sa: blocklisterPubKeysAlgos[i], w: blocklisterPubKeysWeights[i])
1223 pubKeyAttrs.append(pka)
1224 let key = PublicKey(
1225 publicKey: blocklisterPubKeys[i].decodeHex(),
1226 signatureAlgorithm: SignatureAlgorithm(rawValue: blocklisterPubKeysAlgos[i]) ?? panic ("Invalid signature algo")
1227 )
1228 blocklisterAccount.keys.add(
1229 publicKey: key,
1230 hashAlgorithm: HashAlgorithm.SHA3_256,
1231 weight: blocklisterPubKeysWeights[i]
1232 )
1233 i = i + 1
1234 }
1235 blocklisterAccount.save(<- self.createNewBlocklister(publicKeys: blocklisterPubKeys, pubKeyAttrs: pubKeyAttrs), to: self.BlocklisterStoragePath)
1236 blocklisterAccount.link<&Blocklister{OnChainMultiSig.PublicSigner}>(self.BlocklisterPubSigner, target: self.BlocklisterStoragePath)
1237 blocklisterAccount.link<&Blocklister{ResourceId}>(self.BlocklisterUUIDPubPath, target: self.BlocklisterStoragePath)
1238 blocklisterAccount.link<&Blocklister{BlocklisterCapReceiver}>(self.BlocklisterCapReceiverPubPath, target: self.BlocklisterStoragePath)
1239
1240 // Setup the Pauser
1241 pubKeyAttrs = []
1242 i = 0
1243 while i < pauserPubKeys.length {
1244 let pka = OnChainMultiSig.PubKeyAttr(sa: pauserPubKeysAlgos[i], w: pauserPubKeysWeights[i])
1245 pubKeyAttrs.append(pka)
1246 let key = PublicKey(
1247 publicKey: pauserPubKeys[i].decodeHex(),
1248 signatureAlgorithm: SignatureAlgorithm(rawValue: pauserPubKeysAlgos[i]) ?? panic ("Invalid signature algo")
1249 )
1250 pauserAccount.keys.add(
1251 publicKey: key,
1252 hashAlgorithm: HashAlgorithm.SHA3_256,
1253 weight: pauserPubKeysWeights[i]
1254 )
1255 i = i + 1
1256 }
1257 pauserAccount.save(<- self.createNewPauser(publicKeys: pauserPubKeys, pubKeyAttrs: pubKeyAttrs), to: self.PauserStoragePath)
1258 pauserAccount.link<&Pauser{OnChainMultiSig.PublicSigner}>(self.PauserPubSigner, target: self.PauserStoragePath)
1259 pauserAccount.link<&Pauser{ResourceId}>(self.PauserUUIDPubPath, target: self.PauserStoragePath)
1260 pauserAccount.link<&Pauser{PauseCapReceiver}>(self.PauserCapReceiverPubPath, target: self.PauserStoragePath)
1261
1262 // Assign the admin capabilities
1263 let adminExecutorRef = contractAccount.borrow<&FiatToken.AdminExecutor>(from: self.AdminExecutorStoragePath)
1264 ?? panic("cannot borrow AdminExecutor from storage")
1265 let ownerExecutorRef = contractAccount.borrow<&FiatToken.OwnerExecutor>(from: self.OwnerExecutorStoragePath)
1266 ?? panic("cannot borrow OwnerExecutor from storage")
1267 adminExecutorRef.changeAdmin(to: adminAccount.address, newPath: initialAdminCapabilityPrivPath)
1268 ownerExecutorRef.reassignOwner(to: ownerAccount.address, newPath: initialOwnerCapabilityPrivPath)
1269 ownerExecutorRef.reassignMasterMinter(to: masterMinterAccount.address, newPath: initialMasterMinterCapabilityPrivPath)
1270 ownerExecutorRef.reassignBlocklister(to: blocklisterAccount.address, newPath: initialBlocklisterCapabilityPrivPath)
1271 ownerExecutorRef.reassignPauser(to: pauserAccount.address, newPath: initialPauserCapabilityPrivPath)
1272
1273 // Create a Vault with the initial totalSupply
1274 let vault <- create Vault(balance: self.totalSupply)
1275 self.account.save(<-vault, to: self.VaultStoragePath)
1276
1277 // Create public capabilities to the vault
1278 contractAccount.link<&FiatToken.Vault{FungibleToken.Receiver}>(self.VaultReceiverPubPath, target: self.VaultStoragePath)
1279 contractAccount.link<&FiatToken.Vault{FungibleToken.Balance}>(self.VaultBalancePubPath, target: self.VaultStoragePath)
1280 contractAccount.link<&FiatToken.Vault{FiatToken.ResourceId}>(self.VaultUUIDPubPath, target: self.VaultStoragePath)
1281
1282 // Emit the TokensInitialized event
1283 emit TokensInitialized(initialSupply: self.totalSupply)
1284
1285 }
1286
1287}
1288