Smart Contract

BlackMarketplace

A.117396d8a72ad372.BlackMarketplace

Deployed

1d ago
Feb 27, 2026, 03:00:30 PM UTC

Dependents

0 imports
1// Black Hunter's Market
2// Yosh! -swt
3//
4//
5import FungibleToken from 0xf233dcee88fe0abe
6import FUSD from 0x3c5959b568896393
7import NonFungibleToken from 0x1d7e57aa55817448
8import NFTDayTreasureChest from 0x117396d8a72ad372
9
10access(all)
11contract BlackMarketplace{ 
12
13	access(all) entitlement SaleCollectionOwner
14	
15	// -----------------------------------------------------------------------
16	// BlackMarketplace Events
17	// -----------------------------------------------------------------------
18	access(all)
19	event ForSale(id: UInt64, price: UFix64)
20	
21	access(all)
22	event PriceChanged(id: UInt64, newPrice: UFix64)
23	
24	access(all)
25	event TokenPurchased(id: UInt64, price: UFix64, from: Address, to: Address)
26	
27	access(all)
28	event RoyaltyPaid(id: UInt64, amount: UFix64, to: Address, name: String)
29	
30	access(all)
31	event SaleWithdrawn(id: UInt64)
32	
33	// -----------------------------------------------------------------------
34	// Named Paths
35	// -----------------------------------------------------------------------
36	access(all)
37	let CollectionStoragePath: StoragePath
38	
39	access(all)
40	let CollectionPublicPath: PublicPath
41	
42	access(all)
43	let marketplaceWallet: Capability<&FUSD.Vault>
44	
45	access(contract)
46	var whitelistUsed: [Address]
47	
48	access(contract)
49	var sellers: [Address]
50	
51	access(all)
52	resource interface SalePublic{ 
53		access(all)
54		fun purchaseWithWhitelist(
55			tokenID: UInt64,
56			recipientCap: Capability<&{NFTDayTreasureChest.NFTDayTreasureChestCollectionPublic}>,
57			buyTokens: @{FungibleToken.Vault}
58		): Void
59		
60		access(all)
61		fun purchaseWithTreasureChest(
62			tokenID: UInt64,
63			recipientCap: Capability<&{NFTDayTreasureChest.NFTDayTreasureChestCollectionPublic}>,
64			buyTokens: @{FungibleToken.Vault},
65			chest: @NFTDayTreasureChest.NFT
66		): @NFTDayTreasureChest.NFT
67		
68		access(all) view
69		fun idPrice(tokenID: UInt64): UFix64?
70		
71		access(all) view
72		fun getIDs(): [UInt64]
73	}
74	
75	access(all) resource SaleCollection: SalePublic{ 
76		access(self) var forSale: @{UInt64: NFTDayTreasureChest.NFT}
77		
78		access(self)
79		var prices:{ UInt64: UFix64}
80		
81		access(account)
82		let ownerVault: Capability<&{FungibleToken.Receiver}>
83		
84		init(vault: Capability<&{FungibleToken.Receiver}>){ 
85			self.forSale <-{} 
86			self.ownerVault = vault
87			self.prices ={} 
88		}
89		
90		access(SaleCollectionOwner)
91		fun withdraw(tokenID: UInt64): @NFTDayTreasureChest.NFT{ 
92			self.prices.remove(key: tokenID)
93			let token <- self.forSale.remove(key: tokenID) ?? panic("missing NFT")
94			emit SaleWithdrawn(id: tokenID)
95			return <-token
96		}
97		
98		access(SaleCollectionOwner)
99		fun listForSale(token: @NFTDayTreasureChest.NFT, price: UFix64){ 
100			let id = token.id
101			self.prices[id] = price
102			let oldToken <- self.forSale[id] <- token
103			destroy oldToken
104			if !BlackMarketplace.sellers.contains((self.owner!).address){ 
105				BlackMarketplace.sellers.append((self.owner!).address)
106			}
107			emit ForSale(id: id, price: price)
108		}
109		
110		access(SaleCollectionOwner)
111		fun changePrice(tokenID: UInt64, newPrice: UFix64){ 
112			self.prices[tokenID] = newPrice
113			emit PriceChanged(id: tokenID, newPrice: newPrice)
114		}
115		
116		// Requires a whitelist to purchase
117		access(all)
118		fun purchaseWithWhitelist(tokenID: UInt64, recipientCap: Capability<&{NFTDayTreasureChest.NFTDayTreasureChestCollectionPublic}>, buyTokens: @{FungibleToken.Vault}){ 
119			pre{ 
120				self.forSale[tokenID] != nil && self.prices[tokenID] != nil:
121					"No token matching this ID for sale!"
122				buyTokens.balance >= self.prices[tokenID] ?? 0.0:
123					"Not enough tokens to by the NFT!"
124				!BlackMarketplace.whitelistUsed.contains(((recipientCap.borrow()!).owner!).address):
125					"Cannot purchase: Whitelist used"
126				NFTDayTreasureChest.getWhitelist().contains(((recipientCap.borrow()!).owner!).address):
127					"Cannot purchase: Must be whitelisted"
128			}
129			let recipient = recipientCap.borrow()!
130			let price = self.prices[tokenID]!
131			self.prices[tokenID] = nil
132			let vaultRef = self.ownerVault.borrow() ?? panic("Could not borrow reference to owner token vault")
133			let token <- self.withdraw(tokenID: tokenID)
134			let marketplaceWallet = BlackMarketplace.marketplaceWallet.borrow()!
135			let marketplaceFee = price * 0.05 // 5% marketplace cut
136			
137			marketplaceWallet.deposit(from: <-buyTokens.withdraw(amount: marketplaceFee))
138			emit RoyaltyPaid(id: tokenID, amount: marketplaceFee, to: (marketplaceWallet.owner!).address, name: "Marketplace")
139			vaultRef.deposit(from: <-buyTokens)
140			recipient.deposit(token: <-token)
141			BlackMarketplace.whitelistUsed.append((recipient.owner!).address)
142			emit TokenPurchased(id: tokenID, price: price, from: (vaultRef.owner!).address, to: (recipient.owner!).address)
143		}
144		
145		// Requires a chest to purchase
146		access(all)
147		fun purchaseWithTreasureChest(tokenID: UInt64, recipientCap: Capability<&{NFTDayTreasureChest.NFTDayTreasureChestCollectionPublic}>, buyTokens: @{FungibleToken.Vault}, chest: @NFTDayTreasureChest.NFT): @NFTDayTreasureChest.NFT{ 
148			pre{ 
149				self.forSale[tokenID] != nil && self.prices[tokenID] != nil:
150					"No token matching this ID for sale!"
151				buyTokens.balance >= self.prices[tokenID] ?? 0.0:
152					"Not enough tokens to by the NFT!"
153			}
154			let recipient = recipientCap.borrow()!
155			let price = self.prices[tokenID]!
156			self.prices[tokenID] = nil
157			let vaultRef = self.ownerVault.borrow() ?? panic("Could not borrow reference to owner token vault")
158			let token <- self.withdraw(tokenID: tokenID)
159			let marketplaceWallet = BlackMarketplace.marketplaceWallet.borrow()!
160			let marketplaceFee = price * 0.05 // 5% marketplace cut
161			
162			marketplaceWallet.deposit(from: <-buyTokens.withdraw(amount: marketplaceFee))
163			emit RoyaltyPaid(id: tokenID, amount: marketplaceFee, to: (marketplaceWallet.owner!).address, name: "Marketplace")
164			vaultRef.deposit(from: <-buyTokens)
165			recipient.deposit(token: <-token)
166			emit TokenPurchased(id: tokenID, price: price, from: (vaultRef.owner!).address, to: (recipient.owner!).address)
167			return <-chest
168		}
169		
170		access(all) view
171		fun idPrice(tokenID: UInt64): UFix64?{ 
172			return self.prices[tokenID]
173		}
174		
175		access(all) view
176		fun getIDs(): [UInt64]{ 
177			return self.forSale.keys
178		}
179	}
180	
181	access(all)
182	fun createSaleCollection(ownerVault: Capability<&{FungibleToken.Receiver}>): @SaleCollection{ 
183		return <-create SaleCollection(vault: ownerVault)
184	}
185	
186	access(all) view
187	fun getWhitelistUsed(): [Address]{ 
188		return self.whitelistUsed
189	}
190	
191	access(all) view
192	fun getSellers(): [Address]{ 
193		return self.sellers
194	}
195	
196	init(){ 
197		self.CollectionStoragePath = /storage/BasicBeastsBlackMarketplace
198		self.CollectionPublicPath = /public/BasicBeastsBlackMarketplace
199		if self.account.storage.borrow<&FUSD.Vault>(from: /storage/fusdVault) == nil{ 
200			// Create a new FUSD Vault and put it in storage
201			self.account.storage.save(<-FUSD.createEmptyVault(vaultType: Type<@FUSD.Vault>()), to: /storage/fusdVault)
202			
203			// Create a public capability to the Vault that only exposes
204			// the deposit function through the Receiver interface
205			var capability_1 = self.account.capabilities.storage.issue<&FUSD.Vault>(/storage/fusdVault)
206			self.account.capabilities.publish(capability_1, at: /public/fusdReceiver)
207			
208			// Create a public capability to the Vault that only exposes
209			// the balance field through the Balance interface
210			var capability_2 = self.account.capabilities.storage.issue<&FUSD.Vault>(/storage/fusdVault)
211			self.account.capabilities.publish(capability_2, at: /public/fusdBalance)
212		}
213		self.marketplaceWallet = self.account.capabilities.get<&FUSD.Vault>(/public/fusdReceiver)!
214		self.whitelistUsed = []
215		self.sellers = []
216	}
217}
218