Smart Contract

MoxyToken

A.123cb47fe122f6e3.MoxyToken

Deployed

2d ago
Feb 25, 2026, 12:53:19 AM UTC

Dependents

36 imports
1import FungibleToken from 0xf233dcee88fe0abe
2import MoxyVaultToken from 0x123cb47fe122f6e3
3
4pub contract MoxyToken: FungibleToken {
5
6    /// Total supply of MoxyTokens in existence
7    pub var totalSupply: UFix64
8    
9    /// TokensInitialized
10    ///
11    /// The event that is emitted when the contract is created
12    pub event TokensInitialized(initialSupply: UFix64)
13
14    /// TokensWithdrawn
15    ///
16    /// The event that is emitted when tokens are withdrawn from a Vault
17    pub event TokensWithdrawn(amount: UFix64, from: Address?)
18
19    /// TokensDeposited
20    ///
21    /// The event that is emitted when tokens are deposited to a Vault
22    pub event TokensDeposited(amount: UFix64, to: Address?)
23
24    /// TokensMinted
25    ///
26    /// The event that is emitted when new tokens are minted
27    pub event TokensMinted(amount: UFix64)
28
29    /// TokensBurned
30    ///
31    /// The event that is emitted when tokens are destroyed
32    pub event TokensBurned(amount: UFix64)
33
34    /// MinterCreated
35    ///
36    /// The event that is emitted when a new minter resource is created
37    pub event MinterCreated(allowedAmount: UFix64)
38
39    /// BurnerCreated
40    ///
41    /// The event that is emitted when a new burner resource is created
42    pub event BurnerCreated()
43
44    pub event MOXtoMVConvertionRequested(address: Address, amount: UFix64)
45
46    /// Vault
47    ///
48    /// Each user stores an instance of only the Vault in their storage
49    /// The functions in the Vault and governed by the pre and post conditions
50    /// in FungibleToken when they are called.
51    /// The checks happen at runtime whenever a function is called.
52    ///
53    /// Resources can only be created in the context of the contract that they
54    /// are defined in, so there is no way for a malicious user to create Vaults
55    /// out of thin air. A special Minter resource needs to be defined to mint
56    /// new tokens.
57    ///
58    pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance {
59
60        /// The total balance of this vault
61        pub var balance: UFix64
62
63        // initialize the balance at resource creation time
64        init(balance: UFix64) {
65            self.balance = balance
66        }
67
68        /// withdraw
69        ///
70        /// Function that takes an amount as an argument
71        /// and withdraws that amount from the Vault.
72        ///
73        /// It creates a new temporary Vault that is used to hold
74        /// the money that is being transferred. It returns the newly
75        /// created Vault to the context that called so it can be deposited
76        /// elsewhere.
77        ///
78        pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
79            self.balance = self.balance - amount
80            emit TokensWithdrawn(amount: amount, from: self.owner?.address)
81            return <-create Vault(balance: amount)
82        }
83
84        /// deposit
85        ///
86        /// Function that takes a Vault object as an argument and adds
87        /// its balance to the balance of the owners Vault.
88        ///
89        /// It is allowed to destroy the sent Vault because the Vault
90        /// was a temporary holder of the tokens. The Vault's balance has
91        /// been consumed and therefore can be destroyed.
92        ///
93        pub fun deposit(from: @FungibleToken.Vault) {
94            let vault <- from as! @MoxyToken.Vault
95            self.balance = self.balance + vault.balance
96            emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
97            vault.balance = 0.0
98            destroy vault
99        }
100
101        access(account) fun depositLocked(from: @FungibleToken.Vault) {
102            return self.deposit(from: <-from)
103        }
104
105        destroy() {
106            MoxyToken.totalSupply = MoxyToken.totalSupply - self.balance
107        }
108    }
109
110    /// createEmptyVault
111    ///
112    /// Function that creates a new Vault with a balance of zero
113    /// and returns it to the calling context. A user must call this function
114    /// and store the returned Vault in their storage in order to allow their
115    /// account to be able to receive deposits of this token type.
116    ///
117    pub fun createEmptyVault(): @Vault {
118        return <-create Vault(balance: 0.0)
119    }
120
121    pub resource Administrator {
122
123        /// createNewMinter
124        ///
125        /// Function that creates and returns a new minter resource
126        ///
127        
128        pub fun createNewMinter(allowedAmount: UFix64): @Minter {
129            emit MinterCreated(allowedAmount: allowedAmount)
130            return <-create Minter(allowedAmount: allowedAmount)
131        }
132
133        /// createNewBurner
134        ///
135        /// Function that creates and returns a new burner resource
136        ///
137
138        pub fun createNewBurner(): @Burner {
139            emit BurnerCreated()
140            return <-create Burner()
141        }
142
143    }
144
145    /// Minter
146    ///
147    /// Resource object that token admin accounts can hold to mint new tokens.
148    ///
149    pub resource Minter {
150
151        /// The amount of tokens that the minter is allowed to mint
152        pub var allowedAmount: UFix64
153
154        /// mintTokens
155        ///
156        /// Function that mints new tokens, adds them to the total supply,
157        /// and returns them to the calling context.
158        ///
159
160        pub fun mintTokens(amount: UFix64): @MoxyToken.Vault {
161            pre {
162                amount > 0.0: "Amount mined must be greater than zero ".concat(amount.toString())
163                amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
164            }
165            MoxyToken.totalSupply = MoxyToken.totalSupply + amount
166            self.allowedAmount = self.allowedAmount - amount
167            emit TokensMinted(amount: amount)
168            return <-create Vault(balance: amount)
169        }
170
171        init(allowedAmount: UFix64) {
172            self.allowedAmount = allowedAmount
173        }
174    }
175
176    /// Burner
177    ///
178    /// Resource object that token admin accounts can hold to burn tokens.
179    ///
180    pub resource Burner {
181
182        /// burnTokens
183        ///
184        /// Function that destroys a Vault instance, effectively burning the tokens.
185        ///
186        /// Note: the burned tokens are automatically subtracted from the
187        /// total supply in the Vault destructor.
188        ///
189        pub fun burnTokens(from: @FungibleToken.Vault) {
190            let vault <- from as! @MoxyToken.Vault
191            let amount = vault.balance
192            destroy vault
193            emit TokensBurned(amount: amount)
194        }
195    }
196
197    pub let moxyTokenVaultStorage: StoragePath
198    pub let moxyTokenLockedVaultStorage: StoragePath
199    pub let moxyTokenLockedVaultPrivate: PrivatePath
200    pub let moxyTokenAdminStorage: StoragePath
201    pub let moxyTokenReceiverPath: PublicPath
202    pub let moxyTokenBalancePath: PublicPath
203    pub let moxyTokenLockedBalancePath: PublicPath
204    pub let moxyTokenLockedReceiverPath: PublicPath
205    // Paths for Locked tonkens due MOX to MV conversion
206    pub let moxyTokenLockedMVVaultStorage: StoragePath
207    pub let moxyTokenLockedMVBalancePath: PublicPath
208    pub let moxyTokenLockedMVReceiverPath: PublicPath
209    // Play and Earn Paths
210    pub let moxyTokenPlayAndEarnVaultStorage: StoragePath
211    pub let moxyTokenPlayAndEarnVaultPrivate: PrivatePath
212    pub let moxyTokenPlayAndEarnBalancePath: PublicPath
213
214    init() {
215        // The initial total supply corresponds with the total amount
216        // to release in the different Token allocations rounds
217        self.totalSupply = 0.0
218
219        self.moxyTokenVaultStorage = /storage/moxyTokenVault
220        self.moxyTokenLockedVaultStorage = /storage/moxyTokenLockedVault
221        self.moxyTokenLockedVaultPrivate = /private/moxyTokenLockedVault
222        self.moxyTokenAdminStorage = /storage/moxyTokenAdmin
223        self.moxyTokenReceiverPath = /public/moxyTokenReceiver
224        self.moxyTokenBalancePath = /public/moxyTokenBalance
225        self.moxyTokenLockedBalancePath = /public/moxyTokenLockedBalance
226        self.moxyTokenLockedReceiverPath = /public/moxyTokenLockedReceiver
227        // Locked vaults due to MOX to MV conversion
228        self.moxyTokenLockedMVVaultStorage = /storage/moxyTokenLockedMVVault
229        self.moxyTokenLockedMVBalancePath = /public/moxyTokenLockedMVBalance
230        self.moxyTokenLockedMVReceiverPath = /public/moxyTokenLockedMVReceiver
231        //Play and Earn Storage
232        self.moxyTokenPlayAndEarnVaultStorage = /storage/moxyTokenPlayAndEarnVault
233        self.moxyTokenPlayAndEarnVaultPrivate = /private/moxyTokenPlayAndEarnVault
234        self.moxyTokenPlayAndEarnBalancePath = /public/moxyTokenPlayAndEarnBalance
235
236        // Create the Vault with the total supply of tokens and save it in storage
237        //
238        let vault <- create Vault(balance: self.totalSupply)
239        self.account.save(<-vault, to: self.moxyTokenVaultStorage)
240
241        // Create a public capability to the stored Vault that only exposes
242        // the `deposit` method through the `Receiver` interface
243        //
244        self.account.link<&{FungibleToken.Receiver}>(
245            self.moxyTokenReceiverPath,
246            target: self.moxyTokenVaultStorage
247        )
248
249        // Create a public capability to the stored Vault that only exposes
250        // the `balance` field through the `Balance` interface
251        //
252        self.account.link<&MoxyToken.Vault{FungibleToken.Balance}>(
253            self.moxyTokenBalancePath,
254            target: self.moxyTokenVaultStorage
255        )
256
257        // Create Play & Earn resource
258        let playAndEarnvault <- self.createEmptyVault()
259        self.account.save(<-playAndEarnvault, to: self.moxyTokenPlayAndEarnVaultStorage)
260
261        self.account.link<&FungibleToken.Vault>(
262            self.moxyTokenPlayAndEarnVaultPrivate,
263            target: self.moxyTokenPlayAndEarnVaultStorage
264        )
265        self.account.link<&FungibleToken.Vault{FungibleToken.Balance}>(
266            self.moxyTokenPlayAndEarnBalancePath,
267            target: self.moxyTokenPlayAndEarnVaultStorage
268        )
269
270
271        // Create admin resource
272        let admin <- create Administrator()
273        self.account.save(<-admin, to: self.moxyTokenAdminStorage)
274
275        // Emit an event that shows that the contract was initialized
276        //
277        emit TokensInitialized(initialSupply: self.totalSupply)
278    }
279}
280 
281