10

I'm having a hard time understanding why and when SetApprovalForAll is called on NFT generating contracts.

Take Cool Cats, for example. And for convenience there's a screen shot of relevant transactions, below.

I've noticed that for this contract and others, Set Approval For All is repeatedly called. In my own limited experience with a contract that allows minting, via _safeMint, I'm seeing a SetApprovalForAll transaction in the logs too. It's not called directly in my code.

Why is it being called? Are wallets doing it as part of the minting process?

enter image description here

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Doug P
  • 361
  • 1
  • 4
  • 15
  • Hi, i can i ask you something related to your question? in the setApprovalForAll it is asking me to pass an operator (which is supposed to be an address). does this mean i should pass all the wallet addresses manual? – kd12345 Jan 17 '22 at 12:26

2 Answers2

9

When you sell NFTs on a Marketplace, you need to authorize this marketplace to transfer sold items from your address to the buyer's address.

This is what SetApprovalForAll is used for: because you trust the marketplace, you "approve" it to sell your NFTs (not all your NFTs, but the NFTs you own in the context of this contract).

The marketplace is what is called the "operator" in the context of this API.

Olivier Liechti
  • 3,138
  • 2
  • 19
  • 26
  • Why do you need to authorise the marketplace to transfer ALL your NFTs (in the context of that contract) even when you only want to list a single NFT for sale? I tested this on NFTrade. I went to list one NFT that I own, and it wants to call setApprovalForAll(). Even if I do trust them, why should I give them more permissions than needed? They should be able to send an NFT for me by just having me call approve() on a single token ID. Am I missing something? – matteo Aug 12 '22 at 09:31
  • There is a cost associated with `setApprovalForAll`, so maybe they thought it was more cost effective to set it once per collection contract – chrysb Aug 27 '22 at 21:03
0

this is openzeppelin ERC721.sol

setApprovalForAll calls this function:

// Approve `operator` to operate on all of `owner` tokens
function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

_operatorApprovals is a mapping:

// owner address allows operator address
mapping(address => mapping(address => bool)) private _operatorApprovals;

An operator is a third party that is trusted and can be approved by an owner to have access to all the NFTs owned by them. If an owner gives permission to an operator, that operator is allowed to withdraw any NFT from that owner's address and they are allowed to transfer it to themselves or others.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202