// 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.
*/pragmasolidity ^0.8;import"./interfaces/IAuthorizableV08.sol";
import"./errors/LibRichErrorsV08.sol";
import"./errors/LibAuthorizableRichErrorsV08.sol";
import"./OwnableV08.sol";
contractAuthorizableV08isOwnableV08, IAuthorizableV08{
/// @dev Only authorized addresses can invoke functions with this modifier.modifieronlyAuthorized() {
_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) publicoverride authorized;
// @dev Whether an address is authorized to call privileged functions.// @param 0 Index of authorized address.// @return 0 Authorized address.address[] publicoverride authorities;
/// @dev Initializes the `owner` address.constructor() OwnableV08() {}
/// @dev Authorizes an address./// @param target Address to authorize.functionaddAuthorizedAddress(address target) externaloverrideonlyOwner{
_addAuthorizedAddress(target);
}
/// @dev Removes authorizion of an address./// @param target Address to remove authorization from.functionremoveAuthorizedAddress(address target) externaloverrideonlyOwner{
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.functionremoveAuthorizedAddressAtIndex(address target, uint256 index) externaloverrideonlyOwner{
_removeAuthorizedAddressAtIndex(target, index);
}
/// @dev Gets all authorized addresses./// @return Array of authorized addresses.functiongetAuthorizedAddresses() externalviewoverridereturns (address[] memory) {
return authorities;
}
/// @dev Reverts if msg.sender is not authorized.function_assertSenderIsAuthorized() internalview{
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);
}
}
Contract Source Code
File 2 of 10: IAuthorizableV08.sol
// 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.
*/pragmasolidity ^0.8;import"./IOwnableV08.sol";
interfaceIAuthorizableV08isIOwnableV08{
// Event logged when a new address is authorized.eventAuthorizedAddressAdded(addressindexed target, addressindexed caller);
// Event logged when a currently authorized address is unauthorized.eventAuthorizedAddressRemoved(addressindexed target, addressindexed caller);
/// @dev Authorizes an address./// @param target Address to authorize.functionaddAuthorizedAddress(address target) external;
/// @dev Removes authorizion of an address./// @param target Address to remove authorization from.functionremoveAuthorizedAddress(address target) external;
/// @dev Removes authorizion of an address./// @param target Address to remove authorization from./// @param index Index of target in authorities array.functionremoveAuthorizedAddressAtIndex(address target, uint256 index) external;
/// @dev Gets all authorized addresses./// @return authorizedAddresses Array of authorized addresses.functiongetAuthorizedAddresses() externalviewreturns (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.functionauthorized(address addr) externalviewreturns (bool isAuthorized);
/// @dev All addresseses authorized to call privileged functions./// @param idx Index of authorized address./// @return addr Authorized address.functionauthorities(uint256 idx) externalviewreturns (address addr);
}
Contract Source Code
File 3 of 10: IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)pragmasolidity ^0.8.20;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address to, uint256 value) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 value) externalreturns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(addressfrom, address to, uint256 value) externalreturns (bool);
}
// 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.
*/pragmasolidity ^0.8;interfaceIOwnableV08{
/// @dev Emitted by Ownable when ownership is transferred./// @param previousOwner The previous owner of the contract./// @param newOwner The new owner of the contract.eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/// @dev Transfers ownership of the contract to a new address./// @param newOwner The address that will become the owner.functiontransferOwnership(address newOwner) external;
/// @dev The owner of this contract./// @return ownerAddress The owner address.functionowner() externalviewreturns (address ownerAddress);
}
Contract Source Code
File 6 of 10: LibAuthorizableRichErrorsV08.sol
// 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.
*/pragmasolidity ^0.8;libraryLibAuthorizableRichErrorsV08{
// bytes4(keccak256("AuthorizedAddressMismatchError(address,address)"))bytes4internalconstant AUTHORIZED_ADDRESS_MISMATCH_ERROR_SELECTOR =0x140a84db;
// bytes4(keccak256("IndexOutOfBoundsError(uint256,uint256)"))bytes4internalconstant INDEX_OUT_OF_BOUNDS_ERROR_SELECTOR =0xe9f83771;
// bytes4(keccak256("SenderNotAuthorizedError(address)"))bytes4internalconstant SENDER_NOT_AUTHORIZED_ERROR_SELECTOR =0xb65a25b9;
// bytes4(keccak256("TargetAlreadyAuthorizedError(address)"))bytes4internalconstant TARGET_ALREADY_AUTHORIZED_ERROR_SELECTOR =0xde16f1a0;
// bytes4(keccak256("TargetNotAuthorizedError(address)"))bytes4internalconstant TARGET_NOT_AUTHORIZED_ERROR_SELECTOR =0xeb5108a2;
// bytes4(keccak256("ZeroCantBeAuthorizedError()"))bytesinternalconstant ZERO_CANT_BE_AUTHORIZED_ERROR_BYTES =hex"57654fe4";
functionAuthorizedAddressMismatchError(address authorized, address target) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(AUTHORIZED_ADDRESS_MISMATCH_ERROR_SELECTOR, authorized, target);
}
functionIndexOutOfBoundsError(uint256 index, uint256 length) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(INDEX_OUT_OF_BOUNDS_ERROR_SELECTOR, index, length);
}
functionSenderNotAuthorizedError(address sender) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(SENDER_NOT_AUTHORIZED_ERROR_SELECTOR, sender);
}
functionTargetAlreadyAuthorizedError(address target) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(TARGET_ALREADY_AUTHORIZED_ERROR_SELECTOR, target);
}
functionTargetNotAuthorizedError(address target) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(TARGET_NOT_AUTHORIZED_ERROR_SELECTOR, target);
}
functionZeroCantBeAuthorizedError() internalpurereturns (bytesmemory) {
return ZERO_CANT_BE_AUTHORIZED_ERROR_BYTES;
}
}
Contract Source Code
File 7 of 10: LibOwnableRichErrorsV08.sol
// 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.
*/pragmasolidity ^0.8;libraryLibOwnableRichErrorsV08{
// bytes4(keccak256("OnlyOwnerError(address,address)"))bytes4internalconstant ONLY_OWNER_ERROR_SELECTOR =0x1de45ad1;
// bytes4(keccak256("TransferOwnerToZeroError()"))bytesinternalconstant TRANSFER_OWNER_TO_ZERO_ERROR_BYTES =hex"e69edc3e";
functionOnlyOwnerError(address sender, address owner) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(ONLY_OWNER_ERROR_SELECTOR, sender, owner);
}
functionTransferOwnerToZeroError() internalpurereturns (bytesmemory) {
return TRANSFER_OWNER_TO_ZERO_ERROR_BYTES;
}
}
Contract Source Code
File 8 of 10: LibRichErrorsV08.sol
// 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.
*/pragmasolidity ^0.8;libraryLibRichErrorsV08{
// bytes4(keccak256("Error(string)"))bytes4internalconstant 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.functionStandardError(stringmemory message) internalpurereturns (bytesmemory) {
returnabi.encodeWithSelector(STANDARD_ERROR_SELECTOR, bytes(message));
}
/// @dev Reverts an encoded rich revert reason `errorData`./// @param errorData ABI encoded error data.functionrrevert(bytesmemory errorData) internalpure{
assembly ("memory-safe") {
revert(add(errorData, 0x20), mload(errorData))
}
}
}
// 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.
*/pragmasolidity ^0.8;import"./interfaces/IOwnableV08.sol";
import"./errors/LibRichErrorsV08.sol";
import"./errors/LibOwnableRichErrorsV08.sol";
contractOwnableV08isIOwnableV08{
/// @dev The owner of this contract./// @return 0 The owner address.addresspublicoverride owner;
constructor() {
owner =msg.sender;
}
modifieronlyOwner() {
_assertSenderIsOwner();
_;
}
/// @dev Change the owner of this contract./// @param newOwner New owner address.functiontransferOwnership(address newOwner) publicoverrideonlyOwner{
if (newOwner ==address(0)) {
LibRichErrorsV08.rrevert(LibOwnableRichErrorsV08.TransferOwnerToZeroError());
} else {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
function_assertSenderIsOwner() internalview{
if (msg.sender!= owner) {
LibRichErrorsV08.rrevert(LibOwnableRichErrorsV08.OnlyOwnerError(msg.sender, owner));
}
}
}