1

This is my first project with solidity (newbie here!) and I'm trying to implement ERC2981 in a ERC721 contract for my own marketplace, not just the minting part but the buying and transfer process as well. I saw that question and answer here, but I wanted to be sure I've implemented it right in my own marketplace structure. At the moment, I'm having troubles at the buy nft (createMarketSale) step, I can't seem to get it right, any bits of hints and information cwould greatly appreciated! Thanks in advance!

Here is my work in progress contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";

contract NFTMarket is ReentrancyGuard, ERC2981 {
    using Counters for Counters.Counter;
    Counters.Counter private _itemIds;
    Counters.Counter private _itemsSold;

    address payable owner;
    uint256 listingPrice = 0.025 ether; // is matic

    constructor(address receiver, uint96 feeNumerator) {
        _setDefaultRoyalty(receiver,feeNumerator);
        owner = payable(msg.sender);
    }

    struct MarketItem {
     uint itemId;
     address nftContract;
     uint256 tokenId;
     address payable seller;
     address payable owner;
     uint256 price;
     bool sold;
    }

    mapping(uint256 => MarketItem) private idToMarketItem;

    event MarketItemCreated (

     uint indexed itemId,
     address indexed nftContract,
     uint256 indexed tokenId,
     address seller,
     address owner,
     uint256 price,
     bool sold
    );

    /* Returns the listing price of the contract */
    function getListingPrice() public view returns (uint256) {
      return listingPrice;
 }

    function setDefaultRoyalty(address _receiver, uint96 _feeNumerator) public {
      _setDefaultRoyalty(_receiver, _feeNumerator);
  }
    
function createMarketItem(
     address nftContract,
     uint256 tokenId,
     uint256 price

) public payable nonReentrant {
    require(price > 0, "Price must be at least 1 wei");
    require(msg.value == listingPrice, "Price must be equal to listing price");

    _itemIds.increment();
    uint256 itemId = _itemIds.current();

    idToMarketItem[itemId] = MarketItem (
        itemId,
        nftContract,
        tokenId,
        payable(msg.sender),
        payable(address(0)),
        price,
        false
    );

    IERC721(nftContract).transferFrom(msg.sender,address(this),tokenId);

    emit MarketItemCreated(
        itemId,
        nftContract,
        tokenId,
        msg.sender,
        address(0),
        price,
        false
      );

}

function createMarketSale(
    address nftContract,
    uint256 itemId
) public payable nonReentrant{
    uint price = idToMarketItem[itemId].price;
    uint tokenId = idToMarketItem[itemId].tokenId;
    require(msg.value == price, "Please submit the asking price in order to complete the purchase");

    idToMarketItem[itemId].seller.transfer(msg.value);
    IERC721(nftContract).transferFrom(address(this),msg.sender, tokenId);
    idToMarketItem[itemId].owner = payable(msg.sender);
    idToMarketItem[itemId].sold = true;
    _itemsSold.increment();
    payable(owner).transfer(listingPrice);

}

function fetchMarketItems() public view returns (MarketItem[] memory){
    uint itemCount = _itemIds.current();
    uint unsoldItemCount = _itemIds.current() - _itemsSold.current();
    uint currentIndex = 0;

    MarketItem[] memory items = new MarketItem[](unsoldItemCount);
    for (uint i = 0; i < itemCount; i++){
        if (idToMarketItem[i + 1].owner == address(0)){
            uint currentId = idToMarketItem [i+1].itemId;
            MarketItem storage currentItem = idToMarketItem[currentId];
            items[currentIndex] = currentItem;
            currentIndex +=1;
        }
    }
    return items;
}

function fetchMyNFTs() public view returns (MarketItem[] memory) {
    uint totalItemCount = _itemIds.current();
    uint itemCount = 0;
    uint currentIndex = 0;

    for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].owner == msg.sender) {
          itemCount += 1;
        }
      } 


     MarketItem[] memory items = new MarketItem[](itemCount);
      for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].owner == msg.sender) {
          uint currentId = idToMarketItem [i + 1].itemId;
          MarketItem storage currentItem = idToMarketItem[currentId];
          items[currentIndex] = currentItem;
          currentIndex += 1;
        }
      }
      return items;
}  

function fetchItemsCreated () public view returns (MarketItem[] memory) {
    uint totalItemCount = _itemIds.current();
    uint itemCount = 0;
    uint currentIndex = 0;

    for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].seller == msg.sender){
            itemCount += 1;
        }
    }

    MarketItem[] memory items = new MarketItem[](itemCount);
    for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i +1].seller == msg.sender) {
            uint currentId = idToMarketItem[i +1].itemId;
            MarketItem storage currentItem = idToMarketItem[currentId];
            items [currentIndex] = currentItem;
            currentIndex += 1;
    }
}


return items;

    }

} 
3
  • Hi Alice! Welcome to Ethereum Stackexchange! Can you provide more details about the problem? What functions are you calling? What is the expected output? What are you getting instead?
    – Ismael
    Feb 26, 2023 at 1:45
  • Hello Ismael, I am trying to submit royalties to the receiver when someone is buying an nft using the function specified above (function createMarketSale). So far I can’t get it to work, no royalties sent to the receiver, only the nft price. I want to validate if my contract is ok/well written? Thanks!
    – Alice
    Feb 26, 2023 at 2:11
  • The output that I’m getting at the moment is just the correct price payment with gas fees paid by the buyer without the royalties paid to the receiver.
    – Alice
    Feb 26, 2023 at 2:23

1 Answer 1

0

The ERC-2981 only provides an standardized way to retrieve royalty information from a NFT contract. It is each market responsibility to implement the distribution of royalties.

1
  • Ok, I understand now that I will need to design around that standardization.
    – Alice
    Feb 26, 2023 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.