Add missing hook to ERC777, fix relevant documentation (#2191)
* 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
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
@ -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
|
||||
|
||||
@ -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,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 () {
|
||||
@ -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);
|
||||
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user