A production-grade, OpenZeppelin-powered NFT marketplace ecosystem optimized for the Base network. Features gas-efficient ERC-721 minting, secure marketplace trading, auction functionality, and comprehensive royalty management.
- Overview
- Architecture
- Contract Flow
- Features
- Installation
- Usage
- API Documentation
- Security
- Testing
- Deployment
- Contributing
- License
BasedNFTMarketPlace is a decentralized NFT ecosystem built specifically for the Base network, providing:
- Gas-efficient NFT minting with batch operations
- Secure marketplace with escrow-based trading
- Auction system for competitive bidding
- Royalty management via ERC-2981 standard
- Multi-layered security with OpenZeppelin contracts
The platform drives Base network activity through strategic fee structures while maintaining enterprise-grade security and user experience.
Base Sepolia Testnet (Chain ID: 84532)
| Contract | Address | Status | Verification |
|---|---|---|---|
| BasedNFT | 0x9CFEd3BD95eA962658318E3E3BBe9b4B4fC7edB4 |
β Deployed | β Verified |
| BasedNFTMarket | 0x4f6558d101CAF8c20B9cA61B824DD039eeBb5644 |
β Deployed | β Verified |
Deployment Date: December 22, 2025
Total Gas Used: 5,618,348
Deployment Cost: 0.000610357336637816 ETH
graph TB
subgraph "Base Network (Chain ID: 84532)"
subgraph "Smart Contracts"
BNFT[BasedNFT<br/>ERC-721 Minter]
MARKET[BasedNFTMarket<br/>Marketplace & Auctions]
end
subgraph "External Integrations"
OZ[OpenZeppelin<br/>Contracts v5.5.0]
ERC2981[ERC-2981<br/>Royalties]
ERC721[ERC-721<br/>Standard]
end
subgraph "Users"
MINTER[NFT Minters]
TRADER[Traders]
AUCTIONEER[Auction Participants]
end
end
MINTER -->|Mint NFTs| BNFT
TRADER -->|List/Buy NFTs| MARKET
AUCTIONEER -->|Create/Bid in Auctions| MARKET
BNFT -->|ERC-721 Tokens| MARKET
MARKET -->|Royalty Payments| BNFT
BNFT -.->|Inherits| OZ
MARKET -.->|Inherits| OZ
BNFT -.->|Implements| ERC2981
MARKET -.->|Integrates| ERC721
classDiagram
class BasedNFT {
+mint(quantity, tokenURI)
+batchMint(to[], quantities[])
+tokenURI(tokenId)
+setTreasury(address)
+withdrawFees()
+supportsInterface(bytes4)
-_nextTokenId
-_tokenURIs
-treasury
}
class BasedNFTMarket {
+listItem(nftContract, tokenId, price)
+buyItem(nftContract, tokenId)
+createAuction(nftContract, tokenId, reserve, duration)
+bid(nftContract, tokenId)
+endAuction(nftContract, tokenId)
+withdraw()
-listings
-auctions
-pendingReturns
}
class ERC721 {
<<interface>>
+transferFrom(from, to, tokenId)
+safeTransferFrom(from, to, tokenId)
+ownerOf(tokenId)
+approve(to, tokenId)
}
class ERC2981 {
<<interface>>
+royaltyInfo(tokenId, salePrice)
}
BasedNFT ..|> ERC721 : implements
BasedNFT ..|> ERC2981 : implements
BasedNFTMarket ..> ERC721 : uses
BasedNFTMarket ..> ERC2981 : uses
sequenceDiagram
participant User
participant BasedNFT
participant Treasury
User->>BasedNFT: mint(quantity, tokenURI) + 0.001 ETH/NFT
BasedNFT->>BasedNFT: Validate chainId == 84532
BasedNFT->>BasedNFT: Check payment >= MINT_FEE * quantity
BasedNFT->>BasedNFT: Mint NFTs to User
BasedNFT->>BasedNFT: Set tokenURIs
BasedNFT->>Treasury: Accumulate fees
BasedNFT-->>User: Emit Minted events
sequenceDiagram
participant Seller
participant BasedNFT
participant Market
participant Buyer
participant RoyaltyReceiver
Seller->>BasedNFT: approve(Market, tokenId)
Seller->>Market: listItem(nftContract, tokenId, price) + 0.0001 ETH
Market->>Market: Transfer NFT to escrow
Market->>Market: Store listing details
Buyer->>Market: buyItem(nftContract, tokenId) + price
Market->>Market: Validate payment
Market->>Market: Calculate fees & royalties
Market->>RoyaltyReceiver: Pay royalties (ERC-2981)
Market->>Market: Pay market fee (1.5%) to treasury
Market->>Seller: Pay seller proceeds
Market->>Buyer: Transfer NFT from escrow
Market-->>Seller: Emit ItemSold event
sequenceDiagram
participant Seller
participant BasedNFT
participant Market
participant Bidder
participant Winner
Seller->>BasedNFT: approve(Market, tokenId)
Seller->>Market: createAuction(nftContract, tokenId, reserve, duration)
Market->>Market: Transfer NFT to escrow
Market->>Market: Initialize auction
loop Bidding Phase
Bidder->>Market: bid(nftContract, tokenId) + bidAmount
Market->>Market: Update highest bid
Market->>Market: Refund previous bidder
end
Winner->>Market: Wait for auction end
Market->>Market: End auction automatically
Market->>Market: Calculate fees & royalties
Market->>RoyaltyReceiver: Pay royalties
Market->>Market: Pay market fee to treasury
Market->>Seller: Pay seller proceeds
Market->>Winner: Transfer NFT from escrow
- Gas-Optimized Minting: Batch minting with efficient loops
- Secure Marketplace: Escrow-based NFT trading
- Auction System: English auction with reserve prices
- Royalty Management: ERC-2981 compliant royalty payments
- Multi-Token Support: ERC-721 compatible collections
- OpenZeppelin Security: ReentrancyGuard, Pausable, Ownable
- Chain Validation: Base network chain ID enforcement
- Custom Errors: Gas-efficient error handling
- Access Control: Role-based permissions
- Emergency Controls: Circuit breaker functionality
- Mint Fee: 0.001 ETH per NFT β Treasury
- Market Fee: 1.5% of sale price β Treasury
- Listing Fee: 0.0001 ETH β Liquidity pool
- Royalties: Configurable via ERC-2981
# Clone the repository
git clone <repository-url>
cd BasedNFTMarketPlace
# Install dependencies
forge install
# Copy environment file
cp .env.example .env
# Edit .env with your configuration# .env file
BASESCAN_API_KEY=your_basescan_api_key
ACCOUNT=defaultKey
SENDER=your_wallet_address
SEPOLIA_RPC_URL=https://sepolia.base.org# Run tests
forge test
# Start local node
anvil
# Deploy locally
forge script script/DeployBase.s.sol --fork-url http://localhost:8545# Deploy to testnet
./deploy.sh
# Verify contracts
forge verify-contract <contract-address> src/BasedNFT.sol:BasedNFT --chain-id 84532// Single mint
nft.mint(1, "ipfs://your-metadata") {value: 0.001 ether}
// Batch mint
address[] memory recipients = [user1, user2];
uint256[] memory quantities = [2, 1];
nft.batchMint(recipients, quantities) {value: 0.003 ether}// List NFT
nft.approve(address(market), tokenId);
market.listItem(address(nft), tokenId, 1 ether) {value: 0.0001 ether}
// Buy NFT
market.buyItem(address(nft), tokenId) {value: 1 ether}// Create auction
nft.approve(address(market), tokenId);
market.createAuction(address(nft), tokenId, 0.5 ether, 7 days);
// Place bid
market.bid(address(nft), tokenId) {value: 1 ether};Mints specified quantity of NFTs to caller.
Parameters:
quantity: Number of NFTs to mint_tokenURI: Metadata URI for NFTs
Requirements:
- Payment of 0.001 ETH per NFT
- Contract not paused
Batch mints NFTs to multiple recipients.
Parameters:
to: Array of recipient addressesquantities: Array of quantities for each recipient
Returns the metadata URI for a token.
Withdraws accumulated minting fees to treasury.
Lists an NFT for sale.
Parameters:
nftContract: NFT contract addresstokenId: Token ID to listprice: Listing price in wei
Purchases a listed NFT.
createAuction(address nftContract, uint256 tokenId, uint256 reservePrice, uint256 duration) external
Creates an auction for an NFT.
Places a bid in an active auction.
Ends an auction and distributes funds.
- OpenZeppelin Contracts v5.5.0 (battle-tested)
- Custom logic follows OpenZeppelin patterns
- Comprehensive test coverage (100%)
- Reentrancy protection on all external functions
- ReentrancyGuard: Prevents reentrancy attacks
- Pausable: Emergency circuit breaker
- Ownable: Administrative controls
- Input Validation: Comprehensive parameter checking
- Chain Validation: Base network enforcement
- Single royalty receiver per collection (ERC-2981 limitation)
- No flash loan protection for auctions
- Requires manual auction ending
# Run all tests
forge test
# Run specific test file
forge test --match-path test/BasedNFT.t.sol
# Run with gas reporting
forge test --gas-report
# Run fuzz tests
forge test --fuzz-runs 1000- Unit Tests: Individual contract functions
- Integration Tests: Cross-contract interactions
- Security Tests: Access control and edge cases
- Gas Tests: Optimization verification
./deploy.sh# Update .env with mainnet RPC
forge script script/DeployBase.s.sol \
--rpc-url $BASE_MAINNET_RPC_URL \
--account $ACCOUNT \
--sender $SENDER \
--etherscan-api-key $BASESCAN_API_KEY \
--broadcast \
--verifyAfter deployment, contracts will be deployed to:
- BasedNFT: 0x9CFEd3BD95eA962658318E3E3BBe9b4B4fC7edB4
- BasedNFTMarket: 0x4f6558d101CAF8c20B9cA61B824DD039eeBb5644
Base Sepolia Testnet Deployment (December 22, 2025)
β
Deployment Status: Successful
β
Contracts Verified: Both contracts verified on Basescan
β
Gas Used: 5,618,348 gas
β
Total Cost: 0.000610357336637816 ETH
β
Network: Base Sepolia (Chain ID: 84532)
Transaction Hashes:
- BasedNFT: 0xe7761cb447083e798bcf20223b3390e9ff1debe31efe30e75b15619914510e4a
- BasedNFTMarket: 0xd6240dfbe9640dfdbb1fc0b65b91cd6784b0efcbb86a1e06bb0b1e5dae7c4929
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Implement changes
- Ensure all tests pass
- Submit a pull request
- Follow Solidity style guide
- Comprehensive NatSpec documentation
- 100% test coverage
- Gas optimization
- Security-first approach
This project is licensed under the MIT License - see the LICENSE file for details.
- OpenZeppelin for secure contract libraries
- Foundry for development tooling
- Base for the network infrastructure
For questions or support:
- Open an issue
- Join our Discord
- Read the documentation
Built with β€οΈ for the Base ecosystem $ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
### Cast
```shell
$ cast <subcommand>
$ forge --help
$ anvil --help
$ cast --help