浏览代码

Refactor time helper and remove custom error helper. (#4803)

Co-authored-by: ernestognw <ernestognw@gmail.com>
Hadrien Croubois 1 年之前
父节点
当前提交
015ef69287
共有 32 个文件被更改,包括 158 次插入209 次删除
  1. 26 28
      test/access/AccessControl.behavior.js
  2. 6 6
      test/access/manager/AccessManaged.test.js
  3. 7 6
      test/access/manager/AccessManager.predicate.js
  4. 31 34
      test/access/manager/AccessManager.test.js
  5. 1 1
      test/access/manager/AuthorityUtils.test.js
  6. 3 3
      test/finance/VestingWallet.behavior.js
  7. 2 1
      test/finance/VestingWallet.test.js
  8. 16 16
      test/governance/TimelockController.test.js
  9. 2 5
      test/governance/extensions/GovernorTimelockAccess.test.js
  10. 1 1
      test/governance/extensions/GovernorTimelockControl.test.js
  11. 1 1
      test/governance/utils/Votes.behavior.js
  12. 1 1
      test/governance/utils/Votes.test.js
  13. 6 9
      test/helpers/access-manager.js
  14. 1 9
      test/helpers/constants.js
  15. 0 45
      test/helpers/customError.js
  16. 4 4
      test/helpers/governance.js
  17. 4 10
      test/helpers/namespaced-storage.js
  18. 30 18
      test/helpers/time.js
  19. 1 3
      test/proxy/utils/Initializable.test.js
  20. 1 0
      test/token/ERC1155/ERC1155.behavior.js
  21. 1 1
      test/token/ERC1155/ERC1155.test.js
  22. 1 0
      test/token/ERC20/extensions/ERC20Burnable.test.js
  23. 1 0
      test/utils/math/Math.test.js
  24. 1 0
      test/utils/math/SafeCast.test.js
  25. 1 0
      test/utils/math/SignedMath.test.js
  26. 1 1
      test/utils/structs/BitMap.test.js
  27. 1 1
      test/utils/structs/Checkpoints.test.js
  28. 1 1
      test/utils/structs/DoubleEndedQueue.test.js
  29. 1 1
      test/utils/structs/EnumerableMap.behavior.js
  30. 1 0
      test/utils/structs/EnumerableMap.test.js
  31. 1 0
      test/utils/structs/EnumerableSet.test.js
  32. 3 3
      test/utils/types/Time.test.js

+ 26 - 28
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) {

+ 6 - 6
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]();

+ 7 - 6
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();

+ 31 - 34
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({

+ 1 - 1
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();

+ 3 - 3
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);
     }

+ 2 - 1
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');
 

+ 16 - 16
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);

+ 2 - 5
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(

+ 1 - 1
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(

+ 1 - 1
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');
 

+ 1 - 1
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');
 

+ 6 - 9
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],
     ),

+ 1 - 9
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,
-};

+ 0 - 45
test/helpers/customError.js

@@ -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 '(?<name>\w+)\((?<args>.*)\)'/);
-      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,
-};

+ 4 - 4
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

+ 4 - 10
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,
 };

+ 30 - 18
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)))),
 };

+ 1 - 3
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 () {

+ 1 - 0
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');

+ 1 - 1
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';

+ 1 - 0
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';

+ 1 - 0
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 },

+ 1 - 0
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() {

+ 1 - 0
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) {

+ 1 - 1
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() {

+ 1 - 1
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');

+ 1 - 1
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() {

+ 1 - 1
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]]);
 

+ 1 - 0
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');

+ 1 - 0
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');

+ 3 - 3
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);