You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
5.0 KiB
160 lines
5.0 KiB
const { ethers } = require('hardhat');
|
|
const { expect } = require('chai');
|
|
|
|
module.exports = function shouldBehaveLikeClone() {
|
|
const assertProxyInitialization = function ({ value, balance }) {
|
|
it('initializes the proxy', async function () {
|
|
const dummy = await ethers.getContractAt('DummyImplementation', this.proxy);
|
|
expect(await dummy.value()).to.equal(value);
|
|
});
|
|
|
|
it('has expected balance', async function () {
|
|
expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance);
|
|
});
|
|
};
|
|
|
|
describe('construct with value', function () {
|
|
const value = 10n;
|
|
|
|
it('factory has enough balance', async function () {
|
|
await this.deployer.sendTransaction({ to: this.factory, value });
|
|
|
|
const instance = await this.createClone({ deployValue: value });
|
|
await expect(instance.deploymentTransaction()).to.changeEtherBalances([this.factory, instance], [-value, value]);
|
|
|
|
expect(await ethers.provider.getBalance(instance)).to.equal(value);
|
|
});
|
|
|
|
it('factory does not have enough balance', async function () {
|
|
await expect(this.createClone({ deployValue: value }))
|
|
.to.be.revertedWithCustomError(this.factory, 'InsufficientBalance')
|
|
.withArgs(0n, value);
|
|
});
|
|
});
|
|
|
|
describe('initialization without parameters', function () {
|
|
describe('non payable', function () {
|
|
const expectedInitializedValue = 10n;
|
|
|
|
beforeEach(async function () {
|
|
this.initializeData = await this.implementation.interface.encodeFunctionData('initializeNonPayable');
|
|
});
|
|
|
|
describe('when not sending balance', function () {
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: 0,
|
|
});
|
|
});
|
|
|
|
describe('when sending some balance', function () {
|
|
const value = 10n ** 6n;
|
|
|
|
it('reverts', async function () {
|
|
await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted;
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('payable', function () {
|
|
const expectedInitializedValue = 100n;
|
|
|
|
beforeEach(async function () {
|
|
this.initializeData = await this.implementation.interface.encodeFunctionData('initializePayable');
|
|
});
|
|
|
|
describe('when not sending balance', function () {
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: 0,
|
|
});
|
|
});
|
|
|
|
describe('when sending some balance', function () {
|
|
const value = 10n ** 6n;
|
|
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData, initValue: value });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: value,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('initialization with parameters', function () {
|
|
describe('non payable', function () {
|
|
const expectedInitializedValue = 10n;
|
|
|
|
beforeEach(async function () {
|
|
this.initializeData = await this.implementation.interface.encodeFunctionData('initializeNonPayableWithValue', [
|
|
expectedInitializedValue,
|
|
]);
|
|
});
|
|
|
|
describe('when not sending balance', function () {
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: 0,
|
|
});
|
|
});
|
|
|
|
describe('when sending some balance', function () {
|
|
const value = 10n ** 6n;
|
|
|
|
it('reverts', async function () {
|
|
await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted;
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('payable', function () {
|
|
const expectedInitializedValue = 42n;
|
|
|
|
beforeEach(function () {
|
|
this.initializeData = this.implementation.interface.encodeFunctionData('initializePayableWithValue', [
|
|
expectedInitializedValue,
|
|
]);
|
|
});
|
|
|
|
describe('when not sending balance', function () {
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: 0,
|
|
});
|
|
});
|
|
|
|
describe('when sending some balance', function () {
|
|
const value = 10n ** 6n;
|
|
|
|
beforeEach('creating proxy', async function () {
|
|
this.proxy = await this.createClone({ initData: this.initializeData, initValue: value });
|
|
});
|
|
|
|
assertProxyInitialization({
|
|
value: expectedInitializedValue,
|
|
balance: value,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|