Skip to content

Commit

Permalink
Refactored project.
Browse files Browse the repository at this point in the history
  • Loading branch information
ethan-crypto committed Mar 21, 2022
1 parent 6ab628b commit 8094117
Show file tree
Hide file tree
Showing 18 changed files with 207 additions and 317 deletions.
5 changes: 0 additions & 5 deletions src/URI/0.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/1.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/2.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/3.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/4.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/5.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/6.json

This file was deleted.

5 changes: 0 additions & 5 deletions src/URI/7.json

This file was deleted.

34 changes: 11 additions & 23 deletions src/backend/contracts/MusicNFTMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,19 @@ pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MusicNFTMarketplace is ERC721, Ownable {
uint256 public _tokenIds;

uint256 public immutable maxSupply;

contract MusicNFTMarketplace is ERC721("DAppFi", "DAPP"), Ownable {
string public baseURI =
"https://bafybeidhjjbjonyqcahuzlpt7sznmh4xrlbspa3gstop5o47l6gsiaffee.ipfs.nftstorage.link/";
string public baseExtension = ".json";

address public artist;
uint256 public royaltyFee;

MarketItem[] public marketItems;

struct MarketItem {
uint256 tokenId;
address payable seller;
uint256 price;
}
MarketItem[] public marketItems;

event MarketItemBought(
uint256 indexed tokenId,
Expand All @@ -37,35 +31,32 @@ contract MusicNFTMarketplace is ERC721, Ownable {
);

/* In constructor we initalize royalty fee, artist address and prices of music nfts*/
/* All the nfts are minted for the marketplace and we create a market item for each, */
/* setting the deployer as the seller and price as the price in the current index in the prices array */
constructor(
uint256 _royaltyFee,
address _artist,
uint256[] memory _prices
) payable ERC721("DAppFi", "DAPP") {
) payable {
require(
_prices.length * _royaltyFee <= msg.value,
"Deployer must pay royalty fee for each token listed on the marketplace"
);
royaltyFee = _royaltyFee;
artist = _artist;
maxSupply = _prices.length;
for (uint8 i = 0; i < _prices.length; i++) {
require(_prices[i] > 0, "Price must be greater than 0");
_mint(address(this), i);
marketItems.push(MarketItem(i, payable(msg.sender), _prices[i]));
}
}

/* Updates the listing price of the contract */
function updateRoyaltyFee(uint256 _royaltyFee) public payable onlyOwner {
/* Updates the royalty fee of the contract */
function updateRoyaltyFee(uint256 _royaltyFee) external onlyOwner {
royaltyFee = _royaltyFee;
}

/* Creates the sale of a music nft listed on the marketplace */
/* Transfers ownership of the nft, as well as funds between parties */
function buyToken(uint256 _tokenId) public payable {
function buyToken(uint256 _tokenId) external payable {
uint256 price = marketItems[_tokenId].price;
address seller = marketItems[_tokenId].seller;
require(
Expand All @@ -80,17 +71,14 @@ contract MusicNFTMarketplace is ERC721, Ownable {
}

/* Allows someone to resell their music nft */
function resellToken(uint256 _tokenId, uint256 price) public payable {
require(
msg.value == royaltyFee,
"Price must be equal to listing price"
);
require(price > 0, "Price must be greater than zero");
marketItems[_tokenId].price = price;
function resellToken(uint256 _tokenId, uint256 _price) external payable {
require(msg.value == royaltyFee, "Must pay royalty");
require(_price > 0, "Price must be greater than zero");
marketItems[_tokenId].price = _price;
marketItems[_tokenId].seller = payable(msg.sender);

_transfer(msg.sender, address(this), _tokenId);
emit MarketItemRelisted(_tokenId, msg.sender, price);
emit MarketItemRelisted(_tokenId, msg.sender, _price);
}

/* Fetches all the tokens currently listed for sale */
Expand Down
19 changes: 9 additions & 10 deletions src/backend/scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
const toWei = (num) => ethers.utils.parseEther(num.toString())
async function main() {
const toWei = (num) => ethers.utils.parseEther(num.toString())
let royaltyFee = toWei(0.01);
let prices = [toWei(1), toWei(2), toWei(3), toWei(4), toWei(5), toWei(6), toWei(7), toWei(8)]
let deploymentFees = toWei(prices.length*0.01)

let deploymentFees = toWei(prices.length * 0.01)
const [deployer, artist] = await ethers.getSigners();

console.log("Deploying contracts with the account:", deployer.address);
console.log("Account balance:", (await deployer.getBalance()).toString());

// deploy contract here:
const NFTMarketplace = await ethers.getContractFactory("MusicNFTMarketplace");

// Deploy music nft marketplace contract
const nftMarketplace = await NFTMarketplace.deploy(
// deploy contracts here:
const NFTMarketplaceFactory = await ethers.getContractFactory("MusicNFTMarketplace");
nftMarketplace = await NFTMarketplaceFactory.deploy(
royaltyFee,
artist.address,
prices,
{value: deploymentFees}
{ value: deploymentFees }
);


console.log("Smart contract address:", nftMarketplace.address)

// For each contract, pass the deployed contract and name to this function to save a copy of the contract ABI and address to the front end.
saveFrontendFiles(nftMarketplace, "MusicNFTMarketplace");
}
Expand Down
77 changes: 37 additions & 40 deletions src/backend/test/MusicNFTMarketplace.test.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { expect } = require("chai");

const toWei = (num) => ethers.utils.parseEther(num.toString())
const fromWei = (num) => ethers.utils.formatEther(num)

describe("MusicNFTMarketplace", function () {

let NFTMarketplace, nftMarketplace
let nftMarketplace
let deployer, artist, user1, user2, users;
let royaltyFee = toWei(0.01);
let royaltyFee = toWei(0.01); // 1 ether = 10^18 wei
let URI = "https://bafybeidhjjbjonyqcahuzlpt7sznmh4xrlbspa3gstop5o47l6gsiaffee.ipfs.nftstorage.link/"
let prices = [toWei(1), toWei(2), toWei(3), toWei(4), toWei(5), toWei(6), toWei(7), toWei(8)]
let deploymentFees = toWei(prices.length*0.01)
let deploymentFees = toWei(prices.length * 0.01)
beforeEach(async function () {
// Get the ContractFactory and Signers here.
const NFTMarketplace = await ethers.getContractFactory("MusicNFTMarketplace");
const NFTMarketplaceFactory = await ethers.getContractFactory("MusicNFTMarketplace");
[deployer, artist, user1, user2, ...users] = await ethers.getSigners();

// Deploy music nft marketplace contract
nftMarketplace = await NFTMarketplace.deploy(
nftMarketplace = await NFTMarketplaceFactory.deploy(
royaltyFee,
artist.address,
prices,
{value: deploymentFees}
{ value: deploymentFees }
);

});

describe("Deployment", function () {

it("Should track name, symbol, URI, royalty fee and artist ", async function () {
it("Should track name, symbol, URI, royalty fee and artist", async function () {
const nftName = "DAppFi"
const nftSymbol = "DAPP"
expect(await nftMarketplace.name()).to.equal(nftName);
Expand All @@ -41,40 +40,38 @@ describe("MusicNFTMarketplace", function () {

it("Should mint then list all the music nfts", async function () {
expect(await nftMarketplace.balanceOf(nftMarketplace.address)).to.equal(8);
// Get item from items mapping then check fields to ensure they are correct
await Promise.all(prices.map(async(i, indx) => {
// Get each item from the marketItems array then check fields to ensure they are correct
await Promise.all(prices.map(async (i, indx) => {
const item = await nftMarketplace.marketItems(indx)
expect(await nftMarketplace.tokenURI(indx)).to.equal(URI + indx)
expect(item.tokenId).to.equal(indx)
expect(item.seller).to.equal(deployer.address)
expect(item.price).to.equal(i)
}))
}))
});
it("Ether balance should equal deployment fees", async function () {
expect(await ethers.provider.getBalance(nftMarketplace.address)).to.equal(deploymentFees)
});
});

});
describe("Updating royalty fee", function () {

it("Only deployer should be able to update royalty fee", async function () {
const fee = toWei(0.02)
await (await nftMarketplace.updateRoyaltyFee(fee)).wait()
await nftMarketplace.updateRoyaltyFee(fee)
await expect(
nftMarketplace.connect(user1).updateRoyaltyFee(fee)
).to.be.revertedWith("Ownable: caller is not the owner");
expect(await nftMarketplace.royaltyFee()).to.equal(fee)
});

});

describe("Buying tokens", function () {
it("Should update seller to zero address, transfer NFT, pay seller, pay royalty to artist and emit a MarketItemBought event", async function () {
const deployerInitalEthBal = await deployer.getBalance()
const artistInitialEthBal = await artist.getBalance()
// user1 purchases item.
await expect(nftMarketplace.connect(user1).buyToken(0, {value: prices[0]}))
.to.emit(nftMarketplace, "MarketItemBought")
await expect(nftMarketplace.connect(user1).buyToken(0, { value: prices[0] }))
.to.emit(nftMarketplace, "MarketItemBought")
.withArgs(
0,
deployer.address,
Expand All @@ -95,27 +92,26 @@ describe("MusicNFTMarketplace", function () {
it("Should fail when ether amount sent with transaction does not equal asking price", async function () {
// Fails when ether sent does not equal asking price
await expect(
nftMarketplace.connect(user1).buyToken(0, {value: prices[1]})
).to.be.revertedWith("Please send the asking price in order to complete the purchase");
nftMarketplace.connect(user1).buyToken(0, { value: prices[1] })
).to.be.revertedWith("Please send the asking price in order to complete the purchase");
});
})
describe("Reselling tokens", function () {
let price = toWei(2)
let result
beforeEach(async function () {
// user1 purchases item.
await(await nftMarketplace.connect(user1).buyToken(0, {value: prices[0]})).wait();
// user1 purchases an item.
await nftMarketplace.connect(user1).buyToken(0, { value: prices[0] })
})

it("Should track resale item, incr. ether bal by royalty fee, transfer NFT to marketplace and emit MarketItemRelisted event", async function () {
const resaleprice = toWei(2)
const initMarketBal = await ethers.provider.getBalance(nftMarketplace.address)
// user1 lists the nft for a price of 2 hoping to flip it and double their money
await expect(nftMarketplace.connect(user1).resellToken(0, price, {value: royaltyFee}))
await expect(nftMarketplace.connect(user1).resellToken(0, resaleprice, { value: royaltyFee }))
.to.emit(nftMarketplace, "MarketItemRelisted")
.withArgs(
0,
user1.address,
price
resaleprice
)
const finalMarketBal = await ethers.provider.getBalance(nftMarketplace.address)
// Expect final market bal to equal inital + royalty fee
Expand All @@ -126,28 +122,29 @@ describe("MusicNFTMarketplace", function () {
const item = await nftMarketplace.marketItems(0)
expect(item.tokenId).to.equal(0)
expect(item.seller).to.equal(user1.address)
expect(item.price).to.equal(price)
expect(item.price).to.equal(resaleprice)
});

it("Should fail if price is set to zero", async function () {
it("Should fail if price is set to zero and royalty fee is not paid", async function () {
await expect(
nftMarketplace.connect(user1).resellToken(0, 0, {value: royaltyFee})
nftMarketplace.connect(user1).resellToken(0, 0, { value: royaltyFee })
).to.be.revertedWith("Price must be greater than zero");
await expect(
nftMarketplace.connect(user1).resellToken(0, toWei(1), { value: 0 })
).to.be.revertedWith("Must pay royalty");
});

});

describe("Getter functions", function () {
let soldItems = [0,1,4]
let ownedByUser1 = [0,1]
let soldItems = [0, 1, 4]
let ownedByUser1 = [0, 1]
let ownedByUser2 = [4]
beforeEach(async function () {
// user1 purchases item 0.
await(await nftMarketplace.connect(user1).buyToken(0, {value: prices[0]})).wait();
// user1 purchases item 1.
await(await nftMarketplace.connect(user1).buyToken(1, {value: prices[1]})).wait();
// user2 purchases item 4.
await(await nftMarketplace.connect(user2).buyToken(4, {value: prices[4]})).wait();
// user1 purchases item 0.
await (await nftMarketplace.connect(user1).buyToken(0, { value: prices[0] })).wait();
// user1 purchases item 1.
await (await nftMarketplace.connect(user1).buyToken(1, { value: prices[1] })).wait();
// user2 purchases item 4.
await (await nftMarketplace.connect(user2).buyToken(4, { value: prices[4] })).wait();
})

it("getAllUnsoldTokens should fetch all the marketplace items up for sale", async function () {
Expand All @@ -170,4 +167,4 @@ describe("MusicNFTMarketplace", function () {
expect(ownedByUser2.length === myItems.length).to.equal(true)
});
});
})
})
Loading

0 comments on commit 8094117

Please sign in to comment.