@0x/contracts-zero-ex: Merge Migrate into Ownable

This commit is contained in:
Lawrence Forman
2020-04-23 12:22:09 -04:00
parent 85509ea251
commit 0042e42160
20 changed files with 178 additions and 371 deletions

View File

@@ -10,7 +10,6 @@ import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json';
import * as FixinOwnable from '../test/generated-artifacts/FixinOwnable.json';
import * as IBootstrap from '../test/generated-artifacts/IBootstrap.json';
import * as IFeature from '../test/generated-artifacts/IFeature.json';
import * as IMigrate from '../test/generated-artifacts/IMigrate.json';
import * as InitialMigration from '../test/generated-artifacts/InitialMigration.json';
import * as IOwnable from '../test/generated-artifacts/IOwnable.json';
import * as ISimpleFunctionRegistry from '../test/generated-artifacts/ISimpleFunctionRegistry.json';
@@ -18,8 +17,6 @@ import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts
import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json';
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
import * as LibMigrate from '../test/generated-artifacts/LibMigrate.json';
import * as LibMigrateRichErrors from '../test/generated-artifacts/LibMigrateRichErrors.json';
import * as LibMigrateStorage from '../test/generated-artifacts/LibMigrateStorage.json';
import * as LibOwnableRichErrors from '../test/generated-artifacts/LibOwnableRichErrors.json';
import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorage.json';
import * as LibProxyRichErrors from '../test/generated-artifacts/LibProxyRichErrors.json';
@@ -27,7 +24,6 @@ import * as LibProxyStorage from '../test/generated-artifacts/LibProxyStorage.js
import * as LibSimpleFunctionRegistryRichErrors from '../test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json';
import * as LibSimpleFunctionRegistryStorage from '../test/generated-artifacts/LibSimpleFunctionRegistryStorage.json';
import * as LibStorage from '../test/generated-artifacts/LibStorage.json';
import * as Migrate from '../test/generated-artifacts/Migrate.json';
import * as Ownable from '../test/generated-artifacts/Ownable.json';
import * as SimpleFunctionRegistry from '../test/generated-artifacts/SimpleFunctionRegistry.json';
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
@@ -39,17 +35,14 @@ import * as ZeroEx from '../test/generated-artifacts/ZeroEx.json';
export const artifacts = {
ZeroEx: ZeroEx as ContractArtifact,
LibCommonRichErrors: LibCommonRichErrors as ContractArtifact,
LibMigrateRichErrors: LibMigrateRichErrors as ContractArtifact,
LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact,
LibProxyRichErrors: LibProxyRichErrors as ContractArtifact,
LibSimpleFunctionRegistryRichErrors: LibSimpleFunctionRegistryRichErrors as ContractArtifact,
Bootstrap: Bootstrap as ContractArtifact,
IBootstrap: IBootstrap as ContractArtifact,
IFeature: IFeature as ContractArtifact,
IMigrate: IMigrate as ContractArtifact,
IOwnable: IOwnable as ContractArtifact,
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
Migrate: Migrate as ContractArtifact,
Ownable: Ownable as ContractArtifact,
SimpleFunctionRegistry: SimpleFunctionRegistry as ContractArtifact,
FixinCommon: FixinCommon as ContractArtifact,
@@ -57,7 +50,6 @@ export const artifacts = {
InitialMigration: InitialMigration as ContractArtifact,
LibBootstrap: LibBootstrap as ContractArtifact,
LibMigrate: LibMigrate as ContractArtifact,
LibMigrateStorage: LibMigrateStorage as ContractArtifact,
LibOwnableStorage: LibOwnableStorage as ContractArtifact,
LibProxyStorage: LibProxyStorage as ContractArtifact,
LibSimpleFunctionRegistryStorage: LibSimpleFunctionRegistryStorage as ContractArtifact,

View File

@@ -1,94 +0,0 @@
import { blockchainTests, expect, LogDecoder, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
import { hexUtils, OwnableRevertErrors, StringRevertError, ZeroExRevertErrors } from '@0x/utils';
import { artifacts } from '../artifacts';
import { initialMigrateAsync } from '../utils/migration';
import { IMigrateContract, IOwnableContract, TestMigratorContract, TestMigratorEvents } from '../wrappers';
blockchainTests.resets('Migrate feature', env => {
let owner: string;
let ownable: IOwnableContract;
let migrate: IMigrateContract;
let testMigrator: TestMigratorContract;
let succeedingMigrateFnCallData: string;
let failingMigrateFnCallData: string;
let revertingMigrateFnCallData: string;
let logDecoder: LogDecoder;
before(async () => {
logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
[owner] = await env.getAccountAddressesAsync();
const zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
migrate = new IMigrateContract(zeroEx.address, env.provider, env.txDefaults);
testMigrator = await TestMigratorContract.deployFrom0xArtifactAsync(
artifacts.TestMigrator,
env.provider,
env.txDefaults,
artifacts,
);
succeedingMigrateFnCallData = testMigrator.succeedingMigrate().getABIEncodedTransactionData();
failingMigrateFnCallData = testMigrator.failingMigrate().getABIEncodedTransactionData();
revertingMigrateFnCallData = testMigrator.revertingMigrate().getABIEncodedTransactionData();
});
describe('migrate()', () => {
it('non-owner cannot call migrate()', async () => {
const notOwner = randomAddress();
const tx = migrate
.migrate(testMigrator.address, succeedingMigrateFnCallData)
.awaitTransactionSuccessAsync({ from: notOwner });
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner));
});
it('can successfully execute a migration', async () => {
const receipt = await migrate
.migrate(testMigrator.address, succeedingMigrateFnCallData)
.awaitTransactionSuccessAsync({ from: owner });
const { logs } = logDecoder.decodeReceiptLogs(receipt);
verifyEventsFromLogs(
logs,
[
{
callData: succeedingMigrateFnCallData,
owner: migrate.address,
actualOwner: owner,
},
],
TestMigratorEvents.TestMigrateCalled,
);
});
it('owner is restored after a migration', async () => {
await migrate
.migrate(testMigrator.address, succeedingMigrateFnCallData)
.awaitTransactionSuccessAsync({ from: owner });
const currentOwner = await ownable.getOwner().callAsync();
expect(currentOwner).to.eq(owner);
});
it('failing migration reverts', async () => {
const tx = migrate
.migrate(testMigrator.address, failingMigrateFnCallData)
.awaitTransactionSuccessAsync({ from: owner });
return expect(tx).to.revertWith(
new ZeroExRevertErrors.Migrate.MigrateCallFailedError(
testMigrator.address,
hexUtils.rightPad('0xdeadbeef'),
),
);
});
it('reverting migration reverts', async () => {
const tx = migrate
.migrate(testMigrator.address, revertingMigrateFnCallData)
.awaitTransactionSuccessAsync({ from: owner });
return expect(tx).to.revertWith(
new ZeroExRevertErrors.Migrate.MigrateCallFailedError(
testMigrator.address,
new StringRevertError('OOPSIE').encode(),
),
);
});
});
});

View File

@@ -1,18 +1,34 @@
import { blockchainTests, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
import { OwnableRevertErrors } from '@0x/utils';
import { blockchainTests, expect, LogDecoder, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
import { hexUtils, OwnableRevertErrors, StringRevertError, ZeroExRevertErrors } from '@0x/utils';
import { artifacts } from '../artifacts';
import { initialMigrateAsync } from '../utils/migration';
import { IOwnableContract, IOwnableEvents } from '../wrappers';
import { IOwnableContract, IOwnableEvents, TestMigratorContract, TestMigratorEvents } from '../wrappers';
blockchainTests.resets('Ownable feature', env => {
const notOwner = randomAddress();
let owner: string;
let ownable: IOwnableContract;
let testMigrator: TestMigratorContract;
let succeedingMigrateFnCallData: string;
let failingMigrateFnCallData: string;
let revertingMigrateFnCallData: string;
let logDecoder: LogDecoder;
before(async () => {
[owner] = await env.getAccountAddressesAsync();
logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
const zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
testMigrator = await TestMigratorContract.deployFrom0xArtifactAsync(
artifacts.TestMigrator,
env.provider,
env.txDefaults,
artifacts,
);
succeedingMigrateFnCallData = testMigrator.succeedingMigrate().getABIEncodedTransactionData();
failingMigrateFnCallData = testMigrator.failingMigrate().getABIEncodedTransactionData();
revertingMigrateFnCallData = testMigrator.revertingMigrate().getABIEncodedTransactionData();
});
describe('transferOwnership()', () => {
@@ -38,4 +54,57 @@ blockchainTests.resets('Ownable feature', env => {
expect(await ownable.getOwner().callAsync()).to.eq(newOwner);
});
});
describe('migrate()', () => {
const newOwner = randomAddress();
it('non-owner cannot call migrate()', async () => {
const tx = ownable
.migrate(testMigrator.address, succeedingMigrateFnCallData, newOwner)
.awaitTransactionSuccessAsync({ from: notOwner });
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner));
});
it('can successfully execute a migration', async () => {
const receipt = await ownable
.migrate(testMigrator.address, succeedingMigrateFnCallData, newOwner)
.awaitTransactionSuccessAsync({ from: owner });
const { logs } = logDecoder.decodeReceiptLogs(receipt);
verifyEventsFromLogs(
logs,
[
{
callData: succeedingMigrateFnCallData,
owner: ownable.address,
},
],
TestMigratorEvents.TestMigrateCalled,
);
expect(await ownable.getOwner().callAsync()).to.eq(newOwner);
});
it('failing migration reverts', async () => {
const tx = ownable
.migrate(testMigrator.address, failingMigrateFnCallData, newOwner)
.awaitTransactionSuccessAsync({ from: owner });
return expect(tx).to.revertWith(
new ZeroExRevertErrors.Ownable.MigrateCallFailedError(
testMigrator.address,
hexUtils.rightPad('0xdeadbeef'),
),
);
});
it('reverting migration reverts', async () => {
const tx = ownable
.migrate(testMigrator.address, revertingMigrateFnCallData, newOwner)
.awaitTransactionSuccessAsync({ from: owner });
return expect(tx).to.revertWith(
new ZeroExRevertErrors.Ownable.MigrateCallFailedError(
testMigrator.address,
new StringRevertError('OOPSIE').encode(),
),
);
});
});
});

View File

@@ -8,7 +8,6 @@ export * from '../test/generated-wrappers/fixin_common';
export * from '../test/generated-wrappers/fixin_ownable';
export * from '../test/generated-wrappers/i_bootstrap';
export * from '../test/generated-wrappers/i_feature';
export * from '../test/generated-wrappers/i_migrate';
export * from '../test/generated-wrappers/i_ownable';
export * from '../test/generated-wrappers/i_simple_function_registry';
export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
@@ -16,8 +15,6 @@ export * from '../test/generated-wrappers/initial_migration';
export * from '../test/generated-wrappers/lib_bootstrap';
export * from '../test/generated-wrappers/lib_common_rich_errors';
export * from '../test/generated-wrappers/lib_migrate';
export * from '../test/generated-wrappers/lib_migrate_rich_errors';
export * from '../test/generated-wrappers/lib_migrate_storage';
export * from '../test/generated-wrappers/lib_ownable_rich_errors';
export * from '../test/generated-wrappers/lib_ownable_storage';
export * from '../test/generated-wrappers/lib_proxy_rich_errors';
@@ -25,7 +22,6 @@ export * from '../test/generated-wrappers/lib_proxy_storage';
export * from '../test/generated-wrappers/lib_simple_function_registry_rich_errors';
export * from '../test/generated-wrappers/lib_simple_function_registry_storage';
export * from '../test/generated-wrappers/lib_storage';
export * from '../test/generated-wrappers/migrate';
export * from '../test/generated-wrappers/ownable';
export * from '../test/generated-wrappers/simple_function_registry';
export * from '../test/generated-wrappers/test_initial_migration';