Merge tag 'v2.1.1' of github.com:OpenZeppelin/openzeppelin-solidity

v2.1.1
This commit is contained in:
Francisco Giordano
2019-01-18 15:33:51 -03:00
237 changed files with 8562 additions and 4937 deletions

View File

@ -1,15 +1,11 @@
const expectEvent = require('../../helpers/expectEvent');
const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior');
const { assertRevert } = require('../../helpers/assertRevert');
const { decodeLogs } = require('../../helpers/decodeLogs');
const { sendTransaction } = require('../../helpers/sendTransaction');
const _ = require('lodash');
const shouldFail = require('../../helpers/shouldFail');
const { ZERO_ADDRESS } = require('../../helpers/constants');
const send = require('../../helpers/send');
const ERC721Receiver = artifacts.require('ERC721ReceiverMock.sol');
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock.sol');
require('../../helpers/setup');
function shouldBehaveLikeERC721 (
creator,
@ -19,7 +15,6 @@ function shouldBehaveLikeERC721 (
const firstTokenId = 1;
const secondTokenId = 2;
const unknownTokenId = 3;
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const RECEIVER_MAGIC_VALUE = '0x150b7a02';
describe('like an ERC721', function () {
@ -44,7 +39,7 @@ function shouldBehaveLikeERC721 (
context('when querying the zero address', function () {
it('throws', async function () {
await assertRevert(this.token.balanceOf(0));
await shouldFail.reverting(this.token.balanceOf(0));
});
});
});
@ -62,7 +57,7 @@ function shouldBehaveLikeERC721 (
const tokenId = unknownTokenId;
it('reverts', async function () {
await assertRevert(this.token.ownerOf(tokenId));
await shouldFail.reverting(this.token.ownerOf(tokenId));
});
});
});
@ -89,19 +84,19 @@ function shouldBehaveLikeERC721 (
if (approved) {
it('emit only a transfer event', async function () {
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('Transfer');
logs[0].args.from.should.be.equal(owner);
logs[0].args.to.should.be.equal(this.toWhom);
logs[0].args.tokenId.should.be.bignumber.equal(tokenId);
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
to: this.toWhom,
tokenId: tokenId,
});
});
} else {
it('emits only a transfer event', async function () {
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('Transfer');
logs[0].args.from.should.be.equal(owner);
logs[0].args.to.should.be.equal(this.toWhom);
logs[0].args.tokenId.should.be.bignumber.equal(tokenId);
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
to: this.toWhom,
tokenId: tokenId,
});
});
}
@ -162,11 +157,11 @@ function shouldBehaveLikeERC721 (
});
it('emits only a transfer event', async function () {
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('Transfer');
logs[0].args.from.should.be.equal(owner);
logs[0].args.to.should.be.equal(owner);
logs[0].args.tokenId.should.be.bignumber.equal(tokenId);
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
to: owner,
tokenId: tokenId,
});
});
it('keeps the owner balance', async function () {
@ -175,35 +170,37 @@ function shouldBehaveLikeERC721 (
it('keeps same tokens by index', async function () {
if (!this.token.tokenOfOwnerByIndex) return;
const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenOfOwnerByIndex(owner, i)));
const tokensListed = await Promise.all(
[0, 1].map(i => this.token.tokenOfOwnerByIndex(owner, i))
);
tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]);
});
});
context('when the address of the previous owner is incorrect', function () {
it('reverts', async function () {
await assertRevert(transferFunction.call(this, anyone, anyone, tokenId, { from: owner })
await shouldFail.reverting(transferFunction.call(this, anyone, anyone, tokenId, { from: owner })
);
});
});
context('when the sender is not authorized for the token id', function () {
it('reverts', async function () {
await assertRevert(transferFunction.call(this, owner, anyone, tokenId, { from: anyone })
await shouldFail.reverting(transferFunction.call(this, owner, anyone, tokenId, { from: anyone })
);
});
});
context('when the given token ID does not exist', function () {
it('reverts', async function () {
await assertRevert(transferFunction.call(this, owner, anyone, unknownTokenId, { from: owner })
await shouldFail.reverting(transferFunction.call(this, owner, anyone, unknownTokenId, { from: owner })
);
});
});
context('when the address to transfer the token to is the zero address', function () {
it('reverts', async function () {
await assertRevert(transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner }));
await shouldFail.reverting(transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner }));
});
});
};
@ -216,7 +213,7 @@ function shouldBehaveLikeERC721 (
describe('via safeTransferFrom', function () {
const safeTransferFromWithData = function (from, to, tokenId, opts) {
return sendTransaction(
return send.transaction(
this.token,
'safeTransferFrom',
'address,address,uint256,bytes',
@ -236,43 +233,37 @@ function shouldBehaveLikeERC721 (
describe('to a valid receiver contract', function () {
beforeEach(async function () {
this.receiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, false);
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false);
this.toWhom = this.receiver.address;
});
shouldTransferTokensByUsers(transferFun);
it('should call onERC721Received', async function () {
const result = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner });
result.receipt.logs.length.should.be.equal(2);
const [log] = decodeLogs([result.receipt.logs[1]], ERC721Receiver, this.receiver.address);
log.event.should.be.equal('Received');
log.args.operator.should.be.equal(owner);
log.args.from.should.be.equal(owner);
log.args.tokenId.toNumber().should.be.equal(tokenId);
log.args.data.should.be.equal(data);
const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner });
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
operator: owner,
from: owner,
tokenId: tokenId,
data: data,
});
});
it('should call onERC721Received from approved', async function () {
const result = await transferFun.call(this, owner, this.receiver.address, tokenId, {
from: approved,
const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: approved });
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
operator: approved,
from: owner,
tokenId: tokenId,
data: data,
});
result.receipt.logs.length.should.be.equal(2);
const [log] = decodeLogs(
[result.receipt.logs[1]],
ERC721Receiver,
this.receiver.address
);
log.event.should.be.equal('Received');
log.args.operator.should.be.equal(approved);
log.args.from.should.be.equal(owner);
log.args.tokenId.toNumber().should.be.equal(tokenId);
log.args.data.should.be.equal(data);
});
describe('with an invalid token id', function () {
it('reverts', async function () {
await assertRevert(
await shouldFail.reverting(
transferFun.call(
this,
owner,
@ -296,22 +287,28 @@ function shouldBehaveLikeERC721 (
describe('to a receiver contract returning unexpected value', function () {
it('reverts', async function () {
const invalidReceiver = await ERC721Receiver.new('0x42', false);
await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }));
const invalidReceiver = await ERC721ReceiverMock.new('0x42', false);
await shouldFail.reverting(
this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })
);
});
});
describe('to a receiver contract that throws', function () {
it('reverts', async function () {
const invalidReceiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, true);
await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }));
const invalidReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, true);
await shouldFail.reverting(
this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })
);
});
});
describe('to a contract that does not implement the required function', function () {
it('reverts', async function () {
const invalidReceiver = this.token;
await assertRevert(this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }));
await shouldFail.reverting(
this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner })
);
});
});
});
@ -336,11 +333,11 @@ function shouldBehaveLikeERC721 (
const itEmitsApprovalEvent = function (address) {
it('emits an approval event', async function () {
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('Approval');
logs[0].args.owner.should.be.equal(owner);
logs[0].args.approved.should.be.equal(address);
logs[0].args.tokenId.should.be.bignumber.equal(tokenId);
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
approved: address,
tokenId: tokenId,
});
});
};
@ -398,7 +395,7 @@ function shouldBehaveLikeERC721 (
context('when the address that receives the approval is the owner', function () {
it('reverts', async function () {
await assertRevert(
await shouldFail.reverting(
this.token.approve(owner, tokenId, { from: owner })
);
});
@ -406,14 +403,14 @@ function shouldBehaveLikeERC721 (
context('when the sender does not own the given token ID', function () {
it('reverts', async function () {
await assertRevert(this.token.approve(approved, tokenId, { from: anyone }));
await shouldFail.reverting(this.token.approve(approved, tokenId, { from: anyone }));
});
});
context('when the sender is approved for the given token ID', function () {
it('reverts', async function () {
await this.token.approve(approved, tokenId, { from: owner });
await assertRevert(this.token.approve(anotherApproved, tokenId, { from: approved }));
await shouldFail.reverting(this.token.approve(anotherApproved, tokenId, { from: approved }));
});
});
@ -429,7 +426,7 @@ function shouldBehaveLikeERC721 (
context('when the given token ID does not exist', function () {
it('reverts', async function () {
await assertRevert(this.token.approve(approved, unknownTokenId, { from: operator }));
await shouldFail.reverting(this.token.approve(approved, unknownTokenId, { from: operator }));
});
});
});
@ -446,11 +443,11 @@ function shouldBehaveLikeERC721 (
it('emits an approval event', async function () {
const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner });
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('ApprovalForAll');
logs[0].args.owner.should.be.equal(owner);
logs[0].args.operator.should.be.equal(operator);
logs[0].args.approved.should.equal(true);
expectEvent.inLogs(logs, 'ApprovalForAll', {
owner: owner,
operator: operator,
approved: true,
});
});
});
@ -468,11 +465,11 @@ function shouldBehaveLikeERC721 (
it('emits an approval event', async function () {
const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner });
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('ApprovalForAll');
logs[0].args.owner.should.be.equal(owner);
logs[0].args.operator.should.be.equal(operator);
logs[0].args.approved.should.equal(true);
expectEvent.inLogs(logs, 'ApprovalForAll', {
owner: owner,
operator: operator,
approved: true,
});
});
it('can unset the operator approval', async function () {
@ -496,18 +493,18 @@ function shouldBehaveLikeERC721 (
it('emits an approval event', async function () {
const { logs } = await this.token.setApprovalForAll(operator, true, { from: owner });
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('ApprovalForAll');
logs[0].args.owner.should.be.equal(owner);
logs[0].args.operator.should.be.equal(operator);
logs[0].args.approved.should.equal(true);
expectEvent.inLogs(logs, 'ApprovalForAll', {
owner: owner,
operator: operator,
approved: true,
});
});
});
});
context('when the operator is the owner', function () {
it('reverts', async function () {
await assertRevert(this.token.setApprovalForAll(owner, true, { from: owner }));
await shouldFail.reverting(this.token.setApprovalForAll(owner, true, { from: owner }));
});
});
});

View File

@ -1,16 +1,112 @@
require('../../helpers/setup');
const { ZERO_ADDRESS } = require('../../helpers/constants');
const expectEvent = require('../../helpers/expectEvent');
const send = require('../../helpers/send');
const shouldFail = require('../../helpers/shouldFail');
const { shouldBehaveLikeERC721 } = require('./ERC721.behavior');
const ERC721Mock = artifacts.require('ERC721Mock.sol');
const BigNumber = web3.BigNumber;
const ERC721 = artifacts.require('ERC721Mock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('ERC721', function ([_, creator, ...accounts]) {
contract('ERC721', function ([_, creator, tokenOwner, anyone, ...accounts]) {
beforeEach(async function () {
this.token = await ERC721.new({ from: creator });
this.token = await ERC721Mock.new({ from: creator });
});
shouldBehaveLikeERC721(creator, creator, accounts);
describe('internal functions', function () {
const tokenId = 5042;
describe('_mint(address, uint256)', function () {
it('reverts with a null destination address', async function () {
await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, tokenId));
});
context('with minted token', async function () {
beforeEach(async function () {
({ logs: this.logs } = await this.token.mint(tokenOwner, tokenId));
});
it('emits a Transfer event', function () {
expectEvent.inLogs(this.logs, 'Transfer', { from: ZERO_ADDRESS, to: tokenOwner, tokenId });
});
it('creates the token', async function () {
(await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(1);
(await this.token.ownerOf(tokenId)).should.equal(tokenOwner);
});
it('reverts when adding a token id that already exists', async function () {
await shouldFail.reverting(this.token.mint(tokenOwner, tokenId));
});
});
});
describe('_burn(address, uint256)', function () {
it('reverts when burning a non-existent token id', async function () {
await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId]));
});
context('with minted token', function () {
beforeEach(async function () {
await this.token.mint(tokenOwner, tokenId);
});
it('reverts when the account is not the owner', async function () {
await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [anyone, tokenId]));
});
context('with burnt token', function () {
beforeEach(async function () {
({ logs: this.logs } =
await send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId]));
});
it('emits a Transfer event', function () {
expectEvent.inLogs(this.logs, 'Transfer', { from: tokenOwner, to: ZERO_ADDRESS, tokenId });
});
it('deletes the token', async function () {
(await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(0);
await shouldFail.reverting(this.token.ownerOf(tokenId));
});
it('reverts when burning a token id that has been deleted', async function () {
await shouldFail.reverting(send.transaction(this.token, 'burn', 'address,uint256', [tokenOwner, tokenId]));
});
});
});
});
describe('_burn(uint256)', function () {
it('reverts when burning a non-existent token id', async function () {
await shouldFail.reverting(send.transaction(this.token, 'burn', 'uint256', [tokenId]));
});
context('with minted token', function () {
beforeEach(async function () {
await this.token.mint(tokenOwner, tokenId);
});
context('with burnt token', function () {
beforeEach(async function () {
({ logs: this.logs } = await send.transaction(this.token, 'burn', 'uint256', [tokenId]));
});
it('emits a Transfer event', function () {
expectEvent.inLogs(this.logs, 'Transfer', { from: tokenOwner, to: ZERO_ADDRESS, tokenId });
});
it('deletes the token', async function () {
(await this.token.balanceOf(tokenOwner)).should.be.bignumber.equal(0);
await shouldFail.reverting(this.token.ownerOf(tokenId));
});
it('reverts when burning a token id that has been deleted', async function () {
await shouldFail.reverting(send.transaction(this.token, 'burn', 'uint256', [tokenId]));
});
});
});
});
});
});

View File

@ -3,18 +3,15 @@ const {
shouldBehaveLikeMintAndBurnERC721,
} = require('./ERC721MintBurn.behavior');
const BigNumber = web3.BigNumber;
const ERC721Burnable = artifacts.require('ERC721MintableBurnableImpl.sol');
const ERC721BurnableImpl = artifacts.require('ERC721MintableBurnableImpl.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
require('../../helpers/setup');
contract('ERC721Burnable', function ([_, creator, ...accounts]) {
const minter = creator;
beforeEach(async function () {
this.token = await ERC721Burnable.new({ from: creator });
this.token = await ERC721BurnableImpl.new({ from: creator });
});
shouldBehaveLikeERC721(creator, minter, accounts);

View File

@ -1,14 +1,10 @@
const { assertRevert } = require('../../helpers/assertRevert');
const shouldFail = require('../../helpers/shouldFail');
const { shouldBehaveLikeERC721 } = require('./ERC721.behavior');
const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior');
const _ = require('lodash');
const BigNumber = web3.BigNumber;
const ERC721FullMock = artifacts.require('ERC721FullMock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
require('../../helpers/setup');
contract('ERC721Full', function ([
creator,
@ -27,7 +23,6 @@ contract('ERC721Full', function ([
owner,
newOwner,
another,
anyone,
] = accounts;
beforeEach(async function () {
@ -70,37 +65,7 @@ contract('ERC721Full', function ([
it('burns all tokens', async function () {
await this.token.burn(secondTokenId, { from: owner });
(await this.token.totalSupply()).toNumber().should.be.equal(0);
await assertRevert(this.token.tokenByIndex(0));
});
});
describe('removeTokenFrom', function () {
it('reverts if the correct owner is not passed', async function () {
await assertRevert(
this.token.removeTokenFrom(anyone, firstTokenId, { from: owner })
);
});
context('once removed', function () {
beforeEach(async function () {
await this.token.removeTokenFrom(owner, firstTokenId, { from: owner });
});
it('has been removed', async function () {
await assertRevert(this.token.tokenOfOwnerByIndex(owner, 1));
});
it('adjusts token list', async function () {
(await this.token.tokenOfOwnerByIndex(owner, 0)).toNumber().should.be.equal(secondTokenId);
});
it('adjusts owner count', async function () {
(await this.token.balanceOf(owner)).toNumber().should.be.equal(1);
});
it('does not adjust supply', async function () {
(await this.token.totalSupply()).toNumber().should.be.equal(2);
});
await shouldFail.reverting(this.token.tokenByIndex(0));
});
});
@ -121,7 +86,7 @@ contract('ERC721Full', function ([
});
it('reverts when setting metadata for non existent token id', async function () {
await assertRevert(this.token.setTokenURI(nonExistentTokenId, sampleUri));
await shouldFail.reverting(this.token.setTokenURI(nonExistentTokenId, sampleUri));
});
it('can burn token with metadata', async function () {
@ -135,7 +100,16 @@ contract('ERC721Full', function ([
});
it('reverts when querying metadata for non existent token id', async function () {
await assertRevert(this.token.tokenURI(nonExistentTokenId));
await shouldFail.reverting(this.token.tokenURI(nonExistentTokenId));
});
});
describe('tokensOfOwner', function () {
it('returns total tokens of owner', async function () {
const tokenIds = await this.token.tokensOfOwner(owner);
tokenIds.length.should.equal(2);
tokenIds[0].should.be.bignumber.equal(firstTokenId);
tokenIds[1].should.be.bignumber.equal(secondTokenId);
});
});
@ -154,13 +128,13 @@ contract('ERC721Full', function ([
describe('when the index is greater than or equal to the total tokens owned by the given address', function () {
it('reverts', async function () {
await assertRevert(this.token.tokenOfOwnerByIndex(owner, 2));
await shouldFail.reverting(this.token.tokenOfOwnerByIndex(owner, 2));
});
});
describe('when the given address does not own any token', function () {
it('reverts', async function () {
await assertRevert(this.token.tokenOfOwnerByIndex(another, 0));
await shouldFail.reverting(this.token.tokenOfOwnerByIndex(another, 0));
});
});
@ -172,25 +146,29 @@ contract('ERC721Full', function ([
it('returns correct token IDs for target', async function () {
(await this.token.balanceOf(another)).toNumber().should.be.equal(2);
const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenOfOwnerByIndex(another, i)));
const tokensListed = await Promise.all(
[0, 1].map(i => this.token.tokenOfOwnerByIndex(another, i))
);
tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]);
});
it('returns empty collection for original owner', async function () {
(await this.token.balanceOf(owner)).toNumber().should.be.equal(0);
await assertRevert(this.token.tokenOfOwnerByIndex(owner, 0));
await shouldFail.reverting(this.token.tokenOfOwnerByIndex(owner, 0));
});
});
});
describe('tokenByIndex', function () {
it('should return all tokens', async function () {
const tokensListed = await Promise.all(_.range(2).map(i => this.token.tokenByIndex(i)));
const tokensListed = await Promise.all(
[0, 1].map(i => this.token.tokenByIndex(i))
);
tokensListed.map(t => t.toNumber()).should.have.members([firstTokenId, secondTokenId]);
});
it('should revert if index is greater than supply', async function () {
await assertRevert(this.token.tokenByIndex(2));
await shouldFail.reverting(this.token.tokenByIndex(2));
});
[firstTokenId, secondTokenId].forEach(function (tokenId) {
@ -204,9 +182,10 @@ contract('ERC721Full', function ([
(await this.token.totalSupply()).toNumber().should.be.equal(3);
const tokensListed = await Promise.all(_.range(3).map(i => this.token.tokenByIndex(i)));
const expectedTokens = _.filter(
[firstTokenId, secondTokenId, newTokenId, anotherNewTokenId],
const tokensListed = await Promise.all(
[0, 1, 2].map(i => this.token.tokenByIndex(i))
);
const expectedTokens = [firstTokenId, secondTokenId, newTokenId, anotherNewTokenId].filter(
x => (x !== tokenId)
);
tokensListed.map(t => t.toNumber()).should.have.members(expectedTokens);

View File

@ -1,8 +1,7 @@
const ERC721Holder = artifacts.require('ERC721Holder.sol');
const ERC721Mintable = artifacts.require('ERC721MintableBurnableImpl.sol');
require('chai')
.should();
require('../../helpers/setup');
contract('ERC721Holder', function ([creator]) {
it('receives an ERC721 token', async function () {

View File

@ -1,10 +1,7 @@
const { assertRevert } = require('../../helpers/assertRevert');
const shouldFail = require('../../helpers/shouldFail');
const expectEvent = require('../../helpers/expectEvent');
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
const { ZERO_ADDRESS } = require('../../helpers/constants');
require('../../helpers/setup');
function shouldBehaveLikeMintAndBurnERC721 (
creator,
@ -15,7 +12,6 @@ function shouldBehaveLikeMintAndBurnERC721 (
const secondTokenId = 2;
const thirdTokenId = 3;
const unknownTokenId = 4;
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const MOCK_URI = 'https://example.com';
describe('like a mintable and burnable ERC721', function () {
@ -42,23 +38,23 @@ function shouldBehaveLikeMintAndBurnERC721 (
});
it('emits a transfer and minted event', async function () {
await expectEvent.inLogs(logs, 'Transfer', {
expectEvent.inLogs(logs, 'Transfer', {
from: ZERO_ADDRESS,
to: newOwner,
tokenId: thirdTokenId,
});
logs[0].args.tokenId.should.be.bignumber.equal(thirdTokenId);
});
});
describe('when the given owner address is the zero address', function () {
it('reverts', async function () {
await assertRevert(this.token.mint(ZERO_ADDRESS, thirdTokenId, { from: minter }));
await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, thirdTokenId, { from: minter }));
});
});
describe('when the given token ID was already tracked by this contract', function () {
it('reverts', async function () {
await assertRevert(this.token.mint(owner, firstTokenId, { from: minter }));
await shouldFail.reverting(this.token.mint(owner, firstTokenId, { from: minter }));
});
});
});
@ -82,16 +78,16 @@ function shouldBehaveLikeMintAndBurnERC721 (
});
it('burns the given token ID and adjusts the balance of the owner', async function () {
await assertRevert(this.token.ownerOf(tokenId));
await shouldFail.reverting(this.token.ownerOf(tokenId));
(await this.token.balanceOf(owner)).should.be.bignumber.equal(1);
});
it('emits a burn event', async function () {
logs.length.should.be.equal(1);
logs[0].event.should.be.equal('Transfer');
logs[0].args.from.should.be.equal(owner);
logs[0].args.to.should.be.equal(ZERO_ADDRESS);
logs[0].args.tokenId.should.be.bignumber.equal(tokenId);
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
to: ZERO_ADDRESS,
tokenId: tokenId,
});
});
});
@ -104,14 +100,14 @@ function shouldBehaveLikeMintAndBurnERC721 (
context('getApproved', function () {
it('reverts', async function () {
await assertRevert(this.token.getApproved(tokenId));
await shouldFail.reverting(this.token.getApproved(tokenId));
});
});
});
describe('when the given token ID was not tracked by this contract', function () {
it('reverts', async function () {
await assertRevert(
await shouldFail.reverting(
this.token.burn(unknownTokenId, { from: creator })
);
});

View File

@ -3,18 +3,15 @@ const {
shouldBehaveLikeMintAndBurnERC721,
} = require('./ERC721MintBurn.behavior');
const BigNumber = web3.BigNumber;
const ERC721Mintable = artifacts.require('ERC721MintableBurnableImpl.sol');
const ERC721MintableImpl = artifacts.require('ERC721MintableBurnableImpl.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
require('../../helpers/setup');
contract('ERC721Mintable', function ([_, creator, ...accounts]) {
const minter = creator;
beforeEach(async function () {
this.token = await ERC721Mintable.new({
this.token = await ERC721MintableImpl.new({
from: creator,
});
});

View File

@ -2,12 +2,9 @@ const { shouldBehaveLikeERC721PausedToken } = require('./ERC721PausedToken.behav
const { shouldBehaveLikeERC721 } = require('./ERC721.behavior');
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
const BigNumber = web3.BigNumber;
const ERC721Pausable = artifacts.require('ERC721PausableMock.sol');
const ERC721PausableMock = artifacts.require('ERC721PausableMock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
require('../../helpers/setup');
contract('ERC721Pausable', function ([
_,
@ -18,7 +15,7 @@ contract('ERC721Pausable', function ([
...accounts
]) {
beforeEach(async function () {
this.token = await ERC721Pausable.new({ from: creator });
this.token = await ERC721PausableMock.new({ from: creator });
});
describe('pauser role', function () {

View File

@ -1,17 +1,13 @@
const { assertRevert } = require('../../helpers/assertRevert');
const { sendTransaction } = require('../../helpers/sendTransaction');
const shouldFail = require('../../helpers/shouldFail');
const send = require('../../helpers/send');
const { ZERO_ADDRESS } = require('../../helpers/constants');
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
require('../../helpers/setup');
function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) {
const firstTokenId = 1;
const mintedTokens = 1;
const mockData = '0x42';
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
describe('like a paused ERC721', function () {
beforeEach(async function () {
@ -19,24 +15,24 @@ function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) {
});
it('reverts when trying to approve', async function () {
await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner }));
await shouldFail.reverting(this.token.approve(recipient, firstTokenId, { from: owner }));
});
it('reverts when trying to setApprovalForAll', async function () {
await assertRevert(this.token.setApprovalForAll(operator, true, { from: owner }));
await shouldFail.reverting(this.token.setApprovalForAll(operator, true, { from: owner }));
});
it('reverts when trying to transferFrom', async function () {
await assertRevert(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner }));
await shouldFail.reverting(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner }));
});
it('reverts when trying to safeTransferFrom', async function () {
await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner }));
await shouldFail.reverting(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner }));
});
it('reverts when trying to safeTransferFrom with data', async function () {
await assertRevert(
sendTransaction(
await shouldFail.reverting(
send.transaction(
this.token,
'safeTransferFrom',
'address,address,uint256,bytes',