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