@0x/contracts-zero-ex`: Create ZeroEx (proxy) contracts
This commit is contained in:
		
							
								
								
									
										10
									
								
								contracts/zero-ex/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								contracts/zero-ex/.npmignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | # Blacklist all files | ||||||
|  | .* | ||||||
|  | * | ||||||
|  | # Whitelist lib | ||||||
|  | !lib/**/* | ||||||
|  | # Whitelist Solidity contracts | ||||||
|  | !contracts/src/**/* | ||||||
|  | # Blacklist tests in lib | ||||||
|  | /lib/test/* | ||||||
|  | # Package specific ignore | ||||||
							
								
								
									
										11
									
								
								contracts/zero-ex/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								contracts/zero-ex/CHANGELOG.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | [ | ||||||
|  |     { | ||||||
|  |         "version": "0.1.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Create this package", | ||||||
|  |                 "pr": 2540 | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | ] | ||||||
							
								
								
									
										6
									
								
								contracts/zero-ex/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								contracts/zero-ex/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | <!-- | ||||||
|  | changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly. | ||||||
|  | Edit the package's CHANGELOG.json file only. | ||||||
|  | --> | ||||||
|  |  | ||||||
|  | CHANGELOG | ||||||
							
								
								
									
										1
									
								
								contracts/zero-ex/DEPLOYS.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								contracts/zero-ex/DEPLOYS.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | [] | ||||||
							
								
								
									
										65
									
								
								contracts/zero-ex/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								contracts/zero-ex/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | ## ERC20BridgeSampler | ||||||
|  |  | ||||||
|  | This package contains contracts contracts for the ZeroEx extensible contract architecture. | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | **Install** | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | npm install @0x/contracts-zero-ex --save | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Contributing | ||||||
|  |  | ||||||
|  | We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository. | ||||||
|  |  | ||||||
|  | For proposals regarding the 0x protocol's smart contract architecture, message format, or additional functionality, go to the [0x Improvement Proposals (ZEIPs)](https://github.com/0xProject/ZEIPs) repository and follow the contribution guidelines provided therein. | ||||||
|  |  | ||||||
|  | Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. | ||||||
|  |  | ||||||
|  | ### Install Dependencies | ||||||
|  |  | ||||||
|  | If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | yarn config set workspaces-experimental true | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Then install dependencies | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | yarn install | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Build | ||||||
|  |  | ||||||
|  | To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | PKG=@0x/contracts-zero-ex yarn build | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Or continuously rebuild on change: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | PKG=@0x/contracts-zero-ex yarn watch | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Clean | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | yarn clean | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Lint | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | yarn lint | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Run Tests | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | yarn test | ||||||
|  | ``` | ||||||
							
								
								
									
										27
									
								
								contracts/zero-ex/compiler.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								contracts/zero-ex/compiler.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  |     "artifactsDir": "./test/generated-artifacts", | ||||||
|  |     "contractsDir": "./contracts", | ||||||
|  |     "useDockerisedSolc": false, | ||||||
|  |     "isOfflineMode": false, | ||||||
|  |     "shouldSaveStandardInput": true, | ||||||
|  |     "compilerSettings": { | ||||||
|  |         "evmVersion": "istanbul", | ||||||
|  |         "optimizer": { | ||||||
|  |             "enabled": true, | ||||||
|  |             "runs": 1000000, | ||||||
|  |             "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } | ||||||
|  |         }, | ||||||
|  |         "outputSelection": { | ||||||
|  |             "*": { | ||||||
|  |                 "*": [ | ||||||
|  |                     "abi", | ||||||
|  |                     "devdoc", | ||||||
|  |                     "evm.bytecode.object", | ||||||
|  |                     "evm.bytecode.sourceMap", | ||||||
|  |                     "evm.deployedBytecode.object", | ||||||
|  |                     "evm.deployedBytecode.sourceMap" | ||||||
|  |                 ] | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										122
									
								
								contracts/zero-ex/contracts/src/ZeroEx.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								contracts/zero-ex/contracts/src/ZeroEx.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/LibBytesV06.sol"; | ||||||
|  | import "./interfaces/IZeroExBootstrapper.sol"; | ||||||
|  | import "./storage/LibProxyStorage.sol"; | ||||||
|  | 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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // solhint-disable state-visibility | ||||||
|  |  | ||||||
|  |     /// @dev Forwards calls to the appropriate implementation contract. | ||||||
|  |     fallback() external payable { | ||||||
|  |         bytes4 selector = msg.data.readBytes4(0); | ||||||
|  |         address impl = getFunctionImplementation(selector); | ||||||
|  |         if (impl == address(0)) { | ||||||
|  |             _revertWithData(LibProxyRichErrors.NotImplementedError(selector)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         (bool success, bytes memory resultData) = impl.delegatecall(msg.data); | ||||||
|  |         if (!success) { | ||||||
|  |             _revertWithData(resultData); | ||||||
|  |         } | ||||||
|  |         _returnWithData(resultData); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Fallback for just receiving ether. | ||||||
|  |     receive() external payable {} | ||||||
|  |  | ||||||
|  |     // 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. | ||||||
|  |     function getFunctionImplementation(bytes4 selector) | ||||||
|  |         public | ||||||
|  |         view | ||||||
|  |         returns (address impl) | ||||||
|  |     { | ||||||
|  |         return LibProxyStorage.getStorage().impls[selector]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Revert with arbitrary bytes. | ||||||
|  |     /// @param data Revert data. | ||||||
|  |     function _revertWithData(bytes memory data) private pure { | ||||||
|  |         assembly { revert(add(data, 32), mload(data)) } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Return with arbitrary bytes. | ||||||
|  |     /// @param data Return data. | ||||||
|  |     function _returnWithData(bytes memory data) private pure { | ||||||
|  |         assembly { return(add(data, 32), mload(data)) } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,36 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 LibCommonRichErrors { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     function OnlyCallableBySelfError(address sender) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("OnlyCallableBySelfError(address)")), | ||||||
|  |             sender | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -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; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | library LibOwnableRichErrors { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     function OnlyOwnerError( | ||||||
|  |         address sender, | ||||||
|  |         address owner | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("OnlyOwnerError(address,address)")), | ||||||
|  |             sender, | ||||||
|  |             owner | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function TransferOwnerToZeroError() | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("TransferOwnerToZeroError()")) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,58 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 LibProxyRichErrors { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     function NotImplementedError(bytes4 selector) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("NotImplementedError(bytes4)")), | ||||||
|  |             selector | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function AlreadyBootstrappedError() | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("AlreadyBootstrappedError()")) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function InvalidBootstrapCallerError(address caller, address expectedCaller) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("InvalidBootstrapCallerError(address,address)")), | ||||||
|  |             caller, | ||||||
|  |             expectedCaller | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 LibSimpleFunctionRegistryRichErrors { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     function NoRollbackHistoryError( | ||||||
|  |         bytes4 selector | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("NoRollbackHistoryError(bytes4)")), | ||||||
|  |             selector | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										79
									
								
								contracts/zero-ex/contracts/src/features/Ownable.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								contracts/zero-ex/contracts/src/features/Ownable.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 "../interfaces/IFeature.sol"; | ||||||
|  | import "../interfaces/IOwnable.sol"; | ||||||
|  | import "../interfaces/ISimpleFunctionRegistry.sol"; | ||||||
|  | import "../interfaces/IZeroExBootstrapper.sol"; | ||||||
|  | import "../errors/LibOwnableRichErrors.sol"; | ||||||
|  | import "../storage/LibOwnableStorage.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Owner management features. | ||||||
|  | contract Ownable is | ||||||
|  |     IFeature, | ||||||
|  |     IOwnable, | ||||||
|  |     IZeroExBootstrapper, | ||||||
|  |     FixinOwnable | ||||||
|  | { | ||||||
|  |     // solhint-disable const-name-snakecase | ||||||
|  |  | ||||||
|  |     /// @dev Name of this feature. | ||||||
|  |     string constant public override FEATURE_NAME = "Ownable"; | ||||||
|  |     /// @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 { | ||||||
|  |         // Set the owner. | ||||||
|  |         LibOwnableStorage.getStorage().owner = msg.sender; | ||||||
|  |  | ||||||
|  |         // Register feature functions. | ||||||
|  |         ISimpleFunctionRegistry(address(this)).extendSelf(this.transferOwnership.selector, impl); | ||||||
|  |         ISimpleFunctionRegistry(address(this)).extendSelf(this.getOwner.selector, impl); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Change the owner of this contract. | ||||||
|  |     ///      Only directly callable by the owner. | ||||||
|  |     /// @param newOwner New owner address. | ||||||
|  |     function transferOwnership(address newOwner) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         onlyOwner | ||||||
|  |     { | ||||||
|  |         LibOwnableStorage.Storage storage proxyStor = LibOwnableStorage.getStorage(); | ||||||
|  |  | ||||||
|  |         if (newOwner == address(0)) { | ||||||
|  |             _rrevert(LibOwnableRichErrors.TransferOwnerToZeroError()); | ||||||
|  |         } else { | ||||||
|  |             proxyStor.owner = newOwner; | ||||||
|  |             emit OwnershipTransferred(msg.sender, newOwner); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the owner of this contract. | ||||||
|  |     /// @return owner_ The owner of this contract. | ||||||
|  |     function getOwner() external override view returns (address owner_) { | ||||||
|  |         return LibOwnableStorage.getStorage().owner; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,139 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 "../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"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Basic registry management features. | ||||||
|  | contract SimpleFunctionRegistry is | ||||||
|  |     IFeature, | ||||||
|  |     ISimpleFunctionRegistry, | ||||||
|  |     IZeroExBootstrapper, | ||||||
|  |     FixinOwnable | ||||||
|  | { | ||||||
|  |     // solhint-disable const-name-snakecase | ||||||
|  |  | ||||||
|  |     /// @dev Name of this feature. | ||||||
|  |     string constant public override FEATURE_NAME = "SimpleFunctionRegistry"; | ||||||
|  |     /// @dev Version of this feature. | ||||||
|  |     uint256 constant public override FEATURE_VERSION = (1 << 64) | (0 << 32) | (0); | ||||||
|  |  | ||||||
|  |     /// @dev Initializes the feature implementation registry. | ||||||
|  |     /// @param impl The actual address of this feature contract. | ||||||
|  |     function bootstrap(address impl) external override { | ||||||
|  |         // 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); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Roll back to the last implementation of a function. | ||||||
|  |     ///      Only directly callable by an authority. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     function rollback(bytes4 selector) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         onlyOwner | ||||||
|  |     { | ||||||
|  |         ( | ||||||
|  |             LibSimpleFunctionRegistryStorage.Storage storage stor, | ||||||
|  |             LibProxyStorage.Storage storage proxyStor | ||||||
|  |         ) = _getStorages(); | ||||||
|  |  | ||||||
|  |         address[] storage history = stor.implHistory[selector]; | ||||||
|  |         if (history.length == 0) { | ||||||
|  |             _rrevert( | ||||||
|  |                 LibSimpleFunctionRegistryRichErrors.NoRollbackHistoryError(selector) | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         address impl = history[history.length - 1]; | ||||||
|  |         address oldImpl = proxyStor.impls[selector]; | ||||||
|  |         proxyStor.impls[selector] = impl; | ||||||
|  |         history.pop(); | ||||||
|  |         emit ProxyFunctionUpdated(selector, oldImpl, impl); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Register or replace a function. | ||||||
|  |     ///      Only directly callable by an authority. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     /// @param impl The implementation contract for the function. | ||||||
|  |     function extend(bytes4 selector, address impl) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         onlyOwner | ||||||
|  |     { | ||||||
|  |         _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 Register or replace a function. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     /// @param impl The implementation contract for the function. | ||||||
|  |     function _extend(bytes4 selector, address impl) | ||||||
|  |         private | ||||||
|  |     { | ||||||
|  |         ( | ||||||
|  |             LibSimpleFunctionRegistryStorage.Storage storage stor, | ||||||
|  |             LibProxyStorage.Storage storage proxyStor | ||||||
|  |         ) = _getStorages(); | ||||||
|  |  | ||||||
|  |         address oldImpl = proxyStor.impls[selector]; | ||||||
|  |         address[] storage history = stor.implHistory[selector]; | ||||||
|  |         history.push(oldImpl); | ||||||
|  |         proxyStor.impls[selector] = impl; | ||||||
|  |         emit ProxyFunctionUpdated(selector, oldImpl, impl); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage buckets for this feature and the proxy. | ||||||
|  |     /// @return stor Storage bucket for this feature. | ||||||
|  |     /// @return proxyStor age bucket for the proxy. | ||||||
|  |     function _getStorages() | ||||||
|  |         private | ||||||
|  |         pure | ||||||
|  |         returns ( | ||||||
|  |             LibSimpleFunctionRegistryStorage.Storage storage stor, | ||||||
|  |             LibProxyStorage.Storage storage proxyStor | ||||||
|  |         ) | ||||||
|  |     { | ||||||
|  |         return ( | ||||||
|  |             LibSimpleFunctionRegistryStorage.getStorage(), | ||||||
|  |             LibProxyStorage.getStorage() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								contracts/zero-ex/contracts/src/fixins/FixinCommon.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								contracts/zero-ex/contracts/src/fixins/FixinCommon.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; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol"; | ||||||
|  | import "../storage/LibProxyStorage.sol"; | ||||||
|  | import "../errors/LibCommonRichErrors.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Common utilities. | ||||||
|  | contract FixinCommon { | ||||||
|  |  | ||||||
|  |     /// @dev The caller must be this contract. | ||||||
|  |     modifier onlySelf() { | ||||||
|  |         if (msg.sender != address(this)) { | ||||||
|  |             _rrevert(LibCommonRichErrors.OnlyCallableBySelfError(msg.sender)); | ||||||
|  |         } | ||||||
|  |         _; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Reverts with arbitrary data `errorData`. | ||||||
|  |     /// @param errorData ABI encoded error data. | ||||||
|  |     function _rrevert(bytes memory errorData) internal pure { | ||||||
|  |         LibRichErrorsV06.rrevert(errorData); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								contracts/zero-ex/contracts/src/fixins/FixinOwnable.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								contracts/zero-ex/contracts/src/fixins/FixinOwnable.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 "../errors/LibOwnableRichErrors.sol"; | ||||||
|  | import "../storage/LibOwnableStorage.sol"; | ||||||
|  | import "./FixinCommon.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev A feature mixin for restricting callers to owners. | ||||||
|  | contract FixinOwnable is | ||||||
|  |     FixinCommon | ||||||
|  | { | ||||||
|  |     /// @dev The caller of this function must be the owner. | ||||||
|  |     modifier onlyOwner() { | ||||||
|  |         { | ||||||
|  |             address owner = _getOwner(); | ||||||
|  |             if (msg.sender != owner) { | ||||||
|  |                 _rrevert(LibOwnableRichErrors.OnlyOwnerError( | ||||||
|  |                     msg.sender, | ||||||
|  |                     owner | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         _; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the owner of this contract. | ||||||
|  |     /// @return owner The owner of this contract. | ||||||
|  |     function _getOwner() internal view returns (address owner) { | ||||||
|  |         return LibOwnableStorage.getStorage().owner; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								contracts/zero-ex/contracts/src/interfaces/IFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								contracts/zero-ex/contracts/src/interfaces/IFeature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 "../interfaces/IZeroExBootstrapper.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Basic interface for a feature contract. | ||||||
|  | interface IFeature { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     /// @dev The name of this feature set. | ||||||
|  |     function FEATURE_NAME() external view returns (string memory name); | ||||||
|  |  | ||||||
|  |     /// @dev The version of this feature set. | ||||||
|  |     function FEATURE_VERSION() external view returns (uint256 version); | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								contracts/zero-ex/contracts/src/interfaces/IOwnable.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								contracts/zero-ex/contracts/src/interfaces/IOwnable.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/interfaces/IOwnableV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // solhint-disable no-empty-blocks | ||||||
|  | /// @dev Owner management features. | ||||||
|  | interface IOwnable is | ||||||
|  |     IOwnableV06 | ||||||
|  | {} | ||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 "../interfaces/IZeroExBootstrapper.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Basic registry management features. | ||||||
|  | interface ISimpleFunctionRegistry { | ||||||
|  |  | ||||||
|  |     /// @dev A function implementation was updated via `extend()` or `rollback()`. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     /// @param oldImpl The implementation contract address being replaced. | ||||||
|  |     /// @param newImpl The replacement implementation contract address. | ||||||
|  |     event ProxyFunctionUpdated(bytes4 indexed selector, address oldImpl, address newImpl); | ||||||
|  |  | ||||||
|  |     /// @dev Roll back to the last implementation of a function. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     function rollback(bytes4 selector) external; | ||||||
|  |  | ||||||
|  |     /// @dev Register or replace a function. | ||||||
|  |     /// @param selector The function selector. | ||||||
|  |     /// @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; | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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 Interface for a bootstrapping contract that the `ZeroEx` proxy. | ||||||
|  | interface IZeroExBootstrapper { | ||||||
|  |  | ||||||
|  |     /// @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; | ||||||
|  | } | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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); | ||||||
|  |  | ||||||
|  |         // 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,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 `Ownable` feature. | ||||||
|  | library LibOwnableStorage { | ||||||
|  |  | ||||||
|  |     /// @dev Globally unique offset for the storage bucket. | ||||||
|  |     bytes32 constant internal STORAGE_ID = | ||||||
|  |         0xeef73acb590dd70cb88ccc8e9832ea7f198de2f3c87ff92d610497d647795b3c; | ||||||
|  |  | ||||||
|  |     /// @dev Storage bucket for this feature. | ||||||
|  |     struct Storage { | ||||||
|  |         // The owner of this contract. | ||||||
|  |         address owner; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage bucket for this contract. | ||||||
|  |     function getStorage() internal pure returns (Storage storage stor) { | ||||||
|  |         bytes32 storageId = STORAGE_ID; | ||||||
|  |         assembly { stor_slot := storageId } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								contracts/zero-ex/contracts/src/storage/LibProxyStorage.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								contracts/zero-ex/contracts/src/storage/LibProxyStorage.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 Storage helpers for the proxy contract. | ||||||
|  | library LibProxyStorage { | ||||||
|  |  | ||||||
|  |     /// @dev Globally unique offset for the storage bucket. | ||||||
|  |     bytes32 constant internal STORAGE_ID = | ||||||
|  |         0xd7434ab6df6fb6431870c66fc3fc3d21ddd20b029595942d9e0ffc950ce32f66; | ||||||
|  |  | ||||||
|  |     /// @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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage bucket for this contract. | ||||||
|  |     function getStorage() internal pure returns (Storage storage stor) { | ||||||
|  |         bytes32 storageId = STORAGE_ID; | ||||||
|  |         assembly { stor_slot := storageId } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -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 `SimpleFunctionRegistry` feature. | ||||||
|  | library LibSimpleFunctionRegistryStorage { | ||||||
|  |  | ||||||
|  |     /// @dev Globally unique offset for the storage bucket. | ||||||
|  |     bytes32 constant internal STORAGE_ID = | ||||||
|  |         0x9817e79514d088041d4834d6eb535f4fa107927bddb0f3c55c3e6b2bfe43daa5; | ||||||
|  |  | ||||||
|  |     /// @dev Storage bucket for this feature. | ||||||
|  |     struct Storage { | ||||||
|  |         // Mapping of function selector -> implementation history. | ||||||
|  |         mapping(bytes4 => address[]) implHistory; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage bucket for this contract. | ||||||
|  |     function getStorage() internal pure returns (Storage storage stor) { | ||||||
|  |         bytes32 storageId = STORAGE_ID; | ||||||
|  |         assembly { stor_slot := storageId } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface ITestSimpleFunctionRegistryFeature { | ||||||
|  |     function testFn() external view returns (uint256 id); | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								contracts/zero-ex/contracts/test/TestBasicMigration.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								contracts/zero-ex/contracts/test/TestBasicMigration.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/BasicMigration.sol"; | ||||||
|  | import "../src/interfaces/IZeroExBootstrapper.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestBasicMigration is | ||||||
|  |     BasicMigration | ||||||
|  | { | ||||||
|  |     function callBootstrap(ZeroEx zeroEx) external { | ||||||
|  |         IZeroExBootstrapper[] memory bootstrappers; | ||||||
|  |         zeroEx.bootstrap(bootstrappers); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/fixins/FixinCommon.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestSimpleFunctionRegistryFeatureImpl1 is | ||||||
|  |     FixinCommon | ||||||
|  | { | ||||||
|  |     function testFn() | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 id) | ||||||
|  |     { | ||||||
|  |         return 1337; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/fixins/FixinCommon.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestSimpleFunctionRegistryFeatureImpl2 is | ||||||
|  |     FixinCommon | ||||||
|  | { | ||||||
|  |     function testFn() | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (uint256 id) | ||||||
|  |     { | ||||||
|  |         return 1338; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								contracts/zero-ex/contracts/test/TestZeroExFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								contracts/zero-ex/contracts/test/TestZeroExFeature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | /* | ||||||
|  |  | ||||||
|  |   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/fixins/FixinCommon.sol"; | ||||||
|  | import "../src/ZeroEx.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestZeroExFeature is | ||||||
|  |     FixinCommon | ||||||
|  | { | ||||||
|  |     event PayableFnCalled(uint256 value); | ||||||
|  |     event NotPayableFnCalled(); | ||||||
|  |  | ||||||
|  |     function payableFn() | ||||||
|  |         external | ||||||
|  |         payable | ||||||
|  |     { | ||||||
|  |         emit PayableFnCalled(msg.value); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function notPayableFn() | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         emit NotPayableFnCalled(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // solhint-disable no-empty-blocks | ||||||
|  |     function unimplmentedFn() | ||||||
|  |         external | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function internalFn() | ||||||
|  |         external | ||||||
|  |         onlySelf | ||||||
|  |     {} | ||||||
|  | } | ||||||
							
								
								
									
										84
									
								
								contracts/zero-ex/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								contracts/zero-ex/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | { | ||||||
|  |     "name": "@0x/contracts-zero-ex", | ||||||
|  |     "version": "0.1.0", | ||||||
|  |     "engines": { | ||||||
|  |         "node": ">=6.12" | ||||||
|  |     }, | ||||||
|  |     "description": "Extensible contracts for interacting with the 0x protocol", | ||||||
|  |     "main": "lib/src/index.js", | ||||||
|  |     "directories": { | ||||||
|  |         "test": "test" | ||||||
|  |     }, | ||||||
|  |     "scripts": { | ||||||
|  |         "build": "yarn pre_build && tsc -b", | ||||||
|  |         "build:ci": "yarn build", | ||||||
|  |         "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy", | ||||||
|  |         "test": "yarn run_mocha", | ||||||
|  |         "rebuild_and_test": "run-s build test", | ||||||
|  |         "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", | ||||||
|  |         "test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html", | ||||||
|  |         "test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha", | ||||||
|  |         "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", | ||||||
|  |         "compile": "sol-compiler", | ||||||
|  |         "watch": "sol-compiler -w", | ||||||
|  |         "clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers", | ||||||
|  |         "generate_contract_wrappers": "abi-gen --debug --abis  ${npm_package_config_abis} --output test/generated-wrappers --backend ethers", | ||||||
|  |         "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./test/generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", | ||||||
|  |         "fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-wrappers/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts", | ||||||
|  |         "coverage:report:text": "istanbul report text", | ||||||
|  |         "coverage:report:html": "istanbul report html && open coverage/index.html", | ||||||
|  |         "profiler:report:html": "istanbul report html && open coverage/index.html", | ||||||
|  |         "coverage:report:lcov": "istanbul report lcov", | ||||||
|  |         "test:circleci": "yarn test", | ||||||
|  |         "contracts:gen": "contracts-gen generate", | ||||||
|  |         "contracts:copy": "contracts-gen copy", | ||||||
|  |         "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", | ||||||
|  |         "compile:truffle": "truffle compile", | ||||||
|  |         "docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json", | ||||||
|  |         "docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" | ||||||
|  |     }, | ||||||
|  |     "config": { | ||||||
|  |         "publicInterfaceContracts": "ZeroEx,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" | ||||||
|  |     }, | ||||||
|  |     "repository": { | ||||||
|  |         "type": "git", | ||||||
|  |         "url": "https://github.com/0xProject/0x-monorepo.git" | ||||||
|  |     }, | ||||||
|  |     "license": "Apache-2.0", | ||||||
|  |     "bugs": { | ||||||
|  |         "url": "https://github.com/0xProject/0x-monorepo/issues" | ||||||
|  |     }, | ||||||
|  |     "homepage": "https://github.com/0xProject/0x-monorepo/contracts/zero-ex/README.md", | ||||||
|  |     "devDependencies": { | ||||||
|  |         "@0x/abi-gen": "^5.2.2", | ||||||
|  |         "@0x/contracts-gen": "^2.0.8", | ||||||
|  |         "@0x/contracts-test-utils": "^5.3.2", | ||||||
|  |         "@0x/dev-utils": "^3.2.1", | ||||||
|  |         "@0x/sol-compiler": "^4.0.8", | ||||||
|  |         "@0x/subproviders": "^6.0.8", | ||||||
|  |         "@0x/ts-doc-gen": "^0.0.22", | ||||||
|  |         "@0x/tslint-config": "^4.0.0", | ||||||
|  |         "@types/lodash": "4.14.104", | ||||||
|  |         "@types/mocha": "^5.2.7", | ||||||
|  |         "mocha": "^6.2.0", | ||||||
|  |         "npm-run-all": "^4.1.2", | ||||||
|  |         "shx": "^0.2.2", | ||||||
|  |         "solhint": "^1.4.1", | ||||||
|  |         "truffle": "^5.0.32", | ||||||
|  |         "tslint": "5.11.0", | ||||||
|  |         "typedoc": "^0.15.0", | ||||||
|  |         "typescript": "3.0.1" | ||||||
|  |     }, | ||||||
|  |     "dependencies": { | ||||||
|  |         "@0x/base-contract": "^6.2.1", | ||||||
|  |         "@0x/types": "^3.1.2", | ||||||
|  |         "@0x/typescript-typings": "^5.0.2", | ||||||
|  |         "@0x/utils": "^5.4.1", | ||||||
|  |         "ethereum-types": "^3.1.0" | ||||||
|  |     }, | ||||||
|  |     "publishConfig": { | ||||||
|  |         "access": "public" | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								contracts/zero-ex/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								contracts/zero-ex/src/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | /* | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  | import { ContractArtifact } from 'ethereum-types'; | ||||||
|  |  | ||||||
|  | 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, | ||||||
|  |     IOwnable: IOwnable as ContractArtifact, | ||||||
|  |     ISimpleFunctionRegistry: ISimpleFunctionRegistry as ContractArtifact, | ||||||
|  | }; | ||||||
							
								
								
									
										38
									
								
								contracts/zero-ex/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								contracts/zero-ex/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | export { artifacts } from './artifacts'; | ||||||
|  | export { | ||||||
|  |     IOwnableContract, | ||||||
|  |     IOwnableEvents, | ||||||
|  |     ISimpleFunctionRegistryContract, | ||||||
|  |     ISimpleFunctionRegistryEvents, | ||||||
|  |     ZeroExContract, | ||||||
|  | } from './wrappers'; | ||||||
|  | export { ZeroExRevertErrors } from '@0x/utils'; | ||||||
|  | export { | ||||||
|  |     ContractArtifact, | ||||||
|  |     ContractChains, | ||||||
|  |     CompilerOpts, | ||||||
|  |     StandardContractOutput, | ||||||
|  |     CompilerSettings, | ||||||
|  |     ContractChainData, | ||||||
|  |     ContractAbi, | ||||||
|  |     DevdocOutput, | ||||||
|  |     EvmOutput, | ||||||
|  |     CompilerSettingsMetadata, | ||||||
|  |     OptimizerSettings, | ||||||
|  |     OutputField, | ||||||
|  |     ParamDescription, | ||||||
|  |     EvmBytecodeOutput, | ||||||
|  |     EvmBytecodeOutputLinkReferences, | ||||||
|  |     AbiDefinition, | ||||||
|  |     FunctionAbi, | ||||||
|  |     EventAbi, | ||||||
|  |     RevertErrorAbi, | ||||||
|  |     EventParameter, | ||||||
|  |     DataItem, | ||||||
|  |     MethodAbi, | ||||||
|  |     ConstructorAbi, | ||||||
|  |     FallbackAbi, | ||||||
|  |     ConstructorStateMutability, | ||||||
|  |     TupleDataItem, | ||||||
|  |     StateMutability, | ||||||
|  | } from 'ethereum-types'; | ||||||
							
								
								
									
										8
									
								
								contracts/zero-ex/src/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								contracts/zero-ex/src/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | /* | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  | export * from '../generated-wrappers/i_ownable'; | ||||||
|  | export * from '../generated-wrappers/i_simple_function_registry'; | ||||||
|  | export * from '../generated-wrappers/zero_ex'; | ||||||
							
								
								
									
										53
									
								
								contracts/zero-ex/test/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								contracts/zero-ex/test/artifacts.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | /* | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  | import { ContractArtifact } from 'ethereum-types'; | ||||||
|  |  | ||||||
|  | import * as BasicMigration from '../test/generated-artifacts/BasicMigration.json'; | ||||||
|  | import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json'; | ||||||
|  | import * as FixinOwnable from '../test/generated-artifacts/FixinOwnable.json'; | ||||||
|  | import * as IFeature from '../test/generated-artifacts/IFeature.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 LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.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 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 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'; | ||||||
|  | import * as ZeroEx from '../test/generated-artifacts/ZeroEx.json'; | ||||||
|  | export const artifacts = { | ||||||
|  |     ZeroEx: ZeroEx as ContractArtifact, | ||||||
|  |     LibCommonRichErrors: LibCommonRichErrors as ContractArtifact, | ||||||
|  |     LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact, | ||||||
|  |     LibProxyRichErrors: LibProxyRichErrors as ContractArtifact, | ||||||
|  |     LibSimpleFunctionRegistryRichErrors: LibSimpleFunctionRegistryRichErrors 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, | ||||||
|  |     LibOwnableStorage: LibOwnableStorage as ContractArtifact, | ||||||
|  |     LibProxyStorage: LibProxyStorage as ContractArtifact, | ||||||
|  |     LibSimpleFunctionRegistryStorage: LibSimpleFunctionRegistryStorage as ContractArtifact, | ||||||
|  |     ITestSimpleFunctionRegistryFeature: ITestSimpleFunctionRegistryFeature as ContractArtifact, | ||||||
|  |     TestBasicMigration: TestBasicMigration as ContractArtifact, | ||||||
|  |     TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact, | ||||||
|  |     TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact, | ||||||
|  |     TestZeroExFeature: TestZeroExFeature as ContractArtifact, | ||||||
|  | }; | ||||||
							
								
								
									
										62
									
								
								contracts/zero-ex/test/basic_migration_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								contracts/zero-ex/test/basic_migration_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | 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()); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										41
									
								
								contracts/zero-ex/test/features/ownable_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								contracts/zero-ex/test/features/ownable_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | import { blockchainTests, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils'; | ||||||
|  | import { OwnableRevertErrors } from '@0x/utils'; | ||||||
|  |  | ||||||
|  | import { basicMigrateAsync } from '../utils/migration'; | ||||||
|  | import { IOwnableContract, IOwnableEvents } from '../wrappers'; | ||||||
|  |  | ||||||
|  | blockchainTests.resets('Ownable feature', env => { | ||||||
|  |     const notOwner = randomAddress(); | ||||||
|  |     let owner: string; | ||||||
|  |     let auth: 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); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     describe('transferOwnership()', () => { | ||||||
|  |         it('non-owner cannot transfer ownership', async () => { | ||||||
|  |             const newOwner = randomAddress(); | ||||||
|  |             const tx = auth.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 }); | ||||||
|  |             verifyEventsFromLogs( | ||||||
|  |                 receipt.logs, | ||||||
|  |                 [ | ||||||
|  |                     { | ||||||
|  |                         previousOwner: owner, | ||||||
|  |                         newOwner, | ||||||
|  |                     }, | ||||||
|  |                 ], | ||||||
|  |                 IOwnableEvents.OwnershipTransferred, | ||||||
|  |             ); | ||||||
|  |             expect(await auth.getOwner().callAsync()).to.eq(newOwner); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										118
									
								
								contracts/zero-ex/test/features/simple_function_registry_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								contracts/zero-ex/test/features/simple_function_registry_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | |||||||
|  | import { blockchainTests, constants, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils'; | ||||||
|  | import { hexUtils, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils'; | ||||||
|  |  | ||||||
|  | import { artifacts } from '../artifacts'; | ||||||
|  | import { basicMigrateAsync } from '../utils/migration'; | ||||||
|  | import { | ||||||
|  |     ISimpleFunctionRegistryContract, | ||||||
|  |     ISimpleFunctionRegistryEvents, | ||||||
|  |     ITestSimpleFunctionRegistryFeatureContract, | ||||||
|  |     TestSimpleFunctionRegistryFeatureImpl1Contract, | ||||||
|  |     TestSimpleFunctionRegistryFeatureImpl2Contract, | ||||||
|  | } from '../wrappers'; | ||||||
|  |  | ||||||
|  | blockchainTests.resets('SimpleFunctionRegistry feature', env => { | ||||||
|  |     const { NULL_ADDRESS } = constants; | ||||||
|  |     const notOwner = randomAddress(); | ||||||
|  |     let owner: string; | ||||||
|  |     let registry: ISimpleFunctionRegistryContract; | ||||||
|  |     let testFnSelector: string; | ||||||
|  |     let testFeature: ITestSimpleFunctionRegistryFeatureContract; | ||||||
|  |     let testFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1Contract; | ||||||
|  |     let testFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2Contract; | ||||||
|  |  | ||||||
|  |     before(async () => { | ||||||
|  |         [owner] = await env.getAccountAddressesAsync(); | ||||||
|  |         const zeroEx = await basicMigrateAsync(owner, env.provider, env.txDefaults); | ||||||
|  |         registry = new ISimpleFunctionRegistryContract(zeroEx.address, env.provider, { | ||||||
|  |             ...env.txDefaults, | ||||||
|  |             from: owner, | ||||||
|  |         }); | ||||||
|  |         testFeature = new ITestSimpleFunctionRegistryFeatureContract(zeroEx.address, env.provider, env.txDefaults); | ||||||
|  |         testFnSelector = testFeature.getSelector('testFn'); | ||||||
|  |         testFeatureImpl1 = await TestSimpleFunctionRegistryFeatureImpl1Contract.deployFrom0xArtifactAsync( | ||||||
|  |             artifacts.TestSimpleFunctionRegistryFeatureImpl1, | ||||||
|  |             env.provider, | ||||||
|  |             env.txDefaults, | ||||||
|  |             artifacts, | ||||||
|  |         ); | ||||||
|  |         testFeatureImpl2 = await TestSimpleFunctionRegistryFeatureImpl2Contract.deployFrom0xArtifactAsync( | ||||||
|  |             artifacts.TestSimpleFunctionRegistryFeatureImpl2, | ||||||
|  |             env.provider, | ||||||
|  |             env.txDefaults, | ||||||
|  |             artifacts, | ||||||
|  |         ); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('`extend()` cannot be called by a non-owner', async () => { | ||||||
|  |         const tx = registry.extend(hexUtils.random(4), randomAddress()).callAsync({ from: notOwner }); | ||||||
|  |         return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner)); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('`rollback()` cannot be called by a non-owner', async () => { | ||||||
|  |         const tx = registry.rollback(hexUtils.random(4)).callAsync({ from: notOwner }); | ||||||
|  |         return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner, owner)); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('`rollback()` reverts for unregistered function', async () => { | ||||||
|  |         const tx = registry.rollback(testFnSelector).awaitTransactionSuccessAsync(); | ||||||
|  |         return expect(tx).to.revertWith( | ||||||
|  |             new ZeroExRevertErrors.SimpleFunctionRegistry.NoRollbackHistoryError(testFnSelector), | ||||||
|  |         ); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can add a new function with `extend()`', async () => { | ||||||
|  |         const { logs } = await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         verifyEventsFromLogs( | ||||||
|  |             logs, | ||||||
|  |             [{ selector: testFnSelector, oldImpl: NULL_ADDRESS, newImpl: testFeatureImpl1.address }], | ||||||
|  |             ISimpleFunctionRegistryEvents.ProxyFunctionUpdated, | ||||||
|  |         ); | ||||||
|  |         const r = await testFeature.testFn().callAsync(); | ||||||
|  |         expect(r).to.bignumber.eq(1337); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can replace add a function with `extend()`', async () => { | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl2.address).awaitTransactionSuccessAsync(); | ||||||
|  |         const r = await testFeature.testFn().callAsync(); | ||||||
|  |         expect(r).to.bignumber.eq(1338); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can unset a function with `extend()`', async () => { | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.extend(testFnSelector, constants.NULL_ADDRESS).awaitTransactionSuccessAsync(); | ||||||
|  |         return expect(testFeature.testFn().callAsync()).to.revertWith( | ||||||
|  |             new ZeroExRevertErrors.Proxy.NotImplementedError(testFnSelector), | ||||||
|  |         ); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can rollback a new function to unset', async () => { | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         const { logs } = await registry.rollback(testFnSelector).awaitTransactionSuccessAsync(); | ||||||
|  |         verifyEventsFromLogs( | ||||||
|  |             logs, | ||||||
|  |             [{ selector: testFnSelector, oldImpl: testFeatureImpl1.address, newImpl: NULL_ADDRESS }], | ||||||
|  |             ISimpleFunctionRegistryEvents.ProxyFunctionUpdated, | ||||||
|  |         ); | ||||||
|  |         return expect(testFeature.testFn().callAsync()).to.revertWith( | ||||||
|  |             new ZeroExRevertErrors.Proxy.NotImplementedError(testFnSelector), | ||||||
|  |         ); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can rollback a function to a previous version', async () => { | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl2.address).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.rollback(testFnSelector).awaitTransactionSuccessAsync(); | ||||||
|  |         const r = await testFeature.testFn().callAsync(); | ||||||
|  |         expect(r).to.bignumber.eq(1337); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('owner can rollback an unset function to a previous version', async () => { | ||||||
|  |         await registry.extend(testFnSelector, testFeatureImpl1.address).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.extend(testFnSelector, constants.NULL_ADDRESS).awaitTransactionSuccessAsync(); | ||||||
|  |         await registry.rollback(testFnSelector).awaitTransactionSuccessAsync(); | ||||||
|  |         const r = await testFeature.testFn().callAsync(); | ||||||
|  |         expect(r).to.bignumber.eq(1337); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										23
									
								
								contracts/zero-ex/test/utils/migration.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								contracts/zero-ex/test/utils/migration.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | import { SupportedProvider } from '@0x/subproviders'; | ||||||
|  | import { TxData } from 'ethereum-types'; | ||||||
|  |  | ||||||
|  | import { artifacts } from '../artifacts'; | ||||||
|  | import { BasicMigrationContract, ZeroExContract } from '../wrappers'; | ||||||
|  |  | ||||||
|  | // tslint:disable: completed-docs | ||||||
|  | export async function basicMigrateAsync( | ||||||
|  |     owner: string, | ||||||
|  |     provider: SupportedProvider, | ||||||
|  |     txDefaults: Partial<TxData>, | ||||||
|  | ): Promise<ZeroExContract> { | ||||||
|  |     const migrator = await BasicMigrationContract.deployFrom0xArtifactAsync( | ||||||
|  |         artifacts.BasicMigration, | ||||||
|  |         provider, | ||||||
|  |         txDefaults, | ||||||
|  |         artifacts, | ||||||
|  |     ); | ||||||
|  |     const migrateCall = migrator.migrate(owner); | ||||||
|  |     const zeroEx = new ZeroExContract(await migrateCall.callAsync(), provider, {}); | ||||||
|  |     await migrateCall.awaitTransactionSuccessAsync(); | ||||||
|  |     return zeroEx; | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								contracts/zero-ex/test/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								contracts/zero-ex/test/wrappers.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | /* | ||||||
|  |  * ----------------------------------------------------------------------------- | ||||||
|  |  * 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/fixin_common'; | ||||||
|  | export * from '../test/generated-wrappers/fixin_ownable'; | ||||||
|  | export * from '../test/generated-wrappers/i_feature'; | ||||||
|  | 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/lib_common_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_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/ownable'; | ||||||
|  | export * from '../test/generated-wrappers/simple_function_registry'; | ||||||
|  | export * from '../test/generated-wrappers/test_basic_migration'; | ||||||
|  | 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'; | ||||||
|  | export * from '../test/generated-wrappers/zero_ex'; | ||||||
							
								
								
									
										95
									
								
								contracts/zero-ex/test/zero_ex_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								contracts/zero-ex/test/zero_ex_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | import { blockchainTests, constants, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils'; | ||||||
|  | import { BigNumber, ZeroExRevertErrors } from '@0x/utils'; | ||||||
|  |  | ||||||
|  | import { artifacts } from './artifacts'; | ||||||
|  | import { basicMigrateAsync } from './utils/migration'; | ||||||
|  | import { | ||||||
|  |     IFeatureContract, | ||||||
|  |     IOwnableContract, | ||||||
|  |     ISimpleFunctionRegistryContract, | ||||||
|  |     TestZeroExFeatureContract, | ||||||
|  |     TestZeroExFeatureEvents, | ||||||
|  |     ZeroExContract, | ||||||
|  | } from './wrappers'; | ||||||
|  |  | ||||||
|  | blockchainTests.resets('ZeroEx contract', env => { | ||||||
|  |     let owner: string; | ||||||
|  |     let zeroEx: ZeroExContract; | ||||||
|  |     let ownable: IOwnableContract; | ||||||
|  |     let registry: ISimpleFunctionRegistryContract; | ||||||
|  |     let testFeature: TestZeroExFeatureContract; | ||||||
|  |  | ||||||
|  |     before(async () => { | ||||||
|  |         [owner] = await env.getAccountAddressesAsync(); | ||||||
|  |         zeroEx = await basicMigrateAsync(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); | ||||||
|  |         // Register test features. | ||||||
|  |         const testFeatureImpl = await TestZeroExFeatureContract.deployFrom0xArtifactAsync( | ||||||
|  |             artifacts.TestZeroExFeature, | ||||||
|  |             env.provider, | ||||||
|  |             env.txDefaults, | ||||||
|  |             artifacts, | ||||||
|  |         ); | ||||||
|  |         for (const fn of ['payableFn', 'notPayableFn', 'internalFn']) { | ||||||
|  |             await registry | ||||||
|  |                 .extend(testFeature.getSelector(fn), testFeatureImpl.address) | ||||||
|  |                 .awaitTransactionSuccessAsync({ from: owner }); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('can receive ether', async () => { | ||||||
|  |         const txHash = await env.web3Wrapper.sendTransactionAsync({ | ||||||
|  |             from: owner, | ||||||
|  |             to: zeroEx.address, | ||||||
|  |             data: constants.NULL_BYTES, | ||||||
|  |             value: 1, | ||||||
|  |         }); | ||||||
|  |         await env.web3Wrapper.awaitTransactionSuccessAsync(txHash); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('can attach ether to a call', async () => { | ||||||
|  |         const wei = Math.floor(Math.random() * 100); | ||||||
|  |         const receipt = await testFeature.payableFn().awaitTransactionSuccessAsync({ value: wei }); | ||||||
|  |         verifyEventsFromLogs(receipt.logs, [{ value: new BigNumber(wei) }], TestZeroExFeatureEvents.PayableFnCalled); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('reverts when attaching ether to a non-payable function', async () => { | ||||||
|  |         const wei = Math.floor(Math.random() * 100); | ||||||
|  |         const tx = testFeature.notPayableFn().awaitTransactionSuccessAsync({ value: wei }); | ||||||
|  |         // This will cause an empty revert. | ||||||
|  |         return expect(tx).to.be.rejectedWith('revert'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('reverts when calling an unimplmented function', async () => { | ||||||
|  |         const selector = testFeature.getSelector('unimplmentedFn'); | ||||||
|  |         const tx = testFeature.unimplmentedFn().awaitTransactionSuccessAsync(); | ||||||
|  |         return expect(tx).to.revertWith(new ZeroExRevertErrors.Proxy.NotImplementedError(selector)); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('reverts when calling an internal function', async () => { | ||||||
|  |         const tx = testFeature.internalFn().awaitTransactionSuccessAsync({ from: owner }); | ||||||
|  |         return expect(tx).to.revertWith(new ZeroExRevertErrors.Common.OnlyCallableBySelfError(owner)); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     describe('getFunctionImplementation()', () => { | ||||||
|  |         it('returns the correct implementations of the initial features', async () => { | ||||||
|  |             const ownableSelectors = [ownable.getSelector('transferOwnership')]; | ||||||
|  |             const registrySelectors = [ | ||||||
|  |                 registry.getSelector('rollback'), | ||||||
|  |                 registry.getSelector('extend'), | ||||||
|  |                 // registry.getSelector('extendSelf'), | ||||||
|  |             ]; | ||||||
|  |             const selectors = [...ownableSelectors, ...registrySelectors]; | ||||||
|  |             const impls = await Promise.all(selectors.map(s => zeroEx.getFunctionImplementation(s).callAsync())); | ||||||
|  |             for (let i = 0; i < impls.length; ++i) { | ||||||
|  |                 const selector = selectors[i]; | ||||||
|  |                 const impl = impls[i]; | ||||||
|  |                 const feat = new IFeatureContract(impl, env.provider, env.txDefaults); | ||||||
|  |                 const featName = ownableSelectors.includes(selector) ? 'Ownable' : 'SimpleFunctionRegistry'; | ||||||
|  |                 expect(await feat.FEATURE_NAME().callAsync()).to.eq(featName); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										96
									
								
								contracts/zero-ex/truffle-config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								contracts/zero-ex/truffle-config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | /** | ||||||
|  |  * Use this file to configure your truffle project. It's seeded with some | ||||||
|  |  * common settings for different networks and features like migrations, | ||||||
|  |  * compilation and testing. Uncomment the ones you need or modify | ||||||
|  |  * them to suit your project as necessary. | ||||||
|  |  * | ||||||
|  |  * More information about configuration can be found at: | ||||||
|  |  * | ||||||
|  |  * truffleframework.com/docs/advanced/configuration | ||||||
|  |  * | ||||||
|  |  * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) | ||||||
|  |  * to sign your transactions before they're sent to a remote public node. Infura accounts | ||||||
|  |  * are available for free at: infura.io/register. | ||||||
|  |  * | ||||||
|  |  * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate | ||||||
|  |  * public/private key pairs. If you're publishing your code to GitHub make sure you load this | ||||||
|  |  * phrase from a file you've .gitignored so it doesn't accidentally become public. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | // const HDWalletProvider = require('truffle-hdwallet-provider'); | ||||||
|  | // const infuraKey = "fj4jll3k....."; | ||||||
|  | // | ||||||
|  | // const fs = require('fs'); | ||||||
|  | // const mnemonic = fs.readFileSync(".secret").toString().trim(); | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |     /** | ||||||
|  |      * Networks define how you connect to your ethereum client and let you set the | ||||||
|  |      * defaults web3 uses to send transactions. If you don't specify one truffle | ||||||
|  |      * will spin up a development blockchain for you on port 9545 when you | ||||||
|  |      * run `develop` or `test`. You can ask a truffle command to use a specific | ||||||
|  |      * network from the command line, e.g | ||||||
|  |      * | ||||||
|  |      * $ truffle test --network <network-name> | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     networks: { | ||||||
|  |         // Useful for testing. The `development` name is special - truffle uses it by default | ||||||
|  |         // if it's defined here and no other network is specified at the command line. | ||||||
|  |         // You should run a client (like ganache-cli, geth or parity) in a separate terminal | ||||||
|  |         // tab if you use this network and you must also set the `host`, `port` and `network_id` | ||||||
|  |         // options below to some value. | ||||||
|  |         // | ||||||
|  |         // development: { | ||||||
|  |         //  host: "127.0.0.1",     // Localhost (default: none) | ||||||
|  |         //  port: 8545,            // Standard Ethereum port (default: none) | ||||||
|  |         //  network_id: "*",       // Any network (default: none) | ||||||
|  |         // }, | ||||||
|  |         // Another network with more advanced options... | ||||||
|  |         // advanced: { | ||||||
|  |         // port: 8777,             // Custom port | ||||||
|  |         // network_id: 1342,       // Custom network | ||||||
|  |         // gas: 8500000,           // Gas sent with each transaction (default: ~6700000) | ||||||
|  |         // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei) | ||||||
|  |         // from: <address>,        // Account to send txs from (default: accounts[0]) | ||||||
|  |         // websockets: true        // Enable EventEmitter interface for web3 (default: false) | ||||||
|  |         // }, | ||||||
|  |         // Useful for deploying to a public network. | ||||||
|  |         // NB: It's important to wrap the provider as a function. | ||||||
|  |         // ropsten: { | ||||||
|  |         // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), | ||||||
|  |         // network_id: 3,       // Ropsten's id | ||||||
|  |         // gas: 5500000,        // Ropsten has a lower block limit than mainnet | ||||||
|  |         // confirmations: 2,    // # of confs to wait between deployments. (default: 0) | ||||||
|  |         // timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50) | ||||||
|  |         // skipDryRun: true     // Skip dry run before migrations? (default: false for public nets ) | ||||||
|  |         // }, | ||||||
|  |         // Useful for private networks | ||||||
|  |         // private: { | ||||||
|  |         // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), | ||||||
|  |         // network_id: 2111,   // This network is yours, in the cloud. | ||||||
|  |         // production: true    // Treats this network as if it was a public net. (default: false) | ||||||
|  |         // } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // Set default mocha options here, use special reporters etc. | ||||||
|  |     mocha: { | ||||||
|  |         // timeout: 100000 | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // Configure your compilers | ||||||
|  |     compilers: { | ||||||
|  |         solc: { | ||||||
|  |             version: '0.6.5', | ||||||
|  |             settings: { | ||||||
|  |                 evmVersion: 'istanbul', | ||||||
|  |                 optimizer: { | ||||||
|  |                     enabled: true, | ||||||
|  |                     runs: 1000000, | ||||||
|  |                     details: { yul: true, deduplicate: true, cse: true, constantOptimizer: true }, | ||||||
|  |                 }, | ||||||
|  |             }, | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
							
								
								
									
										33
									
								
								contracts/zero-ex/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								contracts/zero-ex/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | { | ||||||
|  |     "extends": "../../tsconfig", | ||||||
|  |     "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, | ||||||
|  |     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], | ||||||
|  |     "files": [ | ||||||
|  |         "generated-artifacts/IOwnable.json", | ||||||
|  |         "generated-artifacts/ISimpleFunctionRegistry.json", | ||||||
|  |         "generated-artifacts/ZeroEx.json", | ||||||
|  |         "test/generated-artifacts/BasicMigration.json", | ||||||
|  |         "test/generated-artifacts/FixinCommon.json", | ||||||
|  |         "test/generated-artifacts/FixinOwnable.json", | ||||||
|  |         "test/generated-artifacts/IFeature.json", | ||||||
|  |         "test/generated-artifacts/IOwnable.json", | ||||||
|  |         "test/generated-artifacts/ISimpleFunctionRegistry.json", | ||||||
|  |         "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json", | ||||||
|  |         "test/generated-artifacts/IZeroExBootstrapper.json", | ||||||
|  |         "test/generated-artifacts/LibCommonRichErrors.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/Ownable.json", | ||||||
|  |         "test/generated-artifacts/SimpleFunctionRegistry.json", | ||||||
|  |         "test/generated-artifacts/TestBasicMigration.json", | ||||||
|  |         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json", | ||||||
|  |         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json", | ||||||
|  |         "test/generated-artifacts/TestZeroExFeature.json", | ||||||
|  |         "test/generated-artifacts/ZeroEx.json" | ||||||
|  |     ], | ||||||
|  |     "exclude": ["./deploy/solc/solc_bin"] | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								contracts/zero-ex/tslint.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								contracts/zero-ex/tslint.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  |     "extends": ["@0x/tslint-config"], | ||||||
|  |     "rules": { | ||||||
|  |         "custom-no-magic-numbers": false, | ||||||
|  |         "max-file-line-count": false | ||||||
|  |     }, | ||||||
|  |     "linterOptions": { | ||||||
|  |         "exclude": ["src/artifacts.ts", "test/artifacts.ts"] | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user