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 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 () {
|
||||
this.accessControl = await AccessControl.new({ from: accounts[0] });
|
||||
await this.accessControl.$_grantRole(DEFAULT_ADMIN_ROLE, accounts[0]);
|
||||
Object.assign(this, await loadFixture(fixture));
|
||||
});
|
||||
|
||||
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 {
|
||||
shouldBehaveLikeAccessControl,
|
||||
shouldBehaveLikeAccessControlDefaultAdminRules,
|
||||
} = require('../AccessControl.behavior.js');
|
||||
|
||||
const AccessControlDefaultAdminRules = artifacts.require('$AccessControlDefaultAdminRules');
|
||||
|
||||
contract('AccessControlDefaultAdminRules', function (accounts) {
|
||||
const delay = web3.utils.toBN(time.duration.hours(10));
|
||||
async function fixture() {
|
||||
const delay = time.duration.hours(10);
|
||||
const [defaultAdmin, ...accounts] = await ethers.getSigners();
|
||||
const mock = await ethers.deployContract('$AccessControlDefaultAdminRules', [delay, defaultAdmin]);
|
||||
return { mock, defaultAdmin, delay, accounts };
|
||||
}
|
||||
|
||||
describe('AccessControlDefaultAdminRules', 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 () {
|
||||
await expectRevert(
|
||||
AccessControlDefaultAdminRules.new(delay, constants.ZERO_ADDRESS),
|
||||
'AccessControlInvalidDefaultAdmin',
|
||||
[constants.ZERO_ADDRESS],
|
||||
);
|
||||
await expect(ethers.deployContract('$AccessControlDefaultAdminRules', [this.delay, ethers.ZeroAddress]))
|
||||
.to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin')
|
||||
.withArgs(ethers.ZeroAddress);
|
||||
});
|
||||
|
||||
shouldBehaveLikeAccessControl(...accounts);
|
||||
shouldBehaveLikeAccessControlDefaultAdminRules(delay, ...accounts);
|
||||
shouldBehaveLikeAccessControl();
|
||||
shouldBehaveLikeAccessControlDefaultAdminRules();
|
||||
});
|
||||
|
||||
@ -1,17 +1,24 @@
|
||||
const { ethers } = require('hardhat');
|
||||
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
|
||||
|
||||
const {
|
||||
DEFAULT_ADMIN_ROLE,
|
||||
shouldBehaveLikeAccessControl,
|
||||
shouldBehaveLikeAccessControlEnumerable,
|
||||
} = 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 () {
|
||||
this.accessControl = await AccessControlEnumerable.new({ from: accounts[0] });
|
||||
await this.accessControl.$_grantRole(DEFAULT_ADMIN_ROLE, accounts[0]);
|
||||
Object.assign(this, await loadFixture(fixture));
|
||||
});
|
||||
|
||||
shouldBehaveLikeAccessControl(...accounts);
|
||||
shouldBehaveLikeAccessControlEnumerable(...accounts);
|
||||
shouldBehaveLikeAccessControl();
|
||||
shouldBehaveLikeAccessControlEnumerable();
|
||||
});
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
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 = {
|
||||
clock: {
|
||||
blocknumber: () => time.latestBlock(),
|
||||
@ -13,6 +15,15 @@ module.exports = {
|
||||
},
|
||||
forward: {
|
||||
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 { selector } = require('../../helpers/methods');
|
||||
|
||||
const INVALID_ID = '0xffffffff';
|
||||
const INTERFACES = {
|
||||
const SIGNATURES = {
|
||||
ERC165: ['supportsInterface(bytes4)'],
|
||||
ERC721: [
|
||||
'balanceOf(address)',
|
||||
@ -81,27 +81,27 @@ const INTERFACES = {
|
||||
ERC2981: ['royaltyInfo(uint256,uint256)'],
|
||||
};
|
||||
|
||||
const INTERFACE_IDS = {};
|
||||
const FN_SIGNATURES = {};
|
||||
for (const k of Object.getOwnPropertyNames(INTERFACES)) {
|
||||
INTERFACE_IDS[k] = makeInterfaceId.ERC165(INTERFACES[k]);
|
||||
for (const fnName of INTERFACES[k]) {
|
||||
// the interface id of a single function is equivalent to its function signature
|
||||
FN_SIGNATURES[fnName] = makeInterfaceId.ERC165([fnName]);
|
||||
}
|
||||
}
|
||||
const INTERFACE_IDS = Object.fromEntries(
|
||||
Object.entries(SIGNATURES).map(([name, signatures]) => [
|
||||
name,
|
||||
ethers.toBeHex(
|
||||
signatures.reduce((id, fnSig) => id ^ BigInt(selector(fnSig)), 0n),
|
||||
4,
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
function shouldSupportInterfaces(interfaces = []) {
|
||||
describe('ERC165', 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 () {
|
||||
it('uses less than 30k gas', async function () {
|
||||
for (const k of interfaces) {
|
||||
const interfaceId = INTERFACE_IDS[k] ?? k;
|
||||
expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000);
|
||||
const interface = INTERFACE_IDS[k] ?? k;
|
||||
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 () {
|
||||
for (const k of interfaces) {
|
||||
// skip interfaces for which we don't have a function list
|
||||
if (INTERFACES[k] === undefined) continue;
|
||||
for (const fnName of INTERFACES[k]) {
|
||||
const fnSig = FN_SIGNATURES[fnName];
|
||||
expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(
|
||||
1,
|
||||
`did not find ${fnName}`,
|
||||
);
|
||||
if (SIGNATURES[k] === undefined) continue;
|
||||
for (const fnSig of SIGNATURES[k]) {
|
||||
// TODO: Remove Truffle case when ethersjs migration is done
|
||||
if (this.contractUnderTest.abi) {
|
||||
const fnSelector = selector(fnSig);
|
||||
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