@0x/contracts-zero-ex: Allow any call target to bootstrap().

This commit is contained in:
Lawrence Forman 2020-04-16 14:07:22 -04:00
parent 12f2250ab5
commit 220039ab00
5 changed files with 15 additions and 19 deletions

View File

@ -39,11 +39,10 @@ contract ZeroEx {
/// @dev Construct this contract and set the bootstrap migration contract. /// @dev Construct this contract and set the bootstrap migration contract.
/// After constructing this contract, `bootstrap()` should be called /// After constructing this contract, `bootstrap()` should be called
/// to seed the initial feature set. /// to seed the initial feature set.
/// @param bootstrapper The bootstrap migration contract. constructor() public {
constructor(address bootstrapper) public {
// Temporarily create and register the bootstrap feature. // Temporarily create and register the bootstrap feature.
// It will deregister itself after `bootstrap()` has been called. // It will deregister itself after `bootstrap()` has been called.
Bootstrap bootstrap = new Bootstrap(msg.sender, bootstrapper); Bootstrap bootstrap = new Bootstrap(msg.sender);
LibProxyStorage.getStorage().impls[bootstrap.bootstrap.selector] = LibProxyStorage.getStorage().impls[bootstrap.bootstrap.selector] =
address(bootstrap); address(bootstrap);
} }

View File

@ -40,28 +40,24 @@ contract Bootstrap is
/// @dev The deployer. /// @dev The deployer.
/// This has to be immutable to persist across delegatecalls. /// This has to be immutable to persist across delegatecalls.
address immutable private _bootstrapCaller; 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 // solhint-enable state-visibility,indent
/// @dev Construct this contract and set the bootstrap migration contract. /// @dev Construct this contract and set the bootstrap migration contract.
/// After constructing this contract, `bootstrap()` should be called /// After constructing this contract, `bootstrap()` should be called
/// to seed the initial feature set. /// to seed the initial feature set.
/// @param bootstrapCaller The allowed caller of `bootstrap()`. /// @param bootstrapCaller The allowed caller of `bootstrap()`.
/// @param bootstrapper The bootstrap migration contract. constructor(address bootstrapCaller) public {
constructor(address bootstrapCaller, address bootstrapper) public {
_deployer = msg.sender; _deployer = msg.sender;
_implementation = address(this); _implementation = address(this);
_bootstrapCaller = bootstrapCaller; _bootstrapCaller = bootstrapCaller;
_bootstrapper = bootstrapper;
} }
/// @dev Bootstrap the initial feature set of this contract by delegatecalling /// @dev Bootstrap the initial feature set of this contract by delegatecalling
/// into `_bootstrapper`. Before exiting the `bootstrap()` function will /// into `_bootstrapper`. Before exiting the `bootstrap()` function will
/// deregister itself from the proxy to prevent being called again. /// deregister itself from the proxy to prevent being called again.
/// @param target The bootstrapper contract address.
/// @param callData The call data to execute on `_bootstrapper`. /// @param callData The call data to execute on `_bootstrapper`.
function bootstrap(bytes calldata callData) external override { function bootstrap(address target, bytes calldata callData) external override {
// Only the bootstrap caller can call this function. // Only the bootstrap caller can call this function.
if (msg.sender != _bootstrapCaller) { if (msg.sender != _bootstrapCaller) {
_rrevert(LibProxyRichErrors.InvalidBootstrapCallerError( _rrevert(LibProxyRichErrors.InvalidBootstrapCallerError(
@ -69,7 +65,7 @@ contract Bootstrap is
_bootstrapCaller _bootstrapCaller
)); ));
} }
LibBootstrap.delegatecallBootstrapFunction(_bootstrapper, callData); LibBootstrap.delegatecallBootstrapFunction(target, callData);
// Deregister. // Deregister.
LibProxyStorage.getStorage().impls[this.bootstrap.selector] = address(0); LibProxyStorage.getStorage().impls[this.bootstrap.selector] = address(0);
// Self-destruct. // Self-destruct.
@ -77,7 +73,7 @@ contract Bootstrap is
} }
/// @dev Self-destructs this contract. /// @dev Self-destructs this contract.
/// Can only be called by the ZeroEx contract. /// Can only be called by the deployer.
function die() external { function die() external {
if (msg.sender != _deployer) { if (msg.sender != _deployer) {
_rrevert(LibProxyRichErrors.InvalidDieCallerError(msg.sender, _deployer)); _rrevert(LibProxyRichErrors.InvalidDieCallerError(msg.sender, _deployer));

View File

@ -26,6 +26,7 @@ interface IBootstrap {
/// @dev Bootstrap the initial feature set of this contract by delegatecalling /// @dev Bootstrap the initial feature set of this contract by delegatecalling
/// into `_bootstrapper`. Before exiting the `bootstrap()` function will /// into `_bootstrapper`. Before exiting the `bootstrap()` function will
/// deregister itself from the proxy to prevent being called again. /// deregister itself from the proxy to prevent being called again.
/// @param target The bootstrapper contract address.
/// @param callData The call data to execute on `_bootstrapper`. /// @param callData The call data to execute on `_bootstrapper`.
function bootstrap(bytes calldata callData) external; function bootstrap(address target, bytes calldata callData) external;
} }

View File

@ -41,13 +41,13 @@ contract InitialMigration {
require(address(_zeroEx) == address(0), "InitialMigration/ALREADY_DEPLOYED"); require(address(_zeroEx) == address(0), "InitialMigration/ALREADY_DEPLOYED");
// Deploy the ZeroEx contract, setting ourselves as the bootstrapper. // Deploy the ZeroEx contract, setting ourselves as the bootstrapper.
zeroEx = _zeroEx = new ZeroEx(address(this)); zeroEx = _zeroEx = new ZeroEx();
// Bootstrap the initial feature set. // Bootstrap the initial feature set.
IBootstrap(address(zeroEx)).bootstrap(abi.encodeWithSelector( IBootstrap(address(zeroEx)).bootstrap(
this.bootstrap.selector, address(this),
owner abi.encodeWithSelector(this.bootstrap.selector, owner)
)); );
} }
/// @dev Sets up the initial state of the `ZeroEx` contract. /// @dev Sets up the initial state of the `ZeroEx` contract.

View File

@ -30,7 +30,7 @@ contract TestInitialMigration is
address public bootstrapFeature; address public bootstrapFeature;
function callBootstrap(ZeroEx zeroEx) external { function callBootstrap(ZeroEx zeroEx) external {
IBootstrap(address(zeroEx)).bootstrap(new bytes(0)); IBootstrap(address(zeroEx)).bootstrap(address(this), new bytes(0));
} }
function getCodeSizeOf(address target) external view returns (uint256 codeSize) { function getCodeSizeOf(address target) external view returns (uint256 codeSize) {