Phrase Trade NFT Marketplace

Overview

The PhraseTradeNFTMarketplace is a Solidity smart contract that implements a decentralized marketplace for trading Non-Fungible Tokens (NFTs). This contract allows users to list their NFTs for sale, buy listed NFTs, and delist their own NFTs. It supports payments in both Ether (ETH) and ERC-20 tokens.

Contract Details

  • License: BSUL

  • Solidity Version: ^0.8.0

  • Inherits From:

    • Ownable: Provides basic authorization control functions

    • IPhraseTradeNFTMarketplace: Interface defining the contract's structure

Key Structures

Listing

struct Listing {
    address seller;
    address paymentToken;
    uint256 price;
}
  • seller: Address of the NFT seller

  • paymentToken: Address of the token to be used for payment (0x0 for ETH)

  • price: Price of the NFT in the specified payment token

State Variables

listings

A nested mapping that stores NFT listings. The first key is the NFT contract address, the second key is the token ID, and the value is the Listing struct.

Functions

listNFT

Lists an NFT for sale.

Parameters:

  • nftContract: Address of the NFT contract

  • tokenId: ID of the NFT

  • paymentToken: Address of the token to be used for payment (0x0 for ETH)

  • price: Price of the NFT in the specified payment token

Functionality:

  1. Transfers the NFT from the seller to the contract

  2. Creates a new Listing and stores it in the listings mapping

  3. Emits an NFTListed event

Security Considerations:

  • Ensure that the contract has approval to transfer the NFT before calling this function

buyNFT

Allows a user to purchase a listed NFT.

Parameters:

  • nftContract: Address of the NFT contract

  • tokenId: ID of the NFT

Functionality:

  1. Retrieves the listing information

  2. Handles payment in ETH or ERC-20 tokens

  3. Transfers the NFT to the buyer

  4. Deletes the listing

  5. Emits an NFTSold event

Security Considerations:

  • Checks if the NFT is listed for sale

  • Ensures sufficient payment is sent for ETH transactions

  • Uses the transferFrom function for ERC-20 payments, requiring prior approval

delistNFT

Allows the seller to remove their NFT from the marketplace.

Parameters:

  • nftContract: Address of the NFT contract

  • tokenId: ID of the NFT

Functionality:

  1. Verifies that the caller is the seller

  2. Transfers the NFT back to the seller

  3. Deletes the listing

  4. Emits an NFTDelisted event

Security Considerations:

  • Only the original seller can delist the NFT

withdrawETH

Allows the contract owner to withdraw ETH from the contract.

Parameters:

  • amount: Amount of ETH to withdraw

Security Considerations:

  • Only the contract owner can call this function

  • Checks if the contract has sufficient balance before withdrawal

withdrawERC20

Allows the contract owner to withdraw ERC-20 tokens from the contract.

Parameters:

  • token: Address of the ERC-20 token

  • amount: Amount of tokens to withdraw

Security Considerations:

  • Only the contract owner can call this function

  • Assumes the contract has sufficient token balance

Events

The contract emits the following events:

  • NFTListed: When an NFT is listed for sale

  • NFTSold: When an NFT is sold

  • NFTDelisted: When an NFT is delisted

Usage Examples

Listing an NFT for sale

Buying an NFT with ETH

Buying an NFT with an ERC-20 token

Security Considerations

  1. Reentrancy: The contract uses the "checks-effects-interactions" pattern to prevent reentrancy attacks.

  2. Access Control: The Ownable contract is used to restrict access to sensitive functions.

  3. Input Validation: The contract checks for valid inputs and sufficient payments.

  4. Token Approvals: Users must approve the contract to transfer their NFTs and ERC-20 tokens before listing or buying.

  5. ETH Handling: The contract uses transfer for sending ETH, which has a gas stipend and can fail silently.

Gas Optimization

  1. The contract uses delete to remove listings, which can save gas by clearing storage.

  2. It uses _msgSender() instead of msg.sender, which is more flexible for potential future upgrades.

Best Practices

  1. The contract follows the Checks-Effects-Interactions pattern for better security.

  2. It uses OpenZeppelin's Ownable contract for standardized ownership management.

  3. The contract emits events for important state changes, allowing for off-chain tracking.

  4. It supports both ETH and ERC-20 token payments, increasing flexibility for users.

Potential Improvements

  1. Implement a fee system for the marketplace.

  2. Add functionality to update listing prices.

  3. Implement batch listing and buying functions for gas efficiency.

  4. Add a mechanism to pause the contract in case of emergencies.

Last updated