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