From a38869e3885360512ebffab87fcfa43015576dbd Mon Sep 17 00:00:00 2001 From: Roman Exempliarov Date: Sun, 5 Aug 2018 18:56:23 +0300 Subject: [PATCH 1/3] ERC721 pausable token --- contracts/mocks/ERC721PausableTokenMock.sol | 18 +++ .../token/ERC721/ERC721PausableToken.sol | 43 +++++++ .../ERC721/ERC721PausableToken.behavior.js | 120 ++++++++++++++++++ test/token/ERC721/ERC721PausableToken.test.js | 16 +++ 4 files changed, 197 insertions(+) create mode 100644 contracts/mocks/ERC721PausableTokenMock.sol create mode 100644 contracts/token/ERC721/ERC721PausableToken.sol create mode 100644 test/token/ERC721/ERC721PausableToken.behavior.js create mode 100644 test/token/ERC721/ERC721PausableToken.test.js diff --git a/contracts/mocks/ERC721PausableTokenMock.sol b/contracts/mocks/ERC721PausableTokenMock.sol new file mode 100644 index 00000000000..a164aeeb20b --- /dev/null +++ b/contracts/mocks/ERC721PausableTokenMock.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.4.24; + +import "../token/ERC721/ERC721PausableToken.sol"; + + +/** + * @title ERC721PausableTokenMock + * This mock just provides a public mint and burn functions for testing purposes + */ +contract ERC721PausableTokenMock is ERC721PausableToken { + function mint(address _to, uint256 _tokenId) public { + super._mint(_to, _tokenId); + } + + function burn(uint256 _tokenId) public { + super._burn(ownerOf(_tokenId), _tokenId); + } +} diff --git a/contracts/token/ERC721/ERC721PausableToken.sol b/contracts/token/ERC721/ERC721PausableToken.sol new file mode 100644 index 00000000000..54e4fe86081 --- /dev/null +++ b/contracts/token/ERC721/ERC721PausableToken.sol @@ -0,0 +1,43 @@ +pragma solidity ^0.4.24; + +import "./ERC721BasicToken.sol"; +import "../../lifecycle/Pausable.sol"; + + +/** + * @title ERC721 Non-Fungible Pausable token + * @dev ERC721BasicToken modified with pausable transfers. + **/ +contract ERC721PausableToken is ERC721BasicToken, Pausable { + + function approve( + address _to, + uint256 _tokenId + ) + public + whenNotPaused + { + super.approve(_to, _tokenId); + } + + function setApprovalForAll( + address _to, + bool _approved + ) + public + whenNotPaused + { + super.setApprovalForAll(_to, _approved); + } + + function transferFrom( + address _from, + address _to, + uint256 _tokenId + ) + public + whenNotPaused + { + super.transferFrom(_from, _to, _tokenId); + } +} \ No newline at end of file diff --git a/test/token/ERC721/ERC721PausableToken.behavior.js b/test/token/ERC721/ERC721PausableToken.behavior.js new file mode 100644 index 00000000000..2fb5737e312 --- /dev/null +++ b/test/token/ERC721/ERC721PausableToken.behavior.js @@ -0,0 +1,120 @@ +const { assertRevert } = require('../../helpers/assertRevert'); +const { sendTransaction } = require('../../helpers/sendTransaction'); + +const BigNumber = web3.BigNumber; + +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +function shouldBehaveLikeERC721PausableToken (accounts) { + const firstTokenId = 1; + const owner = accounts[0]; + const recipient = accounts[1]; + const operator = accounts[2]; + const data = '0x42'; + const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + + const safeTransferFromWithData = function (token, from, to, tokenId, opts) { + return sendTransaction( + token, + 'safeTransferFrom', + 'address,address,uint256,bytes', + [from, to, tokenId, data], + opts + ); + }; + + const shouldBehaveLikeUnpausedToken = function () { + it('approves token transfer', async function () { + await this.token.approve(recipient, firstTokenId, { from: owner }); + const approvedAccount = await this.token.getApproved(firstTokenId); + approvedAccount.should.be.equal(recipient); + }); + + it('approves operator via setApprovalForAll', async function () { + await this.token.setApprovalForAll(operator, true, { from: owner }); + const isApprovedForOperator = await this.token.isApprovedForAll(owner, operator); + isApprovedForOperator.should.be.true; + }); + + it('transfers token', async function () { + await this.token.transferFrom(owner, recipient, firstTokenId, { from: owner }); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(recipient); + }); + + it('transfers token via safeTransferFrom', async function () { + await this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner }); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(recipient); + }); + + it('transfers token via safeTransferFrom with data', async function () { + await safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(recipient); + }); + }; + + describe('when token is not paused yet', function () { + beforeEach(async function () { + await this.token.mint(owner, firstTokenId, { from: owner }); + }); + + shouldBehaveLikeUnpausedToken(); + }); + + describe('when token is paused and unpaused', function () { + beforeEach(async function () { + await this.token.mint(owner, firstTokenId, { from: owner }); + await this.token.pause({ from: owner }); + await this.token.unpause({ from: owner }); + }); + + shouldBehaveLikeUnpausedToken(); + }); + + describe('when token is paused', function () { + beforeEach(async function () { + await this.token.mint(owner, firstTokenId, { from: owner }); + await this.token.pause({ from: owner }); + }); + + it('reverts when trying to approve', async function () { + await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); + const approvedAccount = await this.token.getApproved(firstTokenId); + approvedAccount.should.be.equal(ZERO_ADDRESS); + }); + + it('reverts when trying to setApprovalForAll', async function () { + await assertRevert(this.token.setApprovalForAll(operator, true, { from: owner })); + const isApprovedForOperator = await this.token.isApprovedForAll(owner, operator); + isApprovedForOperator.should.be.false; + }); + + it('reverts when trying to transferFrom', async function () { + await assertRevert(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner })); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(owner); + }); + + it('reverts when trying to safeTransferFrom', async function () { + await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(owner); + }); + + it('reverts when trying to safeTransferFrom', async function () { + await assertRevert( + safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }) + ); + const firstTokenOwner = await this.token.ownerOf(firstTokenId); + firstTokenOwner.should.be.equal(owner); + }); + }); +} + +module.exports = { + shouldBehaveLikeERC721PausableToken, +}; diff --git a/test/token/ERC721/ERC721PausableToken.test.js b/test/token/ERC721/ERC721PausableToken.test.js new file mode 100644 index 00000000000..872c6853e02 --- /dev/null +++ b/test/token/ERC721/ERC721PausableToken.test.js @@ -0,0 +1,16 @@ +const { shouldBehaveLikeERC721PausableToken } = require('./ERC721PausableToken.behavior'); + +const BigNumber = web3.BigNumber; +const ERC721PausableToken = artifacts.require('ERC721PausableTokenMock.sol'); + +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +contract('ERC721PausableToken', function (accounts) { + beforeEach(async function () { + this.token = await ERC721PausableToken.new({ from: accounts[0] }); + }); + + shouldBehaveLikeERC721PausableToken(accounts); +}); From ced966e5a464387e0956c2c281bdfe792032bad5 Mon Sep 17 00:00:00 2001 From: Roman Exempliarov Date: Sat, 11 Aug 2018 01:42:21 +0300 Subject: [PATCH 2/3] Reuse of ERC721 Basic behavior for Pausable, split view checks in paused state & style fixes --- .../token/ERC721/ERC721PausableToken.sol | 3 +- .../ERC721/ERC721PausableToken.behavior.js | 114 +++++++----------- test/token/ERC721/ERC721PausableToken.test.js | 22 +++- 3 files changed, 62 insertions(+), 77 deletions(-) diff --git a/contracts/token/ERC721/ERC721PausableToken.sol b/contracts/token/ERC721/ERC721PausableToken.sol index 54e4fe86081..2da188a7edc 100644 --- a/contracts/token/ERC721/ERC721PausableToken.sol +++ b/contracts/token/ERC721/ERC721PausableToken.sol @@ -9,7 +9,6 @@ import "../../lifecycle/Pausable.sol"; * @dev ERC721BasicToken modified with pausable transfers. **/ contract ERC721PausableToken is ERC721BasicToken, Pausable { - function approve( address _to, uint256 _tokenId @@ -40,4 +39,4 @@ contract ERC721PausableToken is ERC721BasicToken, Pausable { { super.transferFrom(_from, _to, _tokenId); } -} \ No newline at end of file +} diff --git a/test/token/ERC721/ERC721PausableToken.behavior.js b/test/token/ERC721/ERC721PausableToken.behavior.js index 2fb5737e312..88ece9afad4 100644 --- a/test/token/ERC721/ERC721PausableToken.behavior.js +++ b/test/token/ERC721/ERC721PausableToken.behavior.js @@ -7,11 +7,8 @@ require('chai') .use(require('chai-bignumber')(BigNumber)) .should(); -function shouldBehaveLikeERC721PausableToken (accounts) { +function shouldBehaveLikeERC721PausableToken ([owner, recipient, operator]) { const firstTokenId = 1; - const owner = accounts[0]; - const recipient = accounts[1]; - const operator = accounts[2]; const data = '0x42'; const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; @@ -25,92 +22,65 @@ function shouldBehaveLikeERC721PausableToken (accounts) { ); }; - const shouldBehaveLikeUnpausedToken = function () { - it('approves token transfer', async function () { - await this.token.approve(recipient, firstTokenId, { from: owner }); - const approvedAccount = await this.token.getApproved(firstTokenId); - approvedAccount.should.be.equal(recipient); - }); - - it('approves operator via setApprovalForAll', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - const isApprovedForOperator = await this.token.isApprovedForAll(owner, operator); - isApprovedForOperator.should.be.true; - }); - - it('transfers token', async function () { - await this.token.transferFrom(owner, recipient, firstTokenId, { from: owner }); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(recipient); - }); - - it('transfers token via safeTransferFrom', async function () { - await this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner }); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(recipient); - }); - - it('transfers token via safeTransferFrom with data', async function () { - await safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(recipient); - }); - }; + beforeEach(async function () { + await this.token.mint(owner, firstTokenId, { from: owner }); + await this.token.pause({ from: owner }); + }); - describe('when token is not paused yet', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - }); + it('reverts when trying to approve', async function () { + await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); + }); - shouldBehaveLikeUnpausedToken(); + it('reverts when trying to setApprovalForAll', async function () { + await assertRevert(this.token.setApprovalForAll(operator, true, { from: owner })); }); - describe('when token is paused and unpaused', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - await this.token.pause({ from: owner }); - await this.token.unpause({ from: owner }); - }); + it('reverts when trying to transferFrom', async function () { + await assertRevert(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner })); + }); - shouldBehaveLikeUnpausedToken(); + it('reverts when trying to safeTransferFrom', async function () { + await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); }); - describe('when token is paused', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - await this.token.pause({ from: owner }); - }); + it('reverts when trying to safeTransferFrom', async function () { + await assertRevert( + safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }) + ); + }); - it('reverts when trying to approve', async function () { - await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); + describe('getApproved', function () { + it('returns approved address', async function () { const approvedAccount = await this.token.getApproved(firstTokenId); approvedAccount.should.be.equal(ZERO_ADDRESS); }); + }); - it('reverts when trying to setApprovalForAll', async function () { - await assertRevert(this.token.setApprovalForAll(operator, true, { from: owner })); - const isApprovedForOperator = await this.token.isApprovedForAll(owner, operator); - isApprovedForOperator.should.be.false; + describe('balanceOf', function () { + it('returns the amount of tokens owned by the given address', async function () { + const balance = await this.token.balanceOf(owner); + balance.should.be.bignumber.equal(1); }); + }); - it('reverts when trying to transferFrom', async function () { - await assertRevert(this.token.transferFrom(owner, recipient, firstTokenId, { from: owner })); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(owner); + describe('ownerOf', function () { + it('returns the amount of tokens owned by the given address', async function () { + const ownerOfToken = await this.token.ownerOf(firstTokenId); + ownerOfToken.should.be.equal(owner); }); + }); - it('reverts when trying to safeTransferFrom', async function () { - await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(owner); + describe('exists', function () { + it('should return token existance', async function () { + const result = await this.token.exists(firstTokenId); + result.should.be.true; }); + }); - it('reverts when trying to safeTransferFrom', async function () { - await assertRevert( - safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }) - ); - const firstTokenOwner = await this.token.ownerOf(firstTokenId); - firstTokenOwner.should.be.equal(owner); + describe('isApprovedForAll', function () { + it('returns the approval of the operator', async function () { + const isApproved = await this.token.isApprovedForAll(owner, operator); + isApproved.should.be.false; }); }); } diff --git a/test/token/ERC721/ERC721PausableToken.test.js b/test/token/ERC721/ERC721PausableToken.test.js index 872c6853e02..a59906e39e8 100644 --- a/test/token/ERC721/ERC721PausableToken.test.js +++ b/test/token/ERC721/ERC721PausableToken.test.js @@ -1,4 +1,5 @@ const { shouldBehaveLikeERC721PausableToken } = require('./ERC721PausableToken.behavior'); +const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior'); const BigNumber = web3.BigNumber; const ERC721PausableToken = artifacts.require('ERC721PausableTokenMock.sol'); @@ -7,10 +8,25 @@ require('chai') .use(require('chai-bignumber')(BigNumber)) .should(); -contract('ERC721PausableToken', function (accounts) { +contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...otherAccounts]) { beforeEach(async function () { - this.token = await ERC721PausableToken.new({ from: accounts[0] }); + this.token = await ERC721PausableToken.new({ from: owner }); }); - shouldBehaveLikeERC721PausableToken(accounts); + context('when token is paused', function () { + shouldBehaveLikeERC721PausableToken([owner, recipient, operator]); + }); + + context('when token is not paused yet', function () { + shouldBehaveLikeERC721BasicToken([owner, ...otherAccounts]); + }); + + context('when token is paused and then unpaused', function () { + beforeEach(async function () { + await this.token.pause({ from: owner }); + await this.token.unpause({ from: owner }); + }); + + shouldBehaveLikeERC721BasicToken([owner, ...otherAccounts]); + }); }); From d014f65dd927512e0ef96ece5a25d60fa4752167 Mon Sep 17 00:00:00 2001 From: Roman Exempliarov Date: Thu, 23 Aug 2018 22:01:57 +0300 Subject: [PATCH 3/3] [~] paused token behavior --- contracts/mocks/ERC721PausableTokenMock.sol | 6 +- .../ERC721/ERC721PausableToken.behavior.js | 90 ------------------- test/token/ERC721/ERC721PausableToken.test.js | 8 +- .../ERC721/ERC721PausedToken.behavior.js | 88 ++++++++++++++++++ 4 files changed, 99 insertions(+), 93 deletions(-) delete mode 100644 test/token/ERC721/ERC721PausableToken.behavior.js create mode 100644 test/token/ERC721/ERC721PausedToken.behavior.js diff --git a/contracts/mocks/ERC721PausableTokenMock.sol b/contracts/mocks/ERC721PausableTokenMock.sol index a164aeeb20b..b48608114b4 100644 --- a/contracts/mocks/ERC721PausableTokenMock.sol +++ b/contracts/mocks/ERC721PausableTokenMock.sol @@ -5,7 +5,7 @@ import "../token/ERC721/ERC721PausableToken.sol"; /** * @title ERC721PausableTokenMock - * This mock just provides a public mint and burn functions for testing purposes + * This mock just provides a public mint, burn and exists functions for testing purposes */ contract ERC721PausableTokenMock is ERC721PausableToken { function mint(address _to, uint256 _tokenId) public { @@ -15,4 +15,8 @@ contract ERC721PausableTokenMock is ERC721PausableToken { function burn(uint256 _tokenId) public { super._burn(ownerOf(_tokenId), _tokenId); } + + function exists(uint256 _tokenId) public view returns (bool) { + return super._exists(_tokenId); + } } diff --git a/test/token/ERC721/ERC721PausableToken.behavior.js b/test/token/ERC721/ERC721PausableToken.behavior.js deleted file mode 100644 index 88ece9afad4..00000000000 --- a/test/token/ERC721/ERC721PausableToken.behavior.js +++ /dev/null @@ -1,90 +0,0 @@ -const { assertRevert } = require('../../helpers/assertRevert'); -const { sendTransaction } = require('../../helpers/sendTransaction'); - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-bignumber')(BigNumber)) - .should(); - -function shouldBehaveLikeERC721PausableToken ([owner, recipient, operator]) { - const firstTokenId = 1; - const data = '0x42'; - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - - const safeTransferFromWithData = function (token, from, to, tokenId, opts) { - return sendTransaction( - token, - 'safeTransferFrom', - 'address,address,uint256,bytes', - [from, to, tokenId, data], - opts - ); - }; - - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - await this.token.pause({ from: owner }); - }); - - it('reverts when trying to approve', async function () { - await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); - }); - - it('reverts when trying to setApprovalForAll', async function () { - await assertRevert(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 })); - }); - - it('reverts when trying to safeTransferFrom', async function () { - await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); - }); - - it('reverts when trying to safeTransferFrom', async function () { - await assertRevert( - safeTransferFromWithData(this.token, owner, recipient, firstTokenId, { from: owner }) - ); - }); - - describe('getApproved', function () { - it('returns approved address', async function () { - const approvedAccount = await this.token.getApproved(firstTokenId); - approvedAccount.should.be.equal(ZERO_ADDRESS); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const balance = await this.token.balanceOf(owner); - balance.should.be.bignumber.equal(1); - }); - }); - - describe('ownerOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const ownerOfToken = await this.token.ownerOf(firstTokenId); - ownerOfToken.should.be.equal(owner); - }); - }); - - describe('exists', function () { - it('should return token existance', async function () { - const result = await this.token.exists(firstTokenId); - result.should.be.true; - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - const isApproved = await this.token.isApprovedForAll(owner, operator); - isApproved.should.be.false; - }); - }); -} - -module.exports = { - shouldBehaveLikeERC721PausableToken, -}; diff --git a/test/token/ERC721/ERC721PausableToken.test.js b/test/token/ERC721/ERC721PausableToken.test.js index a59906e39e8..03274ffb2b1 100644 --- a/test/token/ERC721/ERC721PausableToken.test.js +++ b/test/token/ERC721/ERC721PausableToken.test.js @@ -1,4 +1,4 @@ -const { shouldBehaveLikeERC721PausableToken } = require('./ERC721PausableToken.behavior'); +const { shouldBehaveLikeERC721PausedToken } = require('./ERC721PausedToken.behavior'); const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior'); const BigNumber = web3.BigNumber; @@ -14,7 +14,11 @@ contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...oth }); context('when token is paused', function () { - shouldBehaveLikeERC721PausableToken([owner, recipient, operator]); + beforeEach(async function () { + await this.token.pause({ from: owner }); + }); + + shouldBehaveLikeERC721PausedToken(owner, [...otherAccounts]); }); context('when token is not paused yet', function () { diff --git a/test/token/ERC721/ERC721PausedToken.behavior.js b/test/token/ERC721/ERC721PausedToken.behavior.js new file mode 100644 index 00000000000..2ef21ec0790 --- /dev/null +++ b/test/token/ERC721/ERC721PausedToken.behavior.js @@ -0,0 +1,88 @@ +const { assertRevert } = require('../../helpers/assertRevert'); +const { sendTransaction } = require('../../helpers/sendTransaction'); + +const BigNumber = web3.BigNumber; + +require('chai') + .use(require('chai-bignumber')(BigNumber)) + .should(); + +function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) { + const firstTokenId = 1; + const mintedTokens = 1; + const mockData = '0x42'; + const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + + describe('like a paused ERC721Token', function () { + beforeEach(async function () { + await this.token.mint(owner, firstTokenId, { from: owner }); + }); + + it('reverts when trying to approve', async function () { + await assertRevert(this.token.approve(recipient, firstTokenId, { from: owner })); + }); + + it('reverts when trying to setApprovalForAll', async function () { + await assertRevert(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 })); + }); + + it('reverts when trying to safeTransferFrom', async function () { + await assertRevert(this.token.safeTransferFrom(owner, recipient, firstTokenId, { from: owner })); + }); + + it('reverts when trying to safeTransferFrom with data', async function () { + await assertRevert( + sendTransaction( + this.token, + 'safeTransferFrom', + 'address,address,uint256,bytes', + [owner, recipient, firstTokenId, mockData], + { from: owner } + ) + ); + }); + + describe('getApproved', function () { + it('returns approved address', async function () { + const approvedAccount = await this.token.getApproved(firstTokenId); + approvedAccount.should.be.equal(ZERO_ADDRESS); + }); + }); + + describe('balanceOf', function () { + it('returns the amount of tokens owned by the given address', async function () { + const balance = await this.token.balanceOf(owner); + balance.should.be.bignumber.equal(mintedTokens); + }); + }); + + describe('ownerOf', function () { + it('returns the amount of tokens owned by the given address', async function () { + const ownerOfToken = await this.token.ownerOf(firstTokenId); + ownerOfToken.should.be.equal(owner); + }); + }); + + describe('exists', function () { + it('should return token existance', async function () { + const result = await this.token.exists(firstTokenId); + result.should.eq(true); + }); + }); + + describe('isApprovedForAll', function () { + it('returns the approval of the operator', async function () { + const isApproved = await this.token.isApprovedForAll(owner, operator); + isApproved.should.eq(false); + }); + }); + }); +} + +module.exports = { + shouldBehaveLikeERC721PausedToken, +};