Inspiration

Although gas is inefficient, building a smart contract where users can buy and sell packs of NFTs rather than just individual ones sounded interesting to try and create, so that’s what I attempted to do.

What it does

Terminology for the below paragraph:
Set ---> The group to which an NFT belongs.
Pack ---> NFTs being sold together.
This project has several different pieces, two smart contracts, a database, and a front-end. Of the smart contracts, one is a marketplace, and the other is an ERC721 token factory. Within the marketplace, users can create and sell packs of owned NFTs that were made in the ERC721 factory contract. When a pack is bought, all NFTs in that pack are transferred to the pack buyer, and the pack seller receives 97% of the total sale. The marketplace owner receives a 3% transaction fee.
To incentivize users to continuously buy and sell packs, NFTs created by the marketplace owner can be created as part of a set. If a user collects all NFTs belonging to the same set, their account will be eligible for rewards in the form of NFTs. Each set that a user completes will increase their reward multiplier by a factor of one. This will give them higher odds of winning an NFT when rewards are distributed. The mechanism that distributes rewards relies on the Chainlink VRF Oracle. For every five addresses that are eligible for rewards, one NFT will be randomly distributed amongst the addresses. note: The first 1 - 4 addresses have a chance to receive one NFT reward.
Each NFT created in the factory smart contract has one of three rarities assigned to it with increasing scarcity. They are, "Iron", "Gold", and "Diamond". Naturally the diamond NFTs will be worth the most while both the gold and diamond NFTs have a chance to become ultra scarce, and therefore, ultra valuable. This can happen since users have a way to mint NFTs within the factory smart contract (through the front-end). The catch is that NFTs created by users (not owners) will always start as iron NFTs. As the iron NFTs flood the market, the value of the gold and diamond NFTs will increase as they become even rarer.
The front-end of this project serves as an interface for users to interact with the protocol, and there are four main components.

  • 1) Marketplace: Users can browse packs they would like to buy. They can also view the contents of the pack to check what NFTs are inside.
  • 2) Create Items:
    This is where users can create an NFT pack, preview it, and list it for sale. Users can also mint an Iron NFT provided they already have a metadata URI.
  • 3) Profile:
    Here you can:
    a) View owned NFTs belonging to the ERC721 factory smart contract address.
    b) View your pack listings with the option to delist it.
    c) Check how many NFTs you own in a set.
    d) Check the rarity of an NFT based on the input token ID.
    e) Verify that you have a complete NFT set to become eligible for rewards.
    f) View listing pack IDs that an input address is selling.
    g) View addresses who are eligible for rewards.

How I built it

I wrote the smart contracts in Solidity, and used Hardhat and Chai to assist in development. The front-end is powered by a combination of React, JavaScript, and Html/Css wrapped in Moralis. To display the NFT pack listings in the marketplace, the Moralis server is configured to create a table every time a new listing event is emitted from the marketplace smart contract. These tables are then updated and deleted as packs are bought, sold, and delisted. When distributing rewards, I figured the fairest way to do so was using some form of randomness, and that is why I chose the Chainlink VRF Oracle. When the Oracle returns a number(s), the value(s) gets modified to be a number that is between zero, and the length of the eligible address array minus one. This enables the distributeRewards function to reliably pick a winner based on its index within the eligible winners array. There can be multiple winners depending on how many addresses are eligible for rewards.
Another thing I want to address is that the NFT rarities are assigned using a mapping rather than being hard coded in the metadata. This was done to give an easy way to upgrade a given NFTs rarity. In the future I want to modify the factory smart contract to have some mechanism by which you can upgrade your NFT, but that idea is not currently implemented. The mapping is just preemptive so I wouldn’t have to go back and re-code things.

Challenges I ran into

One of the challenges that sticks out was popping pack listings out of user mappings of address => struct[]. Since deleteing a uint out of a uint[] at a certain index just re-initializes it to zero without actually removing it, finding a way to shift elements before popping it off the end proved challenging, yet rewarding.

Accomplishments that I'm proud of

Honestly I'm just happy to have finished this project. As someone who wants to break into becoming a developer, these hackathons have been a great way to learn, grow and gain experience. I know it's not the greatest project of all time, but I thoroughly enjoyed creating it.

What I learned

I learned a ton. Specifically about React, and how I could use it with Moralis. I also learned a lot about Css as I am a complete front-end noob. I also leveled up my abilities in pretty much all other aspects. I really enjoyed using version two of the VRF Oracle. Being able to get multiple values back is a sweet feature!

What's next for Card Nft Marketplace

I want to change the styling on pretty much all of the front-end lol. I definitely want to spend more time learning Css and just fron-end in general. Lol.

Built With

Share this project:

Updates