chiru-labs / ERC721A

https://ERC721A.org
MIT License
2.51k stars 843 forks source link

OpenSea On-Chain Enforcement Tool not working with ERC721A #434

Closed Martin-Fritsche closed 2 years ago

Martin-Fritsche commented 2 years ago

I'm working on trying to enforce royalties for a smart contract. I just read that OpenSea came out with a contract extension that excludes marketplaces that don't enforce royalties.

I'm currently implementing this extension into a smart contract. However, I am getting an error that I can't resolve.

The contract inherits from ERC721A.

THIS IS THE ERROR

TypeError: Overriding function changes state mutability from "payable" to "nonpayable". --> contracts/MyNFTContractTest.sol:66:5: | 66 | function transferFrom(address from, address to, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperator(from) { | ^ (Relevant source part starts here and spans across multiple lines). Note: Overridden function is here: --> erc721a/contracts/ERC721A.sol:540:5:

THIS IS THE ERROR

THIS IS THE CONTRACT -- edited for space

// SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0;

import "erc721a/contracts/ERC721A.sol"; import "erc721a/contracts/extensions/ERC721AQueryable.sol"; import "erc721a/contracts/extensions/ERC721ABurnable.sol"; import "erc721a/contracts/extensions/ERC4907A.sol"; import "./DefaultOperatorFilterer721.sol";

import "@openzeppelin/contracts/token/common/ERC2981.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract MyNFTContractTest is ERC2981, ERC721A, ERC721AQueryable, ERC721ABurnable, ERC4907A, Ownable, DefaultOperatorFilterer721{

constructor(uint96 _royaltyFeesInBips, string memory _contractURI) ERC721A("MNCTest", "MNCTT") {
    setRoyaltyInfo(msg.sender, _royaltyFeesInBips);
    contractURI = _contractURI;
}

function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC2981, ERC4907A, ERC721A, IERC721A)
    returns (bool)
{
    return super.supportsInterface(interfaceId) || 
    interfaceId == type(IERC2981).interfaceId || 
    interfaceId == type(IERC721A).interfaceId || 
    interfaceId == type(IERC721ABurnable).interfaceId || 
    interfaceId == type(IERC721AQueryable).interfaceId;
}

function _startTokenId() internal view virtual override returns (uint256) {
    return 1;
}


*THESE FUNCTIONS CAUSE THE ERROR***

function transferFrom(address from, address to, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperator(from) {
    super.transferFrom(from, to, tokenId);
}

function safeTransferFrom(address from, address to, uint256 tokenId) public override(ERC721A, IERC721A) onlyAllowedOperator(from) {
    super.safeTransferFrom(from, to, tokenId);
}

function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
    public
    override(ERC721A, IERC721A)
    onlyAllowedOperator(from)
{
    super.safeTransferFrom(from, to, tokenId, data);
}

*THESE FUNCTIONS CAUSE THE ERROR***




function mint(uint256 _quantity) external payable{
    require(active, "Contract is currently Inactive");
    require(publicSale, "Public Sale Inactive.");
    require((totalSupply() + _quantity) <= MAX_SUPPLY, "Exceeded Public Max Supply");
    require(msg.value >= (PUBLIC_SALE_PRICE * _quantity), "You Have Not Provided Enough Eth");

    _safeMint(msg.sender, _quantity);
}

}

THIS IS THE CONTRACT -- edited for space

Martin-Fritsche commented 2 years ago

I think I needed to add payable to the function header of each function. I assumed the mutability would be inherited (IERC721A sets the mutability of these functions to payable), but I needed to be added to the function header explicitly.

It should have been

function transferFrom(address from, address to, uint256 tokenId) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); }

function safeTransferFrom(address from, address to, uint256 tokenId) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); }

function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); }