// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./IMulticallable.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; abstract contract Multicallable is IMulticallable, ERC165 { function _multicall( bytes32 nodehash, bytes[] calldata data ) internal returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { if (nodehash != bytes32(0)) { bytes32 txNamehash = bytes32(data[i][4:36]); require( txNamehash == nodehash, "multicall: All records must have a matching namehash" ); } (bool success, bytes memory result) = address(this).delegatecall( data[i] ); require(success); results[i] = result; } return results; } // This function provides an extra security check when called // from privileged contracts (such as EthRegistrarController) // that can set records on behalf of the node owners function multicallWithNodeCheck( bytes32 nodehash, bytes[] calldata data ) external returns (bytes[] memory results) { return _multicall(nodehash, data); } function multicall( bytes[] calldata data ) public override returns (bytes[] memory results) { return _multicall(bytes32(0), data); } function supportsInterface( bytes4 interfaceID ) public view virtual override returns (bool) { return interfaceID == type(IMulticallable).interfaceId || super.supportsInterface(interfaceID); } }