// SPDX-License-Identifier: MIT // vuln-code-snippet start nftUnlockChallenge pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract JuiceShopSBT is ERC721, ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; constructor() ERC721("JuiceShopSBT", "JS") {} function safeMint(address to, string memory uri) public onlyOwner { uint256 tokenId = _tokenIdCounter.current(); // vuln-code-snippet vuln-line nftUnlockChallenge _tokenIdCounter.increment(); _safeMint(to, tokenId); _setTokenURI(tokenId, uri); } function _beforeTokenTransfer( address from, address to, uint256 tokenId // vuln-code-snippet neutral-line nftUnlockChallenge ) internal override virtual { require(from == address(0), "Err: token transfer is BLOCKED"); super._beforeTokenTransfer(from, to, tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { // vuln-code-snippet neutral-line nftUnlockChallenge super._burn(tokenId); } function tokenURI(uint256 tokenId) // vuln-code-snippet neutral-line nftUnlockChallenge public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } } // vuln-code-snippet end nftUnlockChallenge