@0x/contracts-zero-ex: Merge Migrate into Ownable
This commit is contained in:
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2020 ZeroEx Intl.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity ^0.6.5;
|
|
||||||
|
|
||||||
|
|
||||||
library LibMigrateRichErrors {
|
|
||||||
|
|
||||||
// solhint-disable func-name-mixedcase
|
|
||||||
|
|
||||||
function AlreadyMigratingError()
|
|
||||||
internal
|
|
||||||
pure
|
|
||||||
returns (bytes memory)
|
|
||||||
{
|
|
||||||
return abi.encodeWithSelector(
|
|
||||||
bytes4(keccak256("AlreadyMigratingError()"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MigrateCallFailedError(address target, bytes memory resultData)
|
|
||||||
internal
|
|
||||||
pure
|
|
||||||
returns (bytes memory)
|
|
||||||
{
|
|
||||||
return abi.encodeWithSelector(
|
|
||||||
bytes4(keccak256("MigrateCallFailedError(address,bytes)")),
|
|
||||||
target,
|
|
||||||
resultData
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,4 +47,26 @@ library LibOwnableRichErrors {
|
|||||||
bytes4(keccak256("TransferOwnerToZeroError()"))
|
bytes4(keccak256("TransferOwnerToZeroError()"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AlreadyMigratingError()
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("AlreadyMigratingError()"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function MigrateCallFailedError(address target, bytes memory resultData)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("MigrateCallFailedError(address,bytes)")),
|
||||||
|
target,
|
||||||
|
resultData
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2020 ZeroEx Intl.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity ^0.6.5;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
|
|
||||||
/// @dev Migration features.
|
|
||||||
interface IMigrate {
|
|
||||||
|
|
||||||
/// @dev Emitted when `migrate()` is called.
|
|
||||||
/// @param caller The caller of `migrate()`.
|
|
||||||
/// @param migrator The migration contract.
|
|
||||||
event Migrated(address caller, address migrator);
|
|
||||||
|
|
||||||
/// @dev Execute a migration function in the context of the ZeroEx contract.
|
|
||||||
/// The result of the function being called should be the magic bytes
|
|
||||||
/// 0x2c64c5ef (`keccack('MIGRATE_SUCCESS')`). Only callable by the owner.
|
|
||||||
/// The owner will be temporarily set to `address(this)` inside the call.
|
|
||||||
/// The original owner can be retrieved through `getMigrationOwner()`.`
|
|
||||||
/// @param target The migrator contract address.
|
|
||||||
/// @param data The call data.
|
|
||||||
function migrate(address target, bytes calldata data) external;
|
|
||||||
|
|
||||||
/// @dev Get the true owner of this contract during a migration.
|
|
||||||
/// @return owner The true owner of this contract.
|
|
||||||
function getMigrationOwner() external view returns (address owner);
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,23 @@ import "@0x/contracts-utils/contracts/src/v06/interfaces/IOwnableV06.sol";
|
|||||||
|
|
||||||
|
|
||||||
// solhint-disable no-empty-blocks
|
// solhint-disable no-empty-blocks
|
||||||
/// @dev Owner management features.
|
/// @dev Owner management and migration features.
|
||||||
interface IOwnable is
|
interface IOwnable is
|
||||||
IOwnableV06
|
IOwnableV06
|
||||||
{}
|
{
|
||||||
|
/// @dev Emitted when `migrate()` is called.
|
||||||
|
/// @param caller The caller of `migrate()`.
|
||||||
|
/// @param migrator The migration contract.
|
||||||
|
/// @param newOwner The address of the new owner.
|
||||||
|
event Migrated(address caller, address migrator, address newOwner);
|
||||||
|
|
||||||
|
/// @dev Execute a migration function in the context of the ZeroEx contract.
|
||||||
|
/// The result of the function being called should be the magic bytes
|
||||||
|
/// 0x2c64c5ef (`keccack('MIGRATE_SUCCESS')`). Only callable by the owner.
|
||||||
|
/// The owner will be temporarily set to `address(this)` inside the call.
|
||||||
|
/// Before returning, the owner will be set to `newOwner`.
|
||||||
|
/// @param target The migrator contract address.
|
||||||
|
/// @param newOwner The address of the new owner.
|
||||||
|
/// @param data The call data.
|
||||||
|
function migrate(address target, bytes calldata data, address newOwner) external;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2020 ZeroEx Intl.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity ^0.6.5;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import "../fixins/FixinOwnable.sol";
|
|
||||||
import "../errors/LibOwnableRichErrors.sol";
|
|
||||||
import "../storage/LibOwnableStorage.sol";
|
|
||||||
import "../storage/LibMigrateStorage.sol";
|
|
||||||
import "../migrations/LibMigrate.sol";
|
|
||||||
import "../migrations/LibBootstrap.sol";
|
|
||||||
import "./IFeature.sol";
|
|
||||||
import "./IMigrate.sol";
|
|
||||||
import "./ISimpleFunctionRegistry.sol";
|
|
||||||
|
|
||||||
|
|
||||||
/// @dev Migration features.
|
|
||||||
contract Migrate is
|
|
||||||
IFeature,
|
|
||||||
IMigrate,
|
|
||||||
FixinOwnable
|
|
||||||
{
|
|
||||||
// solhint-disable const-name-snakecase
|
|
||||||
|
|
||||||
/// @dev Name of this feature.
|
|
||||||
string constant public override FEATURE_NAME = "Migrate";
|
|
||||||
/// @dev Version of this feature.
|
|
||||||
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
|
||||||
|
|
||||||
/// @dev Initializes this feature.
|
|
||||||
/// @param impl The actual address of this feature contract.
|
|
||||||
/// @return success Magic bytes if successful.
|
|
||||||
function bootstrap(address impl) external returns (bytes4 success) {
|
|
||||||
// Register feature functions.
|
|
||||||
ISimpleFunctionRegistry(address(this)).extend(this.migrate.selector, impl);
|
|
||||||
ISimpleFunctionRegistry(address(this)).extend(this.getMigrationOwner.selector, impl);
|
|
||||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Execute a migration function in the context of the ZeroEx contract.
|
|
||||||
/// The result of the function being called should be the magic bytes
|
|
||||||
/// 0x2c64c5ef (`keccack('MIGRATE_SUCCESS')`). Only callable by the owner.
|
|
||||||
/// The owner will be temporarily set to `address(this)` inside the call.
|
|
||||||
/// The original owner can be retrieved through `getMigrationOwner()`.`
|
|
||||||
/// @param target The migrator contract address.
|
|
||||||
/// @param data The call data.
|
|
||||||
function migrate(address target, bytes calldata data)
|
|
||||||
external
|
|
||||||
override
|
|
||||||
onlyOwner
|
|
||||||
{
|
|
||||||
LibOwnableStorage.Storage storage ownableStor = LibOwnableStorage.getStorage();
|
|
||||||
LibMigrateStorage.Storage storage stor = LibMigrateStorage.getStorage();
|
|
||||||
address prevOwner = ownableStor.owner;
|
|
||||||
if (prevOwner == address(this)) {
|
|
||||||
// If the owner is already set to ourselves then we've reentered.
|
|
||||||
_rrevert(LibMigrateRichErrors.AlreadyMigratingError());
|
|
||||||
}
|
|
||||||
// Temporarily set the owner to ourselves to enable admin functions.
|
|
||||||
ownableStor.owner = address(this);
|
|
||||||
stor.migrationOwner = prevOwner;
|
|
||||||
|
|
||||||
// Perform the migration.
|
|
||||||
LibMigrate.delegatecallMigrateFunction(target, data);
|
|
||||||
|
|
||||||
// Restore the owner.
|
|
||||||
ownableStor.owner = prevOwner;
|
|
||||||
stor.migrationOwner = address(0);
|
|
||||||
|
|
||||||
emit Migrated(msg.sender, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Get the true owner of this contract during a migration.
|
|
||||||
/// @return owner The true owner of this contract.
|
|
||||||
function getMigrationOwner() external override view returns (address owner) {
|
|
||||||
return LibMigrateStorage.getStorage().migrationOwner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,6 +23,7 @@ import "../fixins/FixinOwnable.sol";
|
|||||||
import "../errors/LibOwnableRichErrors.sol";
|
import "../errors/LibOwnableRichErrors.sol";
|
||||||
import "../storage/LibOwnableStorage.sol";
|
import "../storage/LibOwnableStorage.sol";
|
||||||
import "../migrations/LibBootstrap.sol";
|
import "../migrations/LibBootstrap.sol";
|
||||||
|
import "../migrations/LibMigrate.sol";
|
||||||
import "./IFeature.sol";
|
import "./IFeature.sol";
|
||||||
import "./IOwnable.sol";
|
import "./IOwnable.sol";
|
||||||
import "./ISimpleFunctionRegistry.sol";
|
import "./ISimpleFunctionRegistry.sol";
|
||||||
@@ -34,26 +35,36 @@ contract Ownable is
|
|||||||
IOwnable,
|
IOwnable,
|
||||||
FixinOwnable
|
FixinOwnable
|
||||||
{
|
{
|
||||||
// solhint-disable const-name-snakecase
|
|
||||||
|
|
||||||
|
// solhint-disable const-name-snakecase
|
||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string constant public override FEATURE_NAME = "Ownable";
|
string constant public override FEATURE_NAME = "Ownable";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
||||||
|
// solhint-enable const-name-snakecase
|
||||||
|
|
||||||
|
// solhint-disable
|
||||||
|
/// @dev The deployed address of this contract.
|
||||||
|
address immutable private _implementation;
|
||||||
|
// solhint-enable
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
_implementation = address(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Initializes this feature. The intial owner will be set to this (ZeroEx)
|
/// @dev Initializes this feature. The intial owner will be set to this (ZeroEx)
|
||||||
/// to allow the bootstrappers to call `extend()`. Ownership should be
|
/// to allow the bootstrappers to call `extend()`. Ownership should be
|
||||||
/// transferred to the real owner by the bootstrapper after
|
/// transferred to the real owner by the bootstrapper after
|
||||||
/// bootstrapping is complete.
|
/// bootstrapping is complete.
|
||||||
/// @param impl the actual address of this feature contract.
|
|
||||||
/// @return success Magic bytes if successful.
|
/// @return success Magic bytes if successful.
|
||||||
function bootstrap(address impl) external returns (bytes4 success) {
|
function bootstrap() external returns (bytes4 success) {
|
||||||
// Set the owner to ourselves to allow bootstrappers to call `extend()`.
|
// Set the owner to ourselves to allow bootstrappers to call `extend()`.
|
||||||
LibOwnableStorage.getStorage().owner = address(this);
|
LibOwnableStorage.getStorage().owner = address(this);
|
||||||
|
|
||||||
// Register feature functions.
|
// Register feature functions.
|
||||||
ISimpleFunctionRegistry(address(this)).extend(this.transferOwnership.selector, impl);
|
ISimpleFunctionRegistry(address(this)).extend(this.transferOwnership.selector, _implementation);
|
||||||
ISimpleFunctionRegistry(address(this)).extend(this.getOwner.selector, impl);
|
ISimpleFunctionRegistry(address(this)).extend(this.getOwner.selector, _implementation);
|
||||||
|
ISimpleFunctionRegistry(address(this)).extend(this.migrate.selector, _implementation);
|
||||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +86,37 @@ contract Ownable is
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @dev Execute a migration function in the context of the ZeroEx contract.
|
||||||
|
/// The result of the function being called should be the magic bytes
|
||||||
|
/// 0x2c64c5ef (`keccack('MIGRATE_SUCCESS')`). Only callable by the owner.
|
||||||
|
/// The owner will be temporarily set to `address(this)` inside the call.
|
||||||
|
/// Before returning, the owner will be set to `newOwner`.
|
||||||
|
/// @param target The migrator contract address.
|
||||||
|
/// @param data The call data.
|
||||||
|
/// @param newOwner The address of the new owner.
|
||||||
|
function migrate(address target, bytes calldata data, address newOwner)
|
||||||
|
external
|
||||||
|
override
|
||||||
|
onlyOwner
|
||||||
|
{
|
||||||
|
LibOwnableStorage.Storage storage stor = LibOwnableStorage.getStorage();
|
||||||
|
address prevOwner = stor.owner;
|
||||||
|
if (prevOwner == address(this)) {
|
||||||
|
// If the owner is already set to ourselves then we've reentered.
|
||||||
|
_rrevert(LibOwnableRichErrors.AlreadyMigratingError());
|
||||||
|
}
|
||||||
|
// Temporarily set the owner to ourselves so we can perform admin functions.
|
||||||
|
stor.owner = address(this);
|
||||||
|
|
||||||
|
// Perform the migration.
|
||||||
|
LibMigrate.delegatecallMigrateFunction(target, data);
|
||||||
|
|
||||||
|
// Update the owner.
|
||||||
|
stor.owner = newOwner;
|
||||||
|
|
||||||
|
emit Migrated(msg.sender, target, newOwner);
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Get the owner of this contract.
|
/// @dev Get the owner of this contract.
|
||||||
/// @return owner_ The owner of this contract.
|
/// @return owner_ The owner of this contract.
|
||||||
function getOwner() external override view returns (address owner_) {
|
function getOwner() external override view returns (address owner_) {
|
||||||
|
|||||||
@@ -34,12 +34,22 @@ contract SimpleFunctionRegistry is
|
|||||||
ISimpleFunctionRegistry,
|
ISimpleFunctionRegistry,
|
||||||
FixinOwnable
|
FixinOwnable
|
||||||
{
|
{
|
||||||
// solhint-disable const-name-snakecase
|
|
||||||
|
|
||||||
|
// solhint-disable const-name-snakecase
|
||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string constant public override FEATURE_NAME = "SimpleFunctionRegistry";
|
string constant public override FEATURE_NAME = "SimpleFunctionRegistry";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
||||||
|
// solhint-enable const-name-snakecase
|
||||||
|
|
||||||
|
// solhint-disable
|
||||||
|
/// @dev The deployed address of this contract.
|
||||||
|
address immutable private _implementation;
|
||||||
|
// solhint-enable
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
_implementation = address(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Initializes this feature.
|
/// @dev Initializes this feature.
|
||||||
/// @param impl The actual address of this feature contract.
|
/// @param impl The actual address of this feature contract.
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import "../ZeroEx.sol";
|
|||||||
import "../features/IBootstrap.sol";
|
import "../features/IBootstrap.sol";
|
||||||
import "../features/SimpleFunctionRegistry.sol";
|
import "../features/SimpleFunctionRegistry.sol";
|
||||||
import "../features/Ownable.sol";
|
import "../features/Ownable.sol";
|
||||||
import "../features/Migrate.sol";
|
|
||||||
import "./LibBootstrap.sol";
|
import "./LibBootstrap.sol";
|
||||||
|
|
||||||
|
|
||||||
@@ -72,13 +71,6 @@ contract InitialMigration {
|
|||||||
abi.encodeWithSelector(ownable.bootstrap.selector, address(ownable))
|
abi.encodeWithSelector(ownable.bootstrap.selector, address(ownable))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Initialize Migrate.
|
|
||||||
Migrate migrate = new Migrate();
|
|
||||||
LibBootstrap.delegatecallBootstrapFunction(
|
|
||||||
address(migrate),
|
|
||||||
abi.encodeWithSelector(migrate.bootstrap.selector, address(migrate))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Transfer ownership to the real owner.
|
// Transfer ownership to the real owner.
|
||||||
Ownable(address(this)).transferOwnership(owner);
|
Ownable(address(this)).transferOwnership(owner);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pragma solidity ^0.6.5;
|
|||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||||
import "../errors/LibMigrateRichErrors.sol";
|
import "../errors/LibOwnableRichErrors.sol";
|
||||||
|
|
||||||
|
|
||||||
library LibMigrate {
|
library LibMigrate {
|
||||||
@@ -44,7 +44,7 @@ library LibMigrate {
|
|||||||
abi.decode(resultData, (bytes4)) != MIGRATE_SUCCESS)
|
abi.decode(resultData, (bytes4)) != MIGRATE_SUCCESS)
|
||||||
{
|
{
|
||||||
LibRichErrorsV06.rrevert(
|
LibRichErrorsV06.rrevert(
|
||||||
LibMigrateRichErrors.MigrateCallFailedError(target, resultData)
|
LibOwnableRichErrors.MigrateCallFailedError(target, resultData)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2020 ZeroEx Intl.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity ^0.6.5;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import "./LibStorage.sol";
|
|
||||||
|
|
||||||
|
|
||||||
/// @dev Storage helpers for the `Migrate` feature.
|
|
||||||
library LibMigrateStorage {
|
|
||||||
|
|
||||||
/// @dev Storage bucket for this feature.
|
|
||||||
struct Storage {
|
|
||||||
// The owner of this contract prior to the `migrate()` call.
|
|
||||||
address migrationOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Get the storage bucket for this contract.
|
|
||||||
function getStorage() internal pure returns (Storage storage stor) {
|
|
||||||
uint256 storageOffset = LibStorage.getStorageOffset(
|
|
||||||
LibStorage.StorageId.Migrate
|
|
||||||
);
|
|
||||||
assembly { stor_slot := storageOffset }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,8 +33,7 @@ library LibStorage {
|
|||||||
Unused, // Unused buffer for state accidents.
|
Unused, // Unused buffer for state accidents.
|
||||||
Proxy,
|
Proxy,
|
||||||
SimpleFunctionRegistry,
|
SimpleFunctionRegistry,
|
||||||
Ownable,
|
Ownable
|
||||||
Migrate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Get the storage offset given a storage ID.
|
/// @dev Get the storage offset given a storage ID.
|
||||||
|
|||||||
@@ -21,21 +21,18 @@ pragma experimental ABIEncoderV2;
|
|||||||
|
|
||||||
import "../src/migrations/LibMigrate.sol";
|
import "../src/migrations/LibMigrate.sol";
|
||||||
import "../src/features/IOwnable.sol";
|
import "../src/features/IOwnable.sol";
|
||||||
import "../src/features/IMigrate.sol";
|
|
||||||
|
|
||||||
|
|
||||||
contract TestMigrator {
|
contract TestMigrator {
|
||||||
event TestMigrateCalled(
|
event TestMigrateCalled(
|
||||||
bytes callData,
|
bytes callData,
|
||||||
address owner,
|
address owner
|
||||||
address actualOwner
|
|
||||||
);
|
);
|
||||||
|
|
||||||
function succeedingMigrate() external returns (bytes4 success) {
|
function succeedingMigrate() external returns (bytes4 success) {
|
||||||
emit TestMigrateCalled(
|
emit TestMigrateCalled(
|
||||||
msg.data,
|
msg.data,
|
||||||
IOwnable(address(this)).getOwner(),
|
IOwnable(address(this)).getOwner()
|
||||||
IMigrate(address(this)).getMigrationOwner()
|
|
||||||
);
|
);
|
||||||
return LibMigrate.MIGRATE_SUCCESS;
|
return LibMigrate.MIGRATE_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -43,8 +40,7 @@ contract TestMigrator {
|
|||||||
function failingMigrate() external returns (bytes4 success) {
|
function failingMigrate() external returns (bytes4 success) {
|
||||||
emit TestMigrateCalled(
|
emit TestMigrateCalled(
|
||||||
msg.data,
|
msg.data,
|
||||||
IOwnable(address(this)).getOwner(),
|
IOwnable(address(this)).getOwner()
|
||||||
IMigrate(address(this)).getMigrationOwner()
|
|
||||||
);
|
);
|
||||||
return 0xdeadbeef;
|
return 0xdeadbeef;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,9 +38,9 @@
|
|||||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "ZeroEx,IMigrate,IOwnable,ISimpleFunctionRegistry",
|
"publicInterfaceContracts": "ZeroEx,IOwnable,ISimpleFunctionRegistry",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||||
"abis": "./test/generated-artifacts/@(Bootstrap|FixinCommon|FixinOwnable|IBootstrap|IFeature|IMigrate|IOwnable|ISimpleFunctionRegistry|ITestSimpleFunctionRegistryFeature|InitialMigration|LibBootstrap|LibCommonRichErrors|LibMigrate|LibMigrateRichErrors|LibMigrateStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|Migrate|Ownable|SimpleFunctionRegistry|TestInitialMigration|TestMigrator|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestZeroExFeature|ZeroEx).json"
|
"abis": "./test/generated-artifacts/@(Bootstrap|FixinCommon|FixinOwnable|IBootstrap|IFeature|IOwnable|ISimpleFunctionRegistry|ITestSimpleFunctionRegistryFeature|InitialMigration|LibBootstrap|LibCommonRichErrors|LibMigrate|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|Ownable|SimpleFunctionRegistry|TestInitialMigration|TestMigrator|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestZeroExFeature|ZeroEx).json"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -5,13 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
import { ContractArtifact } from 'ethereum-types';
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
import * as IMigrate from '../generated-artifacts/IMigrate.json';
|
|
||||||
import * as IOwnable from '../generated-artifacts/IOwnable.json';
|
import * as IOwnable from '../generated-artifacts/IOwnable.json';
|
||||||
import * as ISimpleFunctionRegistry from '../generated-artifacts/ISimpleFunctionRegistry.json';
|
import * as ISimpleFunctionRegistry from '../generated-artifacts/ISimpleFunctionRegistry.json';
|
||||||
import * as ZeroEx from '../generated-artifacts/ZeroEx.json';
|
import * as ZeroEx from '../generated-artifacts/ZeroEx.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ZeroEx: ZeroEx as ContractArtifact,
|
ZeroEx: ZeroEx as ContractArtifact,
|
||||||
IMigrate: IMigrate as ContractArtifact,
|
|
||||||
IOwnable: IOwnable as ContractArtifact,
|
IOwnable: IOwnable as ContractArtifact,
|
||||||
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
export * from '../generated-wrappers/i_migrate';
|
|
||||||
export * from '../generated-wrappers/i_ownable';
|
export * from '../generated-wrappers/i_ownable';
|
||||||
export * from '../generated-wrappers/i_simple_function_registry';
|
export * from '../generated-wrappers/i_simple_function_registry';
|
||||||
export * from '../generated-wrappers/zero_ex';
|
export * from '../generated-wrappers/zero_ex';
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json';
|
|||||||
import * as FixinOwnable from '../test/generated-artifacts/FixinOwnable.json';
|
import * as FixinOwnable from '../test/generated-artifacts/FixinOwnable.json';
|
||||||
import * as IBootstrap from '../test/generated-artifacts/IBootstrap.json';
|
import * as IBootstrap from '../test/generated-artifacts/IBootstrap.json';
|
||||||
import * as IFeature from '../test/generated-artifacts/IFeature.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 InitialMigration from '../test/generated-artifacts/InitialMigration.json';
|
||||||
import * as IOwnable from '../test/generated-artifacts/IOwnable.json';
|
import * as IOwnable from '../test/generated-artifacts/IOwnable.json';
|
||||||
import * as ISimpleFunctionRegistry from '../test/generated-artifacts/ISimpleFunctionRegistry.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 LibBootstrap from '../test/generated-artifacts/LibBootstrap.json';
|
||||||
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
|
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
|
||||||
import * as LibMigrate from '../test/generated-artifacts/LibMigrate.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 LibOwnableRichErrors from '../test/generated-artifacts/LibOwnableRichErrors.json';
|
||||||
import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorage.json';
|
import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorage.json';
|
||||||
import * as LibProxyRichErrors from '../test/generated-artifacts/LibProxyRichErrors.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 LibSimpleFunctionRegistryRichErrors from '../test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json';
|
||||||
import * as LibSimpleFunctionRegistryStorage from '../test/generated-artifacts/LibSimpleFunctionRegistryStorage.json';
|
import * as LibSimpleFunctionRegistryStorage from '../test/generated-artifacts/LibSimpleFunctionRegistryStorage.json';
|
||||||
import * as LibStorage from '../test/generated-artifacts/LibStorage.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 Ownable from '../test/generated-artifacts/Ownable.json';
|
||||||
import * as SimpleFunctionRegistry from '../test/generated-artifacts/SimpleFunctionRegistry.json';
|
import * as SimpleFunctionRegistry from '../test/generated-artifacts/SimpleFunctionRegistry.json';
|
||||||
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.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 = {
|
export const artifacts = {
|
||||||
ZeroEx: ZeroEx as ContractArtifact,
|
ZeroEx: ZeroEx as ContractArtifact,
|
||||||
LibCommonRichErrors: LibCommonRichErrors as ContractArtifact,
|
LibCommonRichErrors: LibCommonRichErrors as ContractArtifact,
|
||||||
LibMigrateRichErrors: LibMigrateRichErrors as ContractArtifact,
|
|
||||||
LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact,
|
LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact,
|
||||||
LibProxyRichErrors: LibProxyRichErrors as ContractArtifact,
|
LibProxyRichErrors: LibProxyRichErrors as ContractArtifact,
|
||||||
LibSimpleFunctionRegistryRichErrors: LibSimpleFunctionRegistryRichErrors as ContractArtifact,
|
LibSimpleFunctionRegistryRichErrors: LibSimpleFunctionRegistryRichErrors as ContractArtifact,
|
||||||
Bootstrap: Bootstrap as ContractArtifact,
|
Bootstrap: Bootstrap as ContractArtifact,
|
||||||
IBootstrap: IBootstrap as ContractArtifact,
|
IBootstrap: IBootstrap as ContractArtifact,
|
||||||
IFeature: IFeature as ContractArtifact,
|
IFeature: IFeature as ContractArtifact,
|
||||||
IMigrate: IMigrate as ContractArtifact,
|
|
||||||
IOwnable: IOwnable as ContractArtifact,
|
IOwnable: IOwnable as ContractArtifact,
|
||||||
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
||||||
Migrate: Migrate as ContractArtifact,
|
|
||||||
Ownable: Ownable as ContractArtifact,
|
Ownable: Ownable as ContractArtifact,
|
||||||
SimpleFunctionRegistry: SimpleFunctionRegistry as ContractArtifact,
|
SimpleFunctionRegistry: SimpleFunctionRegistry as ContractArtifact,
|
||||||
FixinCommon: FixinCommon as ContractArtifact,
|
FixinCommon: FixinCommon as ContractArtifact,
|
||||||
@@ -57,7 +50,6 @@ export const artifacts = {
|
|||||||
InitialMigration: InitialMigration as ContractArtifact,
|
InitialMigration: InitialMigration as ContractArtifact,
|
||||||
LibBootstrap: LibBootstrap as ContractArtifact,
|
LibBootstrap: LibBootstrap as ContractArtifact,
|
||||||
LibMigrate: LibMigrate as ContractArtifact,
|
LibMigrate: LibMigrate as ContractArtifact,
|
||||||
LibMigrateStorage: LibMigrateStorage as ContractArtifact,
|
|
||||||
LibOwnableStorage: LibOwnableStorage as ContractArtifact,
|
LibOwnableStorage: LibOwnableStorage as ContractArtifact,
|
||||||
LibProxyStorage: LibProxyStorage as ContractArtifact,
|
LibProxyStorage: LibProxyStorage as ContractArtifact,
|
||||||
LibSimpleFunctionRegistryStorage: LibSimpleFunctionRegistryStorage as ContractArtifact,
|
LibSimpleFunctionRegistryStorage: LibSimpleFunctionRegistryStorage as ContractArtifact,
|
||||||
|
|||||||
@@ -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(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,18 +1,34 @@
|
|||||||
import { blockchainTests, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
import { blockchainTests, expect, LogDecoder, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||||
import { OwnableRevertErrors } from '@0x/utils';
|
import { hexUtils, OwnableRevertErrors, StringRevertError, ZeroExRevertErrors } from '@0x/utils';
|
||||||
|
|
||||||
|
import { artifacts } from '../artifacts';
|
||||||
import { initialMigrateAsync } from '../utils/migration';
|
import { initialMigrateAsync } from '../utils/migration';
|
||||||
import { IOwnableContract, IOwnableEvents } from '../wrappers';
|
import { IOwnableContract, IOwnableEvents, TestMigratorContract, TestMigratorEvents } from '../wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('Ownable feature', env => {
|
blockchainTests.resets('Ownable feature', env => {
|
||||||
const notOwner = randomAddress();
|
const notOwner = randomAddress();
|
||||||
let owner: string;
|
let owner: string;
|
||||||
let ownable: IOwnableContract;
|
let ownable: IOwnableContract;
|
||||||
|
let testMigrator: TestMigratorContract;
|
||||||
|
let succeedingMigrateFnCallData: string;
|
||||||
|
let failingMigrateFnCallData: string;
|
||||||
|
let revertingMigrateFnCallData: string;
|
||||||
|
let logDecoder: LogDecoder;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
[owner] = await env.getAccountAddressesAsync();
|
[owner] = await env.getAccountAddressesAsync();
|
||||||
|
logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
|
||||||
const zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
|
const zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
|
||||||
ownable = new IOwnableContract(zeroEx.address, 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()', () => {
|
describe('transferOwnership()', () => {
|
||||||
@@ -38,4 +54,57 @@ blockchainTests.resets('Ownable feature', env => {
|
|||||||
expect(await ownable.getOwner().callAsync()).to.eq(newOwner);
|
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(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ export * from '../test/generated-wrappers/fixin_common';
|
|||||||
export * from '../test/generated-wrappers/fixin_ownable';
|
export * from '../test/generated-wrappers/fixin_ownable';
|
||||||
export * from '../test/generated-wrappers/i_bootstrap';
|
export * from '../test/generated-wrappers/i_bootstrap';
|
||||||
export * from '../test/generated-wrappers/i_feature';
|
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_ownable';
|
||||||
export * from '../test/generated-wrappers/i_simple_function_registry';
|
export * from '../test/generated-wrappers/i_simple_function_registry';
|
||||||
export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
|
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_bootstrap';
|
||||||
export * from '../test/generated-wrappers/lib_common_rich_errors';
|
export * from '../test/generated-wrappers/lib_common_rich_errors';
|
||||||
export * from '../test/generated-wrappers/lib_migrate';
|
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_rich_errors';
|
||||||
export * from '../test/generated-wrappers/lib_ownable_storage';
|
export * from '../test/generated-wrappers/lib_ownable_storage';
|
||||||
export * from '../test/generated-wrappers/lib_proxy_rich_errors';
|
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_rich_errors';
|
||||||
export * from '../test/generated-wrappers/lib_simple_function_registry_storage';
|
export * from '../test/generated-wrappers/lib_simple_function_registry_storage';
|
||||||
export * from '../test/generated-wrappers/lib_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/ownable';
|
||||||
export * from '../test/generated-wrappers/simple_function_registry';
|
export * from '../test/generated-wrappers/simple_function_registry';
|
||||||
export * from '../test/generated-wrappers/test_initial_migration';
|
export * from '../test/generated-wrappers/test_initial_migration';
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": [
|
"files": [
|
||||||
"generated-artifacts/IMigrate.json",
|
|
||||||
"generated-artifacts/IOwnable.json",
|
"generated-artifacts/IOwnable.json",
|
||||||
"generated-artifacts/ISimpleFunctionRegistry.json",
|
"generated-artifacts/ISimpleFunctionRegistry.json",
|
||||||
"generated-artifacts/ZeroEx.json",
|
"generated-artifacts/ZeroEx.json",
|
||||||
@@ -12,7 +11,6 @@
|
|||||||
"test/generated-artifacts/FixinOwnable.json",
|
"test/generated-artifacts/FixinOwnable.json",
|
||||||
"test/generated-artifacts/IBootstrap.json",
|
"test/generated-artifacts/IBootstrap.json",
|
||||||
"test/generated-artifacts/IFeature.json",
|
"test/generated-artifacts/IFeature.json",
|
||||||
"test/generated-artifacts/IMigrate.json",
|
|
||||||
"test/generated-artifacts/IOwnable.json",
|
"test/generated-artifacts/IOwnable.json",
|
||||||
"test/generated-artifacts/ISimpleFunctionRegistry.json",
|
"test/generated-artifacts/ISimpleFunctionRegistry.json",
|
||||||
"test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
|
"test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
|
||||||
@@ -20,8 +18,6 @@
|
|||||||
"test/generated-artifacts/LibBootstrap.json",
|
"test/generated-artifacts/LibBootstrap.json",
|
||||||
"test/generated-artifacts/LibCommonRichErrors.json",
|
"test/generated-artifacts/LibCommonRichErrors.json",
|
||||||
"test/generated-artifacts/LibMigrate.json",
|
"test/generated-artifacts/LibMigrate.json",
|
||||||
"test/generated-artifacts/LibMigrateRichErrors.json",
|
|
||||||
"test/generated-artifacts/LibMigrateStorage.json",
|
|
||||||
"test/generated-artifacts/LibOwnableRichErrors.json",
|
"test/generated-artifacts/LibOwnableRichErrors.json",
|
||||||
"test/generated-artifacts/LibOwnableStorage.json",
|
"test/generated-artifacts/LibOwnableStorage.json",
|
||||||
"test/generated-artifacts/LibProxyRichErrors.json",
|
"test/generated-artifacts/LibProxyRichErrors.json",
|
||||||
@@ -29,7 +25,6 @@
|
|||||||
"test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json",
|
"test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json",
|
||||||
"test/generated-artifacts/LibSimpleFunctionRegistryStorage.json",
|
"test/generated-artifacts/LibSimpleFunctionRegistryStorage.json",
|
||||||
"test/generated-artifacts/LibStorage.json",
|
"test/generated-artifacts/LibStorage.json",
|
||||||
"test/generated-artifacts/Migrate.json",
|
|
||||||
"test/generated-artifacts/Ownable.json",
|
"test/generated-artifacts/Ownable.json",
|
||||||
"test/generated-artifacts/SimpleFunctionRegistry.json",
|
"test/generated-artifacts/SimpleFunctionRegistry.json",
|
||||||
"test/generated-artifacts/TestInitialMigration.json",
|
"test/generated-artifacts/TestInitialMigration.json",
|
||||||
|
|||||||
Reference in New Issue
Block a user