diff --git a/test/finance/VestingWallet.behavior.js b/test/finance/VestingWallet.behavior.js index 4b4804ac5..819a47ff6 100644 --- a/test/finance/VestingWallet.behavior.js +++ b/test/finance/VestingWallet.behavior.js @@ -1,6 +1,41 @@ +const { ethers } = require('hardhat'); const { expect } = require('chai'); const time = require('../helpers/time'); +async function envSetup(mock, beneficiary, token) { + return { + eth: { + checkRelease: async (tx, amount) => { + await expect(tx).to.changeEtherBalances([mock, beneficiary], [-amount, amount]); + }, + setupFailure: async () => { + const beneficiaryMock = await ethers.deployContract('EtherReceiverMock'); + await beneficiaryMock.setAcceptEther(false); + await mock.connect(beneficiary).transferOwnership(beneficiaryMock); + return { args: [], error: [mock, 'FailedInnerCall'] }; + }, + releasedEvent: 'EtherReleased', + args: [], + }, + token: { + checkRelease: async (tx, amount) => { + await expect(tx).to.emit(token, 'Transfer').withArgs(mock, beneficiary, amount); + await expect(tx).to.changeTokenBalances(token, [mock, beneficiary], [-amount, amount]); + }, + setupFailure: async () => { + const pausableToken = await ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); + await pausableToken.$_pause(); + return { + args: [ethers.Typed.address(pausableToken)], + error: [pausableToken, 'EnforcedPause'], + }; + }, + releasedEvent: 'ERC20Released', + args: [ethers.Typed.address(token)], + }, + }; +} + function shouldBehaveLikeVesting() { it('check vesting schedule', async function () { for (const timestamp of this.schedule) { @@ -18,7 +53,7 @@ function shouldBehaveLikeVesting() { const tx = await this.mock.release(...this.args); await expect(tx) .to.emit(this.mock, this.releasedEvent) - .withArgs(...this.argsVerify, 0); + .withArgs(...this.args, 0); await this.checkRelease(tx, 0n); } @@ -47,5 +82,6 @@ function shouldBehaveLikeVesting() { } module.exports = { + envSetup, shouldBehaveLikeVesting, }; diff --git a/test/finance/VestingWallet.test.js b/test/finance/VestingWallet.test.js index 318013575..b89258d65 100644 --- a/test/finance/VestingWallet.test.js +++ b/test/finance/VestingWallet.test.js @@ -5,7 +5,7 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { min } = require('../helpers/math'); const time = require('../helpers/time'); -const { shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); +const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); async function fixture() { const amount = ethers.parseEther('100'); @@ -19,44 +19,9 @@ async function fixture() { await token.$_mint(mock, amount); await sender.sendTransaction({ to: mock, value: amount }); - const pausableToken = await ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); - const beneficiaryMock = await ethers.deployContract('EtherReceiverMock'); - - const env = { - eth: { - checkRelease: async (tx, amount) => { - await expect(tx).to.emit(mock, 'EtherReleased').withArgs(amount); - await expect(tx).to.changeEtherBalances([mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - await beneficiaryMock.setAcceptEther(false); - await mock.connect(beneficiary).transferOwnership(beneficiaryMock); - return { args: [], error: [mock, 'FailedInnerCall'] }; - }, - releasedEvent: 'EtherReleased', - argsVerify: [], - args: [], - }, - token: { - checkRelease: async (tx, amount) => { - await expect(tx).to.emit(token, 'Transfer').withArgs(mock, beneficiary, amount); - await expect(tx).to.changeTokenBalances(token, [mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - await pausableToken.$_pause(); - return { - args: [ethers.Typed.address(pausableToken)], - error: [pausableToken, 'EnforcedPause'], - }; - }, - releasedEvent: 'ERC20Released', - argsVerify: [token], - args: [ethers.Typed.address(token)], - }, - }; + const env = await envSetup(mock, beneficiary, token); const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); - const vestingFn = timestamp => min(amount, (amount * (timestamp - start)) / duration); return { mock, duration, start, beneficiary, schedule, vestingFn, env }; diff --git a/test/finance/VestingWalletCliff.test.js b/test/finance/VestingWalletCliff.test.js index 810769f5c..799b24c4b 100644 --- a/test/finance/VestingWalletCliff.test.js +++ b/test/finance/VestingWalletCliff.test.js @@ -5,7 +5,7 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { min } = require('../helpers/math'); const time = require('../helpers/time'); -const { shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); +const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); async function fixture() { const amount = ethers.parseEther('100'); @@ -21,46 +21,9 @@ async function fixture() { await token.$_mint(mock, amount); await sender.sendTransaction({ to: mock, value: amount }); - const pausableToken = await ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); - const beneficiaryMock = await ethers.deployContract('EtherReceiverMock'); - - const env = { - eth: { - checkRelease: async (tx, amount) => { - await expect(tx).to.emit(mock, 'EtherReleased').withArgs(amount); - await expect(tx).to.changeEtherBalances([mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - await beneficiaryMock.setAcceptEther(false); - await mock.connect(beneficiary).transferOwnership(beneficiaryMock); - return { args: [], error: [mock, 'FailedInnerCall'] }; - }, - releasedEvent: 'EtherReleased', - argsVerify: [], - args: [], - }, - token: { - checkRelease: async (tx, amount) => { - await expect(tx).to.emit(token, 'Transfer').withArgs(mock, beneficiary, amount); - await expect(tx).to.changeTokenBalances(token, [mock, beneficiary], [-amount, amount]); - }, - setupFailure: async () => { - await pausableToken.$_pause(); - return { - args: [ethers.Typed.address(pausableToken)], - error: [pausableToken, 'EnforcedPause'], - }; - }, - releasedEvent: 'ERC20Released', - argsVerify: [token], - args: [ethers.Typed.address(token)], - }, - }; - - const schedule = Array(64) - .fill() - .map((_, i) => (BigInt(i) * duration) / 60n + start); + const env = await envSetup(mock, beneficiary, token); + const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); const vestingFn = timestamp => min(amount, timestamp < cliff ? 0n : (amount * (timestamp - start)) / duration); return { mock, duration, start, beneficiary, cliff, schedule, vestingFn, env };