@0x/contracts-zero-ex`: Create ZeroEx (proxy) contracts
This commit is contained in:
parent
4212a08337
commit
c11d661b39
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"]
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user