dexorder
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {IERC165} from "./IERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev Implementation of the {IERC165} interface.
|
||||
*
|
||||
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
|
||||
* for the additional interface id that will be supported. For example:
|
||||
*
|
||||
* ```solidity
|
||||
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
abstract contract ERC165 is IERC165 {
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
|
||||
return interfaceId == type(IERC165).interfaceId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {IERC165} from "./IERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev Library used to query support of an interface declared via {IERC165}.
|
||||
*
|
||||
* Note that these functions return the actual result of the query: they do not
|
||||
* `revert` if an interface is not supported. It is up to the caller to decide
|
||||
* what to do in these cases.
|
||||
*/
|
||||
library ERC165Checker {
|
||||
// As per the ERC-165 spec, no interface should ever match 0xffffffff
|
||||
bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff;
|
||||
|
||||
/**
|
||||
* @dev Returns true if `account` supports the {IERC165} interface.
|
||||
*/
|
||||
function supportsERC165(address account) internal view returns (bool) {
|
||||
// Any contract that implements ERC-165 must explicitly indicate support of
|
||||
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
|
||||
return
|
||||
supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&
|
||||
!supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns true if `account` supports the interface defined by
|
||||
* `interfaceId`. Support for {IERC165} itself is queried automatically.
|
||||
*
|
||||
* See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
|
||||
// query support of both ERC-165 as per the spec and support of _interfaceId
|
||||
return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns a boolean array where each value corresponds to the
|
||||
* interfaces passed in and whether they're supported or not. This allows
|
||||
* you to batch check interfaces for a contract where your expectation
|
||||
* is that some interfaces may not be supported.
|
||||
*
|
||||
* See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function getSupportedInterfaces(
|
||||
address account,
|
||||
bytes4[] memory interfaceIds
|
||||
) internal view returns (bool[] memory) {
|
||||
// an array of booleans corresponding to interfaceIds and whether they're supported or not
|
||||
bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
|
||||
|
||||
// query support of ERC-165 itself
|
||||
if (supportsERC165(account)) {
|
||||
// query support of each interface in interfaceIds
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return interfaceIdsSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns true if `account` supports all the interfaces defined in
|
||||
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
|
||||
*
|
||||
* Batch-querying can lead to gas savings by skipping repeated checks for
|
||||
* {IERC165} support.
|
||||
*
|
||||
* See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
|
||||
// query support of ERC-165 itself
|
||||
if (!supportsERC165(account)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// query support of each interface in interfaceIds
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// all interfaces supported
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Query if a contract implements an interface, does not check ERC-165 support
|
||||
* @param account The address of the contract to query for support of an interface
|
||||
* @param interfaceId The interface identifier, as specified in ERC-165
|
||||
* @return true if the contract at account indicates support of the interface with
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Assumes that account contains a contract that supports ERC-165, otherwise
|
||||
* the behavior of this method is undefined. This precondition can be checked
|
||||
* with {supportsERC165}.
|
||||
*
|
||||
* Some precompiled contracts will falsely indicate support for a given interface, so caution
|
||||
* should be exercised when using this function.
|
||||
*
|
||||
* Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
|
||||
// prepare call
|
||||
bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId));
|
||||
|
||||
// perform static call
|
||||
bool success;
|
||||
uint256 returnSize;
|
||||
uint256 returnValue;
|
||||
assembly {
|
||||
success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
|
||||
returnSize := returndatasize()
|
||||
returnValue := mload(0x00)
|
||||
}
|
||||
|
||||
return success && returnSize >= 0x20 && returnValue > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
|
||||
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC-165 standard, as defined in the
|
||||
* https://eips.ethereum.org/EIPS/eip-165[ERC].
|
||||
*
|
||||
* Implementers can declare support of contract interfaces, which can then be
|
||||
* queried by others ({ERC165Checker}).
|
||||
*
|
||||
* For an implementation, see {ERC165}.
|
||||
*/
|
||||
interface IERC165 {
|
||||
/**
|
||||
* @dev Returns true if this contract implements the interface defined by
|
||||
* `interfaceId`. See the corresponding
|
||||
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
|
||||
* to learn more about how these ids are created.
|
||||
*
|
||||
* This function call must use less than 30 000 gas.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool);
|
||||
}
|
||||
Reference in New Issue
Block a user