Smart Contract
FazeUtilityCoin
A.4eded0de73020ca5.FazeUtilityCoin
1// SPDX-License-Identifier: UNLICENSED
2
3import FungibleToken from 0xf233dcee88fe0abe
4// SPDX-License-Identifier: UNLICENSED
5access(all) contract FazeUtilityCoin: FungibleToken {
6 // TokensInitialized
7 //
8 // The event that is emitted when the contract is created
9 access(all) event TokensInitialized(initialSupply: UFix64)
10
11 // TokensWithdrawn
12 //
13 // The event that is emitted when tokens are withdrawn from a Vault
14 access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
15 access(all) event TokensWithdrawnWithSource(amount: UFix64, from: Address?, sourceId: String)
16
17 // TokensDeposited
18 //
19 // The event that is emitted when tokens are deposited to a Vault
20 access(all) event TokensDeposited(amount: UFix64, to: Address?)
21
22 // TokensMinted
23 //
24 // The event that is emitted when new tokens are minted
25 access(all) event TokensMinted(amount: UFix64)
26
27 // TokensBurned
28 //
29 // The event that is emitted when tokens are destroyed
30 access(all) event TokensBurned(amount: UFix64)
31
32 // MinterCreated
33 //
34 // The event that is emitted when a new minter resource is created
35 access(all) event MinterCreated(allowedAmount: UFix64)
36
37 // Named paths
38 //
39 access(all) let VaultStoragePath: StoragePath
40 access(all) let ReceiverPublicPath: PublicPath
41 access(all) let BalancePublicPath: PublicPath
42 access(all) let AdminStoragePath: StoragePath
43
44 // Total supply of FazeUtilityCoins in existence
45 access(all) var totalSupply: UFix64
46
47 access(all) view fun getContractViews(resourceType: Type?): [Type] {
48 return []
49 }
50
51 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
52 return nil
53 }
54
55 // Vault
56 //
57 // Each user stores an instance of only the Vault in their storage
58 // The functions in the Vault and governed by the pre and post conditions
59 // in FungibleToken when they are called.
60 // The checks happen at runtime whenever a function is called.
61 //
62 // Resources can only be created in the context of the contract that they
63 // are defined in, so there is no way for a malicious user to create Vaults
64 // out of thin air. A special Minter resource needs to be defined to mint
65 // new tokens.
66 //
67 access(all) resource Vault: FungibleToken.Vault {
68
69 // The total balance of this vault
70 access(all) var balance: UFix64
71
72 // initialize the balance at resource creation time
73 init(balance: UFix64) {
74 self.balance = balance
75 }
76
77 /// Asks if the amount can be withdrawn from this vault
78 access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
79 return amount <= self.balance
80 }
81
82 access(all) view fun getViews(): [Type] {
83 return FazeUtilityCoin.getContractViews(resourceType: nil)
84 }
85
86 access(all) fun resolveView(_ view: Type): AnyStruct? {
87 return FazeUtilityCoin.resolveContractView(resourceType: nil, viewType: view)
88 }
89
90
91 // withdraw
92 //
93 // Function that takes an amount as an argument
94 // and withdraws that amount from the Vault.
95 //
96 // It creates a new temporary Vault that is used to hold
97 // the money that is being transferred. It returns the newly
98 // created Vault to the context that called so it can be deposited
99 // elsewhere.
100 //
101 access(FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
102 self.balance = self.balance - amount
103 emit TokensWithdrawn(amount: amount, from: self.owner?.address)
104 return <-create Vault(balance: amount)
105 }
106
107 access(FungibleToken.Withdraw) fun withdrawWithSource(amount: UFix64, sourceId: String): @{FungibleToken.Vault} {
108 self.balance = self.balance - amount
109 emit TokensWithdrawn(amount: amount, from: self.owner?.address)
110 emit TokensWithdrawnWithSource(amount: amount, from: self.owner?.address, sourceId: sourceId)
111 return <-create Vault(balance: amount)
112 }
113
114 // deposit
115 //
116 // Function that takes a Vault object as an argument and adds
117 // its balance to the balance of the owners Vault.
118 //
119 // It is allowed to destroy the sent Vault because the Vault
120 // was a temporary holder of the tokens. The Vault's balance has
121 // been consumed and therefore can be destroyed.
122 //
123 access(all) fun deposit(from: @{FungibleToken.Vault}) {
124 let vault <- from as! @FazeUtilityCoin.Vault
125 self.balance = self.balance + vault.balance
126 emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
127 vault.balance = 0.0
128 destroy vault
129 }
130
131 /// Called when a fungible token is burned via the `Burner.burn()` method
132 access(contract) fun burnCallback() {
133 if self.balance > 0.0 {
134 FazeUtilityCoin.totalSupply = FazeUtilityCoin.totalSupply - self.balance
135 }
136 self.balance = 0.0
137 }
138
139 /// createEmptyVault
140 ///
141 /// Function that creates a new Vault with a balance of zero
142 /// and returns it to the calling context. A user must call this function
143 /// and store the returned Vault in their storage in order to allow their
144 /// account to be able to receive deposits of this token type.
145 ///
146 access(all) fun createEmptyVault(): @FazeUtilityCoin.Vault {
147 return <-create Vault(balance: 0.0)
148 }
149 }
150
151 /// createEmptyVault
152 ///
153 /// Function that creates a new Vault with a balance of zero
154 /// and returns it to the calling context. A user must call this function
155 /// and store the returned Vault in their storage in order to allow their
156 /// account to be able to receive deposits of this token type.
157 ///
158 access(all) fun createEmptyVault(vaultType: Type): @FazeUtilityCoin.Vault {
159 return <- create Vault(balance: 0.0)
160 }
161
162 access(all) resource Administrator {
163
164 // createNewMinter
165 //
166 // Function that creates and returns a new minter resource
167 //
168 access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
169 emit MinterCreated(allowedAmount: allowedAmount)
170 return <-create Minter(allowedAmount: allowedAmount)
171 }
172 }
173
174 // Minter
175 //
176 // Resource object that token admin accounts can hold to mint new tokens.
177 //
178 access(all) resource Minter {
179
180 // The amount of tokens that the minter is allowed to mint
181 access(all) var allowedAmount: UFix64
182
183 // mintTokens
184 //
185 // Function that mints new tokens, adds them to the total supply,
186 // and returns them to the calling context.
187 //
188 access(all) fun mintTokens(amount: UFix64): @FazeUtilityCoin.Vault {
189 pre {
190 amount > 0.0: "Amount minted must be greater than zero"
191 amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
192 }
193 FazeUtilityCoin.totalSupply = FazeUtilityCoin.totalSupply + amount
194 self.allowedAmount = self.allowedAmount - amount
195 emit TokensMinted(amount: amount)
196 return <-create Vault(balance: amount)
197 }
198
199 init(allowedAmount: UFix64) {
200 self.allowedAmount = allowedAmount
201 }
202 }
203
204 init() {
205 // Set our named paths.
206 self.VaultStoragePath = /storage/fazeUtilityCoinVault
207 self.ReceiverPublicPath = /public/fazeUtilityCoinReceiver
208 self.BalancePublicPath = /public/fazeUtilityCoinBalance
209 self.AdminStoragePath = /storage/fazeUtilityCoinAdmin
210
211 // Initialize contract state.
212 self.totalSupply = 0.0
213
214 // Create the one true Admin object and deposit it into the conttract account.
215 let admin <- create Administrator()
216 self.account.storage.save(<-admin, to: self.AdminStoragePath)
217
218 // Emit an event that shows that the contract was initialized.
219 emit TokensInitialized(initialSupply: self.totalSupply)
220 }
221}
222