-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1200969
commit 33db2b1
Showing
4 changed files
with
197 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); |