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:
parent
091a10676c
commit
891d173705
63
contracts/erc20/contracts/src/v08/IERC20TokenV08.sol
Normal file
63
contracts/erc20/contracts/src/v08/IERC20TokenV08.sol
Normal 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);
|
||||
}
|
30
contracts/erc20/contracts/src/v08/IEtherTokenV08.sol
Normal file
30
contracts/erc20/contracts/src/v08/IEtherTokenV08.sol
Normal 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;
|
||||
}
|
146
contracts/erc20/contracts/src/v08/LibERC20TokenV08.sol
Normal file
146
contracts/erc20/contracts/src/v08/LibERC20TokenV08.sol
Normal 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);
|
||||
}
|
||||
}
|
@ -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": {
|
||||
|
@ -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,
|
||||
|
@ -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';
|
||||
|
@ -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",
|
||||
|
125
contracts/utils/contracts/src/v08/AuthorizableV08.sol
Normal file
125
contracts/utils/contracts/src/v08/AuthorizableV08.sol
Normal 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);
|
||||
}
|
||||
}
|
434
contracts/utils/contracts/src/v08/LibBytesV08.sol
Normal file
434
contracts/utils/contracts/src/v08/LibBytesV08.sol
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
201
contracts/utils/contracts/src/v08/LibMathV08.sol
Normal file
201
contracts/utils/contracts/src/v08/LibMathV08.sol
Normal 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;
|
||||
}
|
||||
}
|
56
contracts/utils/contracts/src/v08/OwnableV08.sol
Normal file
56
contracts/utils/contracts/src/v08/OwnableV08.sol
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
50
contracts/utils/contracts/src/v08/ReentrancyGuardV08.sol
Normal file
50
contracts/utils/contracts/src/v08/ReentrancyGuardV08.sol
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
35
contracts/utils/contracts/src/v08/interfaces/IOwnableV08.sol
Normal file
35
contracts/utils/contracts/src/v08/interfaces/IOwnableV08.sol
Normal 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);
|
||||
}
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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';
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user