Optimize Address.functionCall removing redundant isContract check (#3469)
Co-authored-by: Francisco <frangio.1@gmail.com>
This commit is contained in:
@ -132,10 +132,8 @@ library Address {
|
||||
string memory errorMessage
|
||||
) internal returns (bytes memory) {
|
||||
require(address(this).balance >= value, "Address: insufficient balance for call");
|
||||
require(isContract(target), "Address: call to non-contract");
|
||||
|
||||
(bool success, bytes memory returndata) = target.call{value: value}(data);
|
||||
return verifyCallResult(success, returndata, errorMessage);
|
||||
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,10 +157,8 @@ library Address {
|
||||
bytes memory data,
|
||||
string memory errorMessage
|
||||
) internal view returns (bytes memory) {
|
||||
require(isContract(target), "Address: static call to non-contract");
|
||||
|
||||
(bool success, bytes memory returndata) = target.staticcall(data);
|
||||
return verifyCallResult(success, returndata, errorMessage);
|
||||
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,15 +182,37 @@ library Address {
|
||||
bytes memory data,
|
||||
string memory errorMessage
|
||||
) internal returns (bytes memory) {
|
||||
require(isContract(target), "Address: delegate call to non-contract");
|
||||
|
||||
(bool success, bytes memory returndata) = target.delegatecall(data);
|
||||
return verifyCallResult(success, returndata, errorMessage);
|
||||
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
|
||||
* revert reason using the provided one.
|
||||
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
|
||||
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
|
||||
*
|
||||
* _Available since v4.8._
|
||||
*/
|
||||
function verifyCallResultFromTarget(
|
||||
address target,
|
||||
bool success,
|
||||
bytes memory returndata,
|
||||
string memory errorMessage
|
||||
) internal view returns (bytes memory) {
|
||||
if (success) {
|
||||
if (returndata.length == 0) {
|
||||
// only check isContract if the call was successful and the return data is empty
|
||||
// otherwise we already know that it was a contract
|
||||
require(isContract(target), "Address: call to non-contract");
|
||||
}
|
||||
return returndata;
|
||||
} else {
|
||||
_revert(returndata, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
|
||||
* revert reason or using the provided one.
|
||||
*
|
||||
* _Available since v4.3._
|
||||
*/
|
||||
@ -206,17 +224,21 @@ library Address {
|
||||
if (success) {
|
||||
return returndata;
|
||||
} else {
|
||||
// Look for revert reason and bubble it up if present
|
||||
if (returndata.length > 0) {
|
||||
// The easiest way to bubble the revert reason is using memory via assembly
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
let returndata_size := mload(returndata)
|
||||
revert(add(32, returndata), returndata_size)
|
||||
}
|
||||
} else {
|
||||
revert(errorMessage);
|
||||
_revert(returndata, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function _revert(bytes memory returndata, string memory errorMessage) private pure {
|
||||
// Look for revert reason and bubble it up if present
|
||||
if (returndata.length > 0) {
|
||||
// The easiest way to bubble the revert reason is using memory via assembly
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
let returndata_size := mload(returndata)
|
||||
revert(add(32, returndata), returndata_size)
|
||||
}
|
||||
} else {
|
||||
revert(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user