Smart Contract
LeofyMarketPlace
A.14af75b8c487333c.LeofyMarketPlace
1import FungibleToken from 0xf233dcee88fe0abe
2import LeofyNFT from 0x14af75b8c487333c
3import LeofyCoin from 0x14af75b8c487333c
4
5pub contract LeofyMarketPlace{
6
7 // The total amount of MarketplaceItems that have been created
8 pub var totalMarketPlaceItems: UInt64
9 pub var cutPercentage: UFix64
10 pub var marketplaceVault: Capability<&{FungibleToken.Receiver}>
11 pub var minimumBidIncrement: UFix64
12 pub var extendsTime: UFix64
13 pub var extendsWhenTimeLowerThan: Fix64
14
15 pub let CollectionStoragePath: StoragePath
16 pub let CollectionPublicPath: PublicPath
17 pub let AdminStoragePath: StoragePath
18
19 pub event Created(tokenID: UInt64, nftID: UInt64?, owner: Address, startPrice: UFix64, startTime: UFix64, auctionLength: UFix64, purchasePrice: UFix64)
20 pub event Bid(tokenID: UInt64, bidderAddress: Address, bidPrice: UFix64)
21 pub event Cancelled(tokenID: UInt64, owner: Address)
22 pub event Settled(tokenID: UInt64, price: UFix64)
23 pub event Purchased(tokenID: UInt64, price: UFix64)
24 pub event MarketplaceEarned(amount:UFix64, owner: Address)
25 pub event DropExtended(tokenID: UInt64, owner: Address, extendWith: UFix64, extendTo: UFix64)
26
27 pub struct MarketplaceStatus{
28 pub let id: UInt64
29 pub let price : UFix64
30 pub let bids : UInt64
31 //Active is probably not needed when we have completed and expired above, consider removing it
32 pub let active: Bool
33 pub let timeRemaining : Fix64
34 pub let endTime : Fix64
35 pub let startTime : Fix64
36 pub let metadata: AnyStruct?
37 pub let nftId: UInt64?
38 pub let owner: Address
39 pub let leader: Address?
40 pub let completed: Bool
41 pub let expired: Bool
42 pub let minNextBid: UFix64
43 pub let purchasePrice: UFix64
44 pub let cutPercentage: UFix64
45
46 init(id:UInt64,
47 currentPrice: UFix64,
48 bids:UInt64,
49 active: Bool,
50 timeRemaining:Fix64,
51 metadata: AnyStruct?,
52 nftId: UInt64?,
53 leader:Address?,
54 owner: Address,
55 startTime: Fix64,
56 endTime: Fix64,
57 completed: Bool,
58 expired:Bool,
59 minNextBid:UFix64,
60 purchasePrice: UFix64,
61 cutPercentage:UFix64
62 ) {
63 self.id=id
64 self.price=currentPrice
65 self.bids=bids
66 self.active=active
67 self.timeRemaining=timeRemaining
68 self.metadata=metadata
69 self.nftId=nftId
70 self.leader= leader
71 self.owner=owner
72 self.startTime=startTime
73 self.endTime=endTime
74 self.completed=completed
75 self.expired=expired
76 self.minNextBid=minNextBid
77 self.purchasePrice=purchasePrice
78 self.cutPercentage=cutPercentage
79 }
80 }
81
82 pub resource MarketplaceItem{
83 priv var numberOfBids: UInt64
84 //This is the escrow vault that holds the tokens for the current largest bid
85 priv var NFT: @LeofyNFT.NFT?
86 priv let bidVault: @FungibleToken.Vault
87
88 //The id of this individual auction
89 pub let marketplaceID: UInt64
90
91 //the time the acution should start at
92 priv var auctionStartTime: UFix64
93
94 //The length in seconds for this auction
95 priv var auctionLength: UFix64
96
97 //Auction Ended
98 priv var auctionCompleted: Bool
99
100 // Auction State
101 access(account) var startPrice: UFix64
102 priv var currentPrice: UFix64
103
104 //the capability that points to the resource where you want the NFT transfered to if you win this bid.
105 priv var recipientCollectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>?
106
107 //the capablity to send the escrow bidVault to if you are outbid
108 priv var recipientVaultCap: Capability<&{FungibleToken.Receiver}>?
109
110 //the capability for the owner of the NFT to return the item to if the auction is cancelled
111 priv let ownerCollectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>
112
113 //the capability to pay the owner of the item when the auction is done
114 priv let ownerVaultCap: Capability<&{FungibleToken.Receiver}>
115
116 priv var purchasePrice: UFix64
117
118 priv var cutPercentage: UFix64
119
120 init(
121 NFT: @LeofyNFT.NFT,
122 auctionStartTime: UFix64,
123 auctionLength: UFix64,
124 startPrice: UFix64,
125 ownerCollectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>,
126 ownerVaultCap: Capability<&{FungibleToken.Receiver}>,
127 purchasePrice: UFix64
128 ) {
129 pre {
130 ownerCollectionCap.check() == true: "Can't validate that the ownerCollectionCapability Exists"
131 ownerVaultCap.check() == true: "Can't validate that the ownerVaultCap Exists"
132 }
133 LeofyMarketPlace.totalMarketPlaceItems = LeofyMarketPlace.totalMarketPlaceItems + (1 as UInt64)
134
135 self.NFT <- NFT;
136 self.numberOfBids = 0
137 self.bidVault <- LeofyCoin.createEmptyVault();
138 self.marketplaceID = LeofyMarketPlace.totalMarketPlaceItems
139 self.auctionStartTime = auctionStartTime;
140 self.auctionLength = auctionLength
141 self.auctionCompleted = false;
142 self.startPrice = startPrice;
143 self.currentPrice = 0.00;
144 self.recipientCollectionCap = nil;
145 self.recipientVaultCap = nil;
146 self.ownerCollectionCap = ownerCollectionCap;
147 self.ownerVaultCap = ownerVaultCap;
148 self.purchasePrice = purchasePrice;
149 self.cutPercentage = LeofyMarketPlace.cutPercentage;
150 }
151
152 // sendNFT sends the NFT to the Collection belonging to the provided Capability
153 access(contract) fun sendNFT(_ capability: Capability<&{LeofyNFT.LeofyCollectionPublic}>) {
154 if let collectionRef = capability.borrow() {
155 let NFT <- self.NFT <- nil
156 collectionRef.deposit(token: <-NFT!)
157 return
158 }
159 if let ownerCollection=self.ownerCollectionCap.borrow() {
160 let NFT <- self.NFT <- nil
161 ownerCollection.deposit(token: <-NFT!)
162 return
163 }
164 }
165
166
167 // sendBidTokens sends the bid tokens to the Vault Receiver belonging to the provided Capability
168 access(contract) fun sendBidTokens(_ capability: Capability<&{FungibleToken.Receiver}>) {
169 // borrow a reference to the owner's NFT receiver
170 if let vaultRef = capability.borrow() {
171 let bidVaultRef = &self.bidVault as &FungibleToken.Vault
172 if(bidVaultRef.balance > 0.0) {
173 vaultRef.deposit(from: <-bidVaultRef.withdraw(amount: bidVaultRef.balance))
174 }
175 return
176 }
177
178 if let ownerRef= self.ownerVaultCap.borrow() {
179 let bidVaultRef = &self.bidVault as &FungibleToken.Vault
180 if(bidVaultRef.balance > 0.0) {
181 ownerRef.deposit(from: <-bidVaultRef.withdraw(amount: bidVaultRef.balance))
182 }
183 return
184 }
185 }
186
187 access(contract) fun releasePreviousBid() {
188 if let vaultCap = self.recipientVaultCap {
189 self.sendBidTokens(self.recipientVaultCap!)
190 return
191 }
192 }
193
194 //This method should probably use preconditions more
195 pub fun settleAuction(cutPercentage: UFix64, cutVault:Capability<&{FungibleToken.Receiver}> ) {
196
197 pre {
198 !self.auctionCompleted : "The auction is already settled"
199 self.NFT != nil: "NFT in auction does not exist"
200 self.isAuctionExpired() : "Auction has not completed yet"
201 }
202
203 // return if there are no bids to settle
204 if self.currentPrice == 0.0{
205 self.returnAuctionItemToOwner()
206 return
207 }
208
209 //Withdraw cutPercentage to marketplace and put it in their vault
210 let amount=self.currentPrice*(cutPercentage/100.00)
211 let beneficiaryCut <- self.bidVault.withdraw(amount:amount )
212
213 let cutVault=cutVault.borrow()!
214 emit MarketplaceEarned(amount: amount, owner: cutVault.owner!.address)
215 cutVault.deposit(from: <- beneficiaryCut)
216
217 self.sendNFT(self.recipientCollectionCap!)
218 self.sendBidTokens(self.ownerVaultCap)
219
220 self.auctionCompleted = true
221
222 emit Settled(tokenID: self.marketplaceID, price: self.currentPrice)
223
224 }
225
226 access(contract) fun returnAuctionItemToOwner() {
227 // release the bidder's tokens
228 self.releasePreviousBid()
229
230 // deposit the NFT into the owner's collection
231 self.sendNFT(self.ownerCollectionCap)
232 }
233
234 //this can be negative if is expired
235 pub fun timeRemaining() : Fix64 {
236 let auctionLength = self.auctionLength
237
238 let startTime = self.auctionStartTime
239 let currentTime = getCurrentBlock().timestamp
240
241 let remaining= Fix64(startTime+auctionLength) - Fix64(currentTime)
242 return remaining
243 }
244
245
246 pub fun isAuctionExpired(): Bool {
247 let timeRemaining= self.timeRemaining()
248 if(self.auctionStartTime == UFix64(0.0) || self.auctionLength == UFix64(0.0)){
249 return false
250 }
251 return timeRemaining < Fix64(0.0)
252 }
253
254 pub fun minNextBid() :UFix64{
255 //If there are bids then the next min bid is the current price plus the increment
256 if self.currentPrice != 0.0 {
257 return self.currentPrice+LeofyMarketPlace.minimumBidIncrement
258 }
259 //else start price
260 return self.startPrice
261 }
262
263 //Extend an auction with a given set of blocks
264 access(contract) fun extendWith(_ amount: UFix64) {
265 self.auctionLength= self.auctionLength + amount
266 emit DropExtended(tokenID: self.marketplaceID, owner: self.ownerCollectionCap.address, extendWith: amount, extendTo: self.auctionStartTime+self.auctionLength)
267 }
268
269 pub fun bidder() : Address? {
270 if let vaultCap = self.recipientVaultCap {
271 return vaultCap.borrow()!.owner!.address
272 }
273 return nil
274 }
275
276 pub fun currentBidForUser(address:Address): UFix64 {
277 if(self.bidder() == address) {
278 return self.bidVault.balance
279 }
280 return 0.0
281 }
282
283 pub fun placeBid(
284 bidTokens: @FungibleToken.Vault,
285 vaultCap: Capability<&{FungibleToken.Receiver}>,
286 collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>
287 ){
288 pre {
289 !self.auctionCompleted : "The auction is already settled"
290 self.NFT != nil: "NFT in auction does not exist"
291 !self.isAuctionExpired(): "Auction already expired"
292 self.auctionStartTime > UFix64(0.0): "Not an auction"
293 self.auctionLength > UFix64(0.0): "Not an auction"
294 }
295
296 let bidderAddress=vaultCap.borrow()!.owner!.address
297
298 let amountYouAreBidding= bidTokens.balance + self.currentBidForUser(address: bidderAddress)
299 let minNextBid=self.minNextBid()
300 if amountYouAreBidding < minNextBid {
301 panic("bid amount + (your current bid) must be larger or equal to the current price + minimum bid increment ".concat(amountYouAreBidding.toString()).concat(" < ").concat(minNextBid.toString()))
302 }
303
304
305 // Return balance from the current BID to the previus bidder
306 if self.bidder() != bidderAddress {
307 if self.bidVault.balance != 0.0 {
308 self.sendBidTokens(self.recipientVaultCap!)
309 }
310 }
311
312 // Deposit and save the new bidder vaults and collections
313
314 self.bidVault.deposit(from: <- bidTokens)
315 self.recipientVaultCap = vaultCap
316 self.recipientCollectionCap = collectionCap
317 self.currentPrice = self.bidVault.balance
318 self.numberOfBids = self.numberOfBids + 1;
319
320 if(self.timeRemaining() < LeofyMarketPlace.extendsWhenTimeLowerThan ){
321 self.extendWith(LeofyMarketPlace.extendsTime)
322 }
323
324 emit Bid(tokenID: self.marketplaceID, bidderAddress: vaultCap.borrow()!.owner!.address, bidPrice: self.currentPrice)
325 }
326
327 pub fun placePurchase(
328 payment: @FungibleToken.Vault,
329 collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>
330 ){
331 pre {
332 !self.auctionCompleted : "The auction is already settled"
333 self.NFT != nil: "NFT in auction does not exist"
334 !self.isAuctionExpired(): "Auction already expired"
335 payment.isInstance(Type<@LeofyCoin.Vault>()): "payment vault is not requested fungible token"
336 self.purchasePrice == payment.balance: "Purchase must be equal to the purchasePrice"
337 self.purchasePrice > 0.00: "Item is not available for sell"
338 self.purchasePrice > self.currentPrice: "Item is now only available for auction"
339 }
340
341 self.releasePreviousBid()
342
343 let cutPercentage = self.getMarketplaceStatus().cutPercentage
344 let cutVault = LeofyMarketPlace.marketplaceVault.borrow()!
345
346 let amount=self.purchasePrice*(cutPercentage/100.00)
347 let beneficiaryCut <- payment.withdraw(amount:amount )
348
349 emit MarketplaceEarned(amount: amount, owner: cutVault.owner!.address)
350 cutVault.deposit(from: <- beneficiaryCut)
351
352 self.sendNFT(collectionCap)
353
354 if let ownerRef= self.ownerVaultCap.borrow() {
355 if(payment.balance > 0.0) {
356 // ownerRef.deposit(from: <- payment)
357 }
358 }
359 let ownerRef = self.ownerVaultCap.borrow()
360 ?? panic("Could not borrow reference to the owner's Vault!")
361
362 ownerRef.deposit(from: <- payment)
363
364 //self.ownerVaultCap.borrow().deposit(from: <- payment)
365
366 self.auctionCompleted = true
367
368 emit Purchased(tokenID: self.marketplaceID, price: self.purchasePrice)
369
370
371
372 }
373
374 pub fun getMarketplaceStatus() : MarketplaceStatus {
375
376 var leader:Address?= nil
377 if let recipient = self.recipientVaultCap {
378 leader=recipient.address
379 }
380
381 let view = self.NFT?.resolveView(Type<LeofyNFT.LeofyNFTMetadataView>())
382
383 return MarketplaceStatus(
384 id:self.marketplaceID,
385 currentPrice: self.currentPrice,
386 bids: self.numberOfBids,
387 active: !self.auctionCompleted && !self.isAuctionExpired(),
388 timeRemaining: self.timeRemaining(),
389 metadata: view,
390 nftId: self.NFT?.id,
391 leader: leader,
392 owner: self.ownerVaultCap.address,
393 startTime: Fix64(self.auctionStartTime),
394 endTime: Fix64(self.auctionStartTime+self.auctionLength),
395 completed: self.auctionCompleted,
396 expired: self.isAuctionExpired(),
397 minNextBid: self.minNextBid(),
398 purchasePrice: self.purchasePrice,
399 cutPercentage: self.cutPercentage
400 )
401 }
402
403 destroy() {
404 if self.NFT != nil {
405 self.sendNFT(self.ownerCollectionCap)
406 }
407
408 // if there's a bidder...
409 if let vaultCap = self.recipientVaultCap {
410 // ...send the bid tokens back to the bidder
411 self.sendBidTokens(vaultCap)
412 }
413
414 destroy self.bidVault;
415 destroy self.NFT;
416 }
417 }
418
419 pub resource interface MarketplaceCollectionPublic {
420 pub fun placeBid(id: UInt64, bidTokens: @FungibleToken.Vault, vaultCap: Capability<&{FungibleToken.Receiver}>, collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>)
421 pub fun placePurchase(id: UInt64, payment: @FungibleToken.Vault, collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>)
422 pub fun getMarketplaceStatuses(): {UInt64: MarketplaceStatus}
423 pub fun getMarketplaceStatus(_ id:UInt64): MarketplaceStatus
424 pub fun settleAuction(_ id: UInt64)
425 }
426
427 pub resource MarketplaceCollection: MarketplaceCollectionPublic{
428 access(account) var marketplaceItems: @{UInt64: MarketplaceItem}
429 init(){
430 self.marketplaceItems <- {}
431 }
432
433 pub fun sellItem(
434 token: @LeofyNFT.NFT,
435 auctionStartTime: UFix64,
436 auctionLength: UFix64,
437 startPrice: UFix64,
438 ownerCollectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>,
439 ownerVaultCap: Capability<&{FungibleToken.Receiver}>,
440 purchasePrice: UFix64
441 ){
442 pre {
443 ( purchasePrice == 0.00 && auctionStartTime > 0.00 && auctionLength > 0.00 || purchasePrice > (startPrice + LeofyMarketPlace.minimumBidIncrement )):
444 "Purchase Price ("
445 .concat(purchasePrice.toString())
446 .concat(") must be higher than startPrice (")
447 .concat(startPrice.toString()).concat(") + the minimumBidIncrement (")
448 .concat(LeofyMarketPlace.minimumBidIncrement.toString())
449 .concat(") or be zero")
450 }
451
452 let marketPlaceItem <- create MarketplaceItem(
453 NFT: <-token,
454 auctionStartTime: auctionStartTime,
455 auctionLength: auctionLength,
456 startPrice: startPrice,
457 ownerCollectionCap: ownerCollectionCap,
458 ownerVaultCap: ownerVaultCap,
459 purchasePrice: purchasePrice
460 )
461
462 let id = marketPlaceItem.marketplaceID
463 let nftID = marketPlaceItem.getMarketplaceStatus().nftId;
464
465 let oldItem <- self.marketplaceItems[marketPlaceItem.marketplaceID] <- marketPlaceItem
466 destroy oldItem
467
468 emit Created(tokenID: id, nftID: nftID, owner: ownerVaultCap.address, startPrice: startPrice, startTime: auctionStartTime, auctionLength: auctionLength, purchasePrice: purchasePrice)
469 }
470
471 // getAuctionPrices returns a dictionary of available NFT IDs with their current price
472 pub fun getMarketplaceStatuses(): {UInt64: MarketplaceStatus} {
473 let priceList: {UInt64: MarketplaceStatus} = {}
474
475 for id in self.marketplaceItems.keys {
476 let itemRef = (&self.marketplaceItems[id] as? &MarketplaceItem?)!
477 priceList[id] = itemRef.getMarketplaceStatus()
478 }
479
480 return priceList
481 }
482
483 pub fun getMarketplaceStatus(_ id:UInt64): MarketplaceStatus {
484 pre {
485 self.marketplaceItems[id] != nil:
486 "NFT doesn't exist"
487 }
488
489 // Get the auction item resources
490 let itemRef = (&self.marketplaceItems[id] as &MarketplaceItem?)!
491 return itemRef.getMarketplaceStatus()
492
493 }
494
495 pub fun cancelAuction(_ id: UInt64) {
496 pre {
497 self.marketplaceItems[id] != nil:
498 "Auction does not exist"
499 }
500 let itemRef = (&self.marketplaceItems[id] as &MarketplaceItem?)!
501
502 let tokenID = itemRef.marketplaceID;
503 let owner = itemRef.getMarketplaceStatus().owner
504 //itemRef.destroy()
505 //itemRef.returnAuctionItemToOwner()
506
507 let oldItem <- self.marketplaceItems[id] <- nil
508 destroy oldItem
509
510 emit Cancelled(tokenID: tokenID, owner: owner)
511
512 }
513
514 pub fun placeBid(id: UInt64, bidTokens: @FungibleToken.Vault, vaultCap: Capability<&{FungibleToken.Receiver}>, collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>) {
515 pre {
516 self.marketplaceItems[id] != nil: "Auction does not exist in this drop"
517 }
518
519 // Get the auction item resources
520 let itemRef = (&self.marketplaceItems[id] as &MarketplaceItem?)!
521 itemRef.placeBid(bidTokens: <- bidTokens,
522 vaultCap:vaultCap,
523 collectionCap:collectionCap)
524
525 }
526
527 pub fun placePurchase(id: UInt64, payment: @FungibleToken.Vault, collectionCap: Capability<&{LeofyNFT.LeofyCollectionPublic}>) {
528 pre {
529 self.marketplaceItems[id] != nil: "Auction does not exist in this drop"
530 }
531
532 // Get the auction item resources
533 let itemRef = (&self.marketplaceItems[id] as &MarketplaceItem?)!
534 itemRef.placePurchase(payment: <- payment,
535 collectionCap:collectionCap)
536
537 let oldItem <- self.marketplaceItems[id] <- nil
538 destroy oldItem
539
540 }
541
542 // settleAuction sends the auction item to the highest bidder
543 // and deposits the FungibleTokens into the auction owner's account
544 pub fun settleAuction(_ id: UInt64) {
545 pre {
546 self.marketplaceItems[id] != nil: "Auction does not exist in this drop"
547 }
548
549 let itemRef = (&self.marketplaceItems[id] as &MarketplaceItem?)!
550 itemRef.settleAuction(cutPercentage: itemRef.getMarketplaceStatus().cutPercentage, cutVault: LeofyMarketPlace.marketplaceVault)
551
552 let oldItem <- self.marketplaceItems[id] <- nil
553 destroy oldItem
554 }
555
556 destroy() {
557 log("destroy auction collection")
558 // destroy the empty resources
559 destroy self.marketplaceItems
560 }
561 }
562
563 // public function that anyone can call to create a new empty collection
564 pub fun createEmptyCollection(): @LeofyMarketPlace.MarketplaceCollection {
565 return <- create MarketplaceCollection()
566 }
567
568 // Only owner of this resource object can call this function
569 pub resource LeofyMarketPlaceAdmin {
570 pub fun changePercentage(_ cutPercentage: UFix64){
571 pre {
572 cutPercentage >= 0.00 && cutPercentage <= 100.00: "Cut percentage must be between 0 and 100"
573 }
574 LeofyMarketPlace.cutPercentage = cutPercentage
575 }
576
577 pub fun changeBidIncrement(_ minimumBidIncrement: UFix64){
578 LeofyMarketPlace.minimumBidIncrement = minimumBidIncrement
579 }
580
581 pub fun changeExtendsTime(_ extendsTime: UFix64){
582 LeofyMarketPlace.extendsTime = extendsTime
583 }
584
585 pub fun changeExtendsWhenTimeLowerThan(_ extendsWhenTimeLowerThan: Fix64){
586 LeofyMarketPlace.extendsWhenTimeLowerThan = extendsWhenTimeLowerThan
587 }
588
589 pub fun changeMarketplaceVault(_ marketplaceVault: Capability<&{FungibleToken.Receiver}>){
590 pre {
591 marketplaceVault.check() == true: "Can't validate that the marketplaceVault Exists"
592 }
593 LeofyMarketPlace.marketplaceVault = marketplaceVault
594 }
595 }
596
597 init() {
598 self.totalMarketPlaceItems = 0
599 self.cutPercentage = 15.00
600 self.marketplaceVault = self.account.getCapability<&AnyResource{FungibleToken.Receiver}>(LeofyCoin.ReceiverPublicPath)
601 self.minimumBidIncrement = 1.00
602 self.extendsTime = 300.00
603 self.extendsWhenTimeLowerThan = 60.00
604
605 self.CollectionStoragePath = /storage/LeofyMarketPlaceCollection
606 self.CollectionPublicPath = /public/LeofyMarketPlaceCollection
607 self.AdminStoragePath = /storage/LeofyMarketPlaceAdmin
608
609 destroy self.account.load<@MarketplaceCollection>(from: self.CollectionStoragePath)
610 let marketplaceCollection <- create MarketplaceCollection()
611 self.account.save(<-marketplaceCollection, to: self.CollectionStoragePath)
612
613 destroy self.account.load<@LeofyMarketPlaceAdmin>(from: self.AdminStoragePath)
614 // Put the Admin in storage
615 self.account.save<@LeofyMarketPlaceAdmin>(<- create LeofyMarketPlaceAdmin(), to: self.AdminStoragePath)
616
617 // create a public capability for the collection
618 self.account.link<&LeofyMarketPlace.MarketplaceCollection{LeofyMarketPlace.MarketplaceCollectionPublic}>(
619 self.CollectionPublicPath,
620 target: self.CollectionStoragePath
621 )
622 }
623}
624