Fix/add erc721 safe mint safe transfer from #1736 (#1816)

* added _safeTransferFrom function

* added safeMint functions

* added package-lock.json for consistency, don't know why it changes

* added initial suggestions/modifications

* change _safeTransferFrom to internal, reverted package-lock.json to original, and changed ERC721Pausable to override _transferFrom instead of transferFrom

* included tests for safeMint functions

* modified safeMint tests to be on ERC721Mock contract

* added safeMint to ERC721Mintable & respective test to ERC721MintBurn.behavior.js
This commit is contained in:
Alan Arvelo
2019-07-29 11:16:55 -04:00
committed by Francisco Giordano
parent 571fa7f4e7
commit 377431bc4c
6 changed files with 159 additions and 5 deletions

View File

@ -4,6 +4,7 @@ const { ZERO_ADDRESS } = constants;
const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior');
const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock.sol');
const ERC721Mock = artifacts.require('ERC721Mock.sol');
function shouldBehaveLikeERC721 (
creator,
@ -324,6 +325,68 @@ function shouldBehaveLikeERC721 (
});
});
describe('safe mint', function () {
const fourthTokenId = new BN(4);
const tokenId = fourthTokenId;
const data = '0x42';
beforeEach(async function () {
this.ERC721Mock = await ERC721Mock.new();
});
describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others
it('should call onERC721Received — with data', async function () {
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false);
const receipt = await this.ERC721Mock.safeMint(this.receiver.address, tokenId, data);
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
from: ZERO_ADDRESS,
tokenId: tokenId,
data: data,
});
});
it('should call onERC721Received — without data', async function () {
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false);
const receipt = await this.ERC721Mock.safeMint(this.receiver.address, tokenId);
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
from: ZERO_ADDRESS,
tokenId: tokenId,
});
});
context('to a receiver contract returning unexpected value', function () {
it('reverts', async function () {
const invalidReceiver = await ERC721ReceiverMock.new('0x42', false);
await expectRevert(
this.ERC721Mock.safeMint(invalidReceiver.address, tokenId),
'ERC721: transfer to non ERC721Receiver implementer'
);
});
});
context('to a receiver contract that throws', function () {
it('reverts', async function () {
const invalidReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, true);
await expectRevert(
this.ERC721Mock.safeMint(invalidReceiver.address, tokenId),
'ERC721ReceiverMock: reverting'
);
});
});
context('to a contract that does not implement the required function', function () {
it('reverts', async function () {
const invalidReceiver = this.token;
await expectRevert.unspecified(
this.ERC721Mock.safeMint(invalidReceiver.address, tokenId)
);
});
});
});
});
describe('approve', function () {
const tokenId = firstTokenId;

View File

@ -13,6 +13,7 @@ function shouldBehaveLikeMintAndBurnERC721 (
const thirdTokenId = new BN(3);
const unknownTokenId = new BN(4);
const MOCK_URI = 'https://example.com';
const data = '0x42';
describe('like a mintable and burnable ERC721', function () {
beforeEach(async function () {
@ -72,6 +73,18 @@ function shouldBehaveLikeMintAndBurnERC721 (
});
});
describe('safeMint', function () {
it('it can safely mint with data', async function () {
await this.token.methods['safeMint(address,uint256,bytes)'](...[newOwner, thirdTokenId, data],
{ from: minter });
});
it('it can safely mint without data', async function () {
await this.token.methods['safeMint(address,uint256)'](...[newOwner, thirdTokenId],
{ from: minter });
});
});
describe('burn', function () {
const tokenId = firstTokenId;
let logs = null;