Smart Contract

FazeUtilityCoin

A.f827352428f8f46b.FazeUtilityCoin

Deployed

1h ago
Feb 26, 2026, 05:56:10 PM UTC

Dependents

0 imports
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