diff --git a/contracts/erc20/contracts/src/v08/IERC20TokenV08.sol b/contracts/erc20/contracts/src/v08/IERC20TokenV08.sol
new file mode 100644
index 0000000000..da2eb35311
--- /dev/null
+++ b/contracts/erc20/contracts/src/v08/IERC20TokenV08.sol
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8.0;
+
+interface IERC20TokenV08 {
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+
+ /// @dev send `value` token to `to` from `msg.sender`
+ /// @param to The address of the recipient
+ /// @param value The amount of token to be transferred
+ /// @return True if transfer was successful
+ function transfer(address to, uint256 value) external returns (bool);
+
+ /// @dev send `value` token to `to` from `from` on the condition it is approved by `from`
+ /// @param from The address of the sender
+ /// @param to The address of the recipient
+ /// @param value The amount of token to be transferred
+ /// @return True if transfer was successful
+ function transferFrom(address from, address to, uint256 value) external returns (bool);
+
+ /// @dev `msg.sender` approves `spender` to spend `value` tokens
+ /// @param spender The address of the account able to transfer the tokens
+ /// @param value The amount of wei to be approved for transfer
+ /// @return Always true if the call has enough gas to complete execution
+ function approve(address spender, uint256 value) external returns (bool);
+
+ /// @dev Query total supply of token
+ /// @return Total supply of token
+ function totalSupply() external view returns (uint256);
+
+ /// @dev Get the balance of `owner`.
+ /// @param owner The address from which the balance will be retrieved
+ /// @return Balance of owner
+ function balanceOf(address owner) external view returns (uint256);
+
+ /// @dev Get the allowance for `spender` to spend from `owner`.
+ /// @param owner The address of the account owning tokens
+ /// @param spender The address of the account able to transfer the tokens
+ /// @return Amount of remaining tokens allowed to spent
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ /// @dev Get the number of decimals this token has.
+ function decimals() external view returns (uint8);
+}
diff --git a/contracts/erc20/contracts/src/v08/IEtherTokenV08.sol b/contracts/erc20/contracts/src/v08/IEtherTokenV08.sol
new file mode 100644
index 0000000000..9dff977e69
--- /dev/null
+++ b/contracts/erc20/contracts/src/v08/IEtherTokenV08.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8.0;
+
+import "./IERC20TokenV08.sol";
+
+interface IEtherTokenV08 is IERC20TokenV08 {
+ /// @dev Wrap ether.
+ function deposit() external payable;
+
+ /// @dev Unwrap ether.
+ function withdraw(uint256 amount) external;
+}
diff --git a/contracts/erc20/contracts/src/v08/LibERC20TokenV08.sol b/contracts/erc20/contracts/src/v08/LibERC20TokenV08.sol
new file mode 100644
index 0000000000..716fcc4006
--- /dev/null
+++ b/contracts/erc20/contracts/src/v08/LibERC20TokenV08.sol
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8.0;
+
+import "@0x/contracts-utils/contracts/src/v08/errors/LibRichErrorsV08.sol";
+import "@0x/contracts-utils/contracts/src/v08/LibBytesV08.sol";
+import "./IERC20TokenV08.sol";
+
+library LibERC20TokenV08 {
+ bytes private constant DECIMALS_CALL_DATA = hex"313ce567";
+
+ /// @dev Calls `IERC20TokenV08(token).approve()`.
+ /// Reverts if the return data is invalid or the call reverts.
+ /// @param token The address of the token contract.
+ /// @param spender The address that receives an allowance.
+ /// @param allowance The allowance to set.
+ function compatApprove(IERC20TokenV08 token, address spender, uint256 allowance) internal {
+ bytes memory callData = abi.encodeCall(token.approve, (spender, allowance));
+ _callWithOptionalBooleanResult(address(token), callData);
+ }
+
+ /// @dev Calls `IERC20TokenV08(token).approve()` and sets the allowance to the
+ /// maximum if the current approval is not already >= an amount.
+ /// Reverts if the return data is invalid or the call reverts.
+ /// @param token The address of the token contract.
+ /// @param spender The address that receives an allowance.
+ /// @param amount The minimum allowance needed.
+ function approveIfBelow(IERC20TokenV08 token, address spender, uint256 amount) internal {
+ if (token.allowance(address(this), spender) < amount) {
+ compatApprove(token, spender, type(uint256).max);
+ }
+ }
+
+ /// @dev Calls `IERC20TokenV08(token).transfer()`.
+ /// Reverts if the return data is invalid or the call reverts.
+ /// @param token The address of the token contract.
+ /// @param to The address that receives the tokens
+ /// @param amount Number of tokens to transfer.
+ function compatTransfer(IERC20TokenV08 token, address to, uint256 amount) internal {
+ bytes memory callData = abi.encodeCall(token.transfer, (to, amount));
+ _callWithOptionalBooleanResult(address(token), callData);
+ }
+
+ /// @dev Calls `IERC20TokenV08(token).transferFrom()`.
+ /// Reverts if the return data is invalid or the call reverts.
+ /// @param token The address of the token contract.
+ /// @param from The owner of the tokens.
+ /// @param to The address that receives the tokens
+ /// @param amount Number of tokens to transfer.
+ function compatTransferFrom(IERC20TokenV08 token, address from, address to, uint256 amount) internal {
+ bytes memory callData = abi.encodeCall(token.transferFrom, (from, to, amount));
+ _callWithOptionalBooleanResult(address(token), callData);
+ }
+
+ /// @dev Retrieves the number of decimals for a token.
+ /// Returns `18` if the call reverts.
+ /// @param token The address of the token contract.
+ /// @return tokenDecimals The number of decimals places for the token.
+ function compatDecimals(IERC20TokenV08 token) internal view returns (uint8 tokenDecimals) {
+ tokenDecimals = 18;
+ (bool didSucceed, bytes memory resultData) = address(token).staticcall(DECIMALS_CALL_DATA);
+ if (didSucceed && resultData.length >= 32) {
+ tokenDecimals = abi.decode(resultData, (uint8));
+ }
+ }
+
+ /// @dev Retrieves the allowance for a token, owner, and spender.
+ /// Returns `0` if the call reverts.
+ /// @param token The address of the token contract.
+ /// @param owner The owner of the tokens.
+ /// @param spender The address the spender.
+ /// @return allowance_ The allowance for a token, owner, and spender.
+ function compatAllowance(
+ IERC20TokenV08 token,
+ address owner,
+ address spender
+ ) internal view returns (uint256 allowance_) {
+ (bool didSucceed, bytes memory resultData) = address(token).staticcall(
+ abi.encodeCall(token.allowance, (owner, spender))
+ );
+ if (didSucceed && resultData.length >= 32) {
+ allowance_ = abi.decode(resultData, (uint256));
+ }
+ }
+
+ /// @dev Retrieves the balance for a token owner.
+ /// Returns `0` if the call reverts.
+ /// @param token The address of the token contract.
+ /// @param owner The owner of the tokens.
+ /// @return balance The token balance of an owner.
+ function compatBalanceOf(IERC20TokenV08 token, address owner) internal view returns (uint256 balance) {
+ (bool didSucceed, bytes memory resultData) = address(token).staticcall(
+ abi.encodeCall(token.balanceOf, (owner))
+ );
+ if (didSucceed && resultData.length >= 32) {
+ balance = abi.decode(resultData, (uint256));
+ }
+ }
+
+ /// @dev Executes a call on address `target` with calldata `callData`
+ /// and asserts that either nothing was returned or a single boolean
+ /// was returned equal to `true`.
+ /// @param target The call target.
+ /// @param callData The abi-encoded call data.
+ function _callWithOptionalBooleanResult(address target, bytes memory callData) private {
+ (bool didSucceed, bytes memory resultData) = target.call(callData);
+ // Revert if the call reverted.
+ if (!didSucceed) {
+ LibRichErrorsV08.rrevert(resultData);
+ }
+ // If we get back 0 returndata, this may be a non-standard ERC-20 that
+ // does not return a boolean. Check that it at least contains code.
+ if (resultData.length == 0) {
+ require(target.code.length > 0, "invalid token address, contains no code");
+ return;
+ }
+ // If we get back at least 32 bytes, we know the target address
+ // contains code, and we assume it is a token that returned a boolean
+ // success value, which must be true.
+ if (resultData.length >= 32) {
+ if (!abi.decode(resultData, (bool))) {
+ LibRichErrorsV08.rrevert(resultData);
+ }
+ }
+ // If 0 < returndatasize < 32, the target is a contract, but not a
+ // valid token.
+ LibRichErrorsV08.rrevert(resultData);
+ }
+}
diff --git a/contracts/erc20/package.json b/contracts/erc20/package.json
index 541b89f68b..a070762e64 100644
--- a/contracts/erc20/package.json
+++ b/contracts/erc20/package.json
@@ -32,7 +32,7 @@
},
"config": {
"publicInterfaceContracts": "DummyERC20Token,ERC20Token,WETH9,ZRXToken,DummyNoReturnERC20Token,DummyMultipleReturnERC20Token",
- "abis": "./test/generated-artifacts/@(DummyERC20Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Token|IERC20Token|IERC20TokenV06|IEtherToken|IEtherTokenV06|LibERC20Token|LibERC20TokenV06|MintableERC20Token|TestLibERC20Token|TestLibERC20TokenTarget|UnlimitedAllowanceERC20Token|UntransferrableDummyERC20Token|WETH9|ZRXToken).json",
+ "abis": "./test/generated-artifacts/@(DummyERC20Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Token|IERC20Token|IERC20TokenV06|IERC20TokenV08|IEtherToken|IEtherTokenV06|IEtherTokenV08|LibERC20Token|LibERC20TokenV06|LibERC20TokenV08|MintableERC20Token|TestLibERC20Token|TestLibERC20TokenTarget|UnlimitedAllowanceERC20Token|UntransferrableDummyERC20Token|WETH9|ZRXToken).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {
diff --git a/contracts/erc20/test/artifacts.ts b/contracts/erc20/test/artifacts.ts
index 54624be41f..c81daa18c0 100644
--- a/contracts/erc20/test/artifacts.ts
+++ b/contracts/erc20/test/artifacts.ts
@@ -11,10 +11,13 @@ import * as DummyNoReturnERC20Token from '../test/generated-artifacts/DummyNoRet
import * as ERC20Token from '../test/generated-artifacts/ERC20Token.json';
import * as IERC20Token from '../test/generated-artifacts/IERC20Token.json';
import * as IERC20TokenV06 from '../test/generated-artifacts/IERC20TokenV06.json';
+import * as IERC20TokenV08 from '../test/generated-artifacts/IERC20TokenV08.json';
import * as IEtherToken from '../test/generated-artifacts/IEtherToken.json';
import * as IEtherTokenV06 from '../test/generated-artifacts/IEtherTokenV06.json';
+import * as IEtherTokenV08 from '../test/generated-artifacts/IEtherTokenV08.json';
import * as LibERC20Token from '../test/generated-artifacts/LibERC20Token.json';
import * as LibERC20TokenV06 from '../test/generated-artifacts/LibERC20TokenV06.json';
+import * as LibERC20TokenV08 from '../test/generated-artifacts/LibERC20TokenV08.json';
import * as MintableERC20Token from '../test/generated-artifacts/MintableERC20Token.json';
import * as TestLibERC20Token from '../test/generated-artifacts/TestLibERC20Token.json';
import * as TestLibERC20TokenTarget from '../test/generated-artifacts/TestLibERC20TokenTarget.json';
@@ -34,6 +37,9 @@ export const artifacts = {
IERC20TokenV06: IERC20TokenV06 as ContractArtifact,
IEtherTokenV06: IEtherTokenV06 as ContractArtifact,
LibERC20TokenV06: LibERC20TokenV06 as ContractArtifact,
+ IERC20TokenV08: IERC20TokenV08 as ContractArtifact,
+ IEtherTokenV08: IEtherTokenV08 as ContractArtifact,
+ LibERC20TokenV08: LibERC20TokenV08 as ContractArtifact,
DummyERC20Token: DummyERC20Token as ContractArtifact,
DummyMultipleReturnERC20Token: DummyMultipleReturnERC20Token as ContractArtifact,
DummyNoReturnERC20Token: DummyNoReturnERC20Token as ContractArtifact,
diff --git a/contracts/erc20/test/wrappers.ts b/contracts/erc20/test/wrappers.ts
index ec3d330a31..b639834d47 100644
--- a/contracts/erc20/test/wrappers.ts
+++ b/contracts/erc20/test/wrappers.ts
@@ -9,10 +9,13 @@ export * from '../test/generated-wrappers/dummy_no_return_erc20_token';
export * from '../test/generated-wrappers/erc20_token';
export * from '../test/generated-wrappers/i_erc20_token';
export * from '../test/generated-wrappers/i_erc20_token_v06';
+export * from '../test/generated-wrappers/i_erc20_token_v08';
export * from '../test/generated-wrappers/i_ether_token';
export * from '../test/generated-wrappers/i_ether_token_v06';
+export * from '../test/generated-wrappers/i_ether_token_v08';
export * from '../test/generated-wrappers/lib_erc20_token';
export * from '../test/generated-wrappers/lib_erc20_token_v06';
+export * from '../test/generated-wrappers/lib_erc20_token_v08';
export * from '../test/generated-wrappers/mintable_erc20_token';
export * from '../test/generated-wrappers/test_lib_erc20_token';
export * from '../test/generated-wrappers/test_lib_erc20_token_target';
diff --git a/contracts/erc20/tsconfig.json b/contracts/erc20/tsconfig.json
index 16af35ff1c..3589fc0b0b 100644
--- a/contracts/erc20/tsconfig.json
+++ b/contracts/erc20/tsconfig.json
@@ -15,10 +15,13 @@
"test/generated-artifacts/ERC20Token.json",
"test/generated-artifacts/IERC20Token.json",
"test/generated-artifacts/IERC20TokenV06.json",
+ "test/generated-artifacts/IERC20TokenV08.json",
"test/generated-artifacts/IEtherToken.json",
"test/generated-artifacts/IEtherTokenV06.json",
+ "test/generated-artifacts/IEtherTokenV08.json",
"test/generated-artifacts/LibERC20Token.json",
"test/generated-artifacts/LibERC20TokenV06.json",
+ "test/generated-artifacts/LibERC20TokenV08.json",
"test/generated-artifacts/MintableERC20Token.json",
"test/generated-artifacts/TestLibERC20Token.json",
"test/generated-artifacts/TestLibERC20TokenTarget.json",
diff --git a/contracts/utils/contracts/src/v08/AuthorizableV08.sol b/contracts/utils/contracts/src/v08/AuthorizableV08.sol
new file mode 100644
index 0000000000..105ad29a14
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/AuthorizableV08.sol
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./interfaces/IAuthorizableV08.sol";
+import "./errors/LibRichErrorsV08.sol";
+import "./errors/LibAuthorizableRichErrorsV08.sol";
+import "./OwnableV08.sol";
+
+contract AuthorizableV08 is OwnableV08, IAuthorizableV08 {
+ /// @dev Only authorized addresses can invoke functions with this modifier.
+ modifier onlyAuthorized() {
+ _assertSenderIsAuthorized();
+ _;
+ }
+
+ // @dev Whether an address is authorized to call privileged functions.
+ // @param 0 Address to query.
+ // @return 0 Whether the address is authorized.
+ mapping(address => bool) public override authorized;
+ // @dev Whether an address is authorized to call privileged functions.
+ // @param 0 Index of authorized address.
+ // @return 0 Authorized address.
+ address[] public override authorities;
+
+ /// @dev Initializes the `owner` address.
+ constructor() OwnableV08() {}
+
+ /// @dev Authorizes an address.
+ /// @param target Address to authorize.
+ function addAuthorizedAddress(address target) external override onlyOwner {
+ _addAuthorizedAddress(target);
+ }
+
+ /// @dev Removes authorizion of an address.
+ /// @param target Address to remove authorization from.
+ function removeAuthorizedAddress(address target) external override onlyOwner {
+ if (!authorized[target]) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.TargetNotAuthorizedError(target));
+ }
+ for (uint256 i = 0; i < authorities.length; i++) {
+ if (authorities[i] == target) {
+ _removeAuthorizedAddressAtIndex(target, i);
+ break;
+ }
+ }
+ }
+
+ /// @dev Removes authorizion of an address.
+ /// @param target Address to remove authorization from.
+ /// @param index Index of target in authorities array.
+ function removeAuthorizedAddressAtIndex(address target, uint256 index) external override onlyOwner {
+ _removeAuthorizedAddressAtIndex(target, index);
+ }
+
+ /// @dev Gets all authorized addresses.
+ /// @return Array of authorized addresses.
+ function getAuthorizedAddresses() external view override returns (address[] memory) {
+ return authorities;
+ }
+
+ /// @dev Reverts if msg.sender is not authorized.
+ function _assertSenderIsAuthorized() internal view {
+ if (!authorized[msg.sender]) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.SenderNotAuthorizedError(msg.sender));
+ }
+ }
+
+ /// @dev Authorizes an address.
+ /// @param target Address to authorize.
+ function _addAuthorizedAddress(address target) internal {
+ // Ensure that the target is not the zero address.
+ if (target == address(0)) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.ZeroCantBeAuthorizedError());
+ }
+
+ // Ensure that the target is not already authorized.
+ if (authorized[target]) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.TargetAlreadyAuthorizedError(target));
+ }
+
+ authorized[target] = true;
+ authorities.push(target);
+ emit AuthorizedAddressAdded(target, msg.sender);
+ }
+
+ /// @dev Removes authorizion of an address.
+ /// @param target Address to remove authorization from.
+ /// @param index Index of target in authorities array.
+ function _removeAuthorizedAddressAtIndex(address target, uint256 index) internal {
+ if (!authorized[target]) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.TargetNotAuthorizedError(target));
+ }
+ if (index >= authorities.length) {
+ LibRichErrorsV08.rrevert(LibAuthorizableRichErrorsV08.IndexOutOfBoundsError(index, authorities.length));
+ }
+ if (authorities[index] != target) {
+ LibRichErrorsV08.rrevert(
+ LibAuthorizableRichErrorsV08.AuthorizedAddressMismatchError(authorities[index], target)
+ );
+ }
+
+ delete authorized[target];
+ authorities[index] = authorities[authorities.length - 1];
+ authorities.pop();
+ emit AuthorizedAddressRemoved(target, msg.sender);
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/LibBytesV08.sol b/contracts/utils/contracts/src/v08/LibBytesV08.sol
new file mode 100644
index 0000000000..366d1a1008
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/LibBytesV08.sol
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./errors/LibBytesRichErrorsV08.sol";
+import "./errors/LibRichErrorsV08.sol";
+
+library LibBytesV08 {
+ using LibBytesV08 for bytes;
+
+ /// @dev Gets the memory address for a byte array.
+ /// @param input Byte array to lookup.
+ /// @return memoryAddress Memory address of byte array. This
+ /// points to the header of the byte array which contains
+ /// the length.
+ function rawAddress(bytes memory input) internal pure returns (uint256 memoryAddress) {
+ assembly ("memory-safe") {
+ memoryAddress := input
+ }
+ return memoryAddress;
+ }
+
+ /// @dev Gets the memory address for the contents of a byte array.
+ /// @param input Byte array to lookup.
+ /// @return memoryAddress Memory address of the contents of the byte array.
+ function contentAddress(bytes memory input) internal pure returns (uint256 memoryAddress) {
+ assembly ("memory-safe") {
+ memoryAddress := add(input, 32)
+ }
+ return memoryAddress;
+ }
+
+ /// @dev Copies `length` bytes from memory location `source` to `dest`.
+ /// @param dest memory address to copy bytes to.
+ /// @param source memory address to copy bytes from.
+ /// @param length number of bytes to copy.
+ function memCopy(uint256 dest, uint256 source, uint256 length) internal pure {
+ if (length < 32) {
+ // Handle a partial word by reading destination and masking
+ // off the bits we are interested in.
+ // This correctly handles overlap, zero lengths and source == dest
+ assembly {
+ let mask := sub(exp(256, sub(32, length)), 1)
+ let s := and(mload(source), not(mask))
+ let d := and(mload(dest), mask)
+ mstore(dest, or(s, d))
+ }
+ } else {
+ // Skip the O(length) loop when source == dest.
+ if (source == dest) {
+ return;
+ }
+
+ // For large copies we copy whole words at a time. The final
+ // word is aligned to the end of the range (instead of after the
+ // previous) to handle partial words. So a copy will look like this:
+ //
+ // ####
+ // ####
+ // ####
+ // ####
+ //
+ // We handle overlap in the source and destination range by
+ // changing the copying direction. This prevents us from
+ // overwriting parts of source that we still need to copy.
+ //
+ // This correctly handles source == dest
+ //
+ if (source > dest) {
+ assembly {
+ // We subtract 32 from `sEnd` and `dEnd` because it
+ // is easier to compare with in the loop, and these
+ // are also the addresses we need for copying the
+ // last bytes.
+ length := sub(length, 32)
+ let sEnd := add(source, length)
+ let dEnd := add(dest, length)
+
+ // Remember the last 32 bytes of source
+ // This needs to be done here and not after the loop
+ // because we may have overwritten the last bytes in
+ // source already due to overlap.
+ let last := mload(sEnd)
+
+ // Copy whole words front to back
+ // Note: the first check is always true,
+ // this could have been a do-while loop.
+ for {
+
+ } lt(source, sEnd) {
+
+ } {
+ mstore(dest, mload(source))
+ source := add(source, 32)
+ dest := add(dest, 32)
+ }
+
+ // Write the last 32 bytes
+ mstore(dEnd, last)
+ }
+ } else {
+ assembly {
+ // We subtract 32 from `sEnd` and `dEnd` because those
+ // are the starting points when copying a word at the end.
+ length := sub(length, 32)
+ let sEnd := add(source, length)
+ let dEnd := add(dest, length)
+
+ // Remember the first 32 bytes of source
+ // This needs to be done here and not after the loop
+ // because we may have overwritten the first bytes in
+ // source already due to overlap.
+ let first := mload(source)
+
+ // Copy whole words back to front
+ // We use a signed comparisson here to allow dEnd to become
+ // negative (happens when source and dest < 32). Valid
+ // addresses in local memory will never be larger than
+ // 2**255, so they can be safely re-interpreted as signed.
+ // Note: the first check is always true,
+ // this could have been a do-while loop.
+ for {
+
+ } slt(dest, dEnd) {
+
+ } {
+ mstore(dEnd, mload(sEnd))
+ sEnd := sub(sEnd, 32)
+ dEnd := sub(dEnd, 32)
+ }
+
+ // Write the first 32 bytes
+ mstore(dest, first)
+ }
+ }
+ }
+ }
+
+ /// @dev Returns a slices from a byte array.
+ /// @param b The byte array to take a slice from.
+ /// @param from The starting index for the slice (inclusive).
+ /// @param to The final index for the slice (exclusive).
+ /// @return result The slice containing bytes at indices [from, to)
+ function slice(bytes memory b, uint256 from, uint256 to) internal pure returns (bytes memory result) {
+ // Ensure that the from and to positions are valid positions for a slice within
+ // the byte array that is being used.
+ if (from > to) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,
+ from,
+ to
+ )
+ );
+ }
+ if (to > b.length) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,
+ to,
+ b.length
+ )
+ );
+ }
+
+ // Create a new bytes structure and copy contents
+ result = new bytes(to - from);
+ memCopy(result.contentAddress(), b.contentAddress() + from, result.length);
+ return result;
+ }
+
+ /// @dev Returns a slice from a byte array without preserving the input.
+ /// When `from == 0`, the original array will match the slice.
+ /// In other cases its state will be corrupted.
+ /// @param b The byte array to take a slice from. Will be destroyed in the process.
+ /// @param from The starting index for the slice (inclusive).
+ /// @param to The final index for the slice (exclusive).
+ /// @return result The slice containing bytes at indices [from, to)
+ function sliceDestructive(bytes memory b, uint256 from, uint256 to) internal pure returns (bytes memory result) {
+ // Ensure that the from and to positions are valid positions for a slice within
+ // the byte array that is being used.
+ if (from > to) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,
+ from,
+ to
+ )
+ );
+ }
+ if (to > b.length) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,
+ to,
+ b.length
+ )
+ );
+ }
+
+ // Create a new bytes structure around [from, to) in-place.
+ assembly {
+ result := add(b, from)
+ mstore(result, sub(to, from))
+ }
+ return result;
+ }
+
+ /// @dev Pops the last byte off of a byte array by modifying its length.
+ /// @param b Byte array that will be modified.
+ /// @return result The byte that was popped off.
+ function popLastByte(bytes memory b) internal pure returns (bytes1 result) {
+ if (b.length == 0) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanZeroRequired,
+ b.length,
+ 0
+ )
+ );
+ }
+
+ // Store last byte.
+ result = b[b.length - 1];
+
+ assembly ("memory-safe") {
+ // Decrement length of byte array.
+ let newLen := sub(mload(b), 1)
+ mstore(b, newLen)
+ }
+ return result;
+ }
+
+ /// @dev Tests equality of two byte arrays.
+ /// @param lhs First byte array to compare.
+ /// @param rhs Second byte array to compare.
+ /// @return equal True if arrays are the same. False otherwise.
+ function equals(bytes memory lhs, bytes memory rhs) internal pure returns (bool equal) {
+ // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.
+ return keccak256(lhs) == keccak256(rhs);
+ }
+
+ /// @dev Reads an address from a position in a byte array.
+ /// @param b Byte array containing an address.
+ /// @param index Index in byte array of address.
+ /// @return result address from byte array.
+ function readAddress(bytes memory b, uint256 index) internal pure returns (address result) {
+ if (b.length < index + 20) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,
+ b.length,
+ index + 20 // 20 is length of address
+ )
+ );
+ }
+
+ // Add offset to index:
+ // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
+ // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
+ index += 20;
+
+ // Read address from array memory
+ assembly ("memory-safe") {
+ // 1. Add index to address of bytes array
+ // 2. Load 32-byte word from memory
+ result := mload(add(b, index))
+ }
+ return result;
+ }
+
+ /// @dev Writes an address into a specific position in a byte array.
+ /// @param b Byte array to insert address into.
+ /// @param index Index in byte array of address.
+ /// @param input Address to put into byte array.
+ function writeAddress(bytes memory b, uint256 index, address input) internal pure {
+ if (b.length < index + 20) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,
+ b.length,
+ index + 20 // 20 is length of address
+ )
+ );
+ }
+
+ // Add offset to index:
+ // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
+ // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
+ index += 20;
+
+ // Store address into array memory
+ assembly ("memory-safe") {
+ // The address occupies 20 bytes and mstore stores 32 bytes.
+ // First fetch the 32-byte word where we'll be storing the address, then
+ // apply a mask so we have only the bytes in the word that the address will not occupy.
+ // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.
+
+ // 1. Add index to address of bytes array
+ // 2. Load 32-byte word from memory
+ // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address
+ let neighbors := and(
+ mload(add(b, index)),
+ 0xffffffffffffffffffffffff0000000000000000000000000000000000000000
+ )
+
+ // Make sure input address is clean.
+ // (Solidity does not guarantee this)
+ input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)
+
+ // Store the neighbors and address into memory
+ mstore(add(b, index), xor(input, neighbors))
+ }
+ }
+
+ /// @dev Reads a bytes32 value from a position in a byte array.
+ /// @param b Byte array containing a bytes32 value.
+ /// @param index Index in byte array of bytes32 value.
+ /// @return result bytes32 value from byte array.
+ function readBytes32(bytes memory b, uint256 index) internal pure returns (bytes32 result) {
+ if (b.length < index + 32) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,
+ b.length,
+ index + 32
+ )
+ );
+ }
+
+ // Arrays are prefixed by a 256 bit length parameter
+ index += 32;
+
+ // Read the bytes32 from array memory
+ assembly ("memory-safe") {
+ result := mload(add(b, index))
+ }
+ return result;
+ }
+
+ /// @dev Writes a bytes32 into a specific position in a byte array.
+ /// @param b Byte array to insert into.
+ /// @param index Index in byte array of .
+ /// @param input bytes32 to put into byte array.
+ function writeBytes32(bytes memory b, uint256 index, bytes32 input) internal pure {
+ if (b.length < index + 32) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,
+ b.length,
+ index + 32
+ )
+ );
+ }
+
+ // Arrays are prefixed by a 256 bit length parameter
+ index += 32;
+
+ // Read the bytes32 from array memory
+ assembly ("memory-safe") {
+ mstore(add(b, index), input)
+ }
+ }
+
+ /// @dev Reads a uint256 value from a position in a byte array.
+ /// @param b Byte array containing a uint256 value.
+ /// @param index Index in byte array of uint256 value.
+ /// @return result uint256 value from byte array.
+ function readUint256(bytes memory b, uint256 index) internal pure returns (uint256 result) {
+ result = uint256(readBytes32(b, index));
+ return result;
+ }
+
+ /// @dev Writes a uint256 into a specific position in a byte array.
+ /// @param b Byte array to insert into.
+ /// @param index Index in byte array of .
+ /// @param input uint256 to put into byte array.
+ function writeUint256(bytes memory b, uint256 index, uint256 input) internal pure {
+ writeBytes32(b, index, bytes32(input));
+ }
+
+ /// @dev Reads an unpadded bytes4 value from a position in a byte array.
+ /// @param b Byte array containing a bytes4 value.
+ /// @param index Index in byte array of bytes4 value.
+ /// @return result bytes4 value from byte array.
+ function readBytes4(bytes memory b, uint256 index) internal pure returns (bytes4 result) {
+ if (b.length < index + 4) {
+ LibRichErrorsV08.rrevert(
+ LibBytesRichErrorsV08.InvalidByteOperationError(
+ LibBytesRichErrorsV08.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsFourRequired,
+ b.length,
+ index + 4
+ )
+ );
+ }
+
+ // Arrays are prefixed by a 32 byte length field
+ index += 32;
+
+ // Read the bytes4 from array memory
+ assembly ("memory-safe") {
+ result := mload(add(b, index))
+ }
+ return result;
+ }
+
+ /// @dev Writes a new length to a byte array.
+ /// Decreasing length will lead to removing the corresponding lower order bytes from the byte array.
+ /// Increasing length may lead to appending adjacent in-memory bytes to the end of the byte array.
+ /// @param b Bytes array to write new length to.
+ /// @param length New length of byte array.
+ function writeLength(bytes memory b, uint256 length) internal pure {
+ assembly {
+ mstore(b, length)
+ }
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/LibMathV08.sol b/contracts/utils/contracts/src/v08/LibMathV08.sol
new file mode 100644
index 0000000000..9dec9e1cec
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/LibMathV08.sol
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./errors/LibRichErrorsV08.sol";
+import "./errors/LibMathRichErrorsV08.sol";
+import "./errors/LibSafeMathRichErrorsV08.sol";
+
+library LibMathV08 {
+ function max256(uint256 a, uint256 b) internal pure returns (uint256) {
+ return a >= b ? a : b;
+ }
+
+ function min256(uint256 a, uint256 b) internal pure returns (uint256) {
+ return a < b ? a : b;
+ }
+
+ function max128(uint128 a, uint128 b) internal pure returns (uint128) {
+ return a >= b ? a : b;
+ }
+
+ function min128(uint128 a, uint128 b) internal pure returns (uint128) {
+ return a < b ? a : b;
+ }
+
+ function safeDowncastToUint128(uint256 a) internal pure returns (uint128) {
+ if (a > type(uint128).max) {
+ LibRichErrorsV08.rrevert(
+ LibSafeMathRichErrorsV08.Uint256DowncastError(
+ LibSafeMathRichErrorsV08.DowncastErrorCodes.VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT128,
+ a
+ )
+ );
+ }
+ return uint128(a);
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// Reverts if rounding error is >= 0.1%
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return partialAmount Partial value of target rounded down.
+ function safeGetPartialAmountFloor(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (uint256 partialAmount) {
+ if (isRoundingErrorFloor(numerator, denominator, target)) {
+ LibRichErrorsV08.rrevert(LibMathRichErrorsV08.RoundingError(numerator, denominator, target));
+ }
+
+ partialAmount = (numerator * target) / denominator;
+ return partialAmount;
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// Reverts if rounding error is >= 0.1%
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return partialAmount Partial value of target rounded up.
+ function safeGetPartialAmountCeil(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (uint256 partialAmount) {
+ if (isRoundingErrorCeil(numerator, denominator, target)) {
+ LibRichErrorsV08.rrevert(LibMathRichErrorsV08.RoundingError(numerator, denominator, target));
+ }
+
+ // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):
+ // ceil(a / b) = floor((a + b - 1) / b)
+ // To implement `ceil(a / b)` using safeDiv.
+ partialAmount = (numerator * target + (denominator - 1)) / denominator;
+
+ return partialAmount;
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return partialAmount Partial value of target rounded down.
+ function getPartialAmountFloor(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (uint256 partialAmount) {
+ partialAmount = (numerator * target) / denominator;
+ return partialAmount;
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return partialAmount Partial value of target rounded up.
+ function getPartialAmountCeil(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (uint256 partialAmount) {
+ // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):
+ // ceil(a / b) = floor((a + b - 1) / b)
+ // To implement `ceil(a / b)` using safeDiv.
+ partialAmount = (numerator * target + (denominator - 1)) / denominator;
+
+ return partialAmount;
+ }
+
+ /// @dev Checks if rounding error >= 0.1% when rounding down.
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to multiply with numerator/denominator.
+ /// @return isError Rounding error is present.
+ function isRoundingErrorFloor(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (bool isError) {
+ if (denominator == 0) {
+ LibRichErrorsV08.rrevert(LibMathRichErrorsV08.DivisionByZeroError());
+ }
+
+ // The absolute rounding error is the difference between the rounded
+ // value and the ideal value. The relative rounding error is the
+ // absolute rounding error divided by the absolute value of the
+ // ideal value. This is undefined when the ideal value is zero.
+ //
+ // The ideal value is `numerator * target / denominator`.
+ // Let's call `numerator * target % denominator` the remainder.
+ // The absolute error is `remainder / denominator`.
+ //
+ // When the ideal value is zero, we require the absolute error to
+ // be zero. Fortunately, this is always the case. The ideal value is
+ // zero iff `numerator == 0` and/or `target == 0`. In this case the
+ // remainder and absolute error are also zero.
+ if (target == 0 || numerator == 0) {
+ return false;
+ }
+
+ // Otherwise, we want the relative rounding error to be strictly
+ // less than 0.1%.
+ // The relative error is `remainder / (numerator * target)`.
+ // We want the relative error less than 1 / 1000:
+ // remainder / (numerator * denominator) < 1 / 1000
+ // or equivalently:
+ // 1000 * remainder < numerator * target
+ // so we have a rounding error iff:
+ // 1000 * remainder >= numerator * target
+ uint256 remainder = mulmod(target, numerator, denominator);
+ isError = remainder * 1000 >= numerator * target;
+ return isError;
+ }
+
+ /// @dev Checks if rounding error >= 0.1% when rounding up.
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to multiply with numerator/denominator.
+ /// @return isError Rounding error is present.
+ function isRoundingErrorCeil(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (bool isError) {
+ if (denominator == 0) {
+ LibRichErrorsV08.rrevert(LibMathRichErrorsV08.DivisionByZeroError());
+ }
+
+ // See the comments in `isRoundingError`.
+ if (target == 0 || numerator == 0) {
+ // When either is zero, the ideal value and rounded value are zero
+ // and there is no rounding error. (Although the relative error
+ // is undefined.)
+ return false;
+ }
+ // Compute remainder as before
+ uint256 remainder = mulmod(target, numerator, denominator);
+ remainder = denominator - (remainder % denominator);
+ isError = remainder * 1000 >= numerator * target;
+ return isError;
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/OwnableV08.sol b/contracts/utils/contracts/src/v08/OwnableV08.sol
new file mode 100644
index 0000000000..cf5a3ce113
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/OwnableV08.sol
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./interfaces/IOwnableV08.sol";
+import "./errors/LibRichErrorsV08.sol";
+import "./errors/LibOwnableRichErrorsV08.sol";
+
+contract OwnableV08 is IOwnableV08 {
+ /// @dev The owner of this contract.
+ /// @return 0 The owner address.
+ address public override owner;
+
+ constructor() {
+ owner = msg.sender;
+ }
+
+ modifier onlyOwner() {
+ _assertSenderIsOwner();
+ _;
+ }
+
+ /// @dev Change the owner of this contract.
+ /// @param newOwner New owner address.
+ function transferOwnership(address newOwner) public override onlyOwner {
+ if (newOwner == address(0)) {
+ LibRichErrorsV08.rrevert(LibOwnableRichErrorsV08.TransferOwnerToZeroError());
+ } else {
+ owner = newOwner;
+ emit OwnershipTransferred(msg.sender, newOwner);
+ }
+ }
+
+ function _assertSenderIsOwner() internal view {
+ if (msg.sender != owner) {
+ LibRichErrorsV08.rrevert(LibOwnableRichErrorsV08.OnlyOwnerError(msg.sender, owner));
+ }
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/ReentrancyGuardV08.sol b/contracts/utils/contracts/src/v08/ReentrancyGuardV08.sol
new file mode 100644
index 0000000000..ea65661445
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/ReentrancyGuardV08.sol
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./errors/LibReentrancyGuardRichErrorsV08.sol";
+import "./errors/LibRichErrorsV08.sol";
+
+contract ReentrancyGuardV08 {
+ // Locked state of mutex.
+ bool private _locked = false;
+
+ /// @dev Functions with this modifer cannot be reentered. The mutex will be locked
+ /// before function execution and unlocked after.
+ modifier nonReentrant() {
+ _lockMutexOrThrowIfAlreadyLocked();
+ _;
+ _unlockMutex();
+ }
+
+ function _lockMutexOrThrowIfAlreadyLocked() internal {
+ // Ensure mutex is unlocked.
+ if (_locked) {
+ LibRichErrorsV08.rrevert(LibReentrancyGuardRichErrorsV08.IllegalReentrancyError());
+ }
+ // Lock mutex.
+ _locked = true;
+ }
+
+ function _unlockMutex() internal {
+ // Unlock mutex.
+ _locked = false;
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibAuthorizableRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibAuthorizableRichErrorsV08.sol
new file mode 100644
index 0000000000..c797694e72
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibAuthorizableRichErrorsV08.sol
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibAuthorizableRichErrorsV08 {
+ // bytes4(keccak256("AuthorizedAddressMismatchError(address,address)"))
+ bytes4 internal constant AUTHORIZED_ADDRESS_MISMATCH_ERROR_SELECTOR = 0x140a84db;
+
+ // bytes4(keccak256("IndexOutOfBoundsError(uint256,uint256)"))
+ bytes4 internal constant INDEX_OUT_OF_BOUNDS_ERROR_SELECTOR = 0xe9f83771;
+
+ // bytes4(keccak256("SenderNotAuthorizedError(address)"))
+ bytes4 internal constant SENDER_NOT_AUTHORIZED_ERROR_SELECTOR = 0xb65a25b9;
+
+ // bytes4(keccak256("TargetAlreadyAuthorizedError(address)"))
+ bytes4 internal constant TARGET_ALREADY_AUTHORIZED_ERROR_SELECTOR = 0xde16f1a0;
+
+ // bytes4(keccak256("TargetNotAuthorizedError(address)"))
+ bytes4 internal constant TARGET_NOT_AUTHORIZED_ERROR_SELECTOR = 0xeb5108a2;
+
+ // bytes4(keccak256("ZeroCantBeAuthorizedError()"))
+ bytes internal constant ZERO_CANT_BE_AUTHORIZED_ERROR_BYTES = hex"57654fe4";
+
+ function AuthorizedAddressMismatchError(address authorized, address target) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(AUTHORIZED_ADDRESS_MISMATCH_ERROR_SELECTOR, authorized, target);
+ }
+
+ function IndexOutOfBoundsError(uint256 index, uint256 length) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(INDEX_OUT_OF_BOUNDS_ERROR_SELECTOR, index, length);
+ }
+
+ function SenderNotAuthorizedError(address sender) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(SENDER_NOT_AUTHORIZED_ERROR_SELECTOR, sender);
+ }
+
+ function TargetAlreadyAuthorizedError(address target) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(TARGET_ALREADY_AUTHORIZED_ERROR_SELECTOR, target);
+ }
+
+ function TargetNotAuthorizedError(address target) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(TARGET_NOT_AUTHORIZED_ERROR_SELECTOR, target);
+ }
+
+ function ZeroCantBeAuthorizedError() internal pure returns (bytes memory) {
+ return ZERO_CANT_BE_AUTHORIZED_ERROR_BYTES;
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibBytesRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibBytesRichErrorsV08.sol
new file mode 100644
index 0000000000..1af85568e3
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibBytesRichErrorsV08.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibBytesRichErrorsV08 {
+ enum InvalidByteOperationErrorCodes {
+ FromLessThanOrEqualsToRequired,
+ ToLessThanOrEqualsLengthRequired,
+ LengthGreaterThanZeroRequired,
+ LengthGreaterThanOrEqualsFourRequired,
+ LengthGreaterThanOrEqualsTwentyRequired,
+ LengthGreaterThanOrEqualsThirtyTwoRequired,
+ LengthGreaterThanOrEqualsNestedBytesLengthRequired,
+ DestinationLengthGreaterThanOrEqualSourceLengthRequired
+ }
+
+ // bytes4(keccak256("InvalidByteOperationError(uint8,uint256,uint256)"))
+ bytes4 internal constant INVALID_BYTE_OPERATION_ERROR_SELECTOR = 0x28006595;
+
+ function InvalidByteOperationError(
+ InvalidByteOperationErrorCodes errorCode,
+ uint256 offset,
+ uint256 required
+ ) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(INVALID_BYTE_OPERATION_ERROR_SELECTOR, errorCode, offset, required);
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibMathRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibMathRichErrorsV08.sol
new file mode 100644
index 0000000000..83c619e256
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibMathRichErrorsV08.sol
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibMathRichErrorsV08 {
+ // bytes4(keccak256("DivisionByZeroError()"))
+ bytes internal constant DIVISION_BY_ZERO_ERROR = hex"a791837c";
+
+ // bytes4(keccak256("RoundingError(uint256,uint256,uint256)"))
+ bytes4 internal constant ROUNDING_ERROR_SELECTOR = 0x339f3de2;
+
+ function DivisionByZeroError() internal pure returns (bytes memory) {
+ return DIVISION_BY_ZERO_ERROR;
+ }
+
+ function RoundingError(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ ) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(ROUNDING_ERROR_SELECTOR, numerator, denominator, target);
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibOwnableRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibOwnableRichErrorsV08.sol
new file mode 100644
index 0000000000..e63eed58b0
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibOwnableRichErrorsV08.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibOwnableRichErrorsV08 {
+ // bytes4(keccak256("OnlyOwnerError(address,address)"))
+ bytes4 internal constant ONLY_OWNER_ERROR_SELECTOR = 0x1de45ad1;
+
+ // bytes4(keccak256("TransferOwnerToZeroError()"))
+ bytes internal constant TRANSFER_OWNER_TO_ZERO_ERROR_BYTES = hex"e69edc3e";
+
+ function OnlyOwnerError(address sender, address owner) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(ONLY_OWNER_ERROR_SELECTOR, sender, owner);
+ }
+
+ function TransferOwnerToZeroError() internal pure returns (bytes memory) {
+ return TRANSFER_OWNER_TO_ZERO_ERROR_BYTES;
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibReentrancyGuardRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibReentrancyGuardRichErrorsV08.sol
new file mode 100644
index 0000000000..b3881c9288
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibReentrancyGuardRichErrorsV08.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibReentrancyGuardRichErrorsV08 {
+ // bytes4(keccak256("IllegalReentrancyError()"))
+ bytes internal constant ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES = hex"0c3b823f";
+
+ function IllegalReentrancyError() internal pure returns (bytes memory) {
+ return ILLEGAL_REENTRANCY_ERROR_SELECTOR_BYTES;
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibRichErrorsV08.sol
new file mode 100644
index 0000000000..f05b40c39a
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibRichErrorsV08.sol
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibRichErrorsV08 {
+ // bytes4(keccak256("Error(string)"))
+ bytes4 internal constant STANDARD_ERROR_SELECTOR = 0x08c379a0;
+
+ /// @dev ABI encode a standard, string revert error payload.
+ /// This is the same payload that would be included by a `revert(string)`
+ /// solidity statement. It has the function signature `Error(string)`.
+ /// @param message The error string.
+ /// @return The ABI encoded error.
+ function StandardError(string memory message) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(STANDARD_ERROR_SELECTOR, bytes(message));
+ }
+
+ /// @dev Reverts an encoded rich revert reason `errorData`.
+ /// @param errorData ABI encoded error data.
+ function rrevert(bytes memory errorData) internal pure {
+ assembly ("memory-safe") {
+ revert(add(errorData, 0x20), mload(errorData))
+ }
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/errors/LibSafeMathRichErrorsV08.sol b/contracts/utils/contracts/src/v08/errors/LibSafeMathRichErrorsV08.sol
new file mode 100644
index 0000000000..7456323664
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/errors/LibSafeMathRichErrorsV08.sol
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+library LibSafeMathRichErrorsV08 {
+ // bytes4(keccak256("Uint256BinOpError(uint8,uint256,uint256)"))
+ bytes4 internal constant UINT256_BINOP_ERROR_SELECTOR = 0xe946c1bb;
+
+ // bytes4(keccak256("Uint256DowncastError(uint8,uint256)"))
+ bytes4 internal constant UINT256_DOWNCAST_ERROR_SELECTOR = 0xc996af7b;
+
+ enum BinOpErrorCodes {
+ ADDITION_OVERFLOW,
+ MULTIPLICATION_OVERFLOW,
+ SUBTRACTION_UNDERFLOW,
+ DIVISION_BY_ZERO
+ }
+
+ enum DowncastErrorCodes {
+ VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT32,
+ VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64,
+ VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96,
+ VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT128
+ }
+
+ function Uint256BinOpError(BinOpErrorCodes errorCode, uint256 a, uint256 b) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(UINT256_BINOP_ERROR_SELECTOR, errorCode, a, b);
+ }
+
+ function Uint256DowncastError(DowncastErrorCodes errorCode, uint256 a) internal pure returns (bytes memory) {
+ return abi.encodeWithSelector(UINT256_DOWNCAST_ERROR_SELECTOR, errorCode, a);
+ }
+}
diff --git a/contracts/utils/contracts/src/v08/interfaces/IAuthorizableV08.sol b/contracts/utils/contracts/src/v08/interfaces/IAuthorizableV08.sol
new file mode 100644
index 0000000000..3102f2ed29
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/interfaces/IAuthorizableV08.sol
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+import "./IOwnableV08.sol";
+
+interface IAuthorizableV08 is IOwnableV08 {
+ // Event logged when a new address is authorized.
+ event AuthorizedAddressAdded(address indexed target, address indexed caller);
+
+ // Event logged when a currently authorized address is unauthorized.
+ event AuthorizedAddressRemoved(address indexed target, address indexed caller);
+
+ /// @dev Authorizes an address.
+ /// @param target Address to authorize.
+ function addAuthorizedAddress(address target) external;
+
+ /// @dev Removes authorizion of an address.
+ /// @param target Address to remove authorization from.
+ function removeAuthorizedAddress(address target) external;
+
+ /// @dev Removes authorizion of an address.
+ /// @param target Address to remove authorization from.
+ /// @param index Index of target in authorities array.
+ function removeAuthorizedAddressAtIndex(address target, uint256 index) external;
+
+ /// @dev Gets all authorized addresses.
+ /// @return authorizedAddresses Array of authorized addresses.
+ function getAuthorizedAddresses() external view returns (address[] memory authorizedAddresses);
+
+ /// @dev Whether an adderss is authorized to call privileged functions.
+ /// @param addr Address to query.
+ /// @return isAuthorized Whether the address is authorized.
+ function authorized(address addr) external view returns (bool isAuthorized);
+
+ /// @dev All addresseses authorized to call privileged functions.
+ /// @param idx Index of authorized address.
+ /// @return addr Authorized address.
+ function authorities(uint256 idx) external view returns (address addr);
+}
diff --git a/contracts/utils/contracts/src/v08/interfaces/IOwnableV08.sol b/contracts/utils/contracts/src/v08/interfaces/IOwnableV08.sol
new file mode 100644
index 0000000000..ba097c0c3d
--- /dev/null
+++ b/contracts/utils/contracts/src/v08/interfaces/IOwnableV08.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+
+ 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.8;
+
+interface IOwnableV08 {
+ /// @dev Emitted by Ownable when ownership is transferred.
+ /// @param previousOwner The previous owner of the contract.
+ /// @param newOwner The new owner of the contract.
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
+
+ /// @dev Transfers ownership of the contract to a new address.
+ /// @param newOwner The address that will become the owner.
+ function transferOwnership(address newOwner) external;
+
+ /// @dev The owner of this contract.
+ /// @return ownerAddress The owner address.
+ function owner() external view returns (address ownerAddress);
+}
diff --git a/contracts/utils/package.json b/contracts/utils/package.json
index 187b65167c..cafa3586dc 100644
--- a/contracts/utils/package.json
+++ b/contracts/utils/package.json
@@ -32,7 +32,7 @@
"config": {
"publicInterfaceContracts": "Authorizable,IAuthorizable,IOwnable,LibAddress,LibAddressArray,LibAddressArrayRichErrors,LibAuthorizableRichErrors,LibBytes,LibBytesRichErrors,LibEIP1271,LibEIP712,LibFractions,LibOwnableRichErrors,LibReentrancyGuardRichErrors,LibRichErrors,LibMath,LibMathRichErrors,LibSafeMath,LibSafeMathRichErrors,Ownable,ReentrancyGuard,Refundable",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
- "abis": "./test/generated-artifacts/@(Authorizable|AuthorizableV06|D18|DeploymentConstants|IAuthorizable|IAuthorizableV06|IOwnable|IOwnableV06|LibAddress|LibAddressArray|LibAddressArrayRichErrors|LibAuthorizableRichErrors|LibAuthorizableRichErrorsV06|LibBytes|LibBytesRichErrors|LibBytesRichErrorsV06|LibBytesV06|LibEIP1271|LibEIP712|LibFractions|LibMath|LibMathRichErrors|LibMathRichErrorsV06|LibMathV06|LibOwnableRichErrors|LibOwnableRichErrorsV06|LibReentrancyGuardRichErrors|LibReentrancyGuardRichErrorsV06|LibRichErrors|LibRichErrorsV06|LibSafeMath|LibSafeMathRichErrors|LibSafeMathRichErrorsV06|LibSafeMathV06|Ownable|OwnableV06|ReentrancyGuard|ReentrancyGuardV06|Refundable|TestAuthorizable|TestLibAddress|TestLibAddressArray|TestLibBytes|TestLibEIP712|TestLibMath|TestLibRichErrors|TestLibSafeMath|TestLogDecoding|TestLogDecodingDownstream|TestOwnable|TestReentrancyGuard|TestRefundable|TestRefundableReceiver).json"
+ "abis": "./test/generated-artifacts/@(Authorizable|AuthorizableV06|AuthorizableV08|D18|DeploymentConstants|IAuthorizable|IAuthorizableV06|IAuthorizableV08|IOwnable|IOwnableV06|IOwnableV08|LibAddress|LibAddressArray|LibAddressArrayRichErrors|LibAuthorizableRichErrors|LibAuthorizableRichErrorsV06|LibAuthorizableRichErrorsV08|LibBytes|LibBytesRichErrors|LibBytesRichErrorsV06|LibBytesRichErrorsV08|LibBytesV06|LibBytesV08|LibEIP1271|LibEIP712|LibFractions|LibMath|LibMathRichErrors|LibMathRichErrorsV06|LibMathRichErrorsV08|LibMathV06|LibMathV08|LibOwnableRichErrors|LibOwnableRichErrorsV06|LibOwnableRichErrorsV08|LibReentrancyGuardRichErrors|LibReentrancyGuardRichErrorsV06|LibReentrancyGuardRichErrorsV08|LibRichErrors|LibRichErrorsV06|LibRichErrorsV08|LibSafeMath|LibSafeMathRichErrors|LibSafeMathRichErrorsV06|LibSafeMathRichErrorsV08|LibSafeMathV06|Ownable|OwnableV06|OwnableV08|ReentrancyGuard|ReentrancyGuardV06|ReentrancyGuardV08|Refundable|TestAuthorizable|TestLibAddress|TestLibAddressArray|TestLibBytes|TestLibEIP712|TestLibMath|TestLibRichErrors|TestLibSafeMath|TestLogDecoding|TestLogDecodingDownstream|TestOwnable|TestReentrancyGuard|TestRefundable|TestRefundableReceiver).json"
},
"repository": {
"type": "git",
diff --git a/contracts/utils/test/artifacts.ts b/contracts/utils/test/artifacts.ts
index 2868d4e26a..fe873bd827 100644
--- a/contracts/utils/test/artifacts.ts
+++ b/contracts/utils/test/artifacts.ts
@@ -7,42 +7,56 @@ import { ContractArtifact } from 'ethereum-types';
import * as Authorizable from '../test/generated-artifacts/Authorizable.json';
import * as AuthorizableV06 from '../test/generated-artifacts/AuthorizableV06.json';
+import * as AuthorizableV08 from '../test/generated-artifacts/AuthorizableV08.json';
import * as D18 from '../test/generated-artifacts/D18.json';
import * as DeploymentConstants from '../test/generated-artifacts/DeploymentConstants.json';
import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json';
import * as IAuthorizableV06 from '../test/generated-artifacts/IAuthorizableV06.json';
+import * as IAuthorizableV08 from '../test/generated-artifacts/IAuthorizableV08.json';
import * as IOwnable from '../test/generated-artifacts/IOwnable.json';
import * as IOwnableV06 from '../test/generated-artifacts/IOwnableV06.json';
+import * as IOwnableV08 from '../test/generated-artifacts/IOwnableV08.json';
import * as LibAddress from '../test/generated-artifacts/LibAddress.json';
import * as LibAddressArray from '../test/generated-artifacts/LibAddressArray.json';
import * as LibAddressArrayRichErrors from '../test/generated-artifacts/LibAddressArrayRichErrors.json';
import * as LibAuthorizableRichErrors from '../test/generated-artifacts/LibAuthorizableRichErrors.json';
import * as LibAuthorizableRichErrorsV06 from '../test/generated-artifacts/LibAuthorizableRichErrorsV06.json';
+import * as LibAuthorizableRichErrorsV08 from '../test/generated-artifacts/LibAuthorizableRichErrorsV08.json';
import * as LibBytes from '../test/generated-artifacts/LibBytes.json';
import * as LibBytesRichErrors from '../test/generated-artifacts/LibBytesRichErrors.json';
import * as LibBytesRichErrorsV06 from '../test/generated-artifacts/LibBytesRichErrorsV06.json';
+import * as LibBytesRichErrorsV08 from '../test/generated-artifacts/LibBytesRichErrorsV08.json';
import * as LibBytesV06 from '../test/generated-artifacts/LibBytesV06.json';
+import * as LibBytesV08 from '../test/generated-artifacts/LibBytesV08.json';
import * as LibEIP1271 from '../test/generated-artifacts/LibEIP1271.json';
import * as LibEIP712 from '../test/generated-artifacts/LibEIP712.json';
import * as LibFractions from '../test/generated-artifacts/LibFractions.json';
import * as LibMath from '../test/generated-artifacts/LibMath.json';
import * as LibMathRichErrors from '../test/generated-artifacts/LibMathRichErrors.json';
import * as LibMathRichErrorsV06 from '../test/generated-artifacts/LibMathRichErrorsV06.json';
+import * as LibMathRichErrorsV08 from '../test/generated-artifacts/LibMathRichErrorsV08.json';
import * as LibMathV06 from '../test/generated-artifacts/LibMathV06.json';
+import * as LibMathV08 from '../test/generated-artifacts/LibMathV08.json';
import * as LibOwnableRichErrors from '../test/generated-artifacts/LibOwnableRichErrors.json';
import * as LibOwnableRichErrorsV06 from '../test/generated-artifacts/LibOwnableRichErrorsV06.json';
+import * as LibOwnableRichErrorsV08 from '../test/generated-artifacts/LibOwnableRichErrorsV08.json';
import * as LibReentrancyGuardRichErrors from '../test/generated-artifacts/LibReentrancyGuardRichErrors.json';
import * as LibReentrancyGuardRichErrorsV06 from '../test/generated-artifacts/LibReentrancyGuardRichErrorsV06.json';
+import * as LibReentrancyGuardRichErrorsV08 from '../test/generated-artifacts/LibReentrancyGuardRichErrorsV08.json';
import * as LibRichErrors from '../test/generated-artifacts/LibRichErrors.json';
import * as LibRichErrorsV06 from '../test/generated-artifacts/LibRichErrorsV06.json';
+import * as LibRichErrorsV08 from '../test/generated-artifacts/LibRichErrorsV08.json';
import * as LibSafeMath from '../test/generated-artifacts/LibSafeMath.json';
import * as LibSafeMathRichErrors from '../test/generated-artifacts/LibSafeMathRichErrors.json';
import * as LibSafeMathRichErrorsV06 from '../test/generated-artifacts/LibSafeMathRichErrorsV06.json';
+import * as LibSafeMathRichErrorsV08 from '../test/generated-artifacts/LibSafeMathRichErrorsV08.json';
import * as LibSafeMathV06 from '../test/generated-artifacts/LibSafeMathV06.json';
import * as Ownable from '../test/generated-artifacts/Ownable.json';
import * as OwnableV06 from '../test/generated-artifacts/OwnableV06.json';
+import * as OwnableV08 from '../test/generated-artifacts/OwnableV08.json';
import * as ReentrancyGuard from '../test/generated-artifacts/ReentrancyGuard.json';
import * as ReentrancyGuardV06 from '../test/generated-artifacts/ReentrancyGuardV06.json';
+import * as ReentrancyGuardV08 from '../test/generated-artifacts/ReentrancyGuardV08.json';
import * as Refundable from '../test/generated-artifacts/Refundable.json';
import * as TestAuthorizable from '../test/generated-artifacts/TestAuthorizable.json';
import * as TestLibAddress from '../test/generated-artifacts/TestLibAddress.json';
@@ -98,6 +112,20 @@ export const artifacts = {
LibSafeMathRichErrorsV06: LibSafeMathRichErrorsV06 as ContractArtifact,
IAuthorizableV06: IAuthorizableV06 as ContractArtifact,
IOwnableV06: IOwnableV06 as ContractArtifact,
+ AuthorizableV08: AuthorizableV08 as ContractArtifact,
+ LibBytesV08: LibBytesV08 as ContractArtifact,
+ LibMathV08: LibMathV08 as ContractArtifact,
+ OwnableV08: OwnableV08 as ContractArtifact,
+ ReentrancyGuardV08: ReentrancyGuardV08 as ContractArtifact,
+ LibAuthorizableRichErrorsV08: LibAuthorizableRichErrorsV08 as ContractArtifact,
+ LibBytesRichErrorsV08: LibBytesRichErrorsV08 as ContractArtifact,
+ LibMathRichErrorsV08: LibMathRichErrorsV08 as ContractArtifact,
+ LibOwnableRichErrorsV08: LibOwnableRichErrorsV08 as ContractArtifact,
+ LibReentrancyGuardRichErrorsV08: LibReentrancyGuardRichErrorsV08 as ContractArtifact,
+ LibRichErrorsV08: LibRichErrorsV08 as ContractArtifact,
+ LibSafeMathRichErrorsV08: LibSafeMathRichErrorsV08 as ContractArtifact,
+ IAuthorizableV08: IAuthorizableV08 as ContractArtifact,
+ IOwnableV08: IOwnableV08 as ContractArtifact,
TestAuthorizable: TestAuthorizable as ContractArtifact,
TestLibAddress: TestLibAddress as ContractArtifact,
TestLibAddressArray: TestLibAddressArray as ContractArtifact,
diff --git a/contracts/utils/test/wrappers.ts b/contracts/utils/test/wrappers.ts
index 8f75985e7a..0400162154 100644
--- a/contracts/utils/test/wrappers.ts
+++ b/contracts/utils/test/wrappers.ts
@@ -5,42 +5,56 @@
*/
export * from '../test/generated-wrappers/authorizable';
export * from '../test/generated-wrappers/authorizable_v06';
+export * from '../test/generated-wrappers/authorizable_v08';
export * from '../test/generated-wrappers/d18';
export * from '../test/generated-wrappers/deployment_constants';
export * from '../test/generated-wrappers/i_authorizable';
export * from '../test/generated-wrappers/i_authorizable_v06';
+export * from '../test/generated-wrappers/i_authorizable_v08';
export * from '../test/generated-wrappers/i_ownable';
export * from '../test/generated-wrappers/i_ownable_v06';
+export * from '../test/generated-wrappers/i_ownable_v08';
export * from '../test/generated-wrappers/lib_address';
export * from '../test/generated-wrappers/lib_address_array';
export * from '../test/generated-wrappers/lib_address_array_rich_errors';
export * from '../test/generated-wrappers/lib_authorizable_rich_errors';
export * from '../test/generated-wrappers/lib_authorizable_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_authorizable_rich_errors_v08';
export * from '../test/generated-wrappers/lib_bytes';
export * from '../test/generated-wrappers/lib_bytes_rich_errors';
export * from '../test/generated-wrappers/lib_bytes_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_bytes_rich_errors_v08';
export * from '../test/generated-wrappers/lib_bytes_v06';
+export * from '../test/generated-wrappers/lib_bytes_v08';
export * from '../test/generated-wrappers/lib_e_i_p1271';
export * from '../test/generated-wrappers/lib_e_i_p712';
export * from '../test/generated-wrappers/lib_fractions';
export * from '../test/generated-wrappers/lib_math';
export * from '../test/generated-wrappers/lib_math_rich_errors';
export * from '../test/generated-wrappers/lib_math_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_math_rich_errors_v08';
export * from '../test/generated-wrappers/lib_math_v06';
+export * from '../test/generated-wrappers/lib_math_v08';
export * from '../test/generated-wrappers/lib_ownable_rich_errors';
export * from '../test/generated-wrappers/lib_ownable_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_ownable_rich_errors_v08';
export * from '../test/generated-wrappers/lib_reentrancy_guard_rich_errors';
export * from '../test/generated-wrappers/lib_reentrancy_guard_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_reentrancy_guard_rich_errors_v08';
export * from '../test/generated-wrappers/lib_rich_errors';
export * from '../test/generated-wrappers/lib_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_rich_errors_v08';
export * from '../test/generated-wrappers/lib_safe_math';
export * from '../test/generated-wrappers/lib_safe_math_rich_errors';
export * from '../test/generated-wrappers/lib_safe_math_rich_errors_v06';
+export * from '../test/generated-wrappers/lib_safe_math_rich_errors_v08';
export * from '../test/generated-wrappers/lib_safe_math_v06';
export * from '../test/generated-wrappers/ownable';
export * from '../test/generated-wrappers/ownable_v06';
+export * from '../test/generated-wrappers/ownable_v08';
export * from '../test/generated-wrappers/reentrancy_guard';
export * from '../test/generated-wrappers/reentrancy_guard_v06';
+export * from '../test/generated-wrappers/reentrancy_guard_v08';
export * from '../test/generated-wrappers/refundable';
export * from '../test/generated-wrappers/test_authorizable';
export * from '../test/generated-wrappers/test_lib_address';
diff --git a/contracts/utils/tsconfig.json b/contracts/utils/tsconfig.json
index 0f4ccb13e4..36c7fc7d26 100644
--- a/contracts/utils/tsconfig.json
+++ b/contracts/utils/tsconfig.json
@@ -27,42 +27,56 @@
"generated-artifacts/Refundable.json",
"test/generated-artifacts/Authorizable.json",
"test/generated-artifacts/AuthorizableV06.json",
+ "test/generated-artifacts/AuthorizableV08.json",
"test/generated-artifacts/D18.json",
"test/generated-artifacts/DeploymentConstants.json",
"test/generated-artifacts/IAuthorizable.json",
"test/generated-artifacts/IAuthorizableV06.json",
+ "test/generated-artifacts/IAuthorizableV08.json",
"test/generated-artifacts/IOwnable.json",
"test/generated-artifacts/IOwnableV06.json",
+ "test/generated-artifacts/IOwnableV08.json",
"test/generated-artifacts/LibAddress.json",
"test/generated-artifacts/LibAddressArray.json",
"test/generated-artifacts/LibAddressArrayRichErrors.json",
"test/generated-artifacts/LibAuthorizableRichErrors.json",
"test/generated-artifacts/LibAuthorizableRichErrorsV06.json",
+ "test/generated-artifacts/LibAuthorizableRichErrorsV08.json",
"test/generated-artifacts/LibBytes.json",
"test/generated-artifacts/LibBytesRichErrors.json",
"test/generated-artifacts/LibBytesRichErrorsV06.json",
+ "test/generated-artifacts/LibBytesRichErrorsV08.json",
"test/generated-artifacts/LibBytesV06.json",
+ "test/generated-artifacts/LibBytesV08.json",
"test/generated-artifacts/LibEIP1271.json",
"test/generated-artifacts/LibEIP712.json",
"test/generated-artifacts/LibFractions.json",
"test/generated-artifacts/LibMath.json",
"test/generated-artifacts/LibMathRichErrors.json",
"test/generated-artifacts/LibMathRichErrorsV06.json",
+ "test/generated-artifacts/LibMathRichErrorsV08.json",
"test/generated-artifacts/LibMathV06.json",
+ "test/generated-artifacts/LibMathV08.json",
"test/generated-artifacts/LibOwnableRichErrors.json",
"test/generated-artifacts/LibOwnableRichErrorsV06.json",
+ "test/generated-artifacts/LibOwnableRichErrorsV08.json",
"test/generated-artifacts/LibReentrancyGuardRichErrors.json",
"test/generated-artifacts/LibReentrancyGuardRichErrorsV06.json",
+ "test/generated-artifacts/LibReentrancyGuardRichErrorsV08.json",
"test/generated-artifacts/LibRichErrors.json",
"test/generated-artifacts/LibRichErrorsV06.json",
+ "test/generated-artifacts/LibRichErrorsV08.json",
"test/generated-artifacts/LibSafeMath.json",
"test/generated-artifacts/LibSafeMathRichErrors.json",
"test/generated-artifacts/LibSafeMathRichErrorsV06.json",
+ "test/generated-artifacts/LibSafeMathRichErrorsV08.json",
"test/generated-artifacts/LibSafeMathV06.json",
"test/generated-artifacts/Ownable.json",
"test/generated-artifacts/OwnableV06.json",
+ "test/generated-artifacts/OwnableV08.json",
"test/generated-artifacts/ReentrancyGuard.json",
"test/generated-artifacts/ReentrancyGuardV06.json",
+ "test/generated-artifacts/ReentrancyGuardV08.json",
"test/generated-artifacts/Refundable.json",
"test/generated-artifacts/TestAuthorizable.json",
"test/generated-artifacts/TestLibAddress.json",