浏览代码

Implicitly clear ERC721 approval on transfers (#3481)

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
Andrew Parker 3 年之前
父节点
当前提交
e02c378745
共有 3 个文件被更改,包括 6 次插入5 次删除
  1. 5 0
      CHANGELOG.md
  2. 1 1
      contracts/token/ERC721/ERC721.sol
  3. 0 4
      test/token/ERC721/ERC721.behavior.js

+ 5 - 0
CHANGELOG.md

@@ -7,6 +7,11 @@
  * `Address`: optimize `functionCall` functions by checking contract size only if there is no returned data. ([#3469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3469))
  * `GovernorCompatibilityBravo`: remove unused `using` statements ([#3506](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3506))
  * `ERC20`: optimize `_transfer`, `_mint` and `_burn` by using `unchecked` arithmetic when possible. ([#3513](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3513))
+ * `ERC721`: optimize transfers by making approval clearing implicit instead of emitting an event. ([#3481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3481))
+
+### Compatibility Note
+
+ERC-721 integrators that interpret contract state from events should make sure that they implement the clearing of approval that is implicit in every transfer according to the EIP. Previous versions of OpenZeppellin Contracts emitted an explicit `Approval` event even though it was not required by the specification, and this is no longer the case.
 
 ## 4.7.0 (2022-06-29)
 

+ 1 - 1
contracts/token/ERC721/ERC721.sol

@@ -338,7 +338,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
         _beforeTokenTransfer(from, to, tokenId);
 
         // Clear approvals from the previous owner
-        _approve(address(0), tokenId);
+        delete _tokenApprovals[tokenId];
 
         _balances[from] -= 1;
         _balances[to] += 1;

+ 0 - 4
test/token/ERC721/ERC721.behavior.js

@@ -96,10 +96,6 @@ function shouldBehaveLikeERC721 (errorPrefix, owner, newOwner, approved, another
           expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS);
         });
 
-        it('emits an Approval event', async function () {
-          expectEvent(receipt, 'Approval', { owner, approved: ZERO_ADDRESS, tokenId: tokenId });
-        });
-
         it('adjusts owners balances', async function () {
           expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1');
         });