Smart Contract
AuctionV2
A.f5b0eb433389ac3f.AuctionV2
1import FungibleToken from 0xf233dcee88fe0abe
2import FUSD from 0x3c5959b568896393
3import Collectible from 0xf5b0eb433389ac3f
4import NonFungibleToken from 0x1d7e57aa55817448
5import Edition from 0xf5b0eb433389ac3f
6
7pub contract AuctionV2 {
8
9 pub let CollectionStoragePath: StoragePath
10 pub let CollectionPublicPath: PublicPath
11
12 pub struct AuctionStatus{
13 pub let id: UInt64
14 pub let price : UFix64
15 pub let bidIncrement : UFix64
16 pub let bids : UInt64
17 pub let active: Bool
18 pub let timeRemaining : Fix64
19 pub let endTime : Fix64
20 pub let startTime : Fix64
21 pub let startBidTime : Fix64
22 pub let metadata: Collectible.Metadata?
23 pub let collectibleId: UInt64?
24 pub let leader: Address?
25 pub let minNextBid: UFix64
26 pub let completed: Bool
27 pub let expired: Bool
28 pub let cancelled: Bool
29 pub let currentLength: UFix64
30
31 init(
32 id:UInt64,
33 currentPrice: UFix64,
34 bids:UInt64,
35 active: Bool,
36 timeRemaining:Fix64,
37 metadata: Collectible.Metadata?,
38 collectibleId: UInt64?,
39 leader:Address?,
40 bidIncrement: UFix64,
41 startTime: Fix64,
42 startBidTime: Fix64,
43 endTime: Fix64,
44 minNextBid:UFix64,
45 completed: Bool,
46 expired:Bool,
47 cancelled: Bool,
48 currentLength: UFix64
49 ) {
50 self.id = id
51 self.price = currentPrice
52 self.bids = bids
53 self.active = active
54 self.timeRemaining = timeRemaining
55 self.metadata = metadata
56 self.collectibleId = collectibleId
57 self.leader = leader
58 self.bidIncrement = bidIncrement
59 self.startTime = startTime
60 self.startBidTime = startBidTime
61 self.endTime = endTime
62 self.minNextBid = minNextBid
63 self.completed = completed
64 self.expired = expired
65 self.cancelled = cancelled
66 self.currentLength = currentLength
67 }
68 }
69
70 // The total amount of AuctionItems that have been created
71 pub var totalAuctions: UInt64
72
73 // Events
74 pub event CollectionCreated()
75 pub event Created(auctionID: UInt64, owner: Address, startPrice: UFix64, startTime: UFix64, auctionLength: UFix64, startBidTime: UFix64)
76 pub event Bid(auctionID: UInt64, bidderAddress: Address, bidPrice: UFix64, placedAt: Fix64)
77 pub event SetStartTime(auctionID: UInt64, startAuctionTime: UFix64)
78 pub event Settled(auctionID: UInt64, price: UFix64)
79 pub event Canceled(auctionID: UInt64)
80 pub event Earned(nftID: UInt64, amount: UFix64, owner: Address, type: String)
81 pub event FailEarned(nftID: UInt64, amount: UFix64, owner: Address, type: String)
82 pub event Extend(auctionID: UInt64, auctionLengthFrom: UFix64, auctionLengthTo: UFix64)
83 pub event AddNFT(auctionID: UInt64, nftID: UInt64)
84 pub event BurnNFT(auctionID: UInt64, nftID: UInt64)
85 pub event SendNFT(auctionID: UInt64, nftID: UInt64, to: Address)
86 pub event FailSendNFT(auctionID: UInt64, nftID: UInt64, to: Address)
87 pub event SendBidTokens(auctionID: UInt64, amount: UFix64, to: Address)
88 pub event FailSendBidTokens(auctionID: UInt64, amount: UFix64, to: Address)
89
90 // AuctionItem contains the Resources and metadata for a single auction
91 pub resource AuctionItem {
92
93 //Number of bids made, that is aggregated to the status struct
94 priv var numberOfBids: UInt64
95
96 //The Item that is sold at this auction
97 priv var NFT: @Collectible.NFT?
98
99 //This is the escrow vault that holds the tokens for the current largest bid
100 priv let bidVault: @FUSD.Vault
101
102 //The id of this individual auction
103 pub let auctionID: UInt64
104
105 //The minimum increment for a bid. This is an english auction style system where bids increase
106 priv let minimumBidIncrement: UFix64
107
108 //the time the auction should start at
109 priv var auctionStartTime: UFix64
110
111 //the start time for bids
112 priv var auctionStartBidTime: UFix64
113
114 //The length in seconds for this auction
115 priv var auctionLength: UFix64
116
117 //The period of time to extend auction
118 priv var extendedLength: UFix64
119
120 //The period of time of rest to extend
121 priv var remainLengthToExtend: UFix64
122
123 //Right now the dropitem is not moved from the collection when it ends, it is just marked here that it has ended
124 priv var auctionCompleted: Bool
125
126 //Start price
127 access(account) var startPrice: UFix64
128
129 //Current price
130 priv var currentPrice: UFix64
131
132 //the capability that points to the resource where you want the NFT transfered to if you win this bid.
133 priv var recipientCollectionCap: Capability<&{Collectible.CollectionPublic}>?
134
135 //the capablity to send the escrow bidVault to if you are outbid
136 priv var recipientVaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>?
137
138 //the vault receive FUSD in case of the recipient of commissiona or the previous bidder are unreachable
139 priv let platformVaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>
140
141 //This action was cancelled
142 priv var auctionCancelled: Bool
143
144 // Manage royalty for copies of the same items
145 priv let editionCap: Capability<&{Edition.EditionCollectionPublic}>
146
147 init(
148 minimumBidIncrement: UFix64,
149 auctionStartTime: UFix64,
150 startPrice: UFix64,
151 auctionStartBidTime: UFix64,
152 auctionLength: UFix64,
153 extendedLength: UFix64,
154 remainLengthToExtend: UFix64,
155 platformVaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>,
156 editionCap: Capability<&{Edition.EditionCollectionPublic}>
157 ) {
158 AuctionV2.totalAuctions = AuctionV2.totalAuctions + (1 as UInt64)
159 self.NFT <- nil
160 self.bidVault <- FUSD.createEmptyVault()
161 self.auctionID = AuctionV2.totalAuctions
162 self.minimumBidIncrement = minimumBidIncrement
163 self.auctionLength = auctionLength
164 self.extendedLength = extendedLength
165 self.remainLengthToExtend = remainLengthToExtend
166 self.startPrice = startPrice
167 self.currentPrice = 0.0
168 self.auctionStartTime = auctionStartTime
169 self.auctionStartBidTime = auctionStartBidTime
170 self.auctionCompleted = false
171 self.recipientCollectionCap = nil
172 self.recipientVaultCap = nil
173 self.platformVaultCap = platformVaultCap
174 self.numberOfBids = 0
175 self.auctionCancelled = false
176 self.editionCap = editionCap
177 }
178
179 // sendNFT sends the NFT to the Collection belonging to the provided Capability
180 priv fun sendNFT(_ capability: Capability<&{Collectible.CollectionPublic}>) {
181 let nftId = self.NFT?.id!
182 if let collectionRef = capability.borrow() {
183 let NFT <- self.NFT <- nil
184 collectionRef.deposit(token: <-NFT!)
185 emit SendNFT(auctionID: self.auctionID, nftID: nftId, to: collectionRef.owner!.address)
186 return
187 }
188 emit FailSendNFT(auctionID: self.auctionID, nftID: nftId, to: self.recipientVaultCap!.borrow()!.owner!.address)
189 }
190
191 priv fun burnNFT() {
192
193 if(self.NFT == nil) {
194 return
195 }
196
197 let nftId = self.NFT?.id!
198
199 let NFT <- self.NFT <- nil
200
201 destroy NFT
202
203 emit BurnNFT(auctionID: self.auctionID, nftID: nftId)
204 }
205
206 // sendBidTokens sends the bid tokens to the previous bidder
207 priv fun sendBidTokens(_ capability: Capability<&FUSD.Vault{FungibleToken.Receiver}>) {
208 // borrow a reference to the prevous bidder's vault
209 if let vaultRef = capability.borrow() {
210 let bidVaultRef = &self.bidVault as &FUSD.Vault
211 let balance = bidVaultRef.balance
212 if(bidVaultRef.balance > 0.0) {
213 vaultRef.deposit(from: <- bidVaultRef.withdraw(amount: balance))
214 }
215
216 emit SendBidTokens(auctionID: self.auctionID, amount: balance, to: vaultRef.owner!.address)
217 return
218 }
219
220 // platform vault get money in case the previous bidder vault is unreachable
221 if let ownerRef = self.platformVaultCap.borrow() {
222 let bidVaultRef = &self.bidVault as &FUSD.Vault
223 let balance = bidVaultRef.balance
224 if(bidVaultRef.balance > 0.0) {
225 ownerRef.deposit(from: <-bidVaultRef.withdraw(amount: balance))
226 }
227 emit FailSendBidTokens(auctionID: self.auctionID, amount: balance, to: ownerRef.owner!.address)
228 return
229 }
230 }
231
232 priv fun releasePreviousBid() {
233 if let vaultCap = self.recipientVaultCap {
234 self.sendBidTokens(self.recipientVaultCap!)
235 return
236 }
237 }
238
239 pub fun getEditionNumber(id: UInt64): UInt64? {
240 return self.NFT?.editionNumber
241 }
242
243 priv fun sendCommissionPayment() {
244
245 let editionNumber = self.NFT?.editionNumber!
246
247 let editionRef = self.editionCap.borrow()!
248
249 let editionStatus = editionRef.getEdition(editionNumber)!
250
251 for key in editionStatus.royalty.keys {
252 if (editionStatus.royalty[key]!.firstSalePercent > 0.0) {
253 let commission = self.currentPrice * editionStatus.royalty[key]!.firstSalePercent * 0.01
254
255 let account = getAccount(key)
256
257 let vaultCap = account.getCapability<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver)
258
259 if (vaultCap.check()) {
260 let vault = vaultCap.borrow()!
261 vault.deposit(from: <- self.bidVault.withdraw(amount: commission))
262 emit Earned(nftID: self.NFT?.id!, amount: commission, owner: key, type: editionStatus.royalty[key]!.description)
263 } else {
264 emit FailEarned(nftID: self.NFT?.id!, amount: commission, owner: key, type: editionStatus.royalty[key]!.description)
265 }
266 }
267 }
268
269 // If commission was not paid, this money get platform
270
271 if (self.bidVault.balance > 0.0) {
272
273 let amount = self.bidVault.balance
274
275 let platformVault = self.platformVaultCap.borrow()!
276
277 platformVault.deposit(from: <- self.bidVault.withdraw(amount: amount))
278
279 emit Earned(nftID: self.NFT?.id!, amount: amount, owner: platformVault.owner!.address, type: "PLATFORM")
280 }
281 }
282
283 pub fun settleAuction() {
284
285 pre {
286 !self.auctionCancelled : "The auction was cancelled"
287 !self.auctionCompleted : "The auction has been already settled"
288 self.NFT != nil: "NFT in auction does not exist"
289 self.isAuctionExpired() : "Auction has not completed yet"
290 }
291
292 // burn token if there are no bids to settle
293 if self.currentPrice == 0.0 {
294 self.burnNFT()
295 self.auctionCompleted = true
296 emit Settled(auctionID: self.auctionID, price: self.currentPrice)
297 return
298 }
299
300 self.sendCommissionPayment()
301
302 self.sendNFT(self.recipientCollectionCap!)
303
304 self.auctionCompleted = true
305
306 emit Settled(auctionID: self.auctionID, price: self.currentPrice)
307 }
308
309 //this can be negative if is expired
310 pub fun timeRemaining() : Fix64 {
311 // Case, when auction time ddi not start, because nobody set the first bid
312 if(self.auctionStartBidTime > 0.0 && self.numberOfBids == 0) {
313 return 0.0
314 }
315
316 let auctionLength = self.auctionLength
317
318 let startTime = self.auctionStartTime
319
320 let currentTime = getCurrentBlock().timestamp
321
322 let remaining = Fix64(startTime + auctionLength) - Fix64(currentTime)
323
324 return remaining
325 }
326
327 pub fun isAuctionExpired(): Bool {
328 let timeRemaining = self.timeRemaining()
329 return timeRemaining < Fix64(0.0)
330 }
331
332 pub fun minNextBid() : UFix64 {
333 //If there are bids then the next min bid is the current price plus the increment
334 if self.currentPrice != 0.0 {
335 return self.currentPrice + self.currentPrice * self.minimumBidIncrement * 0.01
336 }
337
338 //else start Collectible price
339 return self.startPrice
340 }
341
342 priv fun extendAuction() {
343 if (
344 //Auction time left is less than remainLengthToExtend
345 self.timeRemaining() < Fix64(self.remainLengthToExtend)
346 //This is not the first bid in the reserve auction
347 && (self.auctionStartBidTime == 0.0 || (self.auctionStartBidTime > 0.0 && self.numberOfBids > 1))
348 ) {
349 self.auctionLength = self.auctionLength + self.extendedLength
350 emit Extend(auctionID: self.auctionID, auctionLengthFrom: self.auctionLength - self.extendedLength, auctionLengthTo: self.auctionLength)
351 }
352 }
353
354 pub fun bidder() : Address? {
355 if let vaultCap = self.recipientVaultCap {
356 // Check possible situation, where vault was unlinked after bid
357 // Test this case in automated test
358 if !vaultCap.check() {
359 return nil
360 }
361
362 return vaultCap.borrow()!.owner!.address
363 }
364 return nil
365 }
366
367 pub fun currentBidForUser(address:Address): UFix64 {
368 if(self.bidder() == address) {
369 return self.bidVault.balance
370 }
371 return 0.0
372 }
373
374 // This method should probably use preconditions more
375 pub fun placeBid(bidTokens: @FUSD.Vault, vaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>, collectionCap: Capability<&{Collectible.CollectionPublic}>) {
376
377 pre {
378 vaultCap.check() : "Fungible token storage is not initialized on account"
379 collectionCap.check() : "NFT storage is not initialized on account"
380 !self.auctionCancelled : "Auction was cancelled"
381 self.NFT != nil: "NFT in auction does not exist"
382 self.auctionStartTime < getCurrentBlock().timestamp || self.auctionStartTime == 0.0: "The auction has not started yet"
383 !self.isAuctionExpired() : "Time expired"
384 bidTokens.balance <= 999999.99 : "Bid should be less than 1 000 000.00"
385 self.auctionStartBidTime < getCurrentBlock().timestamp || self.auctionStartBidTime == 0.0: "The auction bid time has not started yet"
386 }
387
388 let bidderAddress = vaultCap.borrow()!.owner!.address
389 let collectionAddress = collectionCap.borrow()!.owner!.address
390
391 if bidderAddress != collectionAddress {
392 panic("you cannot make a bid and send the Collectible to somebody else collection")
393 }
394
395 let amountYouAreBidding = bidTokens.balance + self.currentBidForUser(address: bidderAddress)
396
397 let minNextBid = self.minNextBid()
398
399 if amountYouAreBidding < minNextBid {
400 panic("Bid is less than min acceptable")
401 }
402
403 // The first bid sets start auction time if auctionStartTime is not defined
404 if self.bidVault.balance == 0.0 && self.auctionStartTime == 0.0 {
405 self.auctionStartTime = getCurrentBlock().timestamp
406 emit SetStartTime(auctionID: self.auctionID, startAuctionTime: self.auctionStartTime)
407 }
408
409 if self.bidder() != bidderAddress {
410 if self.bidVault.balance != 0.0 {
411 // Return the previous bid
412 self.sendBidTokens(self.recipientVaultCap!)
413 }
414 }
415
416 // Update the bidVault to store the current bid
417 self.bidVault.deposit(from: <-bidTokens)
418
419 //update the capability of the wallet for the address with the current highest bid
420 self.recipientVaultCap = vaultCap
421
422 // Update the current price of the token
423 self.currentPrice = self.bidVault.balance
424
425 // Add the bidder's Vault and NFT receiver references
426 self.recipientCollectionCap = collectionCap
427 self.numberOfBids = self.numberOfBids + (1 as UInt64)
428
429 // Extend auction according to time left and extened length
430 self.extendAuction()
431
432 emit Bid(auctionID: self.auctionID, bidderAddress: bidderAddress, bidPrice: self.currentPrice, placedAt: Fix64(getCurrentBlock().timestamp))
433 }
434
435 pub fun getAuctionStatus() : AuctionStatus {
436
437 var leader : Address? = nil
438
439 if let recipient = self.recipientVaultCap {
440 leader = recipient.borrow()!.owner!.address
441 }
442
443 return AuctionStatus(
444 id: self.auctionID,
445 currentPrice: self.currentPrice,
446 bids: self.numberOfBids,
447 active: !self.auctionCompleted && !self.isAuctionExpired(),
448 timeRemaining: self.timeRemaining(),
449 metadata: self.NFT?.metadata,
450 collectibleId: self.NFT?.id,
451 leader: leader,
452 bidIncrement: self.minimumBidIncrement,
453 startTime: Fix64(self.auctionStartTime),
454 startBidTime: Fix64(self.auctionStartBidTime),
455 endTime: self.auctionStartTime > 0.0 ? Fix64(self.auctionStartTime+self.auctionLength) : Fix64(0.0),
456 minNextBid: self.minNextBid(),
457 completed: self.auctionCompleted,
458 expired: self.isAuctionExpired(),
459 cancelled: self.auctionCancelled,
460 currentLength: self.auctionLength
461 )
462 }
463
464 pub fun cancelAuction() {
465 pre {
466 !self.auctionCancelled : "The auction has been already cancelled"
467 !self.auctionCompleted : "The auction was settled"
468 }
469 self.releasePreviousBid()
470 self.burnNFT()
471 self.auctionCancelled = true
472 }
473
474 pub fun addNFT(NFT: @Collectible.NFT) {
475 pre {
476 self.NFT == nil : "NFT in auction has already existed"
477 }
478
479 let nftID = NFT.id
480
481 self.NFT <-! NFT
482
483 emit AddNFT(auctionID: self.auctionID, nftID: nftID)
484 }
485
486 pub fun reclaimSendNFT(collectionCap: Capability<&{Collectible.CollectionPublic}>) {
487
488 pre {
489 self.auctionCompleted : "The auction has not been settled yet"
490 self.NFT != nil: "NFT in auction does not exist"
491 }
492
493 self.sendNFT(collectionCap)
494 }
495
496 destroy() {
497 log("destroy auction")
498
499 // if there's a bidder, therefore minumum one bid
500 if let vaultCap = self.recipientVaultCap {
501 // ...send the bid tokens back to the bidder
502 self.sendBidTokens(vaultCap)
503 }
504
505 self.burnNFT()
506
507 destroy self.NFT
508 destroy self.bidVault
509 }
510 }
511
512 // AuctionCollectionPublic is a resource interface that restricts users to
513 // retreiving the auction price list and placing bids
514 pub resource interface AuctionCollectionPublic {
515
516 pub fun getAuctionStatuses(): {UInt64: AuctionStatus}
517 pub fun getAuctionStatus(_ id:UInt64): AuctionStatus?
518 pub fun getTimeLeft(_ id: UInt64): Fix64?
519
520 pub fun placeBid(
521 id: UInt64,
522 bidTokens: @FUSD.Vault,
523 vaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>,
524 collectionCap: Capability<&{Collectible.CollectionPublic}>
525 )
526 }
527
528 // AuctionCollection contains a dictionary of AuctionItems and provides
529 // methods for manipulating the AuctionItems
530 pub resource AuctionCollection: AuctionCollectionPublic {
531
532 // Auction Items
533 access(account) var auctionItems: @{UInt64: AuctionItem}
534
535 init() {
536 self.auctionItems <- {}
537 }
538
539 pub fun keys() : [UInt64] {
540 return self.auctionItems.keys
541 }
542
543 // addTokenToAuctionItems adds an NFT to the auction items and sets the meta data
544 // for the auction item
545 pub fun createAuction(
546 minimumBidIncrement: UFix64,
547 auctionLength: UFix64,
548 extendedLength: UFix64,
549 remainLengthToExtend: UFix64,
550 auctionStartTime: UFix64,
551 startPrice: UFix64,
552 startBidTime: UFix64,
553 platformVaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>,
554 editionCap: Capability<&{Edition.EditionCollectionPublic}>
555 ): UInt64 {
556
557 pre {
558 auctionLength > 0.00 : "Auction lenght should be more than 0.00"
559 auctionStartTime > getCurrentBlock().timestamp || auctionStartTime == 0.0: "Auction start time can't be in the past"
560 startPrice > 0.00 : "Start price should be more than 0.00"
561 startPrice <= 999999.99 : "Start bid should be less than 1 000 000.00"
562 minimumBidIncrement > 0.00 : "Minimum bid increment should be more than 0.00"
563 platformVaultCap.check() : "Platform vault should be reachable"
564 startBidTime > getCurrentBlock().timestamp || startBidTime == 0.0: "Auction start bid time can't be in the past"
565 (startBidTime == 0.0 && auctionStartTime == 0.0) == false: "Start bid time and auction start time can't equal 0.0 both"
566 (startBidTime > 0.0 && auctionStartTime > 0.0) == false: "Start bid time and auction start time can't be more than 0.0 both"
567 }
568
569 // create a new auction items resource container
570 let item <- create AuctionItem(
571 minimumBidIncrement: minimumBidIncrement,
572 auctionStartTime: auctionStartTime,
573 startPrice: startPrice,
574 auctionStartBidTime: startBidTime,
575 auctionLength: auctionLength,
576 extendedLength: extendedLength,
577 remainLengthToExtend: remainLengthToExtend,
578 platformVaultCap: platformVaultCap,
579 editionCap: editionCap
580 )
581
582 let id = item.auctionID
583
584 // update the auction items dictionary with the new resources
585 let oldItem <- self.auctionItems[id] <- item
586
587 destroy oldItem
588
589 let owner = platformVaultCap.borrow()!.owner!.address
590
591 emit Created(auctionID: id, owner: owner, startPrice: startPrice, startTime: auctionStartTime, auctionLength: auctionLength, startBidTime: startBidTime)
592
593 return id
594 }
595
596 // getAuctionPrices returns a dictionary of available NFT IDs with their current price
597 pub fun getAuctionStatuses(): {UInt64: AuctionStatus} {
598
599 if self.auctionItems.keys.length == 0 {
600 return {}
601 }
602
603 let priceList: {UInt64: AuctionStatus} = {}
604
605 for id in self.auctionItems.keys {
606 let itemRef = &self.auctionItems[id] as? &AuctionItem?
607 priceList[id] = itemRef!.getAuctionStatus()
608 }
609
610 return priceList
611 }
612
613 pub fun getAuctionStatus(_ id:UInt64): AuctionStatus? {
614
615 if self.auctionItems[id] == nil {
616 return nil
617 }
618
619 // Get the auction item resources
620 let itemRef = &self.auctionItems[id] as &AuctionItem?
621 return itemRef!.getAuctionStatus()
622 }
623
624 pub fun getTimeLeft(_ id: UInt64): Fix64? {
625 if(self.auctionItems[id] == nil) {
626 return nil
627 }
628
629 // Get the auction item resources
630 let itemRef = &self.auctionItems[id] as &AuctionItem?
631 return itemRef!.timeRemaining()
632 }
633
634 // settleAuction sends the auction item to the highest bidder
635 // and deposits the FungibleTokens into the auction owner's account
636 pub fun settleAuction(_ id: UInt64) {
637 pre {
638 self.auctionItems[id] != nil: "Auction does not exist"
639 }
640
641 let itemRef = &self.auctionItems[id] as &AuctionItem?
642 itemRef!.settleAuction()
643 }
644
645 pub fun cancelAuction(_ id: UInt64) {
646 pre {
647 self.auctionItems[id] != nil: "Auction does not exist"
648 }
649 let itemRef = &self.auctionItems[id] as &AuctionItem?
650 itemRef!.cancelAuction()
651 emit Canceled(auctionID: id)
652 }
653
654 // placeBid sends the bidder's tokens to the bid vault and updates the
655 // currentPrice of the current auction item
656 pub fun placeBid(id: UInt64, bidTokens: @FUSD.Vault, vaultCap: Capability<&FUSD.Vault{FungibleToken.Receiver}>, collectionCap: Capability<&{Collectible.CollectionPublic}>) {
657 pre {
658 self.auctionItems[id] != nil:
659 "Auction does not exist in this drop"
660 }
661
662 // Get the auction item resources
663 let itemRef = &self.auctionItems[id] as &AuctionItem?
664 itemRef!.placeBid(
665 bidTokens: <- bidTokens,
666 vaultCap : vaultCap,
667 collectionCap:collectionCap
668 )
669 }
670
671 pub fun addNFT(id: UInt64, NFT: @Collectible.NFT) {
672 pre {
673 self.auctionItems[id] != nil:
674 "Auction does not exist"
675 }
676 let itemRef = &self.auctionItems[id] as &AuctionItem?
677
678 itemRef!.addNFT(NFT: <- NFT)
679 }
680
681 pub fun reclaimSendNFT(id: UInt64, collectionCap: Capability<&{Collectible.CollectionPublic}>) {
682 pre {
683 self.auctionItems[id] != nil: "Auction does not exist"
684 }
685 let itemRef = &self.auctionItems[id] as &AuctionItem?
686 itemRef!.reclaimSendNFT(collectionCap: collectionCap)
687 }
688
689 destroy() {
690 log("destroy auction collection")
691 // destroy the empty resources
692 destroy self.auctionItems
693 }
694 }
695
696 // createAuctionCollection returns a new AuctionCollection resource to the caller
697 priv fun createAuctionCollection(): @AuctionCollection {
698 let auctionCollection <- create AuctionCollection()
699
700 return <- auctionCollection
701 }
702
703 init() {
704 self.totalAuctions = (10 as UInt64)
705 self.CollectionPublicPath = /public/NFTXtinglesBloctoAuctionV2
706 self.CollectionStoragePath = /storage/NFTXtinglesBloctoAuctionV2
707
708 let sale <- AuctionV2.createAuctionCollection()
709 self.account.save(<-sale, to:AuctionV2.CollectionStoragePath)
710 self.account.link<&{AuctionV2.AuctionCollectionPublic}>(AuctionV2.CollectionPublicPath, target:AuctionV2.CollectionStoragePath)
711 }
712}