123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- const { expectRevert } = require('@openzeppelin/test-helpers');
- const { getSlot, ImplementationSlot } = require('../helpers/erc1967');
- const { expect } = require('chai');
- const { expectRevertCustomError } = require('../helpers/customError');
- const DummyImplementation = artifacts.require('DummyImplementation');
- module.exports = function shouldBehaveLikeProxy(createProxy, accounts) {
- const [proxyCreator] = accounts;
- it('cannot be initialized with a non-contract address', async function () {
- const nonContractAddress = proxyCreator;
- const initializeData = Buffer.from('');
- await expectRevert.unspecified(
- createProxy(nonContractAddress, initializeData, {
- from: proxyCreator,
- }),
- );
- });
- before('deploy implementation', async function () {
- this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).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);
- });
- it('initializes the proxy', async function () {
- const dummy = new DummyImplementation(this.proxy);
- expect(await dummy.value()).to.be.bignumber.equal(value.toString());
- });
- it('has expected balance', async function () {
- expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString());
- });
- };
- describe('without initialization', function () {
- const initializeData = Buffer.from('');
- describe('when not sending balance', function () {
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- })
- ).address;
- });
- assertProxyInitialization({ value: 0, balance: 0 });
- });
- describe('when sending some balance', function () {
- const value = 10e5;
- it('reverts', async function () {
- await expectRevertCustomError(
- createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- value,
- }),
- 'ERC1967NonPayable',
- [],
- );
- });
- });
- });
- describe('initialization without parameters', function () {
- describe('non payable', function () {
- const expectedInitializedValue = 10;
- const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI();
- describe('when not sending balance', function () {
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: 0,
- });
- });
- describe('when sending some balance', function () {
- const value = 10e5;
- it('reverts', async function () {
- await expectRevert.unspecified(
- createProxy(this.implementation, initializeData, { from: proxyCreator, value }),
- );
- });
- });
- });
- describe('payable', function () {
- const expectedInitializedValue = 100;
- const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI();
- describe('when not sending balance', function () {
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: 0,
- });
- });
- describe('when sending some balance', function () {
- const value = 10e5;
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- value,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: value,
- });
- });
- });
- });
- describe('initialization with parameters', function () {
- describe('non payable', function () {
- const expectedInitializedValue = 10;
- const initializeData = new DummyImplementation('').contract.methods
- .initializeNonPayableWithValue(expectedInitializedValue)
- .encodeABI();
- describe('when not sending balance', function () {
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: 0,
- });
- });
- describe('when sending some balance', function () {
- const value = 10e5;
- it('reverts', async function () {
- await expectRevert.unspecified(
- createProxy(this.implementation, initializeData, { from: proxyCreator, value }),
- );
- });
- });
- });
- describe('payable', function () {
- const expectedInitializedValue = 42;
- const initializeData = new DummyImplementation('').contract.methods
- .initializePayableWithValue(expectedInitializedValue)
- .encodeABI();
- describe('when not sending balance', function () {
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: 0,
- });
- });
- describe('when sending some balance', function () {
- const value = 10e5;
- beforeEach('creating proxy', async function () {
- this.proxy = (
- await createProxy(this.implementation, initializeData, {
- from: proxyCreator,
- value,
- })
- ).address;
- });
- assertProxyInitialization({
- value: expectedInitializedValue,
- balance: value,
- });
- });
- });
- describe('reverting initialization', function () {
- const initializeData = new DummyImplementation('').contract.methods.reverts().encodeABI();
- it('reverts', async function () {
- await expectRevert(
- createProxy(this.implementation, initializeData, { from: proxyCreator }),
- 'DummyImplementation reverted',
- );
- });
- });
- });
- };
|