-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicitly clear ERC721 approval on transfers #3481
Conversation
As per the ERC721 standard, the transfer function shouldn't emit an Approve event, as clearing the approval is implicit in the Transfer event. Docs regarding Approve event: ``` /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. ``` [EIP-721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md)
Hello @AnAllergyToAnalogy I think we already had this discussion sometime ago. The specification for the Approval event are
Which can indeed be interpreted as "Transfer event implies approval is reset, so no approval event is required". Removing it might break things, but one could argue that the "things" in question should follow the ERC and not our implementation. The question is then, is it clear enough to everybody that they should not expect an Approval event on transfers? |
I would argue that things are currently broken as technically the contract doesn't properly adhere to the standard. Non-OpenZepp ERC721 implementations won't be emitting the event on Transfers, so any 3rd party projects would need to account for that anyway. I would say the onus is on other projects to adhere to the standard as written and not just common implementations. As a side note, not emitting the event saves about 2100 gas. Given the vast majority of ERC721s no mainnet use OpenZepp, and given gas prices and NFT usage over the last few years, this one bug has probably cost a couple of hundred million dollars of wasted gas. It's probably worth patching. |
This is absolutely not a bug. Implementing additional behavior than that required by the standard is okay as long as it's consistent with the rules in it. That approval reset is implied doesn't mean it's wrong to explicitly emit the event. Regardless, I agree this is worth considering because of the large gas savings. I agree that systems integrating with the standard should not be expecting an Approve event. |
@frangio you're right that additional behavior not mentioned in the rules isn't contrary to the standard, but i think in the case of this event since it explicitly says not to emit it, it would be considered a bug. I think beyond the gas it would be low-impact, given it's just an event, but for any system that's using events in even a superficial way it'll produce anomolous behavior that needs to be accounted for. For example, an interface using events to show an NFT's activity would falsely show that the approval was cleared each time it was transferred. |
... but the approval was cleared each time it was transferred. The reset happens, that is clear. Whether it's notified by the Transfer event itself, or by an additional Approval event, that doesn't change the reality that adddess(0) is now approved for this token. The specs don't require the Approval to be emitted only if the approved address changes, but also if it's reaffirmed. So yes, emitting an Approval event is wasteful in terms of gas, but no, it's not a bug |
Let me rephrase, it implies that the user called the approval function to manually clear the approval. Just because the impact is small doesn't make it not a bug. I discovered this bug because I was running unit tests on a project that inherits OpenZeppelin ERC721 contracts, and it was anomalously emitting Approval events when it shouldn't. The spec is very clear that Approval shouldn't be emitted on token transfer,
At the moment the OpenZeppelin contracts aren't fully ERC721 compliant. |
I'll have to disagree on that. The ERC states that the event should be emitted when |
✅ Tests are good. Otherwise, code is good for me. @frangio, do you see anything more needed? |
No. Agree with the changelog and compatibility warning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance you can add the things we mentioned above, or should we go ahead and do it?
Sorry, realizing it may be better for us to do it and get the wording how we want it.
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
As per the ERC721 standard, the transfer function shouldn't emit an Approve event, as clearing the approval is implicit in the Transfer event.
Docs regarding Approve event:
EIP-721
Fixes #3484
PR Checklist