chore: adding V08 contracts [LIT-783] (#646)

* Adding V08 contracts

* Removing LibSafeMathV08

* Apply suggestions from code review

Co-authored-by: duncancmt <1207590+duncancmt@users.noreply.github.com>
This commit is contained in:
Savarn Dontamsetti (Sav) 2023-01-23 18:00:43 -05:00 committed by GitHub
parent 091a10676c
commit 891d173705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1571 additions and 2 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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": {

View File

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

View File

@ -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';

View File

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

View File

@ -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);
}
}

View File

@ -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 <input> into.
/// @param index Index in byte array of <input>.
/// @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 <input> into.
/// @param index Index in byte array of <input>.
/// @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)
}
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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))
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

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

View File

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

View File

@ -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';

View File

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