β οΈ DISCLAIMER: LEARNING PURPOSE ONLY
This project is intended for educational purposes and should not be used in production without thorough security audits and proper testing. While it implements best practices and security measures, it serves primarily as a learning resource for understanding NFT marketplace development and the Diamond Standard (EIP-2535).
A robust, upgradeable NFT marketplace built using the Diamond Standard (EIP-2535), enabling modular functionality and gas-efficient upgrades. The marketplace supports ERC-721 NFTs with ERC-20 token payments.
- π Diamond Standard Implementation: Fully compliant with EIP-2535
- π Upgradeable Architecture: Add/remove/replace functionality without disrupting existing features
- π° Flexible Payments: Configurable ERC-20 token for marketplace transactions
- π·οΈ Fee Management: Adjustable marketplace fees with dedicated recipient
- π Statistics Tracking: Track seller and buyer activities
- π Security Features: Reentrancy protection and ownership controls
- β‘ Gas Optimized: Efficient storage layout and operation batching
- Overview
- Project Structure
- Smart Contract Architecture
- Deployment Guide
- Testing
- Scripts
- Development and Contribution
The NFT Marketplace allows users to:
- List ERC-721 NFTs for sale at a specified price (in wei).
- Buy NFTs using an ERC-20 payment token.
- Remove NFT listings if the seller decides to delist.
The marketplace is built using the Diamond Standard (EIP-2535), which means it is composed of modular "facets," each implementing specific functionality. This architecture enables smooth upgrades and maintenance without disrupting existing data or functionality.
The project is organized as follows:
NFTMarketplace/
βββ contracts/
β βββ diamond/
β β βββ Diamond.sol # Core diamond contract implementing EIP-2535
β β βββ facets/
β β β βββ AdminFacet.sol # Admin functions, including payment token management
β β β βββ ListingFacet.sol # NFT listing functionality
β β β βββ PurchaseFacet.sol # NFT buying functionality
β β β βββ RemoveListingFacet.sol # NFT listing removal functionality
β β βββ interfaces/
β β β βββ IDiamondCut.sol # DiamondCut interface for EIP-2535 compliance
β β β βββ IMarketplace.sol # Marketplace interface
β β βββ libraries/
β β βββ LibDiamond.sol # Diamond Standard library for core functions
β β βββ LibMarketplace.sol # Marketplace storage and helpers
β βββ test/
β βββ Marketplace.test.js # Main tests for NFT Marketplace
β βββ DiamondCut.test.js # DiamondCut and upgrades testing
β βββ helpers/
β βββ deployDiamond.js # Helper to deploy diamond with facets
βββ scripts/
β βββ deploy.js # Script to deploy marketplace on multiple networks
βββ test/
β βββ helpers/
β βββ testHelpers.js # Helper functions for testing
β βββ AdminFacet.test.js # Tests for AdminFacet
β βββ ListingFacet.test.js # Tests for ListingFacet
β βββ Marketplace.test.js # Main tests for NFT Marketplace
β βββ PurchaseFacet.test.js # Tests for PurchaseFacet
β βββ RemoveListingFacet.test.js # Tests for RemoveListingFacet
βββ README.md # Project documentation
βββ hardhat.config.js # Hardhat configuration
- contracts/diamond: Contains the core diamond contract, facets for different marketplace functionalities, and libraries.
- scripts/: Deployment and setup scripts for configuring the marketplace on different networks.
- test/: Comprehensive tests for each facet and the diamond standard implementation.
The Diamond Standard (EIP-2535) allows multiple contracts, called "facets," to be added, replaced, or removed in a single contract called a "diamond." This makes our contract upgradable and highly modular.
The Diamond.sol
contract implements the fallback function, which dynamically delegates function calls to the appropriate facet based on the function selector.
The marketplace implements the following facets:
-
DiamondCutFacet: Core facet for diamond standard operations
- Adding new facets
- Replacing existing facets
- Removing facets
- Emitting DiamondCut events
-
AdminFacet: Administrative functionality
- Payment token configuration
- Fee management
- Fee recipient management
- Access control
-
ListingFacet: NFT listing management
- Create listings
- Price setting
- NFT transfers
- Listing state management
-
PurchaseFacet: Purchase functionality
- Buy NFTs
- Handle payments
- Distribute fees
- Transfer NFTs
-
RemoveListingFacet: Listing removal
- Remove active listings
- Return NFTs to sellers
- Update listing states
- LibDiamond.sol: Contains core storage and helper functions required by the Diamond Standard.
- LibMarketplace.sol: Manages the marketplaceβs storage and includes helpers for payment token configuration and listings.
- Node.js (>= 20.x.x) and npm
- Dependencies: Install project dependencies:
npm install
module.exports = {
solidity: {
version: '0.8.28',
settings: {
optimizer: {
enabled: true,
runs: 1000,
},
},
},
networks: {
localhost: {
url: process.env.LOCALHOST_RPC_URL,
},
testnet: {
url: process.env.SEPOLIA_RPC_URL,
accounts: [process.env.SEPOLIA_PRIVATE_KEY],
},
mainnet: {
chainId: process.env.MAINNET_CHAIN_ID,
url: process.env.MAINNET_RPC_URL,
accounts: [process.env.MAINNET_PRIVATE_KEY],
},
},
paths: {
sources: './contracts',
tests: './test',
cache: './cache',
coverage: './coverage',
artifacts: './artifacts',
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
gasReporter: {
enabled: true,
currency: 'USD',
},
};
-
Localhost:
npx hardhat run scripts/deploy.js --network localhost
-
Testnet (Sepolia):
npx hardhat run scripts/deploy.js --network testnet
-
Mainnet (Polygon):
npx hardhat run scripts/deploy.js --network mainnet
Run tests to verify each part of the marketplace using the Hardhat framework:
npm run test
-
DiamondCut.test.js: Tests for diamond upgrades and facet management, including:
- Adding new facets
- Replacing existing facet functions
- Removing facet functions
- Diamond loupe functionality
- Access control verification
- Invalid operation handling
-
AdminFacet.test.js: Tests for administrative functions:
- Payment token management
- Fee management
- Fee recipient management
- Access control verification
-
ListingFacet.test.js: Tests for NFT listing functionality:
- NFT listing creation
- Price validation
- Ownership verification
- Approval checks
-
PurchaseFacet.test.js: Tests for NFT purchase operations:
- NFT buying process
- Payment handling
- Fee distribution
- Token transfers
-
RemoveListingFacet.test.js: Tests for listing removal:
- Listing removal by seller
- NFT return process
- State updates
- deploy.js: Deploys the diamond and facets on specified networks.
npx hardhat run scripts/deploy.js --network testnet
See CONTRIBUTING.md for guidelines on development and contribution.
Check the SECURITY.md file for more information.
- EIP-2535: Diamond Standard: For more information on the Diamond Standard.
- OpenZeppelin: Utilized for ERC-20 and ERC-721 interfaces and libraries.