@0x/contracts-zero-ex
: bootstrap()
is now a temporary feature, registered in the ZeroEx constructor.
`@0x/contracts-zero-ex`: `bootstrap()` de-registers itself and self-destructs once it's called. `@0x/contracts-zero-ex`: `bootstrap()` now takes arbitrary call data, but the callee is fixed in an immutable. `@0x/contracts-zero-ex`: `bootstrap()` caller is fixed in an immutable. `@0x/contracts-zero-ex`: `bootstrap()` only calls a single target. `@0x/contracts-zero-ex`: Renamed `BasicMigration` to `InitialMigration`. `@0x/contracts-zero-ex`: `InitialMigration` is now the bootstrap target and multiplexes to the initial features. `@0x/contracts-zero-ex`: Add `Migrate` feature and tests. `@0x/contracts-zero-ex`: Re-organize contract locatins (remove `interfaces` folder).
This commit is contained in:
parent
0c33aa16a1
commit
12f2250ab5
@ -20,7 +20,8 @@ pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "./interfaces/IZeroExBootstrapper.sol";
|
||||
import "./migrations/LibBootstrap.sol";
|
||||
import "./features/Bootstrap.sol";
|
||||
import "./storage/LibProxyStorage.sol";
|
||||
import "./errors/LibProxyRichErrors.sol";
|
||||
|
||||
@ -28,17 +29,23 @@ import "./errors/LibProxyRichErrors.sol";
|
||||
/// @dev An extensible proxy contract that serves as a universal entry point for
|
||||
/// interacting with the 0x protocol.
|
||||
contract ZeroEx {
|
||||
|
||||
// solhint-disable separate-by-one-line-in-contract,indent,var-name-mixedcase
|
||||
|
||||
using LibBytesV06 for bytes;
|
||||
|
||||
/// @dev Construct this contract.
|
||||
/// After constructing this contract, the deployer should call
|
||||
/// `bootstrap()` to seed the initial feature set.
|
||||
constructor() public {
|
||||
// Set the `bootstrap()` caller to the deployer.
|
||||
LibProxyStorage.getStorage().bootstrapCaller = msg.sender;
|
||||
/// @dev Magic bytes returned by the bootstrapper to indicate success.
|
||||
bytes4 internal constant BOOTSTRAP_SUCCESS = 0xd150751b;
|
||||
|
||||
/// @dev Construct this contract and set the bootstrap migration contract.
|
||||
/// After constructing this contract, `bootstrap()` should be called
|
||||
/// to seed the initial feature set.
|
||||
/// @param bootstrapper The bootstrap migration contract.
|
||||
constructor(address bootstrapper) public {
|
||||
// Temporarily create and register the bootstrap feature.
|
||||
// It will deregister itself after `bootstrap()` has been called.
|
||||
Bootstrap bootstrap = new Bootstrap(msg.sender, bootstrapper);
|
||||
LibProxyStorage.getStorage().impls[bootstrap.bootstrap.selector] =
|
||||
address(bootstrap);
|
||||
}
|
||||
|
||||
// solhint-disable state-visibility
|
||||
@ -63,40 +70,6 @@ contract ZeroEx {
|
||||
|
||||
// solhint-enable state-visibility
|
||||
|
||||
/// @dev Bootstrap the initial feature set of this contract.
|
||||
/// This can only be called once by the deployer of this contract.
|
||||
/// @param bootstrappers Array of bootstrapping contracts to delegatecall into.
|
||||
function bootstrap(IZeroExBootstrapper[] calldata bootstrappers) external {
|
||||
LibProxyStorage.Storage storage stor = LibProxyStorage.getStorage();
|
||||
|
||||
// If `bootstrapCaller` is zero, the contract has already been bootstrapped.
|
||||
address bootstrapCaller = stor.bootstrapCaller;
|
||||
if (bootstrapCaller == address(0)) {
|
||||
_revertWithData(LibProxyRichErrors.AlreadyBootstrappedError());
|
||||
}
|
||||
// Only the deployer caller can call this function.
|
||||
if (bootstrapCaller != msg.sender) {
|
||||
_revertWithData(
|
||||
LibProxyRichErrors.InvalidBootstrapCallerError(msg.sender, bootstrapCaller)
|
||||
);
|
||||
}
|
||||
// Prevent calling `bootstrap()` again.
|
||||
stor.bootstrapCaller = address(0);
|
||||
|
||||
// Call the bootstrap contracts.
|
||||
for (uint256 i = 0; i < bootstrappers.length; ++i) {
|
||||
// Delegatecall into the bootstrap contract.
|
||||
(bool success, bytes memory resultData) = address(bootstrappers[i])
|
||||
.delegatecall(abi.encodeWithSelector(
|
||||
IZeroExBootstrapper.bootstrap.selector,
|
||||
address(bootstrappers[i])
|
||||
));
|
||||
if (!success) {
|
||||
_revertWithData(resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Get the implementation contract of a registered function.
|
||||
/// @param selector The function selector.
|
||||
/// @return impl The implementation contract address.
|
||||
|
@ -17,17 +17,31 @@
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../src/migrations/BasicMigration.sol";
|
||||
import "../src/interfaces/IZeroExBootstrapper.sol";
|
||||
|
||||
|
||||
contract TestBasicMigration is
|
||||
BasicMigration
|
||||
{
|
||||
function callBootstrap(ZeroEx zeroEx) external {
|
||||
IZeroExBootstrapper[] memory bootstrappers;
|
||||
zeroEx.bootstrap(bootstrappers);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
@ -34,25 +34,39 @@ library LibProxyRichErrors {
|
||||
);
|
||||
}
|
||||
|
||||
function AlreadyBootstrappedError()
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("AlreadyBootstrappedError()"))
|
||||
);
|
||||
}
|
||||
|
||||
function InvalidBootstrapCallerError(address caller, address expectedCaller)
|
||||
function InvalidBootstrapCallerError(address actual, address expected)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("InvalidBootstrapCallerError(address,address)")),
|
||||
caller,
|
||||
expectedCaller
|
||||
actual,
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
function InvalidDieCallerError(address actual, address expected)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("InvalidDieCallerError(address,address)")),
|
||||
actual,
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
function BootstrapCallFailedError(address target, bytes memory resultData)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("BootstrapCallFailedError(address,bytes)")),
|
||||
target,
|
||||
resultData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
87
contracts/zero-ex/contracts/src/features/Bootstrap.sol
Normal file
87
contracts/zero-ex/contracts/src/features/Bootstrap.sol
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
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 "../migrations/LibBootstrap.sol";
|
||||
import "../fixins/FixinCommon.sol";
|
||||
import "../storage/LibProxyStorage.sol";
|
||||
import "./IBootstrap.sol";
|
||||
|
||||
|
||||
/// @dev Detachable `bootstrap()` feature.
|
||||
contract Bootstrap is
|
||||
IBootstrap,
|
||||
FixinCommon
|
||||
{
|
||||
// solhint-disable state-visibility,indent
|
||||
/// @dev The ZeroEx contract.
|
||||
/// This has to be immutable to persist across delegatecalls.
|
||||
address immutable private _deployer;
|
||||
/// @dev The implementation address of this contract.
|
||||
/// This has to be immutable to persist across delegatecalls.
|
||||
address immutable private _implementation;
|
||||
/// @dev The deployer.
|
||||
/// This has to be immutable to persist across delegatecalls.
|
||||
address immutable private _bootstrapCaller;
|
||||
/// @dev The bootstrap migrator.
|
||||
/// This has to be immutable to persist across delegatecalls.
|
||||
address immutable private _bootstrapper;
|
||||
// solhint-enable state-visibility,indent
|
||||
|
||||
/// @dev Construct this contract and set the bootstrap migration contract.
|
||||
/// After constructing this contract, `bootstrap()` should be called
|
||||
/// to seed the initial feature set.
|
||||
/// @param bootstrapCaller The allowed caller of `bootstrap()`.
|
||||
/// @param bootstrapper The bootstrap migration contract.
|
||||
constructor(address bootstrapCaller, address bootstrapper) public {
|
||||
_deployer = msg.sender;
|
||||
_implementation = address(this);
|
||||
_bootstrapCaller = bootstrapCaller;
|
||||
_bootstrapper = bootstrapper;
|
||||
}
|
||||
|
||||
/// @dev Bootstrap the initial feature set of this contract by delegatecalling
|
||||
/// into `_bootstrapper`. Before exiting the `bootstrap()` function will
|
||||
/// deregister itself from the proxy to prevent being called again.
|
||||
/// @param callData The call data to execute on `_bootstrapper`.
|
||||
function bootstrap(bytes calldata callData) external override {
|
||||
// Only the bootstrap caller can call this function.
|
||||
if (msg.sender != _bootstrapCaller) {
|
||||
_rrevert(LibProxyRichErrors.InvalidBootstrapCallerError(
|
||||
msg.sender,
|
||||
_bootstrapCaller
|
||||
));
|
||||
}
|
||||
LibBootstrap.delegatecallBootstrapFunction(_bootstrapper, callData);
|
||||
// Deregister.
|
||||
LibProxyStorage.getStorage().impls[this.bootstrap.selector] = address(0);
|
||||
// Self-destruct.
|
||||
Bootstrap(_implementation).die();
|
||||
}
|
||||
|
||||
/// @dev Self-destructs this contract.
|
||||
/// Can only be called by the ZeroEx contract.
|
||||
function die() external {
|
||||
if (msg.sender != _deployer) {
|
||||
_rrevert(LibProxyRichErrors.InvalidDieCallerError(msg.sender, _deployer));
|
||||
}
|
||||
selfdestruct(msg.sender);
|
||||
}
|
||||
}
|
@ -20,13 +20,12 @@ pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
/// @dev Interface for a bootstrapping contract that the `ZeroEx` proxy.
|
||||
interface IZeroExBootstrapper {
|
||||
/// @dev Detachable `bootstrap()` feature.
|
||||
interface IBootstrap {
|
||||
|
||||
/// @dev Sets up the initial state of the `ZeroEx` contract.
|
||||
/// The `ZeroEx` contract will delegatecall this function so the
|
||||
/// bootstrapper should use this function to register initial
|
||||
/// features.
|
||||
/// @param impl The implementation contract.
|
||||
function bootstrap(address impl) external;
|
||||
/// @dev Bootstrap the initial feature set of this contract by delegatecalling
|
||||
/// into `_bootstrapper`. Before exiting the `bootstrap()` function will
|
||||
/// deregister itself from the proxy to prevent being called again.
|
||||
/// @param callData The call data to execute on `_bootstrapper`.
|
||||
function bootstrap(bytes calldata callData) external;
|
||||
}
|
43
contracts/zero-ex/contracts/src/features/IMigrate.sol
Normal file
43
contracts/zero-ex/contracts/src/features/IMigrate.sol
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
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. 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);
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../interfaces/IZeroExBootstrapper.sol";
|
||||
|
||||
|
||||
/// @dev Basic registry management features.
|
||||
interface ISimpleFunctionRegistry {
|
||||
@ -41,12 +39,6 @@ interface ISimpleFunctionRegistry {
|
||||
/// @param impl The implementation contract for the function.
|
||||
function extend(bytes4 selector, address impl) external;
|
||||
|
||||
/// @dev Register or replace a function.
|
||||
/// Only callable from within.
|
||||
/// @param selector The function selector.
|
||||
/// @param impl The implementation contract for the function.
|
||||
function extendSelf(bytes4 selector, address impl) external;
|
||||
|
||||
/// @dev Retrieve the length of the rollback history for a function.
|
||||
/// @param selector The function selector.
|
||||
/// @return rollbackLength The number of items in the rollback history for
|
94
contracts/zero-ex/contracts/src/features/Migrate.sol
Normal file
94
contracts/zero-ex/contracts/src/features/Migrate.sol
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
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. 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.
|
||||
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;
|
||||
}
|
||||
}
|
@ -20,19 +20,18 @@ pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../fixins/FixinOwnable.sol";
|
||||
import "../interfaces/IFeature.sol";
|
||||
import "../interfaces/IOwnable.sol";
|
||||
import "../interfaces/ISimpleFunctionRegistry.sol";
|
||||
import "../interfaces/IZeroExBootstrapper.sol";
|
||||
import "../errors/LibOwnableRichErrors.sol";
|
||||
import "../storage/LibOwnableStorage.sol";
|
||||
import "../migrations/LibBootstrap.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./IOwnable.sol";
|
||||
import "./ISimpleFunctionRegistry.sol";
|
||||
|
||||
|
||||
/// @dev Owner management features.
|
||||
contract Ownable is
|
||||
IFeature,
|
||||
IOwnable,
|
||||
IZeroExBootstrapper,
|
||||
FixinOwnable
|
||||
{
|
||||
// solhint-disable const-name-snakecase
|
||||
@ -42,15 +41,20 @@ contract Ownable is
|
||||
/// @dev Version of this feature.
|
||||
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
||||
|
||||
/// @dev Initializes the authority feature.
|
||||
/// @param impl The actual address of this feature contract.
|
||||
function bootstrap(address impl) external override {
|
||||
/// @dev Initializes this feature. The intial owner will be set to this (ZeroEx)
|
||||
/// to allow the bootstrappers to call `extend()`. Ownership should be
|
||||
/// transferred to the real owner by the bootstrapper after
|
||||
/// bootstrapping is complete.
|
||||
/// @param impl the actual address of this feature contract.
|
||||
/// @return success Magic bytes if successful.
|
||||
function bootstrap(address impl) external returns (bytes4 success) {
|
||||
// Set the owner.
|
||||
LibOwnableStorage.getStorage().owner = msg.sender;
|
||||
LibOwnableStorage.getStorage().owner = address(this);
|
||||
|
||||
// Register feature functions.
|
||||
ISimpleFunctionRegistry(address(this)).extendSelf(this.transferOwnership.selector, impl);
|
||||
ISimpleFunctionRegistry(address(this)).extendSelf(this.getOwner.selector, impl);
|
||||
ISimpleFunctionRegistry(address(this)).extend(this.transferOwnership.selector, impl);
|
||||
ISimpleFunctionRegistry(address(this)).extend(this.getOwner.selector, impl);
|
||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev Change the owner of this contract.
|
||||
|
@ -19,20 +19,19 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../interfaces/IFeature.sol";
|
||||
import "../interfaces/ISimpleFunctionRegistry.sol";
|
||||
import "../interfaces/IZeroExBootstrapper.sol";
|
||||
import "../fixins/FixinOwnable.sol";
|
||||
import "../storage/LibProxyStorage.sol";
|
||||
import "../storage/LibSimpleFunctionRegistryStorage.sol";
|
||||
import "../errors/LibSimpleFunctionRegistryRichErrors.sol";
|
||||
import "../migrations/LibBootstrap.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./ISimpleFunctionRegistry.sol";
|
||||
|
||||
|
||||
/// @dev Basic registry management features.
|
||||
contract SimpleFunctionRegistry is
|
||||
IFeature,
|
||||
ISimpleFunctionRegistry,
|
||||
IZeroExBootstrapper,
|
||||
FixinOwnable
|
||||
{
|
||||
// solhint-disable const-name-snakecase
|
||||
@ -42,17 +41,18 @@ contract SimpleFunctionRegistry is
|
||||
/// @dev Version of this feature.
|
||||
uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0);
|
||||
|
||||
/// @dev Initializes the feature implementation registry.
|
||||
/// @dev Initializes this feature.
|
||||
/// @param impl The actual address of this feature contract.
|
||||
function bootstrap(address impl) external override {
|
||||
/// @return success Magic bytes if successful.
|
||||
function bootstrap(address impl) external returns (bytes4 success) {
|
||||
// Register the registration functions (inception vibes).
|
||||
_extend(this.extend.selector, impl);
|
||||
_extend(this.extendSelf.selector, impl);
|
||||
// Register the rollback function.
|
||||
_extend(this.rollback.selector, impl);
|
||||
// Register getters.
|
||||
_extend(this.getRollbackLength.selector, impl);
|
||||
_extend(this.getRollbackEntryAtIndex.selector, impl);
|
||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev Roll back to a prior implementation of a function.
|
||||
@ -108,18 +108,6 @@ contract SimpleFunctionRegistry is
|
||||
_extend(selector, impl);
|
||||
}
|
||||
|
||||
/// @dev Register or replace a function.
|
||||
/// Only callable from within.
|
||||
/// @param selector The function selector.
|
||||
/// @param impl The implementation contract for the function.
|
||||
function extendSelf(bytes4 selector, address impl)
|
||||
external
|
||||
override
|
||||
onlySelf
|
||||
{
|
||||
_extend(selector, impl);
|
||||
}
|
||||
|
||||
/// @dev Retrieve the length of the rollback history for a function.
|
||||
/// @param selector The function selector.
|
||||
/// @return rollbackLength The number of items in the rollback history for
|
||||
|
@ -1,70 +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 "../ZeroEx.sol";
|
||||
import "../features/SimpleFunctionRegistry.sol";
|
||||
import "../features/Ownable.sol";
|
||||
import "../interfaces/IOwnable.sol";
|
||||
import "../interfaces/IZeroExBootstrapper.sol";
|
||||
import "../interfaces/ISimpleFunctionRegistry.sol";
|
||||
|
||||
|
||||
/// @dev A contract for deploying and configuring a minimal ZeroEx contract.
|
||||
contract BasicMigration {
|
||||
|
||||
/// @dev Deploy the `ZeroEx` contract with the minimum feature set.
|
||||
/// @param owner The owner of the contract.
|
||||
/// @return zeroEx The deployed and configured `ZeroEx` contract.
|
||||
function migrate(address owner) external returns (ZeroEx zeroEx) {
|
||||
// Deploy the ZeroEx contract.
|
||||
zeroEx = new ZeroEx();
|
||||
|
||||
// Bootstrap the initial feature set.
|
||||
zeroEx.bootstrap(_createBootstrappers());
|
||||
|
||||
// Disable the `extendSelf()` function by rolling it back to zero.
|
||||
ISimpleFunctionRegistry(address(zeroEx))
|
||||
.rollback(ISimpleFunctionRegistry.extendSelf.selector, address(0));
|
||||
|
||||
// Call the _postInitialize hook.
|
||||
_postInitialize(zeroEx);
|
||||
|
||||
// Transfer ownership.
|
||||
if (owner != address(this)) {
|
||||
IOwnable(address(zeroEx)).transferOwnership(owner);
|
||||
}
|
||||
}
|
||||
|
||||
function _createBootstrappers()
|
||||
internal
|
||||
virtual
|
||||
returns (IZeroExBootstrapper[] memory bootstrappers)
|
||||
{
|
||||
bootstrappers = new IZeroExBootstrapper[](2);
|
||||
bootstrappers[0] = IZeroExBootstrapper(address(new SimpleFunctionRegistry()));
|
||||
bootstrappers[1] = IZeroExBootstrapper(address(new Ownable()));
|
||||
}
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
function _postInitialize(ZeroEx zeroEx) internal virtual {
|
||||
// Override me.
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
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 "../ZeroEx.sol";
|
||||
import "../features/IBootstrap.sol";
|
||||
import "../features/SimpleFunctionRegistry.sol";
|
||||
import "../features/Ownable.sol";
|
||||
import "../features/Migrate.sol";
|
||||
import "./LibBootstrap.sol";
|
||||
|
||||
|
||||
/// @dev A contract for deploying and configuring a minimal ZeroEx contract.
|
||||
contract InitialMigration {
|
||||
/// @dev The deployed ZereEx instance.
|
||||
ZeroEx private _zeroEx;
|
||||
|
||||
/// @dev Deploy the `ZeroEx` contract with the minimum feature set,
|
||||
/// transfers ownership to `owner`, then self-destructs.
|
||||
/// @param owner The owner of the contract.
|
||||
/// @return zeroEx The deployed and configured `ZeroEx` contract.
|
||||
function deploy(address owner) public virtual returns (ZeroEx zeroEx) {
|
||||
// Must not have already been run.
|
||||
require(address(_zeroEx) == address(0), "InitialMigration/ALREADY_DEPLOYED");
|
||||
|
||||
// Deploy the ZeroEx contract, setting ourselves as the bootstrapper.
|
||||
zeroEx = _zeroEx = new ZeroEx(address(this));
|
||||
|
||||
// Bootstrap the initial feature set.
|
||||
IBootstrap(address(zeroEx)).bootstrap(abi.encodeWithSelector(
|
||||
this.bootstrap.selector,
|
||||
owner
|
||||
));
|
||||
}
|
||||
|
||||
/// @dev Sets up the initial state of the `ZeroEx` contract.
|
||||
/// The `ZeroEx` contract will delegatecall into this function.
|
||||
/// @param owner The new owner of the ZeroEx contract.
|
||||
/// @return success Magic bytes if successful.
|
||||
function bootstrap(address owner) public virtual returns (bytes4 success) {
|
||||
// Deploy and migrate the initial features.
|
||||
// Order matters here.
|
||||
|
||||
// Initialize Registry.
|
||||
SimpleFunctionRegistry registry = new SimpleFunctionRegistry();
|
||||
LibBootstrap.delegatecallBootstrapFunction(
|
||||
address(registry),
|
||||
abi.encodeWithSelector(registry.bootstrap.selector, address(registry))
|
||||
);
|
||||
|
||||
// Initialize Ownable.
|
||||
Ownable ownable = new Ownable();
|
||||
LibBootstrap.delegatecallBootstrapFunction(
|
||||
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.
|
||||
Ownable(address(this)).transferOwnership(owner);
|
||||
|
||||
success = LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||
}
|
||||
}
|
50
contracts/zero-ex/contracts/src/migrations/LibBootstrap.sol
Normal file
50
contracts/zero-ex/contracts/src/migrations/LibBootstrap.sol
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
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 "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "../errors/LibProxyRichErrors.sol";
|
||||
|
||||
|
||||
library LibBootstrap {
|
||||
|
||||
/// @dev Magic bytes returned by the bootstrapper to indicate success.
|
||||
bytes4 internal constant BOOTSTRAP_SUCCESS = 0xd150751b;
|
||||
|
||||
/// @dev Perform a delegatecall and ensure it returns the magic bytes.
|
||||
/// @param target The call target.
|
||||
/// @param data The call data.
|
||||
function delegatecallBootstrapFunction(
|
||||
address target,
|
||||
bytes memory data
|
||||
)
|
||||
internal
|
||||
{
|
||||
(bool success, bytes memory resultData) = target.delegatecall(data);
|
||||
if (!success ||
|
||||
resultData.length != 32 ||
|
||||
abi.decode(resultData, (bytes4)) != BOOTSTRAP_SUCCESS)
|
||||
{
|
||||
LibRichErrorsV06.rrevert(
|
||||
LibProxyRichErrors.BootstrapCallFailedError(target, resultData)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
50
contracts/zero-ex/contracts/src/migrations/LibMigrate.sol
Normal file
50
contracts/zero-ex/contracts/src/migrations/LibMigrate.sol
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
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 "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "../errors/LibMigrateRichErrors.sol";
|
||||
|
||||
|
||||
library LibMigrate {
|
||||
|
||||
/// @dev Magic bytes returned by a migrator to indicate success.
|
||||
bytes4 internal constant MIGRATE_SUCCESS = 0x2c64c5ef;
|
||||
|
||||
/// @dev Perform a delegatecall and ensure it returns the magic bytes.
|
||||
/// @param target The call target.
|
||||
/// @param data The call data.
|
||||
function delegatecallMigrateFunction(
|
||||
address target,
|
||||
bytes memory data
|
||||
)
|
||||
internal
|
||||
{
|
||||
(bool success, bytes memory resultData) = target.delegatecall(data);
|
||||
if (!success ||
|
||||
resultData.length != 32 ||
|
||||
abi.decode(resultData, (bytes4)) != MIGRATE_SUCCESS)
|
||||
{
|
||||
LibRichErrorsV06.rrevert(
|
||||
LibMigrateRichErrors.MigrateCallFailedError(target, resultData)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
|
||||
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 Storage helpers for the `Migrate` feature.
|
||||
library LibMigrateStorage {
|
||||
|
||||
/// @dev Globally unique offset for the storage bucket.
|
||||
bytes32 constant internal STORAGE_ID =
|
||||
0x0ed67b719caa0e9bebb7147a4de9fdb6f1c82a984b2297d741a9888432214d5c;
|
||||
|
||||
/// @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) {
|
||||
bytes32 storageId = STORAGE_ID;
|
||||
assembly { stor_slot := storageId }
|
||||
}
|
||||
}
|
@ -29,8 +29,6 @@ library LibProxyStorage {
|
||||
|
||||
/// @dev Storage bucket for proxy contract.
|
||||
struct Storage {
|
||||
// The allowed caller for `bootstrap()`.
|
||||
address bootstrapCaller;
|
||||
// Mapping of function selector -> function implementation
|
||||
mapping(bytes4 => address) impls;
|
||||
}
|
||||
|
46
contracts/zero-ex/contracts/test/TestInitialMigration.sol
Normal file
46
contracts/zero-ex/contracts/test/TestInitialMigration.sol
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
|
||||
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 "../src/ZeroEx.sol";
|
||||
import "../src/features/IBootstrap.sol";
|
||||
import "../src/migrations/InitialMigration.sol";
|
||||
|
||||
|
||||
contract TestInitialMigration is
|
||||
InitialMigration
|
||||
{
|
||||
address public bootstrapFeature;
|
||||
|
||||
function callBootstrap(ZeroEx zeroEx) external {
|
||||
IBootstrap(address(zeroEx)).bootstrap(new bytes(0));
|
||||
}
|
||||
|
||||
function getCodeSizeOf(address target) external view returns (uint256 codeSize) {
|
||||
assembly { codeSize := extcodesize(target) }
|
||||
}
|
||||
|
||||
function bootstrap(address owner) public override returns (bytes4 success) {
|
||||
success = InitialMigration.bootstrap(owner);
|
||||
// Snoop the bootstrap feature contract.
|
||||
bootstrapFeature = ZeroEx(address(uint160(address(this))))
|
||||
.getFunctionImplementation(IBootstrap.bootstrap.selector);
|
||||
}
|
||||
}
|
55
contracts/zero-ex/contracts/test/TestMigrator.sol
Normal file
55
contracts/zero-ex/contracts/test/TestMigrator.sol
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
|
||||
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 "../src/migrations/LibMigrate.sol";
|
||||
import "../src/features/IOwnable.sol";
|
||||
import "../src/features/IMigrate.sol";
|
||||
|
||||
|
||||
contract TestMigrator {
|
||||
event TestMigrateCalled(
|
||||
bytes callData,
|
||||
address owner,
|
||||
address actualOwner
|
||||
);
|
||||
|
||||
function succeedingMigrate() external returns (bytes4 success) {
|
||||
emit TestMigrateCalled(
|
||||
msg.data,
|
||||
IOwnable(address(this)).getOwner(),
|
||||
IMigrate(address(this)).getMigrationOwner()
|
||||
);
|
||||
return LibMigrate.MIGRATE_SUCCESS;
|
||||
}
|
||||
|
||||
function failingMigrate() external returns (bytes4 success) {
|
||||
emit TestMigrateCalled(
|
||||
msg.data,
|
||||
IOwnable(address(this)).getOwner(),
|
||||
IMigrate(address(this)).getMigrationOwner()
|
||||
);
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
|
||||
function revertingMigrate() external pure {
|
||||
revert("OOPSIE");
|
||||
}
|
||||
}
|
@ -38,9 +38,9 @@
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ZeroEx,IOwnable,ISimpleFunctionRegistry",
|
||||
"publicInterfaceContracts": "ZeroEx,IMigrate,IOwnable,ISimpleFunctionRegistry",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(BasicMigration|FixinCommon|FixinOwnable|IFeature|IOwnable|ISimpleFunctionRegistry|ITestSimpleFunctionRegistryFeature|IZeroExBootstrapper|LibCommonRichErrors|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|Ownable|SimpleFunctionRegistry|TestBasicMigration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestZeroExFeature|ZeroEx).json"
|
||||
"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|Migrate|Ownable|SimpleFunctionRegistry|TestInitialMigration|TestMigrator|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestZeroExFeature|ZeroEx).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -5,11 +5,13 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as IMigrate from '../generated-artifacts/IMigrate.json';
|
||||
import * as IOwnable from '../generated-artifacts/IOwnable.json';
|
||||
import * as ISimpleFunctionRegistry from '../generated-artifacts/ISimpleFunctionRegistry.json';
|
||||
import * as ZeroEx from '../generated-artifacts/ZeroEx.json';
|
||||
export const artifacts = {
|
||||
ZeroEx: ZeroEx as ContractArtifact,
|
||||
IMigrate: IMigrate as ContractArtifact,
|
||||
IOwnable: IOwnable as ContractArtifact,
|
||||
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
* 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_simple_function_registry';
|
||||
export * from '../generated-wrappers/zero_ex';
|
||||
|
@ -5,24 +5,32 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as BasicMigration from '../test/generated-artifacts/BasicMigration.json';
|
||||
import * as Bootstrap from '../test/generated-artifacts/Bootstrap.json';
|
||||
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';
|
||||
import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json';
|
||||
import * as IZeroExBootstrapper from '../test/generated-artifacts/IZeroExBootstrapper.json';
|
||||
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';
|
||||
import * as LibProxyStorage from '../test/generated-artifacts/LibProxyStorage.json';
|
||||
import * as LibSimpleFunctionRegistryRichErrors from '../test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json';
|
||||
import * as LibSimpleFunctionRegistryStorage from '../test/generated-artifacts/LibSimpleFunctionRegistryStorage.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 TestBasicMigration from '../test/generated-artifacts/TestBasicMigration.json';
|
||||
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
|
||||
import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
|
||||
import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json';
|
||||
import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json';
|
||||
import * as TestZeroExFeature from '../test/generated-artifacts/TestZeroExFeature.json';
|
||||
@ -30,23 +38,31 @@ 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,
|
||||
FixinOwnable: FixinOwnable as ContractArtifact,
|
||||
IFeature: IFeature as ContractArtifact,
|
||||
IOwnable: IOwnable as ContractArtifact,
|
||||
ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact,
|
||||
IZeroExBootstrapper: IZeroExBootstrapper as ContractArtifact,
|
||||
BasicMigration: BasicMigration as ContractArtifact,
|
||||
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,
|
||||
ITestSimpleFunctionRegistryFeature: ITestSimpleFunctionRegistryFeature as ContractArtifact,
|
||||
TestBasicMigration: TestBasicMigration as ContractArtifact,
|
||||
TestInitialMigration: TestInitialMigration as ContractArtifact,
|
||||
TestMigrator: TestMigrator as ContractArtifact,
|
||||
TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact,
|
||||
TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact,
|
||||
TestZeroExFeature: TestZeroExFeature as ContractArtifact,
|
||||
|
@ -1,62 +0,0 @@
|
||||
import { blockchainTests, expect, randomAddress } from '@0x/contracts-test-utils';
|
||||
import { hexUtils, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import {
|
||||
IOwnableContract,
|
||||
ISimpleFunctionRegistryContract,
|
||||
TestBasicMigrationContract,
|
||||
ZeroExContract,
|
||||
} from './wrappers';
|
||||
|
||||
blockchainTests.resets('Basic migration', env => {
|
||||
let owner: string;
|
||||
let zeroEx: ZeroExContract;
|
||||
let migrator: TestBasicMigrationContract;
|
||||
|
||||
before(async () => {
|
||||
[owner] = await env.getAccountAddressesAsync();
|
||||
migrator = await TestBasicMigrationContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestBasicMigration,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
const migrateCall = migrator.migrate(owner);
|
||||
zeroEx = new ZeroExContract(await migrateCall.callAsync(), env.provider, env.txDefaults);
|
||||
await migrateCall.awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
describe('bootstrapping', () => {
|
||||
it('Migrator cannot call bootstrap() again', async () => {
|
||||
const tx = migrator.callBootstrap(zeroEx.address).awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith(new ZeroExRevertErrors.Proxy.AlreadyBootstrappedError());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Ownable feature', () => {
|
||||
let ownable: IOwnableContract;
|
||||
|
||||
before(async () => {
|
||||
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
it('has the correct owner', async () => {
|
||||
const actualOwner = await ownable.getOwner().callAsync();
|
||||
expect(actualOwner).to.eq(owner);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Registry feature', () => {
|
||||
let registry: ISimpleFunctionRegistryContract;
|
||||
|
||||
before(async () => {
|
||||
registry = new ISimpleFunctionRegistryContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
it('`extendSelf()` is unregistered', async () => {
|
||||
const tx = registry.extendSelf(hexUtils.random(4), randomAddress()).callAsync();
|
||||
return expect(tx).to.revertWith(new ZeroExRevertErrors.Proxy.NotImplementedError());
|
||||
});
|
||||
});
|
||||
});
|
94
contracts/zero-ex/test/features/migrate_test.ts
Normal file
94
contracts/zero-ex/test/features/migrate_test.ts
Normal file
@ -0,0 +1,94 @@
|
||||
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,30 +1,30 @@
|
||||
import { blockchainTests, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { OwnableRevertErrors } from '@0x/utils';
|
||||
|
||||
import { basicMigrateAsync } from '../utils/migration';
|
||||
import { initialMigrateAsync } from '../utils/migration';
|
||||
import { IOwnableContract, IOwnableEvents } from '../wrappers';
|
||||
|
||||
blockchainTests.resets('Ownable feature', env => {
|
||||
const notOwner = randomAddress();
|
||||
let owner: string;
|
||||
let auth: IOwnableContract;
|
||||
let ownable: IOwnableContract;
|
||||
|
||||
before(async () => {
|
||||
[owner] = await env.getAccountAddressesAsync();
|
||||
const zeroEx = await basicMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
auth = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
const zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
describe('transferOwnership()', () => {
|
||||
it('non-owner cannot transfer ownership', async () => {
|
||||
const newOwner = randomAddress();
|
||||
const tx = auth.transferOwnership(newOwner).callAsync({ from: notOwner });
|
||||
const tx = ownable.transferOwnership(newOwner).callAsync({ from: notOwner });
|
||||
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner));
|
||||
});
|
||||
|
||||
it('owner can transfer ownership', async () => {
|
||||
const newOwner = randomAddress();
|
||||
const receipt = await auth.transferOwnership(newOwner).awaitTransactionSuccessAsync({ from: owner });
|
||||
const receipt = await ownable.transferOwnership(newOwner).awaitTransactionSuccessAsync({ from: owner });
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
@ -35,7 +35,7 @@ blockchainTests.resets('Ownable feature', env => {
|
||||
],
|
||||
IOwnableEvents.OwnershipTransferred,
|
||||
);
|
||||
expect(await auth.getOwner().callAsync()).to.eq(newOwner);
|
||||
expect(await ownable.getOwner().callAsync()).to.eq(newOwner);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import { blockchainTests, constants, expect, randomAddress, verifyEventsFromLogs
|
||||
import { BigNumber, hexUtils, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { basicMigrateAsync } from '../utils/migration';
|
||||
import { initialMigrateAsync } from '../utils/migration';
|
||||
import {
|
||||
ISimpleFunctionRegistryContract,
|
||||
ISimpleFunctionRegistryEvents,
|
||||
@ -25,7 +25,7 @@ blockchainTests.resets('SimpleFunctionRegistry feature', env => {
|
||||
|
||||
before(async () => {
|
||||
[owner] = await env.getAccountAddressesAsync();
|
||||
zeroEx = await basicMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
registry = new ISimpleFunctionRegistryContract(zeroEx.address, env.provider, {
|
||||
...env.txDefaults,
|
||||
from: owner,
|
||||
|
57
contracts/zero-ex/test/initial_migration_test.ts
Normal file
57
contracts/zero-ex/test/initial_migration_test.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { blockchainTests, expect } from '@0x/contracts-test-utils';
|
||||
import { ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { IBootstrapContract, IOwnableContract, TestInitialMigrationContract, ZeroExContract } from './wrappers';
|
||||
|
||||
blockchainTests.resets('Initial migration', env => {
|
||||
let owner: string;
|
||||
let zeroEx: ZeroExContract;
|
||||
let migrator: TestInitialMigrationContract;
|
||||
let bootstrapFeature: IBootstrapContract;
|
||||
|
||||
before(async () => {
|
||||
[owner] = await env.getAccountAddressesAsync();
|
||||
migrator = await TestInitialMigrationContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestInitialMigration,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
bootstrapFeature = new IBootstrapContract(
|
||||
await migrator.bootstrapFeature().callAsync(),
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
);
|
||||
const deployCall = migrator.deploy(owner);
|
||||
zeroEx = new ZeroExContract(await deployCall.callAsync(), env.provider, env.txDefaults);
|
||||
await deployCall.awaitTransactionSuccessAsync();
|
||||
});
|
||||
|
||||
describe('bootstrapping', () => {
|
||||
it('Migrator cannot call bootstrap() again', async () => {
|
||||
const tx = migrator.callBootstrap(zeroEx.address).awaitTransactionSuccessAsync();
|
||||
const selector = bootstrapFeature.getSelector('bootstrap');
|
||||
return expect(tx).to.revertWith(new ZeroExRevertErrors.Proxy.NotImplementedError(selector));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Ownable feature', () => {
|
||||
let ownable: IOwnableContract;
|
||||
|
||||
before(async () => {
|
||||
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
it('has the correct owner', async () => {
|
||||
const actualOwner = await ownable.getOwner().callAsync();
|
||||
expect(actualOwner).to.eq(owner);
|
||||
});
|
||||
});
|
||||
|
||||
it('bootstrap feature self destructs after deployment', async () => {
|
||||
const codeSize = await migrator.getCodeSizeOf(bootstrapFeature.address).callAsync();
|
||||
expect(codeSize).to.bignumber.eq(0);
|
||||
});
|
||||
});
|
@ -2,22 +2,22 @@ import { SupportedProvider } from '@0x/subproviders';
|
||||
import { TxData } from 'ethereum-types';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { BasicMigrationContract, ZeroExContract } from '../wrappers';
|
||||
import { InitialMigrationContract, ZeroExContract } from '../wrappers';
|
||||
|
||||
// tslint:disable: completed-docs
|
||||
export async function basicMigrateAsync(
|
||||
export async function initialMigrateAsync(
|
||||
owner: string,
|
||||
provider: SupportedProvider,
|
||||
txDefaults: Partial<TxData>,
|
||||
): Promise<ZeroExContract> {
|
||||
const migrator = await BasicMigrationContract.deployFrom0xArtifactAsync(
|
||||
artifacts.BasicMigration,
|
||||
const migrator = await InitialMigrationContract.deployFrom0xArtifactAsync(
|
||||
artifacts.InitialMigration,
|
||||
provider,
|
||||
txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
const migrateCall = migrator.migrate(owner);
|
||||
const zeroEx = new ZeroExContract(await migrateCall.callAsync(), provider, {});
|
||||
await migrateCall.awaitTransactionSuccessAsync();
|
||||
const deployCall = migrator.deploy(owner);
|
||||
const zeroEx = new ZeroExContract(await deployCall.callAsync(), provider, {});
|
||||
await deployCall.awaitTransactionSuccessAsync();
|
||||
return zeroEx;
|
||||
}
|
||||
|
@ -3,24 +3,32 @@
|
||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../test/generated-wrappers/basic_migration';
|
||||
export * from '../test/generated-wrappers/bootstrap';
|
||||
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';
|
||||
export * from '../test/generated-wrappers/i_zero_ex_bootstrapper';
|
||||
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';
|
||||
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/migrate';
|
||||
export * from '../test/generated-wrappers/ownable';
|
||||
export * from '../test/generated-wrappers/simple_function_registry';
|
||||
export * from '../test/generated-wrappers/test_basic_migration';
|
||||
export * from '../test/generated-wrappers/test_initial_migration';
|
||||
export * from '../test/generated-wrappers/test_migrator';
|
||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1';
|
||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2';
|
||||
export * from '../test/generated-wrappers/test_zero_ex_feature';
|
||||
|
@ -2,7 +2,7 @@ import { blockchainTests, constants, expect, verifyEventsFromLogs } from '@0x/co
|
||||
import { BigNumber, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { basicMigrateAsync } from './utils/migration';
|
||||
import { initialMigrateAsync } from './utils/migration';
|
||||
import {
|
||||
IFeatureContract,
|
||||
IOwnableContract,
|
||||
@ -21,7 +21,7 @@ blockchainTests.resets('ZeroEx contract', env => {
|
||||
|
||||
before(async () => {
|
||||
[owner] = await env.getAccountAddressesAsync();
|
||||
zeroEx = await basicMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults);
|
||||
ownable = new IOwnableContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
registry = new ISimpleFunctionRegistryContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
testFeature = new TestZeroExFeatureContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
|
@ -3,27 +3,36 @@
|
||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": [
|
||||
"generated-artifacts/IMigrate.json",
|
||||
"generated-artifacts/IOwnable.json",
|
||||
"generated-artifacts/ISimpleFunctionRegistry.json",
|
||||
"generated-artifacts/ZeroEx.json",
|
||||
"test/generated-artifacts/BasicMigration.json",
|
||||
"test/generated-artifacts/Bootstrap.json",
|
||||
"test/generated-artifacts/FixinCommon.json",
|
||||
"test/generated-artifacts/FixinOwnable.json",
|
||||
"test/generated-artifacts/IBootstrap.json",
|
||||
"test/generated-artifacts/IFeature.json",
|
||||
"test/generated-artifacts/IMigrate.json",
|
||||
"test/generated-artifacts/IOwnable.json",
|
||||
"test/generated-artifacts/ISimpleFunctionRegistry.json",
|
||||
"test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
|
||||
"test/generated-artifacts/IZeroExBootstrapper.json",
|
||||
"test/generated-artifacts/InitialMigration.json",
|
||||
"test/generated-artifacts/LibBootstrap.json",
|
||||
"test/generated-artifacts/LibCommonRichErrors.json",
|
||||
"test/generated-artifacts/LibMigrate.json",
|
||||
"test/generated-artifacts/LibMigrateRichErrors.json",
|
||||
"test/generated-artifacts/LibMigrateStorage.json",
|
||||
"test/generated-artifacts/LibOwnableRichErrors.json",
|
||||
"test/generated-artifacts/LibOwnableStorage.json",
|
||||
"test/generated-artifacts/LibProxyRichErrors.json",
|
||||
"test/generated-artifacts/LibProxyStorage.json",
|
||||
"test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json",
|
||||
"test/generated-artifacts/LibSimpleFunctionRegistryStorage.json",
|
||||
"test/generated-artifacts/Migrate.json",
|
||||
"test/generated-artifacts/Ownable.json",
|
||||
"test/generated-artifacts/SimpleFunctionRegistry.json",
|
||||
"test/generated-artifacts/TestBasicMigration.json",
|
||||
"test/generated-artifacts/TestInitialMigration.json",
|
||||
"test/generated-artifacts/TestMigrator.json",
|
||||
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json",
|
||||
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json",
|
||||
"test/generated-artifacts/TestZeroExFeature.json",
|
||||
|
Loading…
x
Reference in New Issue
Block a user