Przeglądaj źródła

Improve tests for ERC1155 and ERC721 error handling (#3781)

Co-authored-by: Francisco <fg@frang.io>
Hadrien Croubois 2 lat temu
rodzic
commit
365aca6d60

+ 24 - 20
contracts/mocks/token/ERC1155ReceiverMock.sol

@@ -8,26 +8,24 @@ import "../../utils/introspection/ERC165.sol";
 contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
     enum RevertType {
         None,
-        Empty,
-        String,
-        Custom
+        RevertWithoutMessage,
+        RevertWithMessage,
+        RevertWithCustomError,
+        Panic
     }
 
-    bytes4 private _recRetval;
-    RevertType private _recReverts;
-    bytes4 private _batRetval;
-    RevertType private _batReverts;
+    bytes4 private immutable _recRetval;
+    bytes4 private immutable _batRetval;
+    RevertType private immutable _error;
 
     event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas);
     event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas);
+    error CustomError(bytes4);
 
-    error ERC1155ReceiverMockError();
-
-    constructor(bytes4 recRetval, RevertType recReverts, bytes4 batRetval, RevertType batReverts) {
+    constructor(bytes4 recRetval, bytes4 batRetval, RevertType error) {
         _recRetval = recRetval;
-        _recReverts = recReverts;
         _batRetval = batRetval;
-        _batReverts = batReverts;
+        _error = error;
     }
 
     function onERC1155Received(
@@ -37,12 +35,15 @@ contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
         uint256 value,
         bytes calldata data
     ) external returns (bytes4) {
-        if (_recReverts == RevertType.Empty) {
+        if (_error == RevertType.RevertWithoutMessage) {
             revert();
-        } else if (_recReverts == RevertType.String) {
+        } else if (_error == RevertType.RevertWithMessage) {
             revert("ERC1155ReceiverMock: reverting on receive");
-        } else if (_recReverts == RevertType.Custom) {
-            revert ERC1155ReceiverMockError();
+        } else if (_error == RevertType.RevertWithCustomError) {
+            revert CustomError(_recRetval);
+        } else if (_error == RevertType.Panic) {
+            uint256 a = uint256(0) / uint256(0);
+            a;
         }
 
         emit Received(operator, from, id, value, data, gasleft());
@@ -56,12 +57,15 @@ contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
         uint256[] calldata values,
         bytes calldata data
     ) external returns (bytes4) {
-        if (_batReverts == RevertType.Empty) {
+        if (_error == RevertType.RevertWithoutMessage) {
             revert();
-        } else if (_batReverts == RevertType.String) {
+        } else if (_error == RevertType.RevertWithMessage) {
             revert("ERC1155ReceiverMock: reverting on batch receive");
-        } else if (_batReverts == RevertType.Custom) {
-            revert ERC1155ReceiverMockError();
+        } else if (_error == RevertType.RevertWithCustomError) {
+            revert CustomError(_recRetval);
+        } else if (_error == RevertType.Panic) {
+            uint256 a = uint256(0) / uint256(0);
+            a;
         }
 
         emit BatchReceived(operator, from, ids, values, data, gasleft());

+ 13 - 8
contracts/mocks/token/ERC721ReceiverMock.sol

@@ -5,19 +5,21 @@ pragma solidity ^0.8.19;
 import "../../token/ERC721/IERC721Receiver.sol";
 
 contract ERC721ReceiverMock is IERC721Receiver {
-    enum Error {
+    enum RevertType {
         None,
-        RevertWithMessage,
         RevertWithoutMessage,
+        RevertWithMessage,
+        RevertWithCustomError,
         Panic
     }
 
     bytes4 private immutable _retval;
-    Error private immutable _error;
+    RevertType private immutable _error;
 
     event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
+    error CustomError(bytes4);
 
-    constructor(bytes4 retval, Error error) {
+    constructor(bytes4 retval, RevertType error) {
         _retval = retval;
         _error = error;
     }
@@ -28,14 +30,17 @@ contract ERC721ReceiverMock is IERC721Receiver {
         uint256 tokenId,
         bytes memory data
     ) public returns (bytes4) {
-        if (_error == Error.RevertWithMessage) {
-            revert("ERC721ReceiverMock: reverting");
-        } else if (_error == Error.RevertWithoutMessage) {
+        if (_error == RevertType.RevertWithoutMessage) {
             revert();
-        } else if (_error == Error.Panic) {
+        } else if (_error == RevertType.RevertWithMessage) {
+            revert("ERC721ReceiverMock: reverting");
+        } else if (_error == RevertType.RevertWithCustomError) {
+            revert CustomError(_retval);
+        } else if (_error == RevertType.Panic) {
             uint256 a = uint256(0) / uint256(0);
             a;
         }
+
         emit Received(operator, from, tokenId, data, gasleft());
         return _retval;
     }

+ 155 - 144
test/token/ERC1155/ERC1155.behavior.js

@@ -1,14 +1,13 @@
 const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
-const { ZERO_ADDRESS } = constants;
-
 const { expect } = require('chai');
+const { ZERO_ADDRESS } = constants;
 
 const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior');
 const { expectRevertCustomError } = require('../../helpers/customError');
 const { Enum } = require('../../helpers/enums');
 
 const ERC1155ReceiverMock = artifacts.require('ERC1155ReceiverMock');
-const RevertType = Enum('None', 'Empty', 'String', 'Custom');
+const RevertType = Enum('None', 'RevertWithoutMessage', 'RevertWithMessage', 'RevertWithCustomError', 'Panic');
 
 function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, multiTokenHolder, recipient, proxy]) {
   const firstTokenId = new BN(1);
@@ -298,7 +297,6 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
         beforeEach(async function () {
           this.receiver = await ERC1155ReceiverMock.new(
             RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
             RECEIVER_BATCH_MAGIC_VALUE,
             RevertType.None,
           );
@@ -372,12 +370,7 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
 
       context('to a receiver contract returning unexpected value', function () {
         beforeEach(async function () {
-          this.receiver = await ERC1155ReceiverMock.new(
-            '0x00c0ffee',
-            RevertType.None,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.None,
-          );
+          this.receiver = await ERC1155ReceiverMock.new('0x00c0ffee', RECEIVER_BATCH_MAGIC_VALUE, RevertType.None);
         });
 
         it('reverts', async function () {
@@ -392,54 +385,81 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
       });
 
       context('to a receiver contract that reverts', function () {
-        it('with empty reason', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.Empty,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.None,
-          );
+        context('with a revert string', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithMessage,
+            );
+          });
 
-          await expectRevertCustomError(
-            this.token.safeTransferFrom(multiTokenHolder, receiver.address, firstTokenId, firstAmount, '0x', {
-              from: multiTokenHolder,
-            }),
-            'ERC1155InvalidReceiver',
-            [receiver.address],
-          );
+          it('reverts', async function () {
+            await expectRevert(
+              this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
+                from: multiTokenHolder,
+              }),
+              'ERC1155ReceiverMock: reverting on receive',
+            );
+          });
         });
 
-        it('with reason string', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.String,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.None,
-          );
+        context('without a revert string', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithoutMessage,
+            );
+          });
 
-          await expectRevert(
-            this.token.safeTransferFrom(multiTokenHolder, receiver.address, firstTokenId, firstAmount, '0x', {
-              from: multiTokenHolder,
-            }),
-            'ERC1155ReceiverMock: reverting on receive',
-          );
+          it('reverts', async function () {
+            await expectRevertCustomError(
+              this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
+                from: multiTokenHolder,
+              }),
+              'ERC1155InvalidReceiver',
+              [this.receiver.address],
+            );
+          });
         });
 
-        it('with custom error', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.Custom,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.None,
-          );
+        context('with a custom error', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithCustomError,
+            );
+          });
 
-          await expectRevertCustomError(
-            this.token.safeTransferFrom(multiTokenHolder, receiver.address, firstTokenId, firstAmount, '0x', {
-              from: multiTokenHolder,
-            }),
-            'ERC1155ReceiverMockError',
-            [],
-          );
+          it('reverts', async function () {
+            await expectRevertCustomError(
+              this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
+                from: multiTokenHolder,
+              }),
+              'CustomError',
+              [RECEIVER_SINGLE_MAGIC_VALUE],
+            );
+          });
+        });
+
+        context('with a panic', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.Panic,
+            );
+          });
+
+          it('reverts', async function () {
+            await expectRevert.unspecified(
+              this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
+                from: multiTokenHolder,
+              }),
+            );
+          });
         });
       });
 
@@ -629,7 +649,6 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
         beforeEach(async function () {
           this.receiver = await ERC1155ReceiverMock.new(
             RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
             RECEIVER_BATCH_MAGIC_VALUE,
             RevertType.None,
           );
@@ -705,7 +724,6 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
         beforeEach(async function () {
           this.receiver = await ERC1155ReceiverMock.new(
             RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
             RECEIVER_SINGLE_MAGIC_VALUE,
             RevertType.None,
           );
@@ -728,107 +746,100 @@ function shouldBehaveLikeERC1155([minter, firstTokenHolder, secondTokenHolder, m
       });
 
       context('to a receiver contract that reverts', function () {
-        it('with empty reason', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.Empty,
-          );
-
-          await expectRevertCustomError(
-            this.token.safeBatchTransferFrom(
-              multiTokenHolder,
-              receiver.address,
-              [firstTokenId, secondTokenId],
-              [firstAmount, secondAmount],
-              '0x',
-              { from: multiTokenHolder },
-            ),
-            'ERC1155InvalidReceiver',
-            [receiver.address],
-          );
-        });
-
-        it('with reason string', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.String,
-          );
+        context('with a revert string', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithMessage,
+            );
+          });
 
-          await expectRevert(
-            this.token.safeBatchTransferFrom(
-              multiTokenHolder,
-              receiver.address,
-              [firstTokenId, secondTokenId],
-              [firstAmount, secondAmount],
-              '0x',
-              { from: multiTokenHolder },
-            ),
-            'ERC1155ReceiverMock: reverting on batch receive',
-          );
+          it('reverts', async function () {
+            await expectRevert(
+              this.token.safeBatchTransferFrom(
+                multiTokenHolder,
+                this.receiver.address,
+                [firstTokenId, secondTokenId],
+                [firstAmount, secondAmount],
+                '0x',
+                { from: multiTokenHolder },
+              ),
+              'ERC1155ReceiverMock: reverting on batch receive',
+            );
+          });
         });
 
-        it('with custom error', async function () {
-          const receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.None,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.Custom,
-          );
+        context('without a revert string', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithoutMessage,
+            );
+          });
 
-          await expectRevertCustomError(
-            this.token.safeBatchTransferFrom(
-              multiTokenHolder,
-              receiver.address,
-              [firstTokenId, secondTokenId],
-              [firstAmount, secondAmount],
-              '0x',
-              { from: multiTokenHolder },
-            ),
-            'ERC1155ReceiverMockError',
-            [],
-          );
+          it('reverts', async function () {
+            await expectRevertCustomError(
+              this.token.safeBatchTransferFrom(
+                multiTokenHolder,
+                this.receiver.address,
+                [firstTokenId, secondTokenId],
+                [firstAmount, secondAmount],
+                '0x',
+                { from: multiTokenHolder },
+              ),
+              'ERC1155InvalidReceiver',
+              [this.receiver.address],
+            );
+          });
         });
-      });
 
-      context('to a receiver contract that reverts only on single transfers', function () {
-        beforeEach(async function () {
-          this.receiver = await ERC1155ReceiverMock.new(
-            RECEIVER_SINGLE_MAGIC_VALUE,
-            RevertType.String,
-            RECEIVER_BATCH_MAGIC_VALUE,
-            RevertType.None,
-          );
+        context('with a custom error', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.RevertWithCustomError,
+            );
+          });
 
-          this.toWhom = this.receiver.address;
-          this.transferReceipt = await this.token.safeBatchTransferFrom(
-            multiTokenHolder,
-            this.receiver.address,
-            [firstTokenId, secondTokenId],
-            [firstAmount, secondAmount],
-            '0x',
-            { from: multiTokenHolder },
-          );
-          this.transferLogs = this.transferReceipt;
+          it('reverts', async function () {
+            await expectRevertCustomError(
+              this.token.safeBatchTransferFrom(
+                multiTokenHolder,
+                this.receiver.address,
+                [firstTokenId, secondTokenId],
+                [firstAmount, secondAmount],
+                '0x',
+                { from: multiTokenHolder },
+              ),
+              'CustomError',
+              [RECEIVER_SINGLE_MAGIC_VALUE],
+            );
+          });
         });
 
-        batchTransferWasSuccessful.call(this, {
-          operator: multiTokenHolder,
-          from: multiTokenHolder,
-          ids: [firstTokenId, secondTokenId],
-          values: [firstAmount, secondAmount],
-        });
+        context('with a panic', function () {
+          beforeEach(async function () {
+            this.receiver = await ERC1155ReceiverMock.new(
+              RECEIVER_SINGLE_MAGIC_VALUE,
+              RECEIVER_BATCH_MAGIC_VALUE,
+              RevertType.Panic,
+            );
+          });
 
-        it('calls onERC1155BatchReceived', async function () {
-          await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', {
-            operator: multiTokenHolder,
-            from: multiTokenHolder,
-            // ids: [firstTokenId, secondTokenId],
-            // values: [firstAmount, secondAmount],
-            data: null,
+          it('reverts', async function () {
+            await expectRevert.unspecified(
+              this.token.safeBatchTransferFrom(
+                multiTokenHolder,
+                this.receiver.address,
+                [firstTokenId, secondTokenId],
+                [firstAmount, secondAmount],
+                '0x',
+                { from: multiTokenHolder },
+              ),
+            );
           });
         });
       });

+ 45 - 15
test/token/ERC721/ERC721.behavior.js

@@ -4,14 +4,12 @@ const { ZERO_ADDRESS } = constants;
 
 const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior');
 const { expectRevertCustomError } = require('../../helpers/customError');
+const { Enum } = require('../../helpers/enums');
 
 const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock');
 const NonERC721ReceiverMock = artifacts.require('CallReceiverMock');
 
-const Error = ['None', 'RevertWithMessage', 'RevertWithoutMessage', 'Panic'].reduce(
-  (acc, entry, idx) => Object.assign({ [entry]: idx }, acc),
-  {},
-);
+const RevertType = Enum('None', 'RevertWithoutMessage', 'RevertWithMessage', 'RevertWithCustomError', 'Panic');
 
 const firstTokenId = new BN('5042');
 const secondTokenId = new BN('79217');
@@ -234,7 +232,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
           describe('to a valid receiver contract', function () {
             beforeEach(async function () {
-              this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
+              this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.None);
               this.toWhom = this.receiver.address;
             });
 
@@ -284,7 +282,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         describe('to a receiver contract returning unexpected value', function () {
           it('reverts', async function () {
-            const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None);
+            const invalidReceiver = await ERC721ReceiverMock.new('0x42', RevertType.None);
             await expectRevertCustomError(
               this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }),
               'ERC721InvalidReceiver',
@@ -295,7 +293,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         describe('to a receiver contract that reverts with message', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage);
+            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.RevertWithMessage);
             await expectRevert(
               this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
               'ERC721ReceiverMock: reverting',
@@ -305,7 +303,10 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         describe('to a receiver contract that reverts without message', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage);
+            const revertingReceiver = await ERC721ReceiverMock.new(
+              RECEIVER_MAGIC_VALUE,
+              RevertType.RevertWithoutMessage,
+            );
             await expectRevertCustomError(
               this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
               'ERC721InvalidReceiver',
@@ -314,9 +315,23 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
           });
         });
 
+        describe('to a receiver contract that reverts with custom error', function () {
+          it('reverts', async function () {
+            const revertingReceiver = await ERC721ReceiverMock.new(
+              RECEIVER_MAGIC_VALUE,
+              RevertType.RevertWithCustomError,
+            );
+            await expectRevertCustomError(
+              this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
+              'CustomError',
+              [RECEIVER_MAGIC_VALUE],
+            );
+          });
+        });
+
         describe('to a receiver contract that panics', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic);
+            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.Panic);
             await expectRevert.unspecified(
               this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
             );
@@ -343,7 +358,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
       describe('via safeMint', function () {
         // regular minting is tested in ERC721Mintable.test.js and others
         it('calls onERC721Received — with data', async function () {
-          this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
+          this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.None);
           const receipt = await this.token.$_safeMint(this.receiver.address, tokenId, data);
 
           await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
@@ -354,7 +369,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
         });
 
         it('calls onERC721Received — without data', async function () {
-          this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
+          this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.None);
           const receipt = await this.token.$_safeMint(this.receiver.address, tokenId);
 
           await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
@@ -365,7 +380,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         context('to a receiver contract returning unexpected value', function () {
           it('reverts', async function () {
-            const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None);
+            const invalidReceiver = await ERC721ReceiverMock.new('0x42', RevertType.None);
             await expectRevertCustomError(
               this.token.$_safeMint(invalidReceiver.address, tokenId),
               'ERC721InvalidReceiver',
@@ -376,7 +391,7 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         context('to a receiver contract that reverts with message', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage);
+            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.RevertWithMessage);
             await expectRevert(
               this.token.$_safeMint(revertingReceiver.address, tokenId),
               'ERC721ReceiverMock: reverting',
@@ -386,7 +401,10 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
 
         context('to a receiver contract that reverts without message', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage);
+            const revertingReceiver = await ERC721ReceiverMock.new(
+              RECEIVER_MAGIC_VALUE,
+              RevertType.RevertWithoutMessage,
+            );
             await expectRevertCustomError(
               this.token.$_safeMint(revertingReceiver.address, tokenId),
               'ERC721InvalidReceiver',
@@ -395,9 +413,21 @@ function shouldBehaveLikeERC721(owner, newOwner, approved, anotherApproved, oper
           });
         });
 
+        context('to a receiver contract that reverts with custom error', function () {
+          it('reverts', async function () {
+            const revertingReceiver = await ERC721ReceiverMock.new(
+              RECEIVER_MAGIC_VALUE,
+              RevertType.RevertWithCustomError,
+            );
+            await expectRevertCustomError(this.token.$_safeMint(revertingReceiver.address, tokenId), 'CustomError', [
+              RECEIVER_MAGIC_VALUE,
+            ]);
+          });
+        });
+
         context('to a receiver contract that panics', function () {
           it('reverts', async function () {
-            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic);
+            const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, RevertType.Panic);
             await expectRevert.unspecified(this.token.$_safeMint(revertingReceiver.address, tokenId));
           });
         });