ERC721 pausable token (#1154)
* ERC721 pausable token * Reuse of ERC721 Basic behavior for Pausable, split view checks in paused state & style fixes * [~] paused token behavior
This commit is contained in:
committed by
Nicolás Venturo
parent
48fe7b8cbf
commit
9e6307f34b
22
contracts/mocks/ERC721PausableTokenMock.sol
Normal file
22
contracts/mocks/ERC721PausableTokenMock.sol
Normal file
@ -0,0 +1,22 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC721/ERC721PausableToken.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC721PausableTokenMock
|
||||
* 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 {
|
||||
super._mint(_to, _tokenId);
|
||||
}
|
||||
|
||||
function burn(uint256 _tokenId) public {
|
||||
super._burn(ownerOf(_tokenId), _tokenId);
|
||||
}
|
||||
|
||||
function exists(uint256 _tokenId) public view returns (bool) {
|
||||
return super._exists(_tokenId);
|
||||
}
|
||||
}
|
||||
42
contracts/token/ERC721/ERC721PausableToken.sol
Normal file
42
contracts/token/ERC721/ERC721PausableToken.sol
Normal file
@ -0,0 +1,42 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
36
test/token/ERC721/ERC721PausableToken.test.js
Normal file
36
test/token/ERC721/ERC721PausableToken.test.js
Normal file
@ -0,0 +1,36 @@
|
||||
const { shouldBehaveLikeERC721PausedToken } = require('./ERC721PausedToken.behavior');
|
||||
const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
const ERC721PausableToken = artifacts.require('ERC721PausableTokenMock.sol');
|
||||
|
||||
require('chai')
|
||||
.use(require('chai-bignumber')(BigNumber))
|
||||
.should();
|
||||
|
||||
contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...otherAccounts]) {
|
||||
beforeEach(async function () {
|
||||
this.token = await ERC721PausableToken.new({ from: owner });
|
||||
});
|
||||
|
||||
context('when token is paused', function () {
|
||||
beforeEach(async function () {
|
||||
await this.token.pause({ from: owner });
|
||||
});
|
||||
|
||||
shouldBehaveLikeERC721PausedToken(owner, [...otherAccounts]);
|
||||
});
|
||||
|
||||
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]);
|
||||
});
|
||||
});
|
||||
88
test/token/ERC721/ERC721PausedToken.behavior.js
Normal file
88
test/token/ERC721/ERC721PausedToken.behavior.js
Normal file
@ -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,
|
||||
};
|
||||
Reference in New Issue
Block a user