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",