// Source: contracts/utils/Caller.sol pragma solidity ^0.8.0; // SPDX-License-Identifier: MIT // File contracts/interfaces/ICaller.sol interface ICaller { error InvalidContract(address target); error InsufficientBalance(); error ExecutionFailed(); } // File contracts/libs/ContractAddress.sol library ContractAddress { function isContract(address contractAddress) internal view returns (bool) { bytes32 existingCodeHash = contractAddress.codehash; // https://eips.ethereum.org/EIPS/eip-1052 // keccak256('') == 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 return existingCodeHash != bytes32(0) && existingCodeHash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; } } // File contracts/utils/Caller.sol contract Caller is ICaller { using ContractAddress for address; /** * @dev Calls a target address with specified calldata and optionally sends value. */ function _call( address target, bytes calldata callData, uint256 nativeValue ) internal returns (bytes memory) { if (!target.isContract()) revert InvalidContract(target); if (nativeValue > address(this).balance) revert InsufficientBalance(); (bool success, bytes memory data) = target.call{ value: nativeValue }(callData); if (!success) { revert ExecutionFailed(); } return data; } }