Merge tag 'v2.1.2' of github.com:OpenZeppelin/openzeppelin-solidity into merge-v2.1

v2.1.2
This commit is contained in:
Francisco Giordano
2019-01-21 19:42:09 -03:00
96 changed files with 4366 additions and 5226 deletions

View File

@ -1,32 +1,30 @@
const shouldFail = require('../../helpers/shouldFail');
const expectEvent = require('../../helpers/expectEvent');
const { ZERO_ADDRESS } = require('../../helpers/constants');
const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers');
const { ZERO_ADDRESS } = constants;
const ERC20Mock = artifacts.require('ERC20Mock');
const { BigNumber } = require('../../helpers/setup');
contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
contract('ERC20', function ([_, initialHolder, recipient, anotherAccount]) {
const initialSupply = new BN(100);
beforeEach(async function () {
this.token = await ERC20Mock.new(owner, 100);
this.token = await ERC20Mock.new(initialHolder, initialSupply);
});
describe('total supply', function () {
it('returns the total amount of tokens', async function () {
(await this.token.totalSupply()).should.be.bignumber.equal(100);
(await this.token.totalSupply()).should.be.bignumber.equal(initialSupply);
});
});
describe('balanceOf', function () {
describe('when the requested account has no tokens', function () {
it('returns zero', async function () {
(await this.token.balanceOf(anotherAccount)).should.be.bignumber.equal(0);
(await this.token.balanceOf(anotherAccount)).should.be.bignumber.equal('0');
});
});
describe('when the requested account has some tokens', function () {
it('returns the total amount of tokens', async function () {
(await this.token.balanceOf(owner)).should.be.bignumber.equal(100);
(await this.token.balanceOf(initialHolder)).should.be.bignumber.equal(initialSupply);
});
});
});
@ -36,29 +34,29 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const to = recipient;
describe('when the sender does not have enough balance', function () {
const amount = 101;
const amount = initialSupply.addn(1);
it('reverts', async function () {
await shouldFail.reverting(this.token.transfer(to, amount, { from: owner }));
await shouldFail.reverting(this.token.transfer(to, amount, { from: initialHolder }));
});
});
describe('when the sender has enough balance', function () {
const amount = 100;
const amount = initialSupply;
it('transfers the requested amount', async function () {
await this.token.transfer(to, amount, { from: owner });
await this.token.transfer(to, amount, { from: initialHolder });
(await this.token.balanceOf(owner)).should.be.bignumber.equal(0);
(await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0');
(await this.token.balanceOf(to)).should.be.bignumber.equal(amount);
});
it('emits a transfer event', async function () {
const { logs } = await this.token.transfer(to, amount, { from: owner });
const { logs } = await this.token.transfer(to, amount, { from: initialHolder });
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
from: initialHolder,
to: to,
value: amount,
});
@ -70,7 +68,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const to = ZERO_ADDRESS;
it('reverts', async function () {
await shouldFail.reverting(this.token.transfer(to, 100, { from: owner }));
await shouldFail.reverting(this.token.transfer(to, initialSupply, { from: initialHolder }));
});
});
});
@ -80,13 +78,13 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const spender = recipient;
describe('when the sender has enough balance', function () {
const amount = 100;
const amount = initialSupply;
it('emits an approval event', async function () {
const { logs } = await this.token.approve(spender, amount, { from: owner });
const { logs } = await this.token.approve(spender, amount, { from: initialHolder });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: amount,
});
@ -94,33 +92,33 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
describe('when there was no approved amount before', function () {
it('approves the requested amount', async function () {
await this.token.approve(spender, amount, { from: owner });
await this.token.approve(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
describe('when the spender had an approved amount', function () {
beforeEach(async function () {
await this.token.approve(spender, 1, { from: owner });
await this.token.approve(spender, new BN(1), { from: initialHolder });
});
it('approves the requested amount and replaces the previous one', async function () {
await this.token.approve(spender, amount, { from: owner });
await this.token.approve(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
});
describe('when the sender does not have enough balance', function () {
const amount = 101;
const amount = initialSupply.addn(1);
it('emits an approval event', async function () {
const { logs } = await this.token.approve(spender, amount, { from: owner });
const { logs } = await this.token.approve(spender, amount, { from: initialHolder });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: amount,
});
@ -128,32 +126,32 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
describe('when there was no approved amount before', function () {
it('approves the requested amount', async function () {
await this.token.approve(spender, amount, { from: owner });
await this.token.approve(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
describe('when the spender had an approved amount', function () {
beforeEach(async function () {
await this.token.approve(spender, 1, { from: owner });
await this.token.approve(spender, new BN(1), { from: initialHolder });
});
it('approves the requested amount and replaces the previous one', async function () {
await this.token.approve(spender, amount, { from: owner });
await this.token.approve(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
});
});
describe('when the spender is the zero address', function () {
const amount = 100;
const amount = initialSupply;
const spender = ZERO_ADDRESS;
it('reverts', async function () {
await shouldFail.reverting(this.token.approve(spender, amount, { from: owner }));
await shouldFail.reverting(this.token.approve(spender, amount, { from: initialHolder }));
});
});
});
@ -166,89 +164,89 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
describe('when the spender has enough approved balance', function () {
beforeEach(async function () {
await this.token.approve(spender, 100, { from: owner });
await this.token.approve(spender, initialSupply, { from: initialHolder });
});
describe('when the owner has enough balance', function () {
const amount = 100;
describe('when the initial holder has enough balance', function () {
const amount = initialSupply;
it('transfers the requested amount', async function () {
await this.token.transferFrom(owner, to, amount, { from: spender });
await this.token.transferFrom(initialHolder, to, amount, { from: spender });
(await this.token.balanceOf(owner)).should.be.bignumber.equal(0);
(await this.token.balanceOf(initialHolder)).should.be.bignumber.equal('0');
(await this.token.balanceOf(to)).should.be.bignumber.equal(amount);
});
it('decreases the spender allowance', async function () {
await this.token.transferFrom(owner, to, amount, { from: spender });
await this.token.transferFrom(initialHolder, to, amount, { from: spender });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(0);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('0');
});
it('emits a transfer event', async function () {
const { logs } = await this.token.transferFrom(owner, to, amount, { from: spender });
const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender });
expectEvent.inLogs(logs, 'Transfer', {
from: owner,
from: initialHolder,
to: to,
value: amount,
});
});
it('emits an approval event', async function () {
const { logs } = await this.token.transferFrom(owner, to, amount, { from: spender });
const { logs } = await this.token.transferFrom(initialHolder, to, amount, { from: spender });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: await this.token.allowance(owner, spender),
value: await this.token.allowance(initialHolder, spender),
});
});
});
describe('when the owner does not have enough balance', function () {
const amount = 101;
describe('when the initial holder does not have enough balance', function () {
const amount = initialSupply.addn(1);
it('reverts', async function () {
await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender }));
await shouldFail.reverting(this.token.transferFrom(initialHolder, to, amount, { from: spender }));
});
});
});
describe('when the spender does not have enough approved balance', function () {
beforeEach(async function () {
await this.token.approve(spender, 99, { from: owner });
await this.token.approve(spender, initialSupply.subn(1), { from: initialHolder });
});
describe('when the owner has enough balance', function () {
const amount = 100;
describe('when the initial holder has enough balance', function () {
const amount = initialSupply;
it('reverts', async function () {
await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender }));
await shouldFail.reverting(this.token.transferFrom(initialHolder, to, amount, { from: spender }));
});
});
describe('when the owner does not have enough balance', function () {
const amount = 101;
describe('when the initial holder does not have enough balance', function () {
const amount = initialSupply.addn(1);
it('reverts', async function () {
await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender }));
await shouldFail.reverting(this.token.transferFrom(initialHolder, to, amount, { from: spender }));
});
});
});
});
describe('when the recipient is the zero address', function () {
const amount = 100;
const amount = initialSupply;
const to = ZERO_ADDRESS;
beforeEach(async function () {
await this.token.approve(spender, amount, { from: owner });
await this.token.approve(spender, amount, { from: initialHolder });
});
it('reverts', async function () {
await shouldFail.reverting(this.token.transferFrom(owner, to, amount, { from: spender }));
await shouldFail.reverting(this.token.transferFrom(initialHolder, to, amount, { from: spender }));
});
});
});
@ -260,7 +258,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
function shouldDecreaseApproval (amount) {
describe('when there was no approved amount before', function () {
it('reverts', async function () {
await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: owner }));
await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: initialHolder }));
});
});
@ -268,71 +266,73 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const approvedAmount = amount;
beforeEach(async function () {
({ logs: this.logs } = await this.token.approve(spender, approvedAmount, { from: owner }));
({ logs: this.logs } = await this.token.approve(spender, approvedAmount, { from: initialHolder }));
});
it('emits an approval event', async function () {
const { logs } = await this.token.decreaseAllowance(spender, approvedAmount, { from: owner });
const { logs } = await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: 0,
value: new BN(0),
});
});
it('decreases the spender allowance subtracting the requested amount', async function () {
await this.token.decreaseAllowance(spender, approvedAmount - 1, { from: owner });
await this.token.decreaseAllowance(spender, approvedAmount.subn(1), { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(1);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('1');
});
it('sets the allowance to zero when all allowance is removed', async function () {
await this.token.decreaseAllowance(spender, approvedAmount, { from: owner });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(0);
await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder });
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal('0');
});
it('reverts when more than the full allowance is removed', async function () {
await shouldFail.reverting(this.token.decreaseAllowance(spender, approvedAmount + 1, { from: owner }));
await shouldFail.reverting(
this.token.decreaseAllowance(spender, approvedAmount.addn(1), { from: initialHolder })
);
});
});
}
describe('when the sender has enough balance', function () {
const amount = 100;
const amount = initialSupply;
shouldDecreaseApproval(amount);
});
describe('when the sender does not have enough balance', function () {
const amount = 101;
const amount = initialSupply.addn(1);
shouldDecreaseApproval(amount);
});
});
describe('when the spender is the zero address', function () {
const amount = 100;
const amount = initialSupply;
const spender = ZERO_ADDRESS;
it('reverts', async function () {
await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: owner }));
await shouldFail.reverting(this.token.decreaseAllowance(spender, amount, { from: initialHolder }));
});
});
});
describe('increase allowance', function () {
const amount = 100;
const amount = initialSupply;
describe('when the spender is not the zero address', function () {
const spender = recipient;
describe('when the sender has enough balance', function () {
it('emits an approval event', async function () {
const { logs } = await this.token.increaseAllowance(spender, amount, { from: owner });
const { logs } = await this.token.increaseAllowance(spender, amount, { from: initialHolder });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: amount,
});
@ -340,33 +340,33 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
describe('when there was no approved amount before', function () {
it('approves the requested amount', async function () {
await this.token.increaseAllowance(spender, amount, { from: owner });
await this.token.increaseAllowance(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
describe('when the spender had an approved amount', function () {
beforeEach(async function () {
await this.token.approve(spender, 1, { from: owner });
await this.token.approve(spender, new BN(1), { from: initialHolder });
});
it('increases the spender allowance adding the requested amount', async function () {
await this.token.increaseAllowance(spender, amount, { from: owner });
await this.token.increaseAllowance(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount + 1);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount.addn(1));
});
});
});
describe('when the sender does not have enough balance', function () {
const amount = 101;
const amount = initialSupply.addn(1);
it('emits an approval event', async function () {
const { logs } = await this.token.increaseAllowance(spender, amount, { from: owner });
const { logs } = await this.token.increaseAllowance(spender, amount, { from: initialHolder });
expectEvent.inLogs(logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: amount,
});
@ -374,21 +374,21 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
describe('when there was no approved amount before', function () {
it('approves the requested amount', async function () {
await this.token.increaseAllowance(spender, amount, { from: owner });
await this.token.increaseAllowance(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount);
});
});
describe('when the spender had an approved amount', function () {
beforeEach(async function () {
await this.token.approve(spender, 1, { from: owner });
await this.token.approve(spender, new BN(1), { from: initialHolder });
});
it('increases the spender allowance adding the requested amount', async function () {
await this.token.increaseAllowance(spender, amount, { from: owner });
await this.token.increaseAllowance(spender, amount, { from: initialHolder });
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(amount + 1);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(amount.addn(1));
});
});
});
@ -398,14 +398,13 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const spender = ZERO_ADDRESS;
it('reverts', async function () {
await shouldFail.reverting(this.token.increaseAllowance(spender, amount, { from: owner }));
await shouldFail.reverting(this.token.increaseAllowance(spender, amount, { from: initialHolder }));
});
});
});
describe('_mint', function () {
const initialSupply = new BigNumber(100);
const amount = new BigNumber(50);
const amount = new BN(50);
it('rejects a null account', async function () {
await shouldFail.reverting(this.token.mint(ZERO_ADDRESS, amount));
@ -418,7 +417,7 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
});
it('increments totalSupply', async function () {
const expectedSupply = initialSupply.plus(amount);
const expectedSupply = initialSupply.add(amount);
(await this.token.totalSupply()).should.be.bignumber.equal(expectedSupply);
});
@ -438,37 +437,35 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
});
describe('_burn', function () {
const initialSupply = new BigNumber(100);
it('rejects a null account', async function () {
await shouldFail.reverting(this.token.burn(ZERO_ADDRESS, 1));
await shouldFail.reverting(this.token.burn(ZERO_ADDRESS, new BN(1)));
});
describe('for a non null account', function () {
it('rejects burning more than balance', async function () {
await shouldFail.reverting(this.token.burn(owner, initialSupply.plus(1)));
await shouldFail.reverting(this.token.burn(initialHolder, initialSupply.addn(1)));
});
const describeBurn = function (description, amount) {
describe(description, function () {
beforeEach('burning', async function () {
const { logs } = await this.token.burn(owner, amount);
const { logs } = await this.token.burn(initialHolder, amount);
this.logs = logs;
});
it('decrements totalSupply', async function () {
const expectedSupply = initialSupply.minus(amount);
const expectedSupply = initialSupply.sub(amount);
(await this.token.totalSupply()).should.be.bignumber.equal(expectedSupply);
});
it('decrements owner balance', async function () {
const expectedBalance = initialSupply.minus(amount);
(await this.token.balanceOf(owner)).should.be.bignumber.equal(expectedBalance);
it('decrements initialHolder balance', async function () {
const expectedBalance = initialSupply.sub(amount);
(await this.token.balanceOf(initialHolder)).should.be.bignumber.equal(expectedBalance);
});
it('emits Transfer event', async function () {
const event = expectEvent.inLogs(this.logs, 'Transfer', {
from: owner,
from: initialHolder,
to: ZERO_ADDRESS,
});
@ -478,58 +475,57 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
};
describeBurn('for entire balance', initialSupply);
describeBurn('for less amount than balance', initialSupply.sub(1));
describeBurn('for less amount than balance', initialSupply.subn(1));
});
});
describe('_burnFrom', function () {
const initialSupply = new BigNumber(100);
const allowance = new BigNumber(70);
const allowance = new BN(70);
const spender = anotherAccount;
beforeEach('approving', async function () {
await this.token.approve(spender, allowance, { from: owner });
await this.token.approve(spender, allowance, { from: initialHolder });
});
it('rejects a null account', async function () {
await shouldFail.reverting(this.token.burnFrom(ZERO_ADDRESS, 1));
await shouldFail.reverting(this.token.burnFrom(ZERO_ADDRESS, new BN(1)));
});
describe('for a non null account', function () {
it('rejects burning more than allowance', async function () {
await shouldFail.reverting(this.token.burnFrom(owner, allowance.plus(1)));
await shouldFail.reverting(this.token.burnFrom(initialHolder, allowance.addn(1)));
});
it('rejects burning more than balance', async function () {
await shouldFail.reverting(this.token.burnFrom(owner, initialSupply.plus(1)));
await shouldFail.reverting(this.token.burnFrom(initialHolder, initialSupply.addn(1)));
});
const describeBurnFrom = function (description, amount) {
describe(description, function () {
beforeEach('burning', async function () {
const { logs } = await this.token.burnFrom(owner, amount, { from: spender });
const { logs } = await this.token.burnFrom(initialHolder, amount, { from: spender });
this.logs = logs;
});
it('decrements totalSupply', async function () {
const expectedSupply = initialSupply.minus(amount);
const expectedSupply = initialSupply.sub(amount);
(await this.token.totalSupply()).should.be.bignumber.equal(expectedSupply);
});
it('decrements owner balance', async function () {
const expectedBalance = initialSupply.minus(amount);
(await this.token.balanceOf(owner)).should.be.bignumber.equal(expectedBalance);
it('decrements initialHolder balance', async function () {
const expectedBalance = initialSupply.sub(amount);
(await this.token.balanceOf(initialHolder)).should.be.bignumber.equal(expectedBalance);
});
it('decrements spender allowance', async function () {
const expectedAllowance = allowance.minus(amount);
(await this.token.allowance(owner, spender)).should.be.bignumber.equal(expectedAllowance);
const expectedAllowance = allowance.sub(amount);
(await this.token.allowance(initialHolder, spender)).should.be.bignumber.equal(expectedAllowance);
});
it('emits a Transfer event', async function () {
const event = expectEvent.inLogs(this.logs, 'Transfer', {
from: owner,
from: initialHolder,
to: ZERO_ADDRESS,
});
@ -538,16 +534,16 @@ contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
it('emits an Approval event', async function () {
expectEvent.inLogs(this.logs, 'Approval', {
owner: owner,
owner: initialHolder,
spender: spender,
value: await this.token.allowance(owner, spender),
value: await this.token.allowance(initialHolder, spender),
});
});
});
};
describeBurnFrom('for entire allowance', allowance);
describeBurnFrom('for less amount than allowance', allowance.sub(1));
describeBurnFrom('for less amount than allowance', allowance.subn(1));
});
});
});

View File

@ -1,8 +1,10 @@
const { BN } = require('openzeppelin-test-helpers');
const { shouldBehaveLikeERC20Burnable } = require('./behaviors/ERC20Burnable.behavior');
const ERC20BurnableMock = artifacts.require('ERC20BurnableMock');
contract('ERC20Burnable', function ([_, owner, ...otherAccounts]) {
const initialBalance = 1000;
const initialBalance = new BN(1000);
beforeEach(async function () {
this.token = await ERC20BurnableMock.new(owner, initialBalance, { from: owner });

View File

@ -1,16 +1,15 @@
const shouldFail = require('../../helpers/shouldFail');
const { ether } = require('../../helpers/ether');
const { BN, ether, shouldFail } = require('openzeppelin-test-helpers');
const { shouldBehaveLikeERC20Mintable } = require('./behaviors/ERC20Mintable.behavior');
const { shouldBehaveLikeERC20Capped } = require('./behaviors/ERC20Capped.behavior');
const ERC20Capped = artifacts.require('ERC20CappedMock');
contract('ERC20Capped', function ([_, minter, ...otherAccounts]) {
const cap = ether(1000);
const cap = ether('1000');
it('requires a non-zero cap', async function () {
await shouldFail.reverting(
ERC20Capped.new(0, { from: minter })
ERC20Capped.new(new BN(0), { from: minter })
);
});

View File

@ -1,11 +1,11 @@
require('../../helpers/setup');
const { BN } = require('openzeppelin-test-helpers');
const ERC20DetailedMock = artifacts.require('ERC20DetailedMock');
contract('ERC20Detailed', function () {
const _name = 'My Detailed ERC20';
const _symbol = 'MDT';
const _decimals = 18;
const _decimals = new BN(18);
beforeEach(async function () {
this.detailedERC20 = await ERC20DetailedMock.new(_name, _symbol, _decimals);

View File

@ -1,6 +1,6 @@
const { shouldBehaveLikeERC20Mintable } = require('./behaviors/ERC20Mintable.behavior');
const ERC20MintableMock = artifacts.require('ERC20MintableMock');
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
const { shouldBehaveLikePublicRole } = require('../../behaviors/access/roles/PublicRole.behavior');
contract('ERC20Mintable', function ([_, minter, otherMinter, ...otherAccounts]) {
beforeEach(async function () {

View File

@ -1,12 +1,13 @@
const expectEvent = require('../../helpers/expectEvent');
const shouldFail = require('../../helpers/shouldFail');
const { BN, expectEvent, shouldFail } = require('openzeppelin-test-helpers');
const ERC20PausableMock = artifacts.require('ERC20PausableMock');
const { shouldBehaveLikePublicRole } = require('../../access/roles/PublicRole.behavior');
const { shouldBehaveLikePublicRole } = require('../../behaviors/access/roles/PublicRole.behavior');
contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherAccount, ...otherAccounts]) {
const initialSupply = new BN(100);
beforeEach(async function () {
this.token = await ERC20PausableMock.new(pauser, 100, { from: pauser });
this.token = await ERC20PausableMock.new(pauser, initialSupply, { from: pauser });
});
describe('pauser role', function () {
@ -114,132 +115,142 @@ contract('ERC20Pausable', function ([_, pauser, otherPauser, recipient, anotherA
describe('transfer', function () {
it('allows to transfer when unpaused', async function () {
await this.token.transfer(recipient, 100, { from: pauser });
await this.token.transfer(recipient, initialSupply, { from: pauser });
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(0);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(100);
(await this.token.balanceOf(pauser)).should.be.bignumber.equal('0');
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(initialSupply);
});
it('allows to transfer when paused and then unpaused', async function () {
await this.token.pause({ from: pauser });
await this.token.unpause({ from: pauser });
await this.token.transfer(recipient, 100, { from: pauser });
await this.token.transfer(recipient, initialSupply, { from: pauser });
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(0);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(100);
(await this.token.balanceOf(pauser)).should.be.bignumber.equal('0');
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(initialSupply);
});
it('reverts when trying to transfer when paused', async function () {
await this.token.pause({ from: pauser });
await shouldFail.reverting(this.token.transfer(recipient, 100, { from: pauser }));
await shouldFail.reverting(this.token.transfer(recipient, initialSupply, { from: pauser }));
});
});
describe('approve', function () {
it('allows to approve when unpaused', async function () {
await this.token.approve(anotherAccount, 40, { from: pauser });
const allowance = new BN(40);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(40);
it('allows to approve when unpaused', async function () {
await this.token.approve(anotherAccount, allowance, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance);
});
it('allows to approve when paused and then unpaused', async function () {
await this.token.pause({ from: pauser });
await this.token.unpause({ from: pauser });
await this.token.approve(anotherAccount, 40, { from: pauser });
await this.token.approve(anotherAccount, allowance, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(40);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance);
});
it('reverts when trying to approve when paused', async function () {
await this.token.pause({ from: pauser });
await shouldFail.reverting(this.token.approve(anotherAccount, 40, { from: pauser }));
await shouldFail.reverting(this.token.approve(anotherAccount, allowance, { from: pauser }));
});
});
describe('transfer from', function () {
const allowance = new BN(40);
beforeEach(async function () {
await this.token.approve(anotherAccount, 50, { from: pauser });
await this.token.approve(anotherAccount, allowance, { from: pauser });
});
it('allows to transfer from when unpaused', async function () {
await this.token.transferFrom(pauser, recipient, 40, { from: anotherAccount });
await this.token.transferFrom(pauser, recipient, allowance, { from: anotherAccount });
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(60);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(40);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(allowance);
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(initialSupply.sub(allowance));
});
it('allows to transfer when paused and then unpaused', async function () {
await this.token.pause({ from: pauser });
await this.token.unpause({ from: pauser });
await this.token.transferFrom(pauser, recipient, 40, { from: anotherAccount });
await this.token.transferFrom(pauser, recipient, allowance, { from: anotherAccount });
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(60);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(40);
(await this.token.balanceOf(recipient)).should.be.bignumber.equal(allowance);
(await this.token.balanceOf(pauser)).should.be.bignumber.equal(initialSupply.sub(allowance));
});
it('reverts when trying to transfer from when paused', async function () {
await this.token.pause({ from: pauser });
await shouldFail.reverting(this.token.transferFrom(pauser, recipient, 40, { from: anotherAccount }));
await shouldFail.reverting(this.token.transferFrom(pauser, recipient, allowance, { from: anotherAccount }));
});
});
describe('decrease approval', function () {
const allowance = new BN(40);
const decrement = new BN(10);
beforeEach(async function () {
await this.token.approve(anotherAccount, 100, { from: pauser });
await this.token.approve(anotherAccount, allowance, { from: pauser });
});
it('allows to decrease approval when unpaused', async function () {
await this.token.decreaseAllowance(anotherAccount, 40, { from: pauser });
await this.token.decreaseAllowance(anotherAccount, decrement, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(60);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance.sub(decrement));
});
it('allows to decrease approval when paused and then unpaused', async function () {
await this.token.pause({ from: pauser });
await this.token.unpause({ from: pauser });
await this.token.decreaseAllowance(anotherAccount, 40, { from: pauser });
await this.token.decreaseAllowance(anotherAccount, decrement, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(60);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance.sub(decrement));
});
it('reverts when trying to transfer when paused', async function () {
await this.token.pause({ from: pauser });
await shouldFail.reverting(this.token.decreaseAllowance(anotherAccount, 40, { from: pauser }));
await shouldFail.reverting(this.token.decreaseAllowance(anotherAccount, decrement, { from: pauser }));
});
});
describe('increase approval', function () {
const allowance = new BN(40);
const increment = new BN(30);
beforeEach(async function () {
await this.token.approve(anotherAccount, 100, { from: pauser });
await this.token.approve(anotherAccount, allowance, { from: pauser });
});
it('allows to increase approval when unpaused', async function () {
await this.token.increaseAllowance(anotherAccount, 40, { from: pauser });
await this.token.increaseAllowance(anotherAccount, increment, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(140);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance.add(increment));
});
it('allows to increase approval when paused and then unpaused', async function () {
await this.token.pause({ from: pauser });
await this.token.unpause({ from: pauser });
await this.token.increaseAllowance(anotherAccount, 40, { from: pauser });
await this.token.increaseAllowance(anotherAccount, increment, { from: pauser });
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(140);
(await this.token.allowance(pauser, anotherAccount)).should.be.bignumber.equal(allowance.add(increment));
});
it('reverts when trying to increase approval when paused', async function () {
await this.token.pause({ from: pauser });
await shouldFail.reverting(this.token.increaseAllowance(anotherAccount, 40, { from: pauser }));
await shouldFail.reverting(this.token.increaseAllowance(anotherAccount, increment, { from: pauser }));
});
});
});

View File

@ -1,6 +1,4 @@
const shouldFail = require('../../helpers/shouldFail');
require('../../helpers/setup');
const { shouldFail } = require('openzeppelin-test-helpers');
const SafeERC20Helper = artifacts.require('SafeERC20Helper');

View File

@ -1,13 +1,10 @@
const shouldFail = require('../../helpers/shouldFail');
const time = require('../../helpers/time');
const { BigNumber } = require('../../helpers/setup');
const { BN, shouldFail, time } = require('openzeppelin-test-helpers');
const ERC20Mintable = artifacts.require('ERC20MintableMock');
const TokenTimelock = artifacts.require('TokenTimelockMock');
contract('TokenTimelock', function ([_, minter, beneficiary]) {
const amount = new BigNumber(100);
const amount = new BN(100);
context('with token', function () {
beforeEach(async function () {
@ -15,7 +12,7 @@ contract('TokenTimelock', function ([_, minter, beneficiary]) {
});
it('rejects a release time in the past', async function () {
const pastReleaseTime = (await time.latest()) - time.duration.years(1);
const pastReleaseTime = (await time.latest()).sub(time.duration.years(1));
await shouldFail.reverting(
TokenTimelock.new(this.token.address, beneficiary, pastReleaseTime)
);
@ -23,7 +20,7 @@ contract('TokenTimelock', function ([_, minter, beneficiary]) {
context('once deployed', function () {
beforeEach(async function () {
this.releaseTime = (await time.latest()) + time.duration.years(1);
this.releaseTime = (await time.latest()).add(time.duration.years(1));
this.timelock = await TokenTimelock.new(this.token.address, beneficiary, this.releaseTime);
await this.token.mint(this.timelock.address, amount, { from: minter });
});
@ -39,24 +36,24 @@ contract('TokenTimelock', function ([_, minter, beneficiary]) {
});
it('cannot be released just before time limit', async function () {
await time.increaseTo(this.releaseTime - time.duration.seconds(3));
await time.increaseTo(this.releaseTime.sub(time.duration.seconds(3)));
await shouldFail.reverting(this.timelock.release());
});
it('can be released just after limit', async function () {
await time.increaseTo(this.releaseTime + time.duration.seconds(1));
await time.increaseTo(this.releaseTime.add(time.duration.seconds(1)));
await this.timelock.release();
(await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount);
});
it('can be released after time limit', async function () {
await time.increaseTo(this.releaseTime + time.duration.years(1));
await time.increaseTo(this.releaseTime.add(time.duration.years(1)));
await this.timelock.release();
(await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount);
});
it('cannot be released twice', async function () {
await time.increaseTo(this.releaseTime + time.duration.years(1));
await time.increaseTo(this.releaseTime.add(time.duration.years(1)));
await this.timelock.release();
await shouldFail.reverting(this.timelock.release());
(await this.token.balanceOf(beneficiary)).should.be.bignumber.equal(amount);

View File

@ -1,18 +1,15 @@
const shouldFail = require('../../../helpers/shouldFail');
const expectEvent = require('../../../helpers/expectEvent');
const { ZERO_ADDRESS } = require('../../../helpers/constants');
require('../../../helpers/setup');
const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers');
const { ZERO_ADDRESS } = constants;
function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
describe('burn', function () {
describe('when the given amount is not greater than balance of the sender', function () {
context('for a zero amount', function () {
shouldBurn(0);
shouldBurn(new BN(0));
});
context('for a non-zero amount', function () {
shouldBurn(100);
shouldBurn(new BN(100));
});
function shouldBurn (amount) {
@ -21,7 +18,7 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
});
it('burns the requested amount', async function () {
(await this.token.balanceOf(owner)).should.be.bignumber.equal(initialBalance - amount);
(await this.token.balanceOf(owner)).should.be.bignumber.equal(initialBalance.sub(amount));
});
it('emits a transfer event', async function () {
@ -35,7 +32,7 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
});
describe('when the given amount is greater than the balance of the sender', function () {
const amount = initialBalance + 1;
const amount = initialBalance.addn(1);
it('reverts', async function () {
await shouldFail.reverting(this.token.burn(amount, { from: owner }));
@ -46,15 +43,15 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
describe('burnFrom', function () {
describe('on success', function () {
context('for a zero amount', function () {
shouldBurnFrom(0);
shouldBurnFrom(new BN(0));
});
context('for a non-zero amount', function () {
shouldBurnFrom(100);
shouldBurnFrom(new BN(100));
});
function shouldBurnFrom (amount) {
const originalAllowance = amount * 3;
const originalAllowance = amount.muln(3);
beforeEach(async function () {
await this.token.approve(burner, originalAllowance, { from: owner });
@ -63,11 +60,11 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
});
it('burns the requested amount', async function () {
(await this.token.balanceOf(owner)).should.be.bignumber.equal(initialBalance - amount);
(await this.token.balanceOf(owner)).should.be.bignumber.equal(initialBalance.sub(amount));
});
it('decrements allowance', async function () {
(await this.token.allowance(owner, burner)).should.be.bignumber.equal(originalAllowance - amount);
(await this.token.allowance(owner, burner)).should.be.bignumber.equal(originalAllowance.sub(amount));
});
it('emits a transfer event', async function () {
@ -81,7 +78,8 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
});
describe('when the given amount is greater than the balance of the sender', function () {
const amount = initialBalance + 1;
const amount = initialBalance.addn(1);
it('reverts', async function () {
await this.token.approve(burner, amount, { from: owner });
await shouldFail.reverting(this.token.burnFrom(owner, amount, { from: burner }));
@ -89,10 +87,11 @@ function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
});
describe('when the given amount is greater than the allowance', function () {
const amount = 100;
const allowance = new BN(100);
it('reverts', async function () {
await this.token.approve(burner, amount - 1, { from: owner });
await shouldFail.reverting(this.token.burnFrom(owner, amount, { from: burner }));
await this.token.approve(burner, allowance, { from: owner });
await shouldFail.reverting(this.token.burnFrom(owner, allowance.addn(1), { from: burner }));
});
});
});

View File

@ -1,6 +1,4 @@
const shouldFail = require('../../../helpers/shouldFail');
require('../../../helpers/setup');
const { shouldFail } = require('openzeppelin-test-helpers');
function shouldBehaveLikeERC20Capped (minter, [anyone], cap) {
describe('capped token', function () {
@ -11,13 +9,13 @@ function shouldBehaveLikeERC20Capped (minter, [anyone], cap) {
});
it('should mint when amount is less than cap', async function () {
await this.token.mint(anyone, cap.sub(1), { from });
(await this.token.totalSupply()).should.be.bignumber.equal(cap.sub(1));
await this.token.mint(anyone, cap.subn(1), { from });
(await this.token.totalSupply()).should.be.bignumber.equal(cap.subn(1));
});
it('should fail to mint if the ammount exceeds the cap', async function () {
await this.token.mint(anyone, cap.sub(1), { from });
await shouldFail.reverting(this.token.mint(anyone, 100, { from }));
it('should fail to mint if the amount exceeds the cap', async function () {
await this.token.mint(anyone, cap.subn(1), { from });
await shouldFail.reverting(this.token.mint(anyone, 2, { from }));
});
it('should fail to mint after cap is reached', async function () {

View File

@ -1,19 +1,16 @@
const shouldFail = require('../../../helpers/shouldFail');
const expectEvent = require('../../../helpers/expectEvent');
const { ZERO_ADDRESS } = require('../../../helpers/constants');
require('../../../helpers/setup');
const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers');
const { ZERO_ADDRESS } = constants;
function shouldBehaveLikeERC20Mintable (minter, [anyone]) {
describe('as a mintable token', function () {
describe('mint', function () {
const amount = 100;
const amount = new BN(100);
context('when the sender has minting permission', function () {
const from = minter;
context('for a zero amount', function () {
shouldMint(0);
shouldMint(new BN(0));
});
context('for a non-zero amount', function () {