Can someone help me figure out what I'm missing in this contract below.
I get this error Execution reverted: ERC721: caller is not token owner or approved
when I run the createMarketItem
function.
The wallet holds 2 nfts and I want to put one for sale using this smart 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";
contract NFTMarketplace is ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _itemIds;
Counters.Counter private _itemsSold;
address public owner;
constructor() {
owner == msg.sender;
}
struct MarketItem {
uint256 itemId;
address nftContract;
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
mapping(uint256 => MarketItem) private idToMarketItem;
event MarketItemCreated(
uint256 indexed itemId,
address indexed nftContract,
uint256 indexed tokenId,
address seller,
address owner,
uint256 price,
bool sold
);
function createMarketItem(
address nftContract, uint256 tokenId, uint256 price
) public payable nonReentrant {
require(price > 0, "Price must be greater than 0");
_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 {
uint256 price = idToMarketItem[itemId].price;
uint256 tokenId = idToMarketItem[itemId].tokenId;
bool sold = idToMarketItem[itemId].sold;
require(msg.value == price, "Please submit the asking price in order to complete the purchase");
require(sold != true, "This Sale has already finished");
idToMarketItem[itemId].seller.transfer(msg.value);
IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId);
idToMarketItem[itemId].owner = payable(msg.sender);
_itemsSold.increment();
idToMarketItem[itemId].sold = true;
}
function fetchMarketItems() public view returns (MarketItem[] memory) {
uint256 itemCount = _itemIds.current();
uint256 unsoldItemCount = _itemIds.current() - _itemsSold.current();
uint256 currentIndex = 0;
MarketItem[] memory items = new MarketItem[](unsoldItemCount);
for (uint256 i = 0; i < itemCount; i++) {
if (idToMarketItem[i + 1].owner == address(0)) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
}