Create @0x/contracts-rich-reverts-decoder.

This commit is contained in:
Lawrence Forman
2019-04-23 11:48:04 -04:00
committed by Amir Bandeali
parent d942c47f08
commit 7835c6e20c
16 changed files with 576 additions and 0 deletions

View File

@@ -0,0 +1 @@
contracts/src/ZRXToken.sol

View File

@@ -0,0 +1,11 @@
[
{
"version": "1.0.0",
"changes": [
{
"note": "Created",
"pr": TODO
}
]
}
]

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,73 @@
## ERC20 Tokens
This package contains implementations of various [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) tokens, including WETH (Wrapped Ether) and ZRX. Addresses of the deployed contracts can be found in the 0x [wiki](https://0xproject.com/wiki#Deployed-Addresses) or the [DEPLOYS](./DEPLOYS.json) file within this package.
## Installation
**Install**
```bash
npm install @0x/contracts-erc20 --save
```
## Bug bounty
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty).
## 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-erc20 yarn build
```
Or continuously rebuild on change:
```bash
PKG=@0x/contracts-erc20 yarn watch
```
### Clean
```bash
yarn clean
```
### Lint
```bash
yarn lint
```
### Run Tests
```bash
yarn test
```
#### Testing options
Contracts testing options like coverage, profiling, revert traces or backing node choosing - are described [here](../TESTING.md).

View File

@@ -0,0 +1,28 @@
{
"artifactsDir": "./generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": true,
"isOfflineMode": false,
"compilerSettings": {
"evmVersion": "constantinople",
"optimizer": {
"enabled": true,
"runs": 1000000,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
]
}
}
},
"contracts": [
"src/Helper.sol"
]
}

View File

@@ -0,0 +1,27 @@
/*
Copyright 2019 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.5.5;
import "./MixinRichErrors";
// solhint-disable no-empty-blocks
contract Helper is
MixinRichErrors
{ }

View File

@@ -0,0 +1,251 @@
/*
Copyright 2019 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.5.5;
import "@0x/contracts-exchange/contracts/src/interfaces/MExchangeRichErrors.sol";
import "@0x/contracts-utils/contracts/src/mixins/LibBytes.sol";
contract MixinRichErrors {
bytes4 private constant STANDARD_ERROR_SELECTOR =
bytes4(keccak256("Error(string)"));
/// @dev Decompose an ABI-encoded StandardError.
/// This is the standard, string revert() error.
/// @param encoded ABI-encoded revert error.
/// @param encoded ABI-encoded revert error.
/// @return message The error message.
function decomposeStandardError(bytes memory encoded)
public
pure
returns (string memory message)
{
_assertSelectorBytes(encoded, STANDARD_ERROR_SELECTOR);
message = _readErrorParameterAsString(encoded, 0);
}
bytes4 private constant SIGNATURE_ERROR_SELECTOR =
bytes4(keccak256("SignatureError(uint8,bytes32,address,bytes)"));
/// @dev Decompose an ABI-encoded SignatureError.
/// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash.
/// @return signature The full signature.
function decomposeSignatureError(bytes memory encoded)
public
pure
returns (
SignatureErrorCode errorCode,
bytes32 hash,
address signer,
bytes memory signature
)
{
_assertSelectorBytes(encoded, SIGNATURE_ERROR_SELECTOR);
errorCode = SignatureErrorCode(_readErrorParameterAsUint256(encoded, 0));
hash = _readErrorParameterAsBytes32(encoded, 1);
signer = _readErrorParameterAsBytes32(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3);
}
bytes4 private constant SIGNATURE_VALIDATOR_ERROR_SELECTOR =
bytes4(keccak256("SignatureValidatorError(bytes32,address,bytes,bytes)"));
/// @dev Decompose an ABI-encoded SignatureValidatorError.
/// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash.
/// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureValidatorError(bytes memory encoded)
public
pure
returns (
SignatureErrorCode errorCode,
bytes32 hash,
address signer,
bytes memory signature,
bytes memory errorData
)
{
_assertSelectorBytes(encoded, SIGNATURE_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCode(_readErrorParameterAsUint256(encoded, 0));
hash = _readErrorParameterAsBytes32(encoded, 1);
signer = _readErrorParameterAsBytes32(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
}
bytes4 private constant SIGNATURE_WALLET_ERROR_SELECTOR =
bytes4(keccak256("SignatureWalletError(bytes32,address,bytes,bytes)"));
/// @dev Decompose an ABI-encoded SignatureWalletError.
/// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash.
/// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureWalletError(bytes memory encoded)
public
pure
returns (
SignatureErrorCode errorCode,
bytes32 hash,
address signer,
bytes memory signature,
bytes memory errorData
)
{
_assertSelectorBytes(encoded, SIGNATURE_WALLET_ERROR_SELECTOR);
errorCode = SignatureErrorCode(_readErrorParameterAsUint256(encoded, 0));
hash = _readErrorParameterAsBytes32(encoded, 1);
signer = _readErrorParameterAsBytes32(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
}
bytes4 internal constant SIGNATURE_ORDER_VALIDATOR_ERROR_SELECTOR =
bytes4(keccak256("SignatureOrderValidatorError(bytes32,address,bytes,bytes)"));
/// @dev Decompose an ABI-encoded SignatureOrderValidatorError.
/// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash.
/// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureOrderValidatorError(bytes memory encoded)
public
pure
returns (
SignatureErrorCode errorCode,
bytes32 hash,
address signer,
bytes memory signature,
bytes memory errorData
)
{
_assertSelectorBytes(encoded, SIGNATURE_ORDER_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCode(_readErrorParameterAsUint256(encoded, 0));
hash = _readErrorParameterAsBytes32(encoded, 1);
signer = _readErrorParameterAsBytes32(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
}
bytes4 internal constant SIGNATURE_WALLET_ORDER_VALIDATOR_ERROR_SELECTOR =
bytes4(keccak256("SignatureWalletOrderValidatorError(bytes32,address,bytes,bytes)"));
/// @dev Decompose an ABI-encoded SignatureWalletOrderValidatorError.
/// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash.
/// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureWalletOrderValidatorError(bytes memory encoded)
public
pure
returns (
SignatureErrorCode errorCode,
bytes32 hash,
address signer,
bytes memory signature,
bytes memory errorData
)
{
_assertSelectorBytes(encoded, SIGNATURE_WALLET_ORDER_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCode(_readErrorParameterAsUint256(encoded, 0));
hash = _readErrorParameterAsBytes32(encoded, 1);
signer = _readErrorParameterAsBytes32(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
}
bytes4 internal constant ORDER_STATUS_ERROR_SELECTOR =
bytes4(keccak256("OrderStatusError(bytes32,uint8)"));
/// @dev Decompose an ABI-encoded OrderStatusError.
/// @param encoded ABI-encoded revert error.
/// @return orderHash The order hash.
/// @return orderStatus The order status.
function decomposeOrderStatusError(bytes memory encoded)
public
pure
returns (
bytes32 hash,
LibOrder.OrderStatus orderStatus
)
{
_assertSelectorBytes(encoded, ORDER_STATUS_ERROR_SELECTOR);
hash = _readErrorParameterAsBytes32(encoded, 0);
orderStatus = LibOrder.OrderStatus(_readErrorParameterAsUint256(encoded, 1));
}
/// @dev Revert if the leading 4 bytes of `encoded` is not `selector`.
function _assertSelectorBytes(bytes memory encoded, bytes4 selector)
private
pure
{
bytes4 actualSelector = LibBytes.readBytes4(encoded, 0);
require(
actualSelector == selector,
"INVALID_SELECTOR"
);
}
/// @dev Read a parameter at index `index` as a uint256.
function _readErrorParameterAsUint256(bytes memory encoded, uint256 index)
private
pure
returns (uint256 value)
{
uint256 parameterOffset = 4 + index * 32;
return LibBytes.readUint256(encoded, parameterOffset);
}
/// @dev Read a parameter at index `index` as a bytes32.
function _readErrorParameterAsBytes32(bytes memory encoded, uint256 index)
private
pure
returns (uint256 value)
{
uint256 parameterOffset = 4 + index * 32;
return LibBytes.readBytes32(encoded, parameterOffset);
}
/// @dev Read a parameter at index `index` as a bytes.
function _readErrorParameterAsBytes(bytes memory encoded, uint256 index)
private
pure
returns (bytes memory value)
{
uint256 dataOffset = 4 + _readErrorParameterAsUint256(encoded, index);
return LibBytes.readBytesWithLength(encoded, dataOffset);
}
/// @dev Read a parameter at index `index` as a string.
function _readErrorParameterAsString(bytes memory encoded, uint256 index)
private
pure
returns (string memory value)
{
return string(_readErrorParameterAsBytes(encoded, index));
}
}

View File

@@ -0,0 +1,83 @@
{
"name": "@0x/contracts-rich-reverts-decoder",
"version": "1.0.0",
"engines": {
"node": ">=6.12"
},
"description": "Helper contract for 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 generate_contract_wrappers",
"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 generated-artifacts generated-wrappers",
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./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",
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(DummyERC20Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Token|IERC20Token|IEtherToken|MintableERC20Token|UnlimitedAllowanceERC20Token|WETH9|ZRXToken).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"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/helper/README.md",
"devDependencies": {
"@0x/abi-gen": "^2.0.8",
"@0x/contracts-gen": "^1.0.7",
"@0x/contracts-test-utils": "^3.1.1",
"@0x/dev-utils": "^2.2.0",
"@0x/sol-compiler": "^3.1.5",
"@0x/tslint-config": "^3.0.0",
"@types/lodash": "4.14.104",
"@types/node": "*",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.1.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"solhint": "^1.4.1",
"tslint": "5.11.0",
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^5.0.4",
"@0x/contracts-exchange-libs": "^2.1.0",
"@0x/contracts-utils": "^3.1.0",
"@0x/types": "^2.2.1",
"@0x/typescript-typings": "^4.2.1",
"@0x/utils": "^4.3.0",
"@0x/web3-wrapper": "^6.0.4",
"ethereum-types": "^2.1.1",
"lodash": "^4.17.11"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,29 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
import { ContractArtifact } from 'ethereum-types';
import * as DummyERC20Token from '../generated-artifacts/DummyERC20Token.json';
import * as DummyMultipleReturnERC20Token from '../generated-artifacts/DummyMultipleReturnERC20Token.json';
import * as DummyNoReturnERC20Token from '../generated-artifacts/DummyNoReturnERC20Token.json';
import * as ERC20Token from '../generated-artifacts/ERC20Token.json';
import * as IERC20Token from '../generated-artifacts/IERC20Token.json';
import * as IEtherToken from '../generated-artifacts/IEtherToken.json';
import * as MintableERC20Token from '../generated-artifacts/MintableERC20Token.json';
import * as UnlimitedAllowanceERC20Token from '../generated-artifacts/UnlimitedAllowanceERC20Token.json';
import * as WETH9 from '../generated-artifacts/WETH9.json';
import * as ZRXToken from '../generated-artifacts/ZRXToken.json';
export const artifacts = {
ERC20Token: ERC20Token as ContractArtifact,
MintableERC20Token: MintableERC20Token as ContractArtifact,
UnlimitedAllowanceERC20Token: UnlimitedAllowanceERC20Token as ContractArtifact,
WETH9: WETH9 as ContractArtifact,
ZRXToken: (ZRXToken as any) as ContractArtifact,
IERC20Token: IERC20Token as ContractArtifact,
IEtherToken: IEtherToken as ContractArtifact,
DummyERC20Token: DummyERC20Token as ContractArtifact,
DummyMultipleReturnERC20Token: DummyMultipleReturnERC20Token as ContractArtifact,
DummyNoReturnERC20Token: DummyNoReturnERC20Token as ContractArtifact,
};

View File

@@ -0,0 +1,2 @@
export * from './wrappers';
export * from './artifacts';

View File

@@ -0,0 +1,15 @@
/*
* -----------------------------------------------------------------------------
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* -----------------------------------------------------------------------------
*/
export * from '../generated-wrappers/dummy_erc20_token';
export * from '../generated-wrappers/dummy_multiple_return_erc20_token';
export * from '../generated-wrappers/dummy_no_return_erc20_token';
export * from '../generated-wrappers/erc20_token';
export * from '../generated-wrappers/i_erc20_token';
export * from '../generated-wrappers/i_ether_token';
export * from '../generated-wrappers/mintable_erc20_token';
export * from '../generated-wrappers/unlimited_allowance_erc20_token';
export * from '../generated-wrappers/weth9';
export * from '../generated-wrappers/zrx_token';

View File

@@ -0,0 +1,23 @@
import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as chai from 'chai';
import { artifacts, HelperContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('decompose', () => {
before(async () => {
await blockchainLifecycle.startAsync();
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
});
});

View File

@@ -0,0 +1,19 @@
import { env, EnvVars } from '@0x/dev-utils';
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
import { providerUtils } from '@0x/utils';
before('start web3 provider', () => {
providerUtils.startProviderEngine(provider);
});
after('generate coverage report', async () => {
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
const coverageSubprovider = coverage.getCoverageSubproviderSingleton();
await coverageSubprovider.writeCoverageAsync();
}
if (env.parseBoolean(EnvVars.SolidityProfiler)) {
const profilerSubprovider = profiler.getProfilerSubproviderSingleton();
await profilerSubprovider.writeProfilerOutputAsync();
}
provider.stop();
});

View File

@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [],
"exclude": ["./deploy/solc/solc_bin"]
}

View File

@@ -0,0 +1,6 @@
{
"extends": ["@0x/tslint-config"],
"rules": {
"custom-no-magic-numbers": false
}
}