From 015ef69287ba794cba0551db124495d9dd977ad9 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 22 Dec 2023 20:50:25 +0100 Subject: [PATCH] Refactor time helper and remove custom error helper. (#4803) Co-authored-by: ernestognw --- test/access/AccessControl.behavior.js | 54 ++++++++------- test/access/manager/AccessManaged.test.js | 12 ++-- .../access/manager/AccessManager.predicate.js | 13 ++-- test/access/manager/AccessManager.test.js | 65 +++++++++---------- test/access/manager/AuthorityUtils.test.js | 2 +- test/finance/VestingWallet.behavior.js | 6 +- test/finance/VestingWallet.test.js | 3 +- test/governance/TimelockController.test.js | 32 ++++----- .../extensions/GovernorTimelockAccess.test.js | 7 +- .../GovernorTimelockControl.test.js | 2 +- test/governance/utils/Votes.behavior.js | 2 +- test/governance/utils/Votes.test.js | 2 +- test/helpers/access-manager.js | 15 ++--- test/helpers/constants.js | 10 +-- test/helpers/customError.js | 45 ------------- test/helpers/governance.js | 8 +-- test/helpers/namespaced-storage.js | 14 ++-- test/helpers/time.js | 48 +++++++++----- test/proxy/utils/Initializable.test.js | 4 +- test/token/ERC1155/ERC1155.behavior.js | 1 + test/token/ERC1155/ERC1155.test.js | 2 +- .../ERC20/extensions/ERC20Burnable.test.js | 1 + test/utils/math/Math.test.js | 1 + test/utils/math/SafeCast.test.js | 1 + test/utils/math/SignedMath.test.js | 1 + test/utils/structs/BitMap.test.js | 2 +- test/utils/structs/Checkpoints.test.js | 2 +- test/utils/structs/DoubleEndedQueue.test.js | 2 +- test/utils/structs/EnumerableMap.behavior.js | 2 +- test/utils/structs/EnumerableMap.test.js | 1 + test/utils/structs/EnumerableSet.test.js | 1 + test/utils/types/Time.test.js | 6 +- 32 files changed, 158 insertions(+), 209 deletions(-) delete mode 100644 test/helpers/customError.js diff --git a/test/access/AccessControl.behavior.js b/test/access/AccessControl.behavior.js index 836ca2d6af2..e9027cd65e3 100644 --- a/test/access/AccessControl.behavior.js +++ b/test/access/AccessControl.behavior.js @@ -1,5 +1,6 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); + const { bigint: time } = require('../helpers/time'); const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); @@ -279,8 +280,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); // Wait for acceptance - const acceptSchedule = (await time.clock.timestamp()) + this.delay; - await time.forward.timestamp(acceptSchedule + 1n, false); + await time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); const value = await this.mock[getter](); @@ -309,7 +309,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns pending admin and schedule ${tag} it passes if not accepted`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.forward.timestamp(firstSchedule + fromSchedule); + await time.increaseTo.timestamp(firstSchedule + fromSchedule); const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); expect(newAdmin).to.equal(this.newDefaultAdmin.address); @@ -320,7 +320,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it('returns 0 after schedule passes and the transfer was accepted', async function () { // Wait after schedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.forward.timestamp(firstSchedule + 1n, false); + await time.increaseTo.timestamp(firstSchedule + 1n, false); // Accepts await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); @@ -352,7 +352,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule } = await this.mock.pendingDefaultAdminDelay(); - await time.forward.timestamp(schedule + fromSchedule); + await time.increaseTo.timestamp(schedule + fromSchedule); const currentDelay = await this.mock.defaultAdminDelay(); expect(currentDelay).to.equal(expectNew ? newDelay : this.delay); @@ -383,7 +383,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.forward.timestamp(firstSchedule + fromSchedule); + await time.increaseTo.timestamp(firstSchedule + fromSchedule); const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); expect(newDelay).to.equal(expectedDelay); @@ -437,7 +437,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; const acceptSchedule = nextBlockTimestamp + this.delay; - await time.forward.timestamp(nextBlockTimestamp, false); // set timestamp but don't mine the block yet + await time.increaseTo.timestamp(nextBlockTimestamp, false); // set timestamp but don't mine the block yet await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin)) .to.emit(this.mock, 'DefaultAdminTransferScheduled') .withArgs(this.newDefaultAdmin.address, acceptSchedule); @@ -461,7 +461,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { ]) { it(`should be able to begin a transfer again ${tag} acceptSchedule passes`, async function () { // Wait until schedule + fromSchedule - await time.forward.timestamp(this.acceptSchedule + fromSchedule, false); + await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); // defaultAdmin changes its mind and begin again to another address await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.other)).to.emit( @@ -477,7 +477,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it('should not emit a cancellation event if the new default admin accepted', async function () { // Wait until the acceptSchedule has passed - await time.forward.timestamp(this.acceptSchedule + 1n, false); + await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); // Accept and restart await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); @@ -506,7 +506,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { } delay and apply it to next default admin transfer schedule ${schedulePassed} effectSchedule passed`, async function () { // Wait until the expected fromSchedule time const nextBlockTimestamp = this.effectSchedule + fromSchedule; - await time.forward.timestamp(nextBlockTimestamp, false); + await time.increaseTo.timestamp(nextBlockTimestamp, false); // Start the new default admin transfer and get its schedule const expectedDelay = expectNewDelay ? newDelay : this.delay; @@ -531,7 +531,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('should revert if caller is not pending default admin', async function () { - await time.forward.timestamp(this.acceptSchedule + 1n, false); + await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); await expect(this.mock.connect(this.other).acceptDefaultAdminTransfer()) .to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin') .withArgs(this.other.address); @@ -539,7 +539,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when caller is pending default admin and delay has passed', function () { beforeEach(async function () { - await time.forward.timestamp(this.acceptSchedule + 1n, false); + await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); }); it('accepts a transfer and changes default admin', async function () { @@ -568,7 +568,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { [0n, 'equal'], ]) { it(`should revert if block.timestamp is ${tag} to schedule`, async function () { - await time.forward.timestamp(this.acceptSchedule + fromSchedule, false); + await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') .withArgs(this.acceptSchedule); @@ -597,7 +597,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { ]) { it(`resets pending default admin and schedule ${tag} transfer schedule passes`, async function () { // Advance until passed delay - await time.forward.timestamp(this.acceptSchedule + fromSchedule, false); + await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); await expect(this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer()).to.emit( this.mock, @@ -614,7 +614,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { await this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer(); // Advance until passed delay - await time.forward.timestamp(this.acceptSchedule + 1n, false); + await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); // Previous pending default admin should not be able to accept after cancellation. await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) @@ -641,19 +641,17 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { beforeEach(async function () { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(ethers.ZeroAddress); this.expectedSchedule = (await time.clock.timestamp()) + this.delay; - this.delayNotPassed = this.expectedSchedule; - this.delayPassed = this.expectedSchedule + 1n; }); it('reverts if caller is not default admin', async function () { - await time.forward.timestamp(this.delayPassed, false); + await time.increaseBy.timestamp(this.delay + 1n, false); await expect( this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.other), ).to.be.revertedWithCustomError(this.mock, 'AccessControlBadConfirmation'); }); it("renouncing the admin role when not an admin doesn't affect the schedule", async function () { - await time.forward.timestamp(this.delayPassed, false); + await time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); @@ -662,7 +660,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('keeps defaultAdmin consistent with hasRole if another non-defaultAdmin user renounces the DEFAULT_ADMIN_ROLE', async function () { - await time.forward.timestamp(this.delayPassed, false); + await time.increaseBy.timestamp(this.delay + 1n, false); // This passes because it's a noop await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); @@ -672,7 +670,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('renounces role', async function () { - await time.forward.timestamp(this.delayPassed, false); + await time.increaseBy.timestamp(this.delay + 1n, false); await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) .to.emit(this.mock, 'RoleRevoked') .withArgs(DEFAULT_ADMIN_ROLE, this.defaultAdmin.address, this.defaultAdmin.address); @@ -687,7 +685,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('allows to recover access using the internal _grantRole', async function () { - await time.forward.timestamp(this.delayPassed, false); + await time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin); await expect(this.mock.connect(this.defaultAdmin).$_grantRole(DEFAULT_ADMIN_ROLE, this.other)) @@ -701,7 +699,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { [0n, 'equal'], ]) { it(`reverts if block.timestamp is ${tag} to schedule`, async function () { - await time.forward.timestamp(this.delayNotPassed + fromSchedule, false); + await time.increaseBy.timestamp(this.delay + fromSchedule, false); await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') .withArgs(this.expectedSchedule); @@ -736,7 +734,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; const effectSchedule = nextBlockTimestamp + changeDelay; - await time.forward.timestamp(nextBlockTimestamp, false); + await time.increaseTo.timestamp(nextBlockTimestamp, false); // Begins the change await expect(this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(this.newDefaultAdminDelay)) @@ -765,7 +763,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); const nextBlockTimestamp = firstSchedule + fromSchedule; - await time.forward.timestamp(nextBlockTimestamp, false); + await time.increaseTo.timestamp(nextBlockTimestamp, false); // Calculate expected values const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); @@ -788,7 +786,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.forward.timestamp(firstSchedule + fromSchedule, false); + await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); // Default admin changes its mind and begins another delay change const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); @@ -830,7 +828,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`resets pending delay and schedule ${tag} delay change schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.forward.timestamp(firstSchedule + fromSchedule, false); + await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); await this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay(); @@ -843,7 +841,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.forward.timestamp(firstSchedule + fromSchedule, false); + await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); const expected = expect(this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay()); if (passed) { diff --git a/test/access/manager/AccessManaged.test.js b/test/access/manager/AccessManaged.test.js index b468128ff6c..8af07a7ddf6 100644 --- a/test/access/manager/AccessManaged.test.js +++ b/test/access/manager/AccessManaged.test.js @@ -1,7 +1,8 @@ -const { bigint: time } = require('../../helpers/time'); +const { ethers } = require('hardhat'); + const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { impersonate } = require('../../helpers/account'); -const { ethers } = require('hardhat'); +const { bigint: time } = require('../../helpers/time'); async function fixture() { const [admin, roleMember, other] = await ethers.getSigners(); @@ -84,14 +85,13 @@ describe('AccessManaged', function () { const calldata = this.managed.interface.encodeFunctionData(fn, []); // Schedule - const timestamp = await time.clock.timestamp(); - const scheduledAt = timestamp + 1n; + const scheduledAt = (await time.clock.timestamp()) + 1n; const when = scheduledAt + delay; - await time.forward.timestamp(scheduledAt, false); + await time.increaseTo.timestamp(scheduledAt, false); await this.authority.connect(this.roleMember).schedule(this.managed, calldata, when); // Set execution date - await time.forward.timestamp(when, false); + await time.increaseTo.timestamp(when, false); // Shouldn't revert await this.managed.connect(this.roleMember)[this.selector](); diff --git a/test/access/manager/AccessManager.predicate.js b/test/access/manager/AccessManager.predicate.js index 048437e035f..5bf40a3d7fa 100644 --- a/test/access/manager/AccessManager.predicate.js +++ b/test/access/manager/AccessManager.predicate.js @@ -1,8 +1,9 @@ +const { ethers } = require('hardhat'); const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); + const { EXECUTION_ID_STORAGE_SLOT, EXPIRATION, prepareOperation } = require('../../helpers/access-manager'); const { impersonate } = require('../../helpers/account'); const { bigint: time } = require('../../helpers/time'); -const { ethers } = require('hardhat'); // ============ COMMON PREDICATES ============ @@ -146,7 +147,7 @@ function testAsDelay(type, { before, after }) { describe(`when ${type} delay has not taken effect yet`, function () { beforeEach(`set next block timestamp before ${type} takes effect`, async function () { - await time.forward.timestamp(this.delayEffect - 1n, !!before.mineDelay); + await time.increaseTo.timestamp(this.delayEffect - 1n, !!before.mineDelay); }); before(); @@ -154,7 +155,7 @@ function testAsDelay(type, { before, after }) { describe(`when ${type} delay has taken effect`, function () { beforeEach(`set next block timestamp when ${type} takes effect`, async function () { - await time.forward.timestamp(this.delayEffect, !!after.mineDelay); + await time.increaseTo.timestamp(this.delayEffect, !!after.mineDelay); }); after(); @@ -187,7 +188,7 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not beforeEach('set next block time before operation is ready', async function () { this.scheduledAt = await time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.forward.timestamp(schedule - 1n, !!before.mineDelay); + await time.increaseTo.timestamp(schedule - 1n, !!before.mineDelay); }); before(); @@ -197,7 +198,7 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not beforeEach('set next block time when operation is ready for execution', async function () { this.scheduledAt = await time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.forward.timestamp(schedule, !!after.mineDelay); + await time.increaseTo.timestamp(schedule, !!after.mineDelay); }); after(); @@ -207,7 +208,7 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not beforeEach('set next block time when operation expired', async function () { this.scheduledAt = await time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.forward.timestamp(schedule + EXPIRATION, !!expired.mineDelay); + await time.increaseTo.timestamp(schedule + EXPIRATION, !!expired.mineDelay); }); expired(); diff --git a/test/access/manager/AccessManager.test.js b/test/access/manager/AccessManager.test.js index b26a246af47..ed16dd007e6 100644 --- a/test/access/manager/AccessManager.test.js +++ b/test/access/manager/AccessManager.test.js @@ -1,5 +1,12 @@ -const { ethers, expect } = require('hardhat'); +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +const { loadFixture, getStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); + +const { impersonate } = require('../../helpers/account'); +const { MAX_UINT48 } = require('../../helpers/constants'); +const { bigint: time } = require('../../helpers/time'); const { selector } = require('../../helpers/methods'); + const { buildBaseRoles, formatAccess, @@ -26,17 +33,7 @@ const { testAsGetAccess, } = require('./AccessManager.predicate'); -const { - time: { increase }, - getStorageAt, - loadFixture, -} = require('@nomicfoundation/hardhat-network-helpers'); -const { MAX_UINT48 } = require('../../helpers/constants'); -const { impersonate } = require('../../helpers/account'); -const { bigint: time } = require('../../helpers/time'); -const { ZeroAddress: ZERO_ADDRESS, Wallet, toBeHex, id } = require('ethers'); - -const { address: someAddress } = Wallet.createRandom(); +const { address: someAddress } = ethers.Wallet.createRandom(); async function fixture() { const [admin, roleAdmin, roleGuardian, member, user, other] = await ethers.getSigners(); @@ -118,7 +115,7 @@ contract('AccessManager', function () { it('rejects zero address for initialAdmin', async function () { await expect(ethers.deployContract('$AccessManager', [ethers.ZeroAddress])) .to.be.revertedWithCustomError(this.manager, 'AccessManagerInvalidInitialAdmin') - .withArgs(ZERO_ADDRESS); + .withArgs(ethers.ZeroAddress); }); it('initializes setup roles correctly', async function () { @@ -759,7 +756,7 @@ contract('AccessManager', function () { describe('when is not scheduled', function () { it('returns default 0', async function () { - expect(await this.manager.getNonce(id('operation'))).to.equal(0n); + expect(await this.manager.getNonce(ethers.id('operation'))).to.equal(0n); }); }); }); @@ -912,7 +909,7 @@ contract('AccessManager', function () { beforeEach('sets old delay', async function () { this.role = this.roles.SOME; await this.manager.$_setGrantDelay(this.role.id, oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); }); @@ -924,7 +921,7 @@ contract('AccessManager', function () { .withArgs(this.role.id, newDelay, setGrantDelayAt + MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); }); }); @@ -935,7 +932,7 @@ contract('AccessManager', function () { beforeEach('sets old delay', async function () { this.role = this.roles.SOME; await this.manager.$_setGrantDelay(this.role.id, oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); }); @@ -950,7 +947,7 @@ contract('AccessManager', function () { .withArgs(this.role.id, newDelay, setGrantDelayAt + MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); }); }); @@ -973,7 +970,7 @@ contract('AccessManager', function () { .withArgs(this.role.id, newDelay, setGrantDelayAt + setback); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(oldDelay); - await increase(setback); + await time.increaseBy.timestamp(setback); expect(await this.manager.getRoleGrantDelay(this.role.id)).to.equal(newDelay); }); }); @@ -998,7 +995,7 @@ contract('AccessManager', function () { beforeEach('sets old delay', async function () { await this.manager.$_setTargetAdminDelay(target, oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(oldDelay); }); @@ -1010,7 +1007,7 @@ contract('AccessManager', function () { .withArgs(target, newDelay, setTargetAdminDelayAt + MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(newDelay); }); }); @@ -1021,7 +1018,7 @@ contract('AccessManager', function () { beforeEach('sets old delay', async function () { await this.manager.$_setTargetAdminDelay(target, oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(oldDelay); }); @@ -1036,7 +1033,7 @@ contract('AccessManager', function () { .withArgs(target, newDelay, setTargetAdminDelayAt + MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(oldDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); expect(await this.manager.getTargetAdminDelay(target)).to.equal(newDelay); }); }); @@ -1059,7 +1056,7 @@ contract('AccessManager', function () { .withArgs(target, newDelay, setTargetAdminDelayAt + setback); expect(await this.manager.getTargetAdminDelay(target)).to.equal(oldDelay); - await increase(setback); + await time.increaseBy.timestamp(setback); expect(await this.manager.getTargetAdminDelay(target)).to.equal(newDelay); }); }); @@ -1205,7 +1202,7 @@ contract('AccessManager', function () { // Delay granting this.grantDelay = time.duration.weeks(2); await this.manager.$_setGrantDelay(ANOTHER_ROLE, this.grantDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); // Grant role this.executionDelay = time.duration.days(3); @@ -1279,7 +1276,7 @@ contract('AccessManager', function () { // Delay granting this.grantDelay = 0; await this.manager.$_setGrantDelay(ANOTHER_ROLE, this.grantDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); }); it('immediately grants the role to the user', async function () { @@ -1326,7 +1323,7 @@ contract('AccessManager', function () { // Delay granting const grantDelay = time.duration.weeks(2); await this.manager.$_setGrantDelay(ANOTHER_ROLE, grantDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); }); describe('when increasing the execution delay', function () { @@ -1443,7 +1440,7 @@ contract('AccessManager', function () { // Delay granting const grantDelay = 0; await this.manager.$_setGrantDelay(ANOTHER_ROLE, grantDelay); - await increase(MINSETBACK); + await time.increaseBy.timestamp(MINSETBACK); }); describe('when increasing the execution delay', function () { @@ -1942,7 +1939,7 @@ contract('AccessManager', function () { expect(expectedOperationId).to.equal(op1.operationId); // Consume - await increase(this.delay); + await time.increaseBy.timestamp(this.delay); await this.manager.$_consumeScheduledOp(expectedOperationId); // Check nonce @@ -2166,7 +2163,7 @@ contract('AccessManager', function () { delay, }); await schedule(); - await increase(delay); + await time.increaseBy.timestamp(delay); await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) .to.emit(this.manager, 'OperationExecuted') .withArgs(operationId, 1n); @@ -2191,7 +2188,7 @@ contract('AccessManager', function () { // remove the execution delay await this.manager.$_grantRole(this.role.id, this.caller, 0, 0); - await increase(delay); + await time.increaseBy.timestamp(delay); await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) .to.emit(this.manager, 'OperationExecuted') .withArgs(operationId, 1n); @@ -2217,7 +2214,7 @@ contract('AccessManager', function () { delay, }); await schedule(); - await increase(delay); + await time.increaseBy.timestamp(delay); await this.manager.connect(this.caller).execute(this.target, this.calldata); await expect(this.manager.connect(this.caller).execute(this.target, this.calldata)) .to.be.revertedWithCustomError(this.manager, 'AccessManagerNotScheduled') @@ -2241,7 +2238,7 @@ contract('AccessManager', function () { describe('when caller is not consuming scheduled operation', function () { beforeEach('set consuming false', async function () { - await this.target.setIsConsumingScheduledOp(false, toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); + await this.target.setIsConsumingScheduledOp(false, ethers.toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); }); it('reverts as AccessManagerUnauthorizedConsume', async function () { @@ -2253,7 +2250,7 @@ contract('AccessManager', function () { describe('when caller is consuming scheduled operation', function () { beforeEach('set consuming true', async function () { - await this.target.setIsConsumingScheduledOp(true, toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); + await this.target.setIsConsumingScheduledOp(true, ethers.toBeHex(CONSUMING_SCHEDULE_STORAGE_SLOT, 32)); }); testAsSchedulableOperation({ diff --git a/test/access/manager/AuthorityUtils.test.js b/test/access/manager/AuthorityUtils.test.js index 6c353f20609..c17220541da 100644 --- a/test/access/manager/AuthorityUtils.test.js +++ b/test/access/manager/AuthorityUtils.test.js @@ -1,5 +1,5 @@ -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { ethers } = require('hardhat'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); async function fixture() { const [user, other] = await ethers.getSigners(); diff --git a/test/finance/VestingWallet.behavior.js b/test/finance/VestingWallet.behavior.js index d4863bc52d5..53c8c565c71 100644 --- a/test/finance/VestingWallet.behavior.js +++ b/test/finance/VestingWallet.behavior.js @@ -4,7 +4,7 @@ const { bigint: time } = require('../helpers/time'); function shouldBehaveLikeVesting() { it('check vesting schedule', async function () { for (const timestamp of this.schedule) { - await time.forward.timestamp(timestamp); + await time.increaseTo.timestamp(timestamp); const vesting = this.vestingFn(timestamp); expect(await this.mock.vestedAmount(...this.args, timestamp)).to.be.equal(vesting); @@ -24,7 +24,7 @@ function shouldBehaveLikeVesting() { } for (const timestamp of this.schedule) { - await time.forward.timestamp(timestamp, false); + await time.increaseTo.timestamp(timestamp, false); const vested = this.vestingFn(timestamp); const tx = await this.mock.release(...this.args); @@ -39,7 +39,7 @@ function shouldBehaveLikeVesting() { const { args, error } = await this.setupFailure(); for (const timestamp of this.schedule) { - await time.forward.timestamp(timestamp); + await time.increaseTo.timestamp(timestamp); await expect(this.mock.release(...args)).to.be.revertedWithCustomError(...error); } diff --git a/test/finance/VestingWallet.test.js b/test/finance/VestingWallet.test.js index fa60faea723..843918fee10 100644 --- a/test/finance/VestingWallet.test.js +++ b/test/finance/VestingWallet.test.js @@ -1,8 +1,9 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { bigint: time } = require('../helpers/time'); + const { min } = require('../helpers/math'); +const { bigint: time } = require('../helpers/time'); const { shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); diff --git a/test/governance/TimelockController.test.js b/test/governance/TimelockController.test.js index 9d3f5188b41..709104743e0 100644 --- a/test/governance/TimelockController.test.js +++ b/test/governance/TimelockController.test.js @@ -329,7 +329,7 @@ describe('TimelockController', function () { it('revert if execution comes too early 2/2', async function () { // -1 is too tight, test sometime fails - await this.mock.getTimestamp(this.operation.id).then(clock => time.forward.timestamp(clock - 5n)); + await this.mock.getTimestamp(this.operation.id).then(clock => time.increaseTo.timestamp(clock - 5n)); await expect( this.mock @@ -348,7 +348,7 @@ describe('TimelockController', function () { describe('on time', function () { beforeEach(async function () { - await this.mock.getTimestamp(this.operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(this.operation.id).then(time.increaseTo.timestamp); }); it('executor can reveal', async function () { @@ -407,7 +407,7 @@ describe('TimelockController', function () { ); // Advance on time to make the operation executable - await this.mock.getTimestamp(reentrantOperation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(reentrantOperation.id).then(time.increaseTo.timestamp); // Grant executor role to the reentrant contract await this.mock.connect(this.admin).grantRole(EXECUTOR_ROLE, reentrant); @@ -667,7 +667,7 @@ describe('TimelockController', function () { it('revert if execution comes too early 2/2', async function () { // -1 is to tight, test sometime fails - await this.mock.getTimestamp(this.operation.id).then(clock => time.forward.timestamp(clock - 5n)); + await this.mock.getTimestamp(this.operation.id).then(clock => time.increaseTo.timestamp(clock - 5n)); await expect( this.mock @@ -686,7 +686,7 @@ describe('TimelockController', function () { describe('on time', function () { beforeEach(async function () { - await this.mock.getTimestamp(this.operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(this.operation.id).then(time.increaseTo.timestamp); }); it('executor can reveal', async function () { @@ -800,7 +800,7 @@ describe('TimelockController', function () { ); // Advance on time to make the operation executable - await this.mock.getTimestamp(reentrantBatchOperation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(reentrantBatchOperation.id).then(time.increaseTo.timestamp); // Grant executor role to the reentrant contract await this.mock.connect(this.admin).grantRole(EXECUTOR_ROLE, reentrant); @@ -883,7 +883,7 @@ describe('TimelockController', function () { MINDELAY, ); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); await expect( this.mock @@ -965,7 +965,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); await expect( this.mock @@ -1016,7 +1016,7 @@ describe('TimelockController', function () { MINDELAY, ); - await this.mock.getTimestamp(this.operation2.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(this.operation2.id).then(time.increaseTo.timestamp); }); it('cannot execute before dependency', async function () { @@ -1073,7 +1073,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); await this.mock .connect(this.executor) @@ -1095,7 +1095,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); await expect( this.mock @@ -1117,7 +1117,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); // Targeted function reverts with a panic code (0x1) + the timelock bubble the panic code await expect( @@ -1140,7 +1140,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); await expect( this.mock @@ -1164,7 +1164,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); @@ -1192,7 +1192,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); @@ -1220,7 +1220,7 @@ describe('TimelockController', function () { .connect(this.proposer) .schedule(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, MINDELAY); - await this.mock.getTimestamp(operation.id).then(clock => time.forward.timestamp(clock)); + await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); expect(await ethers.provider.getBalance(this.callreceivermock)).to.equal(0n); diff --git a/test/governance/extensions/GovernorTimelockAccess.test.js b/test/governance/extensions/GovernorTimelockAccess.test.js index 2f16d1b991e..a984a7f5e3f 100644 --- a/test/governance/extensions/GovernorTimelockAccess.test.js +++ b/test/governance/extensions/GovernorTimelockAccess.test.js @@ -595,7 +595,7 @@ describe('GovernorTimelockAccess', function () { .to.emit(this.mock, 'ProposalCanceled') .withArgs(original.currentProposal.id); - await time.clock.timestamp().then(clock => time.forward.timestamp(max(clock + 1n, eta))); + await time.clock.timestamp().then(clock => time.increaseTo.timestamp(max(clock + 1n, eta))); await expect(original.execute()) .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') @@ -621,7 +621,7 @@ describe('GovernorTimelockAccess', function () { .to.emit(this.mock, 'ProposalCanceled') .withArgs(this.proposal.id); - await time.clock.timestamp().then(clock => time.forward.timestamp(max(clock + 1n, eta))); + await time.clock.timestamp().then(clock => time.increaseTo.timestamp(max(clock + 1n, eta))); await expect(this.helper.execute()) .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') @@ -639,14 +639,11 @@ describe('GovernorTimelockAccess', function () { await this.helper.waitForSnapshot(); await this.helper.connect(this.voter1).vote({ support: Enums.VoteType.For }); await this.helper.waitForDeadline(); - // await this.helper.queue(); - // const eta = await this.mock.proposalEta(this.proposal.id); await expect(this.helper.cancel('internal')) .to.emit(this.mock, 'ProposalCanceled') .withArgs(this.proposal.id); - // await time.forward.timestamp(eta); await expect(this.helper.execute()) .to.be.revertedWithCustomError(this.mock, 'GovernorUnexpectedProposalState') .withArgs( diff --git a/test/governance/extensions/GovernorTimelockControl.test.js b/test/governance/extensions/GovernorTimelockControl.test.js index 9f6bceb5baa..71c2b188c20 100644 --- a/test/governance/extensions/GovernorTimelockControl.test.js +++ b/test/governance/extensions/GovernorTimelockControl.test.js @@ -374,7 +374,7 @@ describe('GovernorTimelockControl', function () { await this.timelock.connect(this.owner).schedule(...call, delay); - await time.clock.timestamp().then(clock => time.forward.timestamp(clock + delay)); + await time.increaseBy.timestamp(delay); // Error bubbled up from Governor await expect(this.timelock.connect(this.owner).execute(...call)).to.be.revertedWithCustomError( diff --git a/test/governance/utils/Votes.behavior.js b/test/governance/utils/Votes.behavior.js index a08f184c8ac..be3a87db58a 100644 --- a/test/governance/utils/Votes.behavior.js +++ b/test/governance/utils/Votes.behavior.js @@ -2,8 +2,8 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { mine } = require('@nomicfoundation/hardhat-network-helpers'); -const { bigint: time } = require('../../helpers/time'); const { getDomain, Delegation } = require('../../helpers/eip712'); +const { bigint: time } = require('../../helpers/time'); const { shouldBehaveLikeERC6372 } = require('./ERC6372.behavior'); diff --git a/test/governance/utils/Votes.test.js b/test/governance/utils/Votes.test.js index dda5e5c8251..c133609bc7b 100644 --- a/test/governance/utils/Votes.test.js +++ b/test/governance/utils/Votes.test.js @@ -2,9 +2,9 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { bigint: time } = require('../../helpers/time'); const { sum } = require('../../helpers/math'); const { zip } = require('../../helpers/iterate'); +const { bigint: time } = require('../../helpers/time'); const { shouldBehaveLikeVotes } = require('./Votes.behavior'); diff --git a/test/helpers/access-manager.js b/test/helpers/access-manager.js index 5f55dd51876..e08b48d4e73 100644 --- a/test/helpers/access-manager.js +++ b/test/helpers/access-manager.js @@ -1,9 +1,7 @@ -const { - bigint: { MAX_UINT64 }, -} = require('./constants'); +const { ethers } = require('hardhat'); +const { MAX_UINT64 } = require('./constants'); const { namespaceSlot } = require('./namespaced-storage'); const { bigint: time } = require('./time'); -const { keccak256, AbiCoder } = require('ethers'); function buildBaseRoles() { const roles = { @@ -54,9 +52,8 @@ const CONSUMING_SCHEDULE_STORAGE_SLOT = namespaceSlot('AccessManaged', 0n); * @requires this.{manager, caller, target, calldata} */ async function prepareOperation(manager, { caller, target, calldata, delay }) { - const timestamp = await time.clock.timestamp(); - const scheduledAt = timestamp + 1n; - await time.forward.timestamp(scheduledAt, false); // Fix next block timestamp for predictability + const scheduledAt = (await time.clock.timestamp()) + 1n; + await time.increaseTo.timestamp(scheduledAt, false); // Fix next block timestamp for predictability return { schedule: () => manager.connect(caller).schedule(target, calldata, scheduledAt + delay), @@ -68,8 +65,8 @@ async function prepareOperation(manager, { caller, target, calldata, delay }) { const lazyGetAddress = addressable => addressable.address ?? addressable.target ?? addressable; const hashOperation = (caller, target, data) => - keccak256( - AbiCoder.defaultAbiCoder().encode( + ethers.keccak256( + ethers.AbiCoder.defaultAbiCoder().encode( ['address', 'address', 'bytes'], [lazyGetAddress(caller), lazyGetAddress(target), data], ), diff --git a/test/helpers/constants.js b/test/helpers/constants.js index 17937bee108..4dfda5eabae 100644 --- a/test/helpers/constants.js +++ b/test/helpers/constants.js @@ -1,12 +1,4 @@ -// TODO: deprecate the old version in favor of this one -const bigint = { +module.exports = { MAX_UINT48: 2n ** 48n - 1n, MAX_UINT64: 2n ** 64n - 1n, }; - -// TODO: remove toString() when bigint are supported -module.exports = { - MAX_UINT48: bigint.MAX_UINT48.toString(), - MAX_UINT64: bigint.MAX_UINT64.toString(), - bigint, -}; diff --git a/test/helpers/customError.js b/test/helpers/customError.js deleted file mode 100644 index acc3214eb80..00000000000 --- a/test/helpers/customError.js +++ /dev/null @@ -1,45 +0,0 @@ -// DEPRECATED: replace with hardhat-toolbox chai matchers. - -const { expect } = require('chai'); - -/** Revert handler that supports custom errors. */ -async function expectRevertCustomError(promise, expectedErrorName, args) { - if (!Array.isArray(args)) { - expect.fail('Expected 3rd array parameter for error arguments'); - } - - await promise.then( - () => expect.fail("Expected promise to throw but it didn't"), - ({ message }) => { - // The revert message for custom errors looks like: - // VM Exception while processing transaction: - // reverted with custom error 'InvalidAccountNonce("0x70997970C51812dc3A010C7d01b50e0d17dc79C8", 0)' - - // Attempt to parse as a custom error - const match = message.match(/custom error '(?\w+)\((?.*)\)'/); - if (!match) { - expect.fail(`Could not parse as custom error. ${message}`); - } - // Extract the error name and parameters - const errorName = match.groups.name; - const argMatches = [...match.groups.args.matchAll(/-?\w+/g)]; - - // Assert error name - expect(errorName).to.be.equal( - expectedErrorName, - `Unexpected custom error name (with found args: [${argMatches.map(([a]) => a)}])`, - ); - - // Coerce to string for comparison since `arg` can be either a number or hex. - const sanitizedExpected = args.map(arg => arg.toString().toLowerCase()); - const sanitizedActual = argMatches.map(([arg]) => arg.toString().toLowerCase()); - - // Assert argument equality - expect(sanitizedActual).to.have.members(sanitizedExpected, `Unexpected ${errorName} arguments`); - }, - ); -} - -module.exports = { - expectRevertCustomError, -}; diff --git a/test/helpers/governance.js b/test/helpers/governance.js index c2e79461a16..0efb3da5c5c 100644 --- a/test/helpers/governance.js +++ b/test/helpers/governance.js @@ -1,7 +1,7 @@ const { ethers } = require('hardhat'); -const { forward } = require('./time'); const { ProposalState } = require('./enums'); const { unique } = require('./iterate'); +const time = require('./time'); const timelockSalt = (address, descriptionHash) => ethers.toBeHex((ethers.toBigInt(address) << 96n) ^ ethers.toBigInt(descriptionHash), 32); @@ -131,17 +131,17 @@ class GovernorHelper { /// Clock helpers async waitForSnapshot(offset = 0n) { const timepoint = await this.governor.proposalSnapshot(this.id); - return forward[this.mode](timepoint + offset); + return time.increaseTo[this.mode](timepoint + offset); } async waitForDeadline(offset = 0n) { const timepoint = await this.governor.proposalDeadline(this.id); - return forward[this.mode](timepoint + offset); + return time.increaseTo[this.mode](timepoint + offset); } async waitForEta(offset = 0n) { const timestamp = await this.governor.proposalEta(this.id); - return forward.timestamp(timestamp + offset); + return time.increaseTo.timestamp(timestamp + offset); } /// Other helpers diff --git a/test/helpers/namespaced-storage.js b/test/helpers/namespaced-storage.js index 9fa70411363..eccec3b52c0 100644 --- a/test/helpers/namespaced-storage.js +++ b/test/helpers/namespaced-storage.js @@ -1,21 +1,15 @@ -const { keccak256, id, toBeHex, MaxUint256 } = require('ethers'); -const { artifacts } = require('hardhat'); +const { ethers, artifacts } = require('hardhat'); +const { erc7201slot } = require('./erc1967'); function namespaceId(contractName) { return `openzeppelin.storage.${contractName}`; } -function namespaceLocation(value) { - const hashIdBN = BigInt(id(value)) - 1n; // keccak256(id) - 1 - const mask = MaxUint256 - 0xffn; // ~0xff - return BigInt(keccak256(toBeHex(hashIdBN, 32))) & mask; -} - function namespaceSlot(contractName, offset) { try { // Try to get the artifact paths, will throw if it doesn't exist artifacts._getArtifactPathSync(`${contractName}Upgradeable`); - return offset + namespaceLocation(namespaceId(contractName)); + return offset + ethers.toBigInt(erc7201slot(namespaceId(contractName))); } catch (_) { return offset; } @@ -23,6 +17,6 @@ function namespaceSlot(contractName, offset) { module.exports = { namespaceSlot, - namespaceLocation, + namespaceLocation: erc7201slot, namespaceId, }; diff --git a/test/helpers/time.js b/test/helpers/time.js index 5f85b69158a..db72f206367 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -1,27 +1,39 @@ const { ethers } = require('hardhat'); -const { time, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers'); +const { time, mine, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers'); const { mapValues } = require('./iterate'); +const clock = { + blocknumber: () => time.latestBlock(), + timestamp: () => time.latest(), +}; +const clockFromReceipt = { + blocknumber: receipt => Promise.resolve(receipt.blockNumber), + timestamp: receipt => ethers.provider.getBlock(receipt.blockNumber).then(block => block.timestamp), +}; +const increaseBy = { + blockNumber: mine, + timestamp: (delay, mine = true) => + time.latest().then(clock => increaseTo.timestamp(clock + ethers.toNumber(delay), mine)), +}; +const increaseTo = { + blocknumber: mineUpTo, + timestamp: (to, mine = true) => (mine ? time.increaseTo(to) : time.setNextBlockTimestamp(to)), +}; +const duration = time.duration; + module.exports = { - clock: { - blocknumber: () => time.latestBlock(), - timestamp: () => time.latest(), - }, - clockFromReceipt: { - blocknumber: receipt => Promise.resolve(receipt.blockNumber), - timestamp: receipt => ethers.provider.getBlock(receipt.blockNumber).then(block => block.timestamp), - }, - forward: { - blocknumber: mineUpTo, - timestamp: (to, mine = true) => (mine ? time.increaseTo(to) : time.setNextBlockTimestamp(to)), - }, - duration: time.duration, + clock, + clockFromReceipt, + increaseBy, + increaseTo, + duration, }; // TODO: deprecate the old version in favor of this one module.exports.bigint = { - clock: mapValues(module.exports.clock, fn => () => fn().then(ethers.toBigInt)), - clockFromReceipt: mapValues(module.exports.clockFromReceipt, fn => receipt => fn(receipt).then(ethers.toBigInt)), - forward: module.exports.forward, - duration: mapValues(module.exports.duration, fn => n => ethers.toBigInt(fn(ethers.toNumber(n)))), + clock: mapValues(clock, fn => () => fn().then(ethers.toBigInt)), + clockFromReceipt: mapValues(clockFromReceipt, fn => receipt => fn(receipt).then(ethers.toBigInt)), + increaseBy: increaseBy, + increaseTo: increaseTo, + duration: mapValues(duration, fn => n => ethers.toBigInt(fn(ethers.toNumber(n)))), }; diff --git a/test/proxy/utils/Initializable.test.js b/test/proxy/utils/Initializable.test.js index bc26e6b60a5..6bf213f0d9d 100644 --- a/test/proxy/utils/Initializable.test.js +++ b/test/proxy/utils/Initializable.test.js @@ -1,8 +1,6 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); -const { - bigint: { MAX_UINT64 }, -} = require('../../helpers/constants'); +const { MAX_UINT64 } = require('../../helpers/constants'); describe('Initializable', function () { describe('basic testing without inheritance', function () { diff --git a/test/token/ERC1155/ERC1155.behavior.js b/test/token/ERC1155/ERC1155.behavior.js index 4c81ea9d1ed..9ae706f8496 100644 --- a/test/token/ERC1155/ERC1155.behavior.js +++ b/test/token/ERC1155/ERC1155.behavior.js @@ -1,6 +1,7 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); + const { bigint: { RevertType }, } = require('../../helpers/enums'); diff --git a/test/token/ERC1155/ERC1155.test.js b/test/token/ERC1155/ERC1155.test.js index c469dd84584..486d1aec9ec 100644 --- a/test/token/ERC1155/ERC1155.test.js +++ b/test/token/ERC1155/ERC1155.test.js @@ -1,8 +1,8 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { zip } = require('../../helpers/iterate'); +const { zip } = require('../../helpers/iterate'); const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior'); const initialURI = 'https://token-cdn-domain/{id}.json'; diff --git a/test/token/ERC20/extensions/ERC20Burnable.test.js b/test/token/ERC20/extensions/ERC20Burnable.test.js index 8253acbf15f..9fa02e44f3e 100644 --- a/test/token/ERC20/extensions/ERC20Burnable.test.js +++ b/test/token/ERC20/extensions/ERC20Burnable.test.js @@ -1,4 +1,5 @@ const { ethers } = require('hardhat'); +const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const name = 'My Token'; diff --git a/test/utils/math/Math.test.js b/test/utils/math/Math.test.js index 6e4fa3b9c5a..dda94f8d361 100644 --- a/test/utils/math/Math.test.js +++ b/test/utils/math/Math.test.js @@ -2,6 +2,7 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); + const { min, max } = require('../../helpers/math'); const { bigint: { Rounding }, diff --git a/test/utils/math/SafeCast.test.js b/test/utils/math/SafeCast.test.js index dd04f75ba1a..a69e75c9960 100644 --- a/test/utils/math/SafeCast.test.js +++ b/test/utils/math/SafeCast.test.js @@ -1,6 +1,7 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + const { range } = require('../../../scripts/helpers'); async function fixture() { diff --git a/test/utils/math/SignedMath.test.js b/test/utils/math/SignedMath.test.js index 253e7235752..51aa5d8fba6 100644 --- a/test/utils/math/SignedMath.test.js +++ b/test/utils/math/SignedMath.test.js @@ -1,6 +1,7 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + const { min, max } = require('../../helpers/math'); async function testCommutative(fn, lhs, rhs, expected, ...extra) { diff --git a/test/utils/structs/BitMap.test.js b/test/utils/structs/BitMap.test.js index 133f1f734b3..a7685414e5b 100644 --- a/test/utils/structs/BitMap.test.js +++ b/test/utils/structs/BitMap.test.js @@ -1,5 +1,5 @@ -const { expect } = require('chai'); const { ethers } = require('hardhat'); +const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); async function fixture() { diff --git a/test/utils/structs/Checkpoints.test.js b/test/utils/structs/Checkpoints.test.js index c5b9e65a05e..2c15e082d48 100644 --- a/test/utils/structs/Checkpoints.test.js +++ b/test/utils/structs/Checkpoints.test.js @@ -1,5 +1,5 @@ -const { expect } = require('chai'); const { ethers } = require('hardhat'); +const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { VALUE_SIZES } = require('../../../scripts/generate/templates/Checkpoints.opts.js'); diff --git a/test/utils/structs/DoubleEndedQueue.test.js b/test/utils/structs/DoubleEndedQueue.test.js index 92d9f530c1e..1f6e782b5bd 100644 --- a/test/utils/structs/DoubleEndedQueue.test.js +++ b/test/utils/structs/DoubleEndedQueue.test.js @@ -1,5 +1,5 @@ -const { expect } = require('chai'); const { ethers } = require('hardhat'); +const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); async function fixture() { diff --git a/test/utils/structs/EnumerableMap.behavior.js b/test/utils/structs/EnumerableMap.behavior.js index 9c675c62d5c..39e74a68e80 100644 --- a/test/utils/structs/EnumerableMap.behavior.js +++ b/test/utils/structs/EnumerableMap.behavior.js @@ -1,5 +1,5 @@ -const { expect } = require('chai'); const { ethers } = require('hardhat'); +const { expect } = require('chai'); const zip = (array1, array2) => array1.map((item, index) => [item, array2[index]]); diff --git a/test/utils/structs/EnumerableMap.test.js b/test/utils/structs/EnumerableMap.test.js index 183a8c812d5..6df9871aecc 100644 --- a/test/utils/structs/EnumerableMap.test.js +++ b/test/utils/structs/EnumerableMap.test.js @@ -1,5 +1,6 @@ const { ethers } = require('hardhat'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + const { mapValues } = require('../../helpers/iterate'); const { randomArray, generators } = require('../../helpers/random'); const { TYPES, formatType } = require('../../../scripts/generate/templates/EnumerableMap.opts'); diff --git a/test/utils/structs/EnumerableSet.test.js b/test/utils/structs/EnumerableSet.test.js index 4345dfe7d14..db6c5a4536f 100644 --- a/test/utils/structs/EnumerableSet.test.js +++ b/test/utils/structs/EnumerableSet.test.js @@ -1,5 +1,6 @@ const { ethers } = require('hardhat'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + const { mapValues } = require('../../helpers/iterate'); const { randomArray, generators } = require('../../helpers/random'); const { TYPES } = require('../../../scripts/generate/templates/EnumerableSet.opts'); diff --git a/test/utils/types/Time.test.js b/test/utils/types/Time.test.js index c55a769f985..171a8452638 100644 --- a/test/utils/types/Time.test.js +++ b/test/utils/types/Time.test.js @@ -1,12 +1,12 @@ const { ethers } = require('hardhat'); const { expect } = require('chai'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { - bigint: { clock }, -} = require('../../helpers/time'); const { product } = require('../../helpers/iterate'); const { max } = require('../../helpers/math'); +const { + bigint: { clock }, +} = require('../../helpers/time'); const MAX_UINT32 = 1n << (32n - 1n); const MAX_UINT48 = 1n << (48n - 1n);