Migrate AccessControl tests (#4694)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,19 @@
|
|||||||
|
const { ethers } = require('hardhat');
|
||||||
|
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
|
||||||
|
|
||||||
const { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl } = require('./AccessControl.behavior.js');
|
const { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl } = require('./AccessControl.behavior.js');
|
||||||
|
|
||||||
const AccessControl = artifacts.require('$AccessControl');
|
async function fixture() {
|
||||||
|
const [defaultAdmin, ...accounts] = await ethers.getSigners();
|
||||||
|
const mock = await ethers.deployContract('$AccessControl');
|
||||||
|
await mock.$_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
|
||||||
|
return { mock, defaultAdmin, accounts };
|
||||||
|
}
|
||||||
|
|
||||||
contract('AccessControl', function (accounts) {
|
describe('AccessControl', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.accessControl = await AccessControl.new({ from: accounts[0] });
|
Object.assign(this, await loadFixture(fixture));
|
||||||
await this.accessControl.$_grantRole(DEFAULT_ADMIN_ROLE, accounts[0]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
shouldBehaveLikeAccessControl(...accounts);
|
shouldBehaveLikeAccessControl();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,26 +1,30 @@
|
|||||||
const { time, constants, expectRevert } = require('@openzeppelin/test-helpers');
|
const { ethers } = require('hardhat');
|
||||||
|
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
|
||||||
|
const { bigint: time } = require('../../helpers/time');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldBehaveLikeAccessControl,
|
shouldBehaveLikeAccessControl,
|
||||||
shouldBehaveLikeAccessControlDefaultAdminRules,
|
shouldBehaveLikeAccessControlDefaultAdminRules,
|
||||||
} = require('../AccessControl.behavior.js');
|
} = require('../AccessControl.behavior.js');
|
||||||
|
|
||||||
const AccessControlDefaultAdminRules = artifacts.require('$AccessControlDefaultAdminRules');
|
async function fixture() {
|
||||||
|
const delay = time.duration.hours(10);
|
||||||
contract('AccessControlDefaultAdminRules', function (accounts) {
|
const [defaultAdmin, ...accounts] = await ethers.getSigners();
|
||||||
const delay = web3.utils.toBN(time.duration.hours(10));
|
const mock = await ethers.deployContract('$AccessControlDefaultAdminRules', [delay, defaultAdmin]);
|
||||||
|
return { mock, defaultAdmin, delay, accounts };
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('AccessControlDefaultAdminRules', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.accessControl = await AccessControlDefaultAdminRules.new(delay, accounts[0], { from: accounts[0] });
|
Object.assign(this, await loadFixture(fixture));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('initial admin not zero', async function () {
|
it('initial admin not zero', async function () {
|
||||||
await expectRevert(
|
await expect(ethers.deployContract('$AccessControlDefaultAdminRules', [this.delay, ethers.ZeroAddress]))
|
||||||
AccessControlDefaultAdminRules.new(delay, constants.ZERO_ADDRESS),
|
.to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin')
|
||||||
'AccessControlInvalidDefaultAdmin',
|
.withArgs(ethers.ZeroAddress);
|
||||||
[constants.ZERO_ADDRESS],
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
shouldBehaveLikeAccessControl(...accounts);
|
shouldBehaveLikeAccessControl();
|
||||||
shouldBehaveLikeAccessControlDefaultAdminRules(delay, ...accounts);
|
shouldBehaveLikeAccessControlDefaultAdminRules();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,17 +1,24 @@
|
|||||||
|
const { ethers } = require('hardhat');
|
||||||
|
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
DEFAULT_ADMIN_ROLE,
|
DEFAULT_ADMIN_ROLE,
|
||||||
shouldBehaveLikeAccessControl,
|
shouldBehaveLikeAccessControl,
|
||||||
shouldBehaveLikeAccessControlEnumerable,
|
shouldBehaveLikeAccessControlEnumerable,
|
||||||
} = require('../AccessControl.behavior.js');
|
} = require('../AccessControl.behavior.js');
|
||||||
|
|
||||||
const AccessControlEnumerable = artifacts.require('$AccessControlEnumerable');
|
async function fixture() {
|
||||||
|
const [defaultAdmin, ...accounts] = await ethers.getSigners();
|
||||||
|
const mock = await ethers.deployContract('$AccessControlEnumerable');
|
||||||
|
await mock.$_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
|
||||||
|
return { mock, defaultAdmin, accounts };
|
||||||
|
}
|
||||||
|
|
||||||
contract('AccessControlEnumerable', function (accounts) {
|
describe('AccessControlEnumerable', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
this.accessControl = await AccessControlEnumerable.new({ from: accounts[0] });
|
Object.assign(this, await loadFixture(fixture));
|
||||||
await this.accessControl.$_grantRole(DEFAULT_ADMIN_ROLE, accounts[0]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
shouldBehaveLikeAccessControl(...accounts);
|
shouldBehaveLikeAccessControl();
|
||||||
shouldBehaveLikeAccessControlEnumerable(...accounts);
|
shouldBehaveLikeAccessControlEnumerable();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
const { time, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers');
|
const { time, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers');
|
||||||
|
|
||||||
|
const mapObject = (obj, fn) => Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, fn(value)]));
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
clock: {
|
clock: {
|
||||||
blocknumber: () => time.latestBlock(),
|
blocknumber: () => time.latestBlock(),
|
||||||
@ -13,6 +15,15 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
forward: {
|
forward: {
|
||||||
blocknumber: mineUpTo,
|
blocknumber: mineUpTo,
|
||||||
timestamp: time.increaseTo,
|
timestamp: (to, mine = true) => (mine ? time.increaseTo(to) : time.setNextBlockTimestamp(to)),
|
||||||
},
|
},
|
||||||
|
duration: time.duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: deprecate the old version in favor of this one
|
||||||
|
module.exports.bigint = {
|
||||||
|
clock: mapObject(module.exports.clock, fn => () => fn().then(BigInt)),
|
||||||
|
clockFromReceipt: mapObject(module.exports.clockFromReceipt, fn => receipt => fn(receipt).then(BigInt)),
|
||||||
|
forward: module.exports.forward,
|
||||||
|
duration: mapObject(module.exports.duration, fn => n => BigInt(fn(n))),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
const { makeInterfaceId } = require('@openzeppelin/test-helpers');
|
const { ethers } = require('ethers');
|
||||||
|
|
||||||
const { expect } = require('chai');
|
const { expect } = require('chai');
|
||||||
|
const { selector } = require('../../helpers/methods');
|
||||||
|
|
||||||
const INVALID_ID = '0xffffffff';
|
const INVALID_ID = '0xffffffff';
|
||||||
const INTERFACES = {
|
const SIGNATURES = {
|
||||||
ERC165: ['supportsInterface(bytes4)'],
|
ERC165: ['supportsInterface(bytes4)'],
|
||||||
ERC721: [
|
ERC721: [
|
||||||
'balanceOf(address)',
|
'balanceOf(address)',
|
||||||
@ -81,27 +81,27 @@ const INTERFACES = {
|
|||||||
ERC2981: ['royaltyInfo(uint256,uint256)'],
|
ERC2981: ['royaltyInfo(uint256,uint256)'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const INTERFACE_IDS = {};
|
const INTERFACE_IDS = Object.fromEntries(
|
||||||
const FN_SIGNATURES = {};
|
Object.entries(SIGNATURES).map(([name, signatures]) => [
|
||||||
for (const k of Object.getOwnPropertyNames(INTERFACES)) {
|
name,
|
||||||
INTERFACE_IDS[k] = makeInterfaceId.ERC165(INTERFACES[k]);
|
ethers.toBeHex(
|
||||||
for (const fnName of INTERFACES[k]) {
|
signatures.reduce((id, fnSig) => id ^ BigInt(selector(fnSig)), 0n),
|
||||||
// the interface id of a single function is equivalent to its function signature
|
4,
|
||||||
FN_SIGNATURES[fnName] = makeInterfaceId.ERC165([fnName]);
|
),
|
||||||
}
|
]),
|
||||||
}
|
);
|
||||||
|
|
||||||
function shouldSupportInterfaces(interfaces = []) {
|
function shouldSupportInterfaces(interfaces = []) {
|
||||||
describe('ERC165', function () {
|
describe('ERC165', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.contractUnderTest = this.mock || this.token || this.holder || this.accessControl;
|
this.contractUnderTest = this.mock || this.token || this.holder;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the interfaceId is supported', function () {
|
describe('when the interfaceId is supported', function () {
|
||||||
it('uses less than 30k gas', async function () {
|
it('uses less than 30k gas', async function () {
|
||||||
for (const k of interfaces) {
|
for (const k of interfaces) {
|
||||||
const interfaceId = INTERFACE_IDS[k] ?? k;
|
const interface = INTERFACE_IDS[k] ?? k;
|
||||||
expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000);
|
expect(await this.contractUnderTest.supportsInterface.estimateGas(interface)).to.be.lte(30000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -126,13 +126,18 @@ function shouldSupportInterfaces(interfaces = []) {
|
|||||||
it('all interface functions are in ABI', async function () {
|
it('all interface functions are in ABI', async function () {
|
||||||
for (const k of interfaces) {
|
for (const k of interfaces) {
|
||||||
// skip interfaces for which we don't have a function list
|
// skip interfaces for which we don't have a function list
|
||||||
if (INTERFACES[k] === undefined) continue;
|
if (SIGNATURES[k] === undefined) continue;
|
||||||
for (const fnName of INTERFACES[k]) {
|
for (const fnSig of SIGNATURES[k]) {
|
||||||
const fnSig = FN_SIGNATURES[fnName];
|
// TODO: Remove Truffle case when ethersjs migration is done
|
||||||
expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(
|
if (this.contractUnderTest.abi) {
|
||||||
1,
|
const fnSelector = selector(fnSig);
|
||||||
`did not find ${fnName}`,
|
return expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSelector).length).to.equal(
|
||||||
);
|
1,
|
||||||
|
`did not find ${fnSig}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(!!this.contractUnderTest.interface.getFunction(fnSig), `did not find ${fnSig}`).to.be.true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user