I have just finished the crypto zombies tutorial https://cryptozombies.io/ and wanted to get it working locally but also using a solc 0.8.0. Compilation has thrown me lots of errors, many of which I just had to change external to public in my overrides and also add the override modifier. There is one issue, however, that I am unsure how to resolve. The contract inherits from the @openzeppelin/contracts version of ERC721. The two functions I am having issues with use the payable modifier.

  function transferFrom(address _from, address _to, uint256 _tokenId) public payable override {
    require (zombieToOwner[_tokenId] == msg.sender || zombieApprovals[_tokenId] == msg.sender);
    _transfer(_from, _to, _tokenId);

  function approve(address _approved, uint256 _tokenId) public payable override onlyOwnerOf(_tokenId) {
    zombieApprovals[_tokenId] = _approved;
    emit Approval(msg.sender, _approved, _tokenId);

I get an error during compilation..

TypeError: Overriding function changes state mutability from "nonpayable" to "payable".

So I find that in the ERC721 contract, neither of these functions is marked as payable.

So my question is do I remove the payable modifiers in my function overrides? I thought that this would mean the function/tx cannot carry an ether value. Or do I add the modifiers to the functions in the contracts I am inheriting from? Why do the functions lack these modifiers if (from what I have read) solidity expects them to be present in these two functions? Or am I missing something? I am unsure how to proceed so any help would be massively appreciated!

2 Answers 2


Only use payable when you're explicitly sending WETH. Sending tokens or NFTs does not inheritably cost WETH (only gas). If the transfer function calls another function it will inherit payable from the called function.

  • holy moses you're right. thanks for pointing that out!
    – HubertBlu
    Commented Feb 4, 2022 at 15:03

I also have this exact problem. The thing is to be able to integrate royalty I first thought to make the transferFrom function payable but that was not possible.. Then I discovered ERC2981 Contract (royalty protocol).. However I can't get it working.. I mean I minted on my project and then tried to sell it on Opensea but there was no royalty payment.I will post a link here. I hope you can get it working. If you can get it working can you please give feedback about this royalty... The link is : https://eips.ethereum.org/EIPS/eip-2981

  • Royalty is not enforced by opensea yet.
    – Ayudh
    Commented Aug 25, 2023 at 15:09

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.