A security-focused NFT marketplace built with Solidity and Foundry. This project demonstrates core marketplace mechanics along with advanced testing techniques such as fuzzing and invariant testing.
-
List ERC721 NFTs for sale
-
Buy listed NFTs with exact ETH payment
-
Cancel active listings
-
Update listing prices
-
Withdraw proceeds (pull-based payments)
-
Protection against:
- Reentrancy
- Incorrect payments
- Self-buying
- Stale listings
-
Pull-over-Push Payments
- Sellers withdraw ETH manually
- Prevents failed transfers & reentrancy issues
-
Approval Validation
- Ensures marketplace is approved before transfers
-
State Cleanup
- Listings are removed after purchase or invalid state
This project includes:
- Unit Tests – Validate all core flows and edge cases
- Fuzz Tests – Randomized inputs for robustness
- Invariant Tests – Ensure system safety across all states
-
Contract balance always matches expected ETH accounting
-
ETH conservation:
totalEthIn == totalEthOut + contractBalance -
Total proceeds owed never exceed contract balance
-
Listings never exist with zero price
-
Listing
(price, seller)consistency is maintained -
Marketplace never owns NFTs
-
Minted NFTs always have a valid owner
-
Ghost state matches actual contract state
-
Direct ETH transfers always revert
- Solidity ^0.8.19
- Foundry
- OpenZeppelin Contracts
src/
└── NftMarketplace.sol
script/
└── DeployNftMarketplace.s.sol
test/
├── NftMarketplaceTest.t.sol
├── invariant/
│ ├── NftMarketplaceInvariant.t.sol
│ └── NftMarketplaceHandler.t.sol
└── mocks/
├── MockNFT.sol
└── RejectingReceiver.sol
forge build
forge test
forge test --match-path test/invariant/*
forge test --gas-report
-
Designed as a learning + security-focused project, not production-ready
-
Emphasizes:
- Correct state transitions
- Safe ETH handling
- Adversarial testing mindset
-
Demonstrates full marketplace flow: NFT listing → buying → proceeds withdrawal