Smart Contract

FGameLotteryFactory

A.d2abb5dbf5e08666.FGameLotteryFactory

Valid From

86,129,025

Deployed

3d ago
Feb 24, 2026, 11:54:28 PM UTC

Dependents

5 imports
1/**
2> Author: Fixes Lab <https://github.com/fixes-world/>
3
4# FGameLotteryFactory
5
6This contract contains the factory for creating new Lottery Pool.
7
8*/
9import Burner from 0xf233dcee88fe0abe
10import FlowToken from 0x1654653399040a61
11import FungibleToken from 0xf233dcee88fe0abe
12import BlackHole from 0x4396883a58c3a2d1
13// Fixes Imports
14import Fixes from 0xd2abb5dbf5e08666
15import FixesInscriptionFactory from 0xd2abb5dbf5e08666
16import FRC20FTShared from 0xd2abb5dbf5e08666
17import FRC20Indexer from 0xd2abb5dbf5e08666
18import FGameLottery from 0xd2abb5dbf5e08666
19import FGameLotteryRegistry from 0xd2abb5dbf5e08666
20// Fixes Coins
21import FixesTradablePool from 0xd2abb5dbf5e08666
22
23access(all) contract FGameLotteryFactory {
24
25    /* --- Enum --- */
26
27    /// PowerUp Types
28    ///
29    access(all) enum PowerUpType: UInt8 {
30        access(all) case x1
31        access(all) case x2
32        access(all) case x3
33        access(all) case x4
34        access(all) case x5
35        access(all) case x10
36        access(all) case x20
37        access(all) case x50
38        access(all) case x100
39    }
40
41    /// Get the value of the PowerUp
42    ///
43    access(all)
44    view fun getPowerUpValue(_ type: PowerUpType): UFix64 {
45        switch type {
46        case PowerUpType.x2:
47            return 2.0
48        case PowerUpType.x3:
49            return 3.0
50        case PowerUpType.x4:
51            return 4.0
52        case PowerUpType.x5:
53            return 5.0
54        case PowerUpType.x10:
55            return 10.0
56        case PowerUpType.x20:
57            return 20.0
58        case PowerUpType.x50:
59            return 50.0
60        case PowerUpType.x100:
61            return 100.0
62        }
63        // Default is x1
64        return 1.0
65    }
66
67    /* --- Public Methods - Controller --- */
68
69    access(all)
70    view fun getFIXESLotteryPoolName(): String {
71        return "FIXES_BASIS_LOTTERY_POOL"
72    }
73
74    access(all)
75    view fun getFIXESMintingLotteryPoolName(): String {
76        return "FIXES_MINTING_LOTTERY_POOL"
77    }
78
79    /// Initialize the $FIXES Lottery Pool
80    /// This pool is for directly paying $FIXES to purchase lottery tickets.
81    ///
82    access(all)
83    fun initializeFIXESLotteryPool(
84        _ controller: auth(FGameLotteryRegistry.Manage) &FGameLotteryRegistry.RegistryController,
85        newAccount: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>,
86    ) {
87        // initialize with 3 days
88        let epochInterval: UFix64 = UFix64(3 * 24 * 60 * 60) // 3 days
89        self._initializeLotteryPool(
90            controller,
91            name: self.getFIXESLotteryPoolName(),
92            rewardTick: FRC20FTShared.getPlatformUtilityTickerName(),
93            ticketPrice: FixesInscriptionFactory.estimateLotteryFIXESTicketsCost(1, nil),
94            epochInterval: epochInterval,
95            newAccount: newAccount
96        )
97    }
98
99    /// Initialize the $FIXES Minting Lottery Pool
100    /// This pool pays 1 $FLOW each time, while minting $FIXES x 4. The excess FLOW is used to purchase lottery tickets.
101    ///
102    access(all)
103    fun initializeFIXESMintingLotteryPool(
104        _ controller: auth(FGameLotteryRegistry.Manage) &FGameLotteryRegistry.RegistryController,
105        newAccount: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>,
106    ) {
107        // initialize with 3 days
108        let epochInterval: UFix64 = UFix64(3 * 24 * 60 * 60) // 3 days
109        // let epochInterval: UFix64 = UFix64(2 * 60) // 2 min
110        let rewardTick: String = "" // empty string means $FLOW
111        let fixesMintingStr = FixesInscriptionFactory.buildMintFRC20(tick: "fixes", amt: 1000.0)
112        var estimateMintingCost = FixesInscriptionFactory.estimateFrc20InsribeCost(fixesMintingStr)
113        assert(
114            estimateMintingCost < 0.25,
115            message: "Minting cost is too high"
116        )
117        // ensure the minting cost is at least 0.2
118        if estimateMintingCost < 0.2 {
119            estimateMintingCost = 0.21630 // the minting price on mainnet
120        }
121        var ticketPrice: UFix64 = 1.0 - 4.0 * estimateMintingCost // ticket price = 1.0 - 4 x $FIXES minting price
122
123        self._initializeLotteryPool(
124            controller,
125            name: self.getFIXESMintingLotteryPoolName(),
126            rewardTick: rewardTick,
127            ticketPrice: ticketPrice,
128            epochInterval: epochInterval,
129            newAccount: newAccount
130        )
131    }
132
133    /// Genereal initialize the Lottery Pool
134    ///
135    access(contract)
136    fun _initializeLotteryPool(
137        _ controller: auth(FGameLotteryRegistry.Manage) &FGameLotteryRegistry.RegistryController,
138        name: String,
139        rewardTick: String,
140        ticketPrice: UFix64,
141        epochInterval: UFix64,
142        newAccount: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>,
143    ) {
144        let registry = FGameLotteryRegistry.borrowRegistry()
145        assert(
146            registry.getLotteryPoolAddress(name) == nil,
147            message: "Lottery pool name is not available"
148        )
149        // Create the Lottery Pool
150        controller.createLotteryPool(
151            name: name,
152            rewardTick: rewardTick,
153            ticketPrice: ticketPrice,
154            epochInterval: epochInterval,
155            newAccount: newAccount
156        )
157    }
158
159    /* --- Public methods - User --- */
160
161    /// Check if the FIXES Minting is available
162    ///
163    access(all)
164    view fun isFIXESMintingAvailable(): Bool {
165        // Singleton Resource
166        let frc20Indexer = FRC20Indexer.getIndexer()
167        if let tokenMeta = frc20Indexer.getTokenMeta(tick: "fixes") {
168            return tokenMeta.max > tokenMeta.supplied
169        }
170        return false
171    }
172
173    /// Get the cost of buying FIXES Minting Lottery Tickets
174    ///
175    access(all)
176    view fun getFIXESMintingLotteryFlowCost(_ ticketAmount: UInt64, _ powerup: PowerUpType, _ withMinting: Bool): UFix64 {
177        let powerupValue: UFix64 = self.getPowerUpValue(powerup)
178        // singleton resource
179        let registry = FGameLotteryRegistry.borrowRegistry()
180        // Ticket info
181        let poolName = self.getFIXESMintingLotteryPoolName()
182        let lotteryPoolAddr = registry.getLotteryPoolAddress(poolName) ?? panic("Lottery pool not found")
183        let lotteryPoolRef = FGameLottery.borrowLotteryPool(lotteryPoolAddr)
184            ?? panic("Lottery pool not found")
185        let ticketPrice = lotteryPoolRef.getTicketPrice()
186        if self.isFIXESMintingAvailable() && withMinting {
187            return 1.0 * UFix64(ticketAmount) * powerupValue
188        } else {
189            return ticketPrice * UFix64(ticketAmount) * powerupValue
190        }
191    }
192
193    /// Use $FLOW to buy FIXES Minting Lottery Tickets
194    /// Return the inscription ids of the minting transactions
195    ///
196    access(all)
197    fun buyFIXESMintingLottery(
198        flowProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider},
199        ticketAmount: UInt64,
200        powerup: PowerUpType,
201        withMinting: Bool,
202        recipient: Capability<&FGameLottery.TicketCollection>,
203        inscriptionStore: auth(Fixes.Manage) &Fixes.InscriptionsStore,
204    ) {
205        pre {
206            recipient.address == inscriptionStore.owner?.address: "Recipient must be the owner of the inscription store"
207        }
208
209        // Singleton Resource
210        let frc20Indexer = FRC20Indexer.getIndexer()
211        let registry = FGameLotteryRegistry.borrowRegistry()
212
213        // check if the FLOW balance is sufficient
214        let powerupValue: UFix64 = self.getPowerUpValue(powerup)
215
216        // Ticket info
217        let poolName = self.getFIXESMintingLotteryPoolName()
218        let lotteryPoolAddr = registry.getLotteryPoolAddress(poolName) ?? panic("Lottery pool not found")
219        let lotteryPoolRef = FGameLottery.borrowLotteryPool(lotteryPoolAddr)
220            ?? panic("Lottery pool not found")
221        let ticketPrice = lotteryPoolRef.getTicketPrice()
222        let ticketsPayment = ticketPrice * UFix64(ticketAmount) * powerupValue
223        // check if the FLOW balance is sufficient
224        assert(
225            flowProvider.isAvailableToWithdraw(amount: ticketsPayment),
226            message: "Insufficient FLOW balance"
227        )
228        // Withdraw the FLOW from the provider
229
230        // for minting available
231        if withMinting && self.isFIXESMintingAvailable() {
232            let totalCost: UFix64 = 1.0 * UFix64(ticketAmount) * powerupValue
233            log("Total cost: ".concat(totalCost.toString()))
234            assert(
235                flowProvider.isAvailableToWithdraw(amount: totalCost),
236                message: "Insufficient FLOW balance"
237            )
238
239            // check if the total mint amount is valid
240            let totalMintAmount = ticketAmount * UInt64(powerupValue) * 4
241            log("Total Mints: ".concat(totalMintAmount.toString()))
242            assert(
243                totalMintAmount > 0 && totalMintAmount <= 120,
244                message: "Total mint amount must be between 1 and 120"
245            )
246
247            // Mint $FIXES information
248            let fixesMeta = frc20Indexer.getTokenMeta(tick: "fixes") ?? panic("FIXES Token meta not found")
249            let fixesMintingStr = FixesInscriptionFactory.buildMintFRC20(tick: "fixes", amt: fixesMeta.limit)
250
251            var i: UInt64 = 0
252            while i < totalMintAmount && self.isFIXESMintingAvailable() {
253                // required $FLOW per mint
254                let estimatedReqValue = FixesInscriptionFactory.estimateFrc20InsribeCost(fixesMintingStr)
255                let costReserve <- flowProvider.withdraw(amount: estimatedReqValue)
256                // create minting $FIXES inscription and store it
257                let insId = FixesInscriptionFactory.createAndStoreFrc20Inscription(
258                    fixesMintingStr,
259                    <- (costReserve as! @FlowToken.Vault),
260                    inscriptionStore
261                )
262                // apply the minting $FIXES inscription
263                let insRef = inscriptionStore.borrowInscriptionWritableRef(insId)!
264                frc20Indexer.mint(ins: insRef)
265                // next
266                i = i + 1
267            }
268        }
269
270        // wrap the inscription change
271        let change <- FRC20FTShared.wrapFungibleVaultChange(
272            ftVault: <- flowProvider.withdraw(amount: ticketsPayment),
273            from: recipient.address
274        )
275        // buy the tickets
276        lotteryPoolRef.buyTickets(
277            // withdraw flow token from the vault
278            payment: <- change,
279            amount: ticketAmount,
280            powerup: powerupValue,
281            recipient: recipient,
282        )
283    }
284
285    /// Get the cost of buying FIXES Lottery Tickets
286    ///
287    access(all)
288    view fun getFIXESLotteryFlowCost(_ ticketAmount: UInt64, _ powerup: PowerUpType, _ recipient: Address): UFix64 {
289        // check if the FLOW balance is sufficient
290        let ticketPrice = FixesInscriptionFactory.estimateLotteryFIXESTicketsCost(1, nil)
291        let powerupValue: UFix64 = self.getPowerUpValue(powerup)
292        let ticketsPayment: UFix64 = ticketPrice * UFix64(ticketAmount) * powerupValue
293
294        var requiredFlow: UFix64 = FixesInscriptionFactory.estimateFrc20InsribeCost(
295            FixesInscriptionFactory.buildLotteryBuyFIXESTickets(ticketAmount, powerupValue)
296        )
297
298        // Singleton Resource
299        let frc20Indexer = FRC20Indexer.getIndexer()
300
301        // Mint $FIXES information
302        let fixesMeta = frc20Indexer.getTokenMeta(tick: "fixes") ?? panic("FIXES Token meta not found")
303        let fixesMintingStr = FixesInscriptionFactory.buildMintFRC20(tick: "fixes", amt: fixesMeta.limit)
304
305        // check balance of the $FIXES token if it is sufficient to buy the tickets
306        let balance = frc20Indexer.getBalance(tick: "fixes", addr: recipient)
307        // ensure the balance is sufficient
308        if balance < ticketsPayment {
309            // mint enough $FIXES to buy the tickets
310            let totalMintAmount = UInt64((ticketsPayment - balance) / fixesMeta.limit) + 1
311
312            requiredFlow = requiredFlow + UFix64(totalMintAmount) * FixesInscriptionFactory.estimateFrc20InsribeCost(fixesMintingStr)
313        }
314        return requiredFlow
315    }
316
317    /// Use $FIXES to buy FIXES Lottery Tickets
318    ///
319    access(all)
320    fun buyFIXESLottery(
321        flowProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider},
322        ticketAmount: UInt64,
323        powerup: PowerUpType,
324        recipient: Capability<&FGameLottery.TicketCollection>,
325        inscriptionStore: auth(Fixes.Manage) &Fixes.InscriptionsStore,
326    ) {
327        pre {
328            recipient.address == inscriptionStore.owner?.address: "Recipient must be the owner of the inscription store"
329        }
330
331        // Singleton Resource
332        let frc20Indexer = FRC20Indexer.getIndexer()
333        let registry = FGameLotteryRegistry.borrowRegistry()
334
335        // the recipient address
336        let recipientAddr = recipient.address
337
338        // lottery pool
339        let poolName = self.getFIXESLotteryPoolName()
340        let lotteryPoolAddr = registry.getLotteryPoolAddress(poolName) ?? panic("Lottery pool not found")
341        let lotteryPoolRef = FGameLottery.borrowLotteryPool(lotteryPoolAddr)
342            ?? panic("Lottery pool not found")
343        let ticketPrice = lotteryPoolRef.getTicketPrice()
344
345        // check if the FLOW balance is sufficient
346        let powerupValue: UFix64 = self.getPowerUpValue(powerup)
347        let ticketsPayment: UFix64 = ticketPrice * UFix64(ticketAmount) * powerupValue
348
349        // Mint $FIXES information
350        let fixesMeta = frc20Indexer.getTokenMeta(tick: "fixes") ?? panic("FIXES Token meta not found")
351        let fixesMintingStr = FixesInscriptionFactory.buildMintFRC20(tick: "fixes", amt: fixesMeta.limit)
352
353        // check balance of the $FIXES token if it is sufficient to buy the tickets
354        var balance = frc20Indexer.getBalance(tick: "fixes", addr: recipientAddr)
355        // ensure the balance is sufficient
356        if balance < ticketsPayment {
357            // mint enough $FIXES to buy the tickets
358            let totalMintAmount = UInt64((ticketsPayment - balance) / fixesMeta.limit) + 1
359
360            var i: UInt64 = 0
361            while i < totalMintAmount && self.isFIXESMintingAvailable() {
362                // required $FLOW per mint
363                let estimatedReqValue = FixesInscriptionFactory.estimateFrc20InsribeCost(fixesMintingStr)
364                let costReserve <- flowProvider.withdraw(amount: estimatedReqValue)
365                // create minting $FIXES inscription and store it
366                let insId = FixesInscriptionFactory.createAndStoreFrc20Inscription(
367                    fixesMintingStr,
368                    <- (costReserve as! @FlowToken.Vault),
369                    inscriptionStore
370                )
371                // apply the inscription
372                let insRef = inscriptionStore.borrowInscriptionWritableRef(insId)!
373                frc20Indexer.mint(ins: insRef)
374                // next
375                i = i + 1
376            }
377        } // end if
378
379        // check current balance
380        balance = frc20Indexer.getBalance(tick: "fixes", addr: recipientAddr)
381        var ticketAmountFinal = ticketAmount
382        if ticketsPayment > balance {
383            ticketAmountFinal = UInt64(balance / (ticketPrice * powerupValue))
384        }
385        assert(
386            ticketAmountFinal > 0,
387            message: "Insufficient $FIXES balance"
388        )
389
390        // build the inscription string
391        let buyTicketsInsStr = FixesInscriptionFactory.buildLotteryBuyFIXESTickets(ticketAmountFinal, powerupValue)
392        let estimatedBuyTicketsInsCost = FixesInscriptionFactory.estimateFrc20InsribeCost(buyTicketsInsStr)
393        let costReserve <- flowProvider.withdraw(amount: estimatedBuyTicketsInsCost)
394        // create the withdraw inscription
395        let insId = FixesInscriptionFactory.createAndStoreFrc20Inscription(
396            buyTicketsInsStr,
397            <- (costReserve as! @FlowToken.Vault),
398            inscriptionStore
399        )
400        // apply the inscription
401        let insRef = inscriptionStore.borrowInscriptionWritableRef(insId)!
402        // withdraw the $FIXES from the recipient
403        let change <- frc20Indexer.withdrawChange(ins: insRef)
404
405        // buy the tickets
406        lotteryPoolRef.buyTickets(
407            // withdraw flow token from the vault
408            payment: <- change,
409            amount: ticketAmountFinal,
410            powerup: powerupValue,
411            recipient: recipient,
412        )
413    }
414
415    /// Estimate the ticket information
416    ///
417    access(all) struct CoinTicketEstimate {
418        access(all) let poolAddr: Address
419        access(all) let tokenTicker: String
420        access(all) let tokenBoughtAmount: UFix64
421        access(all) let ticketPrice: UFix64
422        access(all) let ticketAmount: UInt64
423        access(all) let powerupValue: UFix64
424
425        view init(
426            poolAddr: Address,
427            tokenTicker: String,
428            tokenBoughtAmount: UFix64,
429            ticketPrice: UFix64,
430            ticketAmount: UInt64,
431            powerupValue: UFix64
432        ) {
433            self.poolAddr = poolAddr
434            self.tokenTicker = tokenTicker
435            self.tokenBoughtAmount = tokenBoughtAmount
436            self.ticketPrice = ticketPrice
437            self.ticketAmount = ticketAmount
438            self.powerupValue = powerupValue
439        }
440    }
441
442    /// Estimate the cost of buying the coin with lottery tickets
443    ///
444    access(all)
445    view fun estimateButTokenWithTickets(
446        _ coinAddr: Address,
447        flowAmount: UFix64,
448    ): CoinTicketEstimate? {
449        let lotteryPoolRef = FGameLottery.borrowLotteryPool(coinAddr)
450            ?? panic("Lottery pool not found")
451
452        let tradablePoolRef = FixesTradablePool.borrowTradablePool(coinAddr)
453            ?? panic("Tradable pool not found")
454
455        // coin's token type
456        let tokenType = tradablePoolRef.getTokenType()
457        let tickerName = FRC20FTShared.buildTicker(tokenType) ?? panic("Ticker is not valid")
458
459        // estimate the required storage
460        let dataStr = FixesInscriptionFactory.buildPureExecuting(tick: tickerName, usage: "init", {})
461        let estimatedReqValue = FixesInscriptionFactory.estimateFrc20InsribeCost(dataStr)
462
463        let tokenBoughtAmountInTotal = tradablePoolRef.getEstimatedBuyingAmountByCost(flowAmount - estimatedReqValue)
464
465        var tokenBoughtAmount = tokenBoughtAmountInTotal * 0.9
466        var tokenToBuyTickets = tokenBoughtAmountInTotal - tokenBoughtAmount
467        if !tradablePoolRef.isLocalActive() {
468            tokenBoughtAmount = 0.0
469            tokenToBuyTickets = tokenBoughtAmountInTotal
470        }
471
472        let ticketPrice = lotteryPoolRef.getTicketPrice()
473        let maxCounter = UInt64(tokenToBuyTickets / ticketPrice)
474        if maxCounter == 0 {
475            return nil
476        }
477
478        // select the powerup value
479        var powerupValue = self.getBestPowerupValue(maxCounter)
480        let ticketAmount = UInt64(tokenToBuyTickets / (ticketPrice * powerupValue))
481        let ticketsPayment: UFix64 = UFix64(ticketAmount) * ticketPrice * powerupValue
482
483        return CoinTicketEstimate(
484            poolAddr: coinAddr,
485            tokenTicker: tickerName,
486            tokenBoughtAmount: tokenBoughtAmount + tokenToBuyTickets - ticketsPayment,
487            ticketPrice: ticketPrice,
488            ticketAmount: ticketAmount,
489            powerupValue: powerupValue
490        )
491    }
492
493    /// Buy the coin with lottery tickets
494    ///
495    access(all)
496    fun buyCoinWithLotteryTicket(
497        _ coinAddr: Address,
498        flowProvider: auth(FungibleToken.Withdraw) &{FungibleToken.Provider},
499        flowAmount: UFix64,
500        ftReceiver: &{FungibleToken.Receiver},
501        ticketRecipient: Capability<&FGameLottery.TicketCollection>,
502        inscriptionStore: auth(Fixes.Manage) &Fixes.InscriptionsStore,
503    ) {
504        pre {
505            ftReceiver.owner?.address == inscriptionStore.owner?.address: "FT Receiver must be the owner of the inscription store"
506            ticketRecipient.address == inscriptionStore.owner?.address: "Ticket Recipient must be the owner of the inscription store"
507        }
508
509        // resources
510        let lotteryPoolRef = FGameLottery.borrowLotteryPool(coinAddr)
511            ?? panic("Lottery pool not found")
512        let tradablePoolRef = FixesTradablePool.borrowTradablePool(coinAddr)
513            ?? panic("Tradable pool not found")
514
515        // coin's token type
516        let tokenType = tradablePoolRef.getTokenType()
517        assert(
518            ftReceiver.isSupportedVaultType(type: tokenType),
519            message: "Unsupported token type"
520        )
521
522        // ---- create the basic inscription ----
523        let tickerName = "$".concat(tradablePoolRef.getSymbol())
524        let dataStr = FixesInscriptionFactory.buildPureExecuting(
525            tick: tickerName,
526            usage: "init",
527            {}
528        )
529        // estimate the required storage
530        let estimatedReqValue = FixesInscriptionFactory.estimateFrc20InsribeCost(dataStr)
531        let costReserve <- flowProvider.withdraw(amount: estimatedReqValue)
532        // create the inscription
533        let insId = FixesInscriptionFactory.createAndStoreFrc20Inscription(
534            dataStr,
535            <- (costReserve as! @FlowToken.Vault),
536            inscriptionStore
537        )
538        // apply the inscription
539        let ins = inscriptionStore.borrowInscriptionWritableRef(insId)!
540        // ---- end ----
541
542        // ---- deposit the but token cost to inscription ----
543        let flowCanUse = flowAmount - estimatedReqValue
544        let costVault <- flowProvider.withdraw(amount: flowCanUse)
545        ins.deposit(<- (costVault as! @FlowToken.Vault))
546        // ---- end ----
547
548        // buy token first
549        let tokenToBuyTickets <- tradablePoolRef.buyTokensWithLottery(ins, recipient: ftReceiver)
550        if tokenToBuyTickets.balance > 0.0 {
551            let ticketPrice = lotteryPoolRef.getTicketPrice()
552            let maxCounter = UInt64(tokenToBuyTickets.balance / ticketPrice)
553
554            // select the powerup value
555            var powerupValue = self.getBestPowerupValue(maxCounter)
556            let ticketAmount = UInt64(tokenToBuyTickets.balance / (ticketPrice * powerupValue))
557            let ticketsPayment: UFix64 = UFix64(ticketAmount) * ticketPrice * powerupValue
558
559            // wrap the inscription change
560            let change <- FRC20FTShared.wrapFungibleVaultChange(
561                ftVault: <- tokenToBuyTickets.withdraw(amount: ticketsPayment),
562                from: ticketRecipient.address
563            )
564            // buy the tickets
565            lotteryPoolRef.buyTickets(
566                // withdraw flow token from the vault
567                payment: <- change,
568                amount: ticketAmount,
569                powerup: powerupValue,
570                recipient: ticketRecipient,
571            )
572        }
573
574        // handle rest of the tokens
575        if tokenToBuyTickets.balance > 0.0 {
576            ftReceiver.deposit(from: <- tokenToBuyTickets)
577        } else {
578            Burner.burn(<- tokenToBuyTickets)
579        }
580    }
581
582    access(all)
583    view fun getBestPowerupValue(_ maxCounter: UInt64): UFix64 {
584        if maxCounter > 10000 {
585            return self.getPowerUpValue(PowerUpType.x100)
586        } else if maxCounter > 2000 {
587            return self.getPowerUpValue(PowerUpType.x50)
588        } else if maxCounter > 1000 {
589            return self.getPowerUpValue(PowerUpType.x20)
590        } else if maxCounter > 200 {
591            return self.getPowerUpValue(PowerUpType.x10)
592        } else if maxCounter > 100 {
593            return self.getPowerUpValue(PowerUpType.x5)
594        } else if maxCounter > 50 {
595            return self.getPowerUpValue(PowerUpType.x4)
596        } else if maxCounter > 20 {
597            return self.getPowerUpValue(PowerUpType.x3)
598        } else if maxCounter > 10 {
599            return self.getPowerUpValue(PowerUpType.x2)
600        }
601        return self.getPowerUpValue(PowerUpType.x1)
602    }
603}
604