|
@@ -0,0 +1,150 @@
|
|
|
+const { expectRevert } = require('@openzeppelin/test-helpers');
|
|
|
+
|
|
|
+const { expect } = require('chai');
|
|
|
+
|
|
|
+const DummyImplementation = artifacts.require('DummyImplementation');
|
|
|
+
|
|
|
+module.exports = function shouldBehaveLikeClone (createClone) {
|
|
|
+ before('deploy implementation', async function () {
|
|
|
+ this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address);
|
|
|
+ });
|
|
|
+
|
|
|
+ const assertProxyInitialization = function ({ value, balance }) {
|
|
|
+ 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('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 createClone(this.implementation, initializeData)
|
|
|
+ ).address;
|
|
|
+ });
|
|
|
+
|
|
|
+ assertProxyInitialization({
|
|
|
+ value: expectedInitializedValue,
|
|
|
+ balance: 0,
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when sending some balance', function () {
|
|
|
+ const value = 10e5;
|
|
|
+
|
|
|
+ it('reverts', async function () {
|
|
|
+ await expectRevert.unspecified(
|
|
|
+ createClone(this.implementation, initializeData, { 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 createClone(this.implementation, initializeData)
|
|
|
+ ).address;
|
|
|
+ });
|
|
|
+
|
|
|
+ assertProxyInitialization({
|
|
|
+ value: expectedInitializedValue,
|
|
|
+ balance: 0,
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when sending some balance', function () {
|
|
|
+ const value = 10e5;
|
|
|
+
|
|
|
+ beforeEach('creating proxy', async function () {
|
|
|
+ this.proxy = (
|
|
|
+ await createClone(this.implementation, initializeData, { 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 createClone(this.implementation, initializeData)
|
|
|
+ ).address;
|
|
|
+ });
|
|
|
+
|
|
|
+ assertProxyInitialization({
|
|
|
+ value: expectedInitializedValue,
|
|
|
+ balance: 0,
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when sending some balance', function () {
|
|
|
+ const value = 10e5;
|
|
|
+
|
|
|
+ it('reverts', async function () {
|
|
|
+ await expectRevert.unspecified(
|
|
|
+ createClone(this.implementation, initializeData, { 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 createClone(this.implementation, initializeData)
|
|
|
+ ).address;
|
|
|
+ });
|
|
|
+
|
|
|
+ assertProxyInitialization({
|
|
|
+ value: expectedInitializedValue,
|
|
|
+ balance: 0,
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('when sending some balance', function () {
|
|
|
+ const value = 10e5;
|
|
|
+
|
|
|
+ beforeEach('creating proxy', async function () {
|
|
|
+ this.proxy = (
|
|
|
+ await createClone(this.implementation, initializeData, { value })
|
|
|
+ ).address;
|
|
|
+ });
|
|
|
+
|
|
|
+ assertProxyInitialization({
|
|
|
+ value: expectedInitializedValue,
|
|
|
+ balance: value,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|