Add Broker rich errors
This commit is contained in:
parent
c581f1bba4
commit
c5e0de51aa
@ -24,10 +24,12 @@ import "@0x/contracts-exchange-forwarder/contracts/src/libs/LibAssetDataTransfer
|
|||||||
import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol";
|
||||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
|
||||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||||
import "@0x/contracts-utils/contracts/src/Refundable.sol";
|
import "@0x/contracts-utils/contracts/src/Refundable.sol";
|
||||||
import "./interfaces/IBroker.sol";
|
import "./interfaces/IBroker.sol";
|
||||||
import "./interfaces/IPropertyValidator.sol";
|
import "./interfaces/IPropertyValidator.sol";
|
||||||
|
import "./libs/LibBrokerRichErrors.sol";
|
||||||
|
|
||||||
|
|
||||||
// solhint-disable space-after-comma
|
// solhint-disable space-after-comma
|
||||||
@ -67,10 +69,22 @@ contract Broker is
|
|||||||
)
|
)
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
require(from == address(this), "INVALID_FROM_ADDRESS");
|
if (from != address(this)) {
|
||||||
require(amounts.length == 1, "MUST_PROVIDE_ONE_AMOUNT");
|
LibRichErrors.rrevert(
|
||||||
|
LibBrokerRichErrors.InvalidFromAddressError(from)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (amounts.length != 1) {
|
||||||
|
LibRichErrors.rrevert(
|
||||||
|
LibBrokerRichErrors.AmountsLengthMustEqualOneError(amounts.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
uint256 remainingAmount = amounts[0];
|
uint256 remainingAmount = amounts[0];
|
||||||
require(_cachedAssetData.length.safeSub(_cacheIndex) >= remainingAmount, "TOO_FEW_BROKERED_ASSETS_PROVIDED");
|
if (_cachedAssetData.length.safeSub(_cacheIndex) < remainingAmount) {
|
||||||
|
LibRichErrors.rrevert(
|
||||||
|
LibBrokerRichErrors.TooFewBrokerAssetsProvidedError(_cachedAssetData.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
while (remainingAmount != 0) {
|
while (remainingAmount != 0) {
|
||||||
bytes memory assetToTransfer = _cachedAssetData[_cacheIndex];
|
bytes memory assetToTransfer = _cachedAssetData[_cacheIndex];
|
||||||
@ -125,11 +139,13 @@ contract Broker is
|
|||||||
_sender = msg.sender;
|
_sender = msg.sender;
|
||||||
|
|
||||||
// Sanity-check the provided function selector
|
// Sanity-check the provided function selector
|
||||||
require(
|
if (
|
||||||
fillFunctionSelector == IExchange(address(0)).fillOrder.selector ||
|
fillFunctionSelector != IExchange(address(0)).fillOrder.selector &&
|
||||||
fillFunctionSelector == IExchange(address(0)).fillOrKillOrder.selector,
|
fillFunctionSelector != IExchange(address(0)).fillOrKillOrder.selector
|
||||||
"UNRECOGNIZED_FUNCTION_SELECTOR"
|
) {
|
||||||
);
|
LibBrokerRichErrors.InvalidFunctionSelectorError(fillFunctionSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Perform the fill
|
// Perform the fill
|
||||||
bytes memory fillCalldata = abi.encodeWithSelector(
|
bytes memory fillCalldata = abi.encodeWithSelector(
|
||||||
@ -177,12 +193,13 @@ contract Broker is
|
|||||||
_sender = msg.sender;
|
_sender = msg.sender;
|
||||||
|
|
||||||
// Sanity-check the provided function selector
|
// Sanity-check the provided function selector
|
||||||
require(
|
if (
|
||||||
batchFillFunctionSelector == IExchange(address(0)).batchFillOrders.selector ||
|
batchFillFunctionSelector != IExchange(address(0)).batchFillOrders.selector &&
|
||||||
batchFillFunctionSelector == IExchange(address(0)).batchFillOrKillOrders.selector ||
|
batchFillFunctionSelector != IExchange(address(0)).batchFillOrKillOrders.selector &&
|
||||||
batchFillFunctionSelector == IExchange(address(0)).batchFillOrdersNoThrow.selector,
|
batchFillFunctionSelector != IExchange(address(0)).batchFillOrdersNoThrow.selector
|
||||||
"UNRECOGNIZED_FUNCTION_SELECTOR"
|
) {
|
||||||
);
|
LibBrokerRichErrors.InvalidFunctionSelectorError(batchFillFunctionSelector);
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the batch fill
|
// Perform the batch fill
|
||||||
bytes memory batchFillCalldata = abi.encodeWithSelector(
|
bytes memory batchFillCalldata = abi.encodeWithSelector(
|
||||||
|
93
contracts/broker/contracts/src/libs/LibBrokerRichErrors.sol
Normal file
93
contracts/broker/contracts/src/libs/LibBrokerRichErrors.sol
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.9;
|
||||||
|
|
||||||
|
|
||||||
|
library LibBrokerRichErrors {
|
||||||
|
|
||||||
|
|
||||||
|
// bytes4(keccak256("InvalidFromAddressError(address)"))
|
||||||
|
bytes4 internal constant INVALID_FROM_ADDRESS_ERROR_SELECTOR =
|
||||||
|
0x906bfb3c;
|
||||||
|
|
||||||
|
// bytes4(keccak256("AmountsLengthMustEqualOneError(uint256)"))
|
||||||
|
bytes4 internal constant AMOUNTS_LENGTH_MUST_EQUAL_ONE_ERROR_SELECTOR =
|
||||||
|
0xba9be200;
|
||||||
|
|
||||||
|
// bytes4(keccak256("TooFewBrokerAssetsProvidedError(uint256)"))
|
||||||
|
bytes4 internal constant TOO_FEW_BROKER_ASSETS_PROVIDED_ERROR_SELECTOR =
|
||||||
|
0x55272586;
|
||||||
|
|
||||||
|
// bytes4(keccak256("InvalidFunctionSelectorError(bytes4)"))
|
||||||
|
bytes4 internal constant INVALID_FUNCTION_SELECTOR_ERROR_SELECTOR =
|
||||||
|
0x540943f1;
|
||||||
|
|
||||||
|
// solhint-disable func-name-mixedcase
|
||||||
|
function InvalidFromAddressError(
|
||||||
|
address from
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
INVALID_FROM_ADDRESS_ERROR_SELECTOR,
|
||||||
|
from
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AmountsLengthMustEqualOneError(
|
||||||
|
uint256 amountsLength
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
AMOUNTS_LENGTH_MUST_EQUAL_ONE_ERROR_SELECTOR,
|
||||||
|
amountsLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TooFewBrokerAssetsProvidedError(
|
||||||
|
uint256 numBrokeredAssets
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
TOO_FEW_BROKER_ASSETS_PROVIDED_ERROR_SELECTOR,
|
||||||
|
numBrokeredAssets
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InvalidFunctionSelectorError(
|
||||||
|
bytes4 selector
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
INVALID_FUNCTION_SELECTOR_ERROR_SELECTOR,
|
||||||
|
selector
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,7 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||||
"abis": "./test/generated-artifacts/@(Broker|GodsUnchainedValidator|IBroker|IGodsUnchained|IPropertyValidator|TestGodsUnchained).json"
|
"abis": "./test/generated-artifacts/@(Broker|GodsUnchainedValidator|IBroker|IGodsUnchained|IPropertyValidator|LibBrokerRichErrors|TestGodsUnchained).json"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -10,12 +10,14 @@ import * as GodsUnchainedValidator from '../generated-artifacts/GodsUnchainedVal
|
|||||||
import * as IBroker from '../generated-artifacts/IBroker.json';
|
import * as IBroker from '../generated-artifacts/IBroker.json';
|
||||||
import * as IGodsUnchained from '../generated-artifacts/IGodsUnchained.json';
|
import * as IGodsUnchained from '../generated-artifacts/IGodsUnchained.json';
|
||||||
import * as IPropertyValidator from '../generated-artifacts/IPropertyValidator.json';
|
import * as IPropertyValidator from '../generated-artifacts/IPropertyValidator.json';
|
||||||
|
import * as LibBrokerRichErrors from '../generated-artifacts/LibBrokerRichErrors.json';
|
||||||
import * as TestGodsUnchained from '../generated-artifacts/TestGodsUnchained.json';
|
import * as TestGodsUnchained from '../generated-artifacts/TestGodsUnchained.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
Broker: Broker as ContractArtifact,
|
Broker: Broker as ContractArtifact,
|
||||||
IBroker: IBroker as ContractArtifact,
|
IBroker: IBroker as ContractArtifact,
|
||||||
IGodsUnchained: IGodsUnchained as ContractArtifact,
|
IGodsUnchained: IGodsUnchained as ContractArtifact,
|
||||||
IPropertyValidator: IPropertyValidator as ContractArtifact,
|
IPropertyValidator: IPropertyValidator as ContractArtifact,
|
||||||
|
LibBrokerRichErrors: LibBrokerRichErrors as ContractArtifact,
|
||||||
GodsUnchainedValidator: GodsUnchainedValidator as ContractArtifact,
|
GodsUnchainedValidator: GodsUnchainedValidator as ContractArtifact,
|
||||||
TestGodsUnchained: TestGodsUnchained as ContractArtifact,
|
TestGodsUnchained: TestGodsUnchained as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,32 @@
|
|||||||
export { artifacts } from './artifacts';
|
export { artifacts } from './artifacts';
|
||||||
export { BrokerContract, GodsUnchainedValidatorContract, TestGodsUnchainedContract } from './wrappers';
|
export { BrokerContract, GodsUnchainedValidatorContract, TestGodsUnchainedContract } from './wrappers';
|
||||||
export { godsUnchainedUtils } from './gods_unchained_utils';
|
export { godsUnchainedUtils } from './gods_unchained_utils';
|
||||||
|
export { BrokerRevertErrors } from '@0x/utils';
|
||||||
|
export {
|
||||||
|
ContractArtifact,
|
||||||
|
ContractChains,
|
||||||
|
CompilerOpts,
|
||||||
|
StandardContractOutput,
|
||||||
|
CompilerSettings,
|
||||||
|
ContractChainData,
|
||||||
|
ContractAbi,
|
||||||
|
DevdocOutput,
|
||||||
|
EvmOutput,
|
||||||
|
CompilerSettingsMetadata,
|
||||||
|
OptimizerSettings,
|
||||||
|
OutputField,
|
||||||
|
ParamDescription,
|
||||||
|
EvmBytecodeOutput,
|
||||||
|
AbiDefinition,
|
||||||
|
FunctionAbi,
|
||||||
|
EventAbi,
|
||||||
|
RevertErrorAbi,
|
||||||
|
EventParameter,
|
||||||
|
DataItem,
|
||||||
|
MethodAbi,
|
||||||
|
ConstructorAbi,
|
||||||
|
FallbackAbi,
|
||||||
|
ConstructorStateMutability,
|
||||||
|
TupleDataItem,
|
||||||
|
StateMutability,
|
||||||
|
} from 'ethereum-types';
|
||||||
|
@ -8,4 +8,5 @@ export * from '../generated-wrappers/gods_unchained_validator';
|
|||||||
export * from '../generated-wrappers/i_broker';
|
export * from '../generated-wrappers/i_broker';
|
||||||
export * from '../generated-wrappers/i_gods_unchained';
|
export * from '../generated-wrappers/i_gods_unchained';
|
||||||
export * from '../generated-wrappers/i_property_validator';
|
export * from '../generated-wrappers/i_property_validator';
|
||||||
|
export * from '../generated-wrappers/lib_broker_rich_errors';
|
||||||
export * from '../generated-wrappers/test_gods_unchained';
|
export * from '../generated-wrappers/test_gods_unchained';
|
||||||
|
@ -10,12 +10,14 @@ import * as GodsUnchainedValidator from '../test/generated-artifacts/GodsUnchain
|
|||||||
import * as IBroker from '../test/generated-artifacts/IBroker.json';
|
import * as IBroker from '../test/generated-artifacts/IBroker.json';
|
||||||
import * as IGodsUnchained from '../test/generated-artifacts/IGodsUnchained.json';
|
import * as IGodsUnchained from '../test/generated-artifacts/IGodsUnchained.json';
|
||||||
import * as IPropertyValidator from '../test/generated-artifacts/IPropertyValidator.json';
|
import * as IPropertyValidator from '../test/generated-artifacts/IPropertyValidator.json';
|
||||||
|
import * as LibBrokerRichErrors from '../test/generated-artifacts/LibBrokerRichErrors.json';
|
||||||
import * as TestGodsUnchained from '../test/generated-artifacts/TestGodsUnchained.json';
|
import * as TestGodsUnchained from '../test/generated-artifacts/TestGodsUnchained.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
Broker: Broker as ContractArtifact,
|
Broker: Broker as ContractArtifact,
|
||||||
IBroker: IBroker as ContractArtifact,
|
IBroker: IBroker as ContractArtifact,
|
||||||
IGodsUnchained: IGodsUnchained as ContractArtifact,
|
IGodsUnchained: IGodsUnchained as ContractArtifact,
|
||||||
IPropertyValidator: IPropertyValidator as ContractArtifact,
|
IPropertyValidator: IPropertyValidator as ContractArtifact,
|
||||||
|
LibBrokerRichErrors: LibBrokerRichErrors as ContractArtifact,
|
||||||
GodsUnchainedValidator: GodsUnchainedValidator as ContractArtifact,
|
GodsUnchainedValidator: GodsUnchainedValidator as ContractArtifact,
|
||||||
TestGodsUnchained: TestGodsUnchained as ContractArtifact,
|
TestGodsUnchained: TestGodsUnchained as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
@ -8,4 +8,5 @@ export * from '../test/generated-wrappers/gods_unchained_validator';
|
|||||||
export * from '../test/generated-wrappers/i_broker';
|
export * from '../test/generated-wrappers/i_broker';
|
||||||
export * from '../test/generated-wrappers/i_gods_unchained';
|
export * from '../test/generated-wrappers/i_gods_unchained';
|
||||||
export * from '../test/generated-wrappers/i_property_validator';
|
export * from '../test/generated-wrappers/i_property_validator';
|
||||||
|
export * from '../test/generated-wrappers/lib_broker_rich_errors';
|
||||||
export * from '../test/generated-wrappers/test_gods_unchained';
|
export * from '../test/generated-wrappers/test_gods_unchained';
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
"generated-artifacts/IBroker.json",
|
"generated-artifacts/IBroker.json",
|
||||||
"generated-artifacts/IGodsUnchained.json",
|
"generated-artifacts/IGodsUnchained.json",
|
||||||
"generated-artifacts/IPropertyValidator.json",
|
"generated-artifacts/IPropertyValidator.json",
|
||||||
|
"generated-artifacts/LibBrokerRichErrors.json",
|
||||||
"generated-artifacts/TestGodsUnchained.json",
|
"generated-artifacts/TestGodsUnchained.json",
|
||||||
"test/generated-artifacts/Broker.json",
|
"test/generated-artifacts/Broker.json",
|
||||||
"test/generated-artifacts/GodsUnchainedValidator.json",
|
"test/generated-artifacts/GodsUnchainedValidator.json",
|
||||||
"test/generated-artifacts/IBroker.json",
|
"test/generated-artifacts/IBroker.json",
|
||||||
"test/generated-artifacts/IGodsUnchained.json",
|
"test/generated-artifacts/IGodsUnchained.json",
|
||||||
"test/generated-artifacts/IPropertyValidator.json",
|
"test/generated-artifacts/IPropertyValidator.json",
|
||||||
|
"test/generated-artifacts/LibBrokerRichErrors.json",
|
||||||
"test/generated-artifacts/TestGodsUnchained.json"
|
"test/generated-artifacts/TestGodsUnchained.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "5.3.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Added Broker revert errors",
|
||||||
|
"pr": 2455
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -27,6 +27,7 @@ export {
|
|||||||
AnyRevertError,
|
AnyRevertError,
|
||||||
} from './revert_error';
|
} from './revert_error';
|
||||||
|
|
||||||
|
export import BrokerRevertErrors = require('./revert_errors/broker/revert_errors');
|
||||||
export import CoordinatorRevertErrors = require('./revert_errors/coordinator/revert_errors');
|
export import CoordinatorRevertErrors = require('./revert_errors/coordinator/revert_errors');
|
||||||
export import ExchangeForwarderRevertErrors = require('./revert_errors/exchange-forwarder/revert_errors');
|
export import ExchangeForwarderRevertErrors = require('./revert_errors/exchange-forwarder/revert_errors');
|
||||||
export import LibMathRevertErrors = require('./revert_errors/exchange-libs/lib_math_revert_errors');
|
export import LibMathRevertErrors = require('./revert_errors/exchange-libs/lib_math_revert_errors');
|
||||||
|
44
packages/utils/src/revert_errors/broker/revert_errors.ts
Normal file
44
packages/utils/src/revert_errors/broker/revert_errors.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { BigNumber } from '../../configured_bignumber';
|
||||||
|
import { RevertError } from '../../revert_error';
|
||||||
|
|
||||||
|
// tslint:disable:max-classes-per-file
|
||||||
|
|
||||||
|
export class InvalidFromAddressError extends RevertError {
|
||||||
|
constructor(from?: string) {
|
||||||
|
super('InvalidFromAddressError', 'InvalidFromAddressError(address from)', { from });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AmountsLengthMustEqualOneError extends RevertError {
|
||||||
|
constructor(amountsLength?: BigNumber | number | string) {
|
||||||
|
super('AmountsLengthMustEqualOneError', 'AmountsLengthMustEqualOneError(uint256 amountsLength)', {
|
||||||
|
amountsLength,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TooFewBrokerAssetsProvidedError extends RevertError {
|
||||||
|
constructor(numBrokeredAssets?: BigNumber | number | string) {
|
||||||
|
super('TooFewBrokerAssetsProvidedError', 'TooFewBrokerAssetsProvidedError(uint256 numBrokeredAssets)', {
|
||||||
|
numBrokeredAssets,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InvalidFunctionSelectorError extends RevertError {
|
||||||
|
constructor(selector?: string) {
|
||||||
|
super('InvalidFunctionSelectorError', 'InvalidFunctionSelectorError(bytes4 selector)', { selector });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const types = [
|
||||||
|
InvalidFromAddressError,
|
||||||
|
AmountsLengthMustEqualOneError,
|
||||||
|
TooFewBrokerAssetsProvidedError,
|
||||||
|
InvalidFunctionSelectorError,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Register the types we've defined.
|
||||||
|
for (const type of types) {
|
||||||
|
RevertError.registerType(type);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user