Skip to content

Commit

Permalink
Add missing hook to ERC777, fix relevant documentation (#2191)
Browse files Browse the repository at this point in the history
* Improve ERC20/721 Pausable docs

* Add ERC20Pausable mint and burn tests

* Add ERC721Pausable mint and burn tests

* Add _beforeTransfer hook in ERC777 to mint and burn
  • Loading branch information
nventuro committed Apr 15, 2020
1 parent b6513f6 commit 3e139ba
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 6 deletions.
8 changes: 8 additions & 0 deletions contracts/mocks/ERC20PausableMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ contract ERC20PausableMock is ERC20Pausable {
function unpause() external {
_unpause();
}

function mint(address to, uint256 amount) public {
_mint(to, amount);
}

function burn(address from, uint256 amount) public {
_burn(from, amount);
}
}
3 changes: 1 addition & 2 deletions contracts/token/ERC20/ERC20Pausable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import "./ERC20.sol";
import "../../utils/Pausable.sol";

/**
* @title Pausable token
* @dev ERC20 with pausable transfers and allowances.
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
Expand Down
14 changes: 12 additions & 2 deletions contracts/token/ERC721/ERC721Pausable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ import "./ERC721.sol";
import "../../utils/Pausable.sol";

/**
* @title ERC721 Non-Fungible Pausable token
* @dev ERC721 modified with pausable transfers.
* @dev ERC721 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*/
abstract contract ERC721Pausable is ERC721, Pausable {
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);

Expand Down
4 changes: 4 additions & 0 deletions contracts/token/ERC777/ERC777.sol
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ contract ERC777 is Context, IERC777, IERC20 {

address operator = _msgSender();

_beforeTokenTransfer(operator, address(0), account, amount);

// Update state variables
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
Expand Down Expand Up @@ -382,6 +384,8 @@ contract ERC777 is Context, IERC777, IERC20 {

address operator = _msgSender();

_beforeTokenTransfer(operator, from, address(0), amount);

_callTokensToSend(operator, from, address(0), amount, data, operatorData);

// Update state variables
Expand Down
54 changes: 54 additions & 0 deletions test/token/ERC20/ERC20Pausable.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,59 @@ describe('ERC20Pausable', function () {
);
});
});

describe('mint', function () {
const amount = new BN('42');

it('allows to mint when unpaused', async function () {
await this.token.mint(recipient, amount);

expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount);
});

it('allows to mint when paused and then unpaused', async function () {
await this.token.pause();
await this.token.unpause();

await this.token.mint(recipient, amount);

expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount);
});

it('reverts when trying to mint when paused', async function () {
await this.token.pause();

await expectRevert(this.token.mint(recipient, amount),
'ERC20Pausable: token transfer while paused'
);
});
});

describe('burn', function () {
const amount = new BN('42');

it('allows to burn when unpaused', async function () {
await this.token.burn(holder, amount);

expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount));
});

it('allows to burn when paused and then unpaused', async function () {
await this.token.pause();
await this.token.unpause();

await this.token.burn(holder, amount);

expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount));
});

it('reverts when trying to burn when paused', async function () {
await this.token.pause();

await expectRevert(this.token.burn(holder, amount),
'ERC20Pausable: token transfer while paused'
);
});
});
});
});
19 changes: 17 additions & 2 deletions test/token/ERC721/ERC721Pausable.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ describe('ERC721Pausable', function () {

context('when token is paused', function () {
const firstTokenId = new BN(1);
const mintedTokens = new BN(1);
const secondTokenId = new BN(1337);

const mockData = '0x42';

beforeEach(async function () {
Expand Down Expand Up @@ -49,6 +50,20 @@ describe('ERC721Pausable', function () {
);
});

it('reverts when trying to mint', async function () {
await expectRevert(
this.token.mint(receiver, secondTokenId),
'ERC721Pausable: token transfer while paused'
);
});

it('reverts when trying to burn', async function () {
await expectRevert(
this.token.burn(firstTokenId),
'ERC721Pausable: token transfer while paused'
);
});

describe('getApproved', function () {
it('returns approved address', async function () {
const approvedAccount = await this.token.getApproved(firstTokenId);
Expand All @@ -59,7 +74,7 @@ describe('ERC721Pausable', function () {
describe('balanceOf', function () {
it('returns the amount of tokens owned by the given address', async function () {
const balance = await this.token.balanceOf(owner);
expect(balance).to.be.bignumber.equal(mintedTokens);
expect(balance).to.be.bignumber.equal('1');
});
});

Expand Down

0 comments on commit 3e139ba

Please sign in to comment.