Migrate proxy folder to ethersjs (#4746)

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
This commit is contained in:
Renan Souza
2023-11-29 21:51:08 +00:00
committed by GitHub
parent c35057978f
commit ae69142379
13 changed files with 785 additions and 856 deletions

View File

@ -1,100 +1,94 @@
const { expectRevert } = require('@openzeppelin/test-helpers');
const { getSlot, ImplementationSlot } = require('../helpers/erc1967');
const { ethers } = require('hardhat');
const { expect } = require('chai');
const { expectRevertCustomError } = require('../helpers/customError');
const DummyImplementation = artifacts.require('DummyImplementation');
const { getAddressInSlot, ImplementationSlot } = require('../helpers/erc1967');
module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
module.exports = function shouldBehaveLikeProxy() {
it('cannot be initialized with a non-contract address', async function () {
const nonContractAddress = accounts[0];
const initializeData = Buffer.from('');
await expectRevert.unspecified(createProxy(nonContractAddress, initializeData));
});
before('deploy implementation', async function () {
this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address);
const initializeData = '0x';
await expect(this.createProxy(this.nonContractAddress, initializeData))
.to.be.revertedWithCustomError(await ethers.getContractFactory('ERC1967Proxy'), 'ERC1967InvalidImplementation')
.withArgs(this.nonContractAddress.address);
});
const assertProxyInitialization = function ({ value, balance }) {
it('sets the implementation address', async function () {
const implementationSlot = await getSlot(this.proxy, ImplementationSlot);
const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40));
expect(implementationAddress).to.be.equal(this.implementation);
expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.implementation.target);
});
it('initializes the proxy', async function () {
const dummy = new DummyImplementation(this.proxy);
expect(await dummy.value()).to.be.bignumber.equal(value.toString());
const dummy = this.implementation.attach(this.proxy);
expect(await dummy.value()).to.equal(value);
});
it('has expected balance', async function () {
expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString());
expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance);
});
};
describe('without initialization', function () {
const initializeData = Buffer.from('');
const initializeData = '0x';
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData)).address;
this.proxy = await this.createProxy(this.implementation, initializeData);
});
assertProxyInitialization({ value: 0, balance: 0 });
assertProxyInitialization({ value: 0n, balance: 0n });
});
describe('when sending some balance', function () {
const value = 10e5;
const value = 10n ** 5n;
it('reverts', async function () {
await expectRevertCustomError(
createProxy(this.implementation, initializeData, { value }),
'ERC1967NonPayable',
[],
);
await expect(this.createProxy(this.implementation, initializeData, { value })).to.be.reverted;
});
});
});
describe('initialization without parameters', function () {
describe('non payable', function () {
const expectedInitializedValue = 10;
const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI();
const expectedInitializedValue = 10n;
beforeEach(function () {
this.initializeData = this.implementation.interface.encodeFunctionData('initializeNonPayable');
});
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData)).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData);
});
assertProxyInitialization({
value: expectedInitializedValue,
balance: 0,
balance: 0n,
});
});
describe('when sending some balance', function () {
const value = 10e5;
const value = 10n ** 5n;
it('reverts', async function () {
await expectRevert.unspecified(createProxy(this.implementation, initializeData, { value }));
await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted;
});
});
});
describe('payable', function () {
const expectedInitializedValue = 100;
const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI();
const expectedInitializedValue = 100n;
beforeEach(function () {
this.initializeData = this.implementation.interface.encodeFunctionData('initializePayable');
});
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData)).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData);
});
assertProxyInitialization({
value: expectedInitializedValue,
balance: 0,
balance: 0n,
});
});
@ -102,7 +96,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
const value = 10e5;
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData, { value })).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData, { value });
});
assertProxyInitialization({
@ -115,14 +109,17 @@ module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
describe('initialization with parameters', function () {
describe('non payable', function () {
const expectedInitializedValue = 10;
const initializeData = new DummyImplementation('').contract.methods
.initializeNonPayableWithValue(expectedInitializedValue)
.encodeABI();
const expectedInitializedValue = 10n;
beforeEach(function () {
this.initializeData = this.implementation.interface.encodeFunctionData('initializeNonPayableWithValue', [
expectedInitializedValue,
]);
});
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData)).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData);
});
assertProxyInitialization({
@ -135,33 +132,36 @@ module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
const value = 10e5;
it('reverts', async function () {
await expectRevert.unspecified(createProxy(this.implementation, initializeData, { value }));
await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted;
});
});
});
describe('payable', function () {
const expectedInitializedValue = 42;
const initializeData = new DummyImplementation('').contract.methods
.initializePayableWithValue(expectedInitializedValue)
.encodeABI();
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 createProxy(this.implementation, initializeData)).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData);
});
assertProxyInitialization({
value: expectedInitializedValue,
balance: 0,
balance: 0n,
});
});
describe('when sending some balance', function () {
const value = 10e5;
const value = 10n ** 5n;
beforeEach('creating proxy', async function () {
this.proxy = (await createProxy(this.implementation, initializeData, { value })).address;
this.proxy = await this.createProxy(this.implementation, this.initializeData, { value });
});
assertProxyInitialization({
@ -172,10 +172,12 @@ module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
});
describe('reverting initialization', function () {
const initializeData = new DummyImplementation('').contract.methods.reverts().encodeABI();
beforeEach(function () {
this.initializeData = this.implementation.interface.encodeFunctionData('reverts');
});
it('reverts', async function () {
await expectRevert(createProxy(this.implementation, initializeData), 'DummyImplementation reverted');
await expect(this.createProxy(this.implementation, this.initializeData)).to.be.reverted;
});
});
});