Commit 4f7fa769 by Francisco Giordano

inline Address.functionDelegateCall and remove from Address library

(cherry picked from commit be866876)
parent 921db111
......@@ -32,11 +32,6 @@ contract AddressImpl {
emit CallReturnValue(abi.decode(returnData, (string)));
}
function functionDelegateCall(address target, bytes calldata data) external {
bytes memory returnData = Address.functionDelegateCall(target, data);
emit CallReturnValue(abi.decode(returnData, (string)));
}
// sendValue's tests require the contract to hold Ether
receive () external payable { }
}
......@@ -64,7 +64,7 @@ abstract contract ERC1967Upgrade {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
_functionDelegateCall(newImplementation, data);
}
}
......@@ -79,7 +79,7 @@ abstract contract ERC1967Upgrade {
// Initial upgrade and setup call
_setImplementation(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
_functionDelegateCall(newImplementation, data);
}
// Perform rollback test if not already in progress
......@@ -87,7 +87,7 @@ abstract contract ERC1967Upgrade {
if (!rollbackTesting.value) {
// Trigger rollback using upgradeTo from the new implementation
rollbackTesting.value = true;
Address.functionDelegateCall(
_functionDelegateCall(
newImplementation,
abi.encodeWithSignature(
"upgradeTo(address)",
......@@ -113,7 +113,7 @@ abstract contract ERC1967Upgrade {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
_functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
......@@ -186,4 +186,37 @@ abstract contract ERC1967Upgrade {
);
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/*
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(Address.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
......@@ -144,30 +144,6 @@ library Address {
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
......
......@@ -16,8 +16,41 @@ abstract contract Multicall {
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint i = 0; i < data.length; i++) {
results[i] = Address.functionDelegateCall(address(this), data[i]);
results[i] = _functionDelegateCall(address(this), data[i]);
}
return results;
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(Address.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
diff --git a/contracts/mocks/AddressImplUpgradeable.sol b/contracts/mocks/AddressImplUpgradeable.sol
index 4e92f588..4cbcabb8 100644
--- a/contracts/mocks/AddressImplUpgradeable.sol
+++ b/contracts/mocks/AddressImplUpgradeable.sol
@@ -39,11 +39,6 @@ contract AddressImplUpgradeable is Initializable {
emit CallReturnValue(abi.decode(returnData, (string)));
}
- function functionDelegateCall(address target, bytes calldata data) external {
- bytes memory returnData = AddressUpgradeable.functionDelegateCall(target, data);
- emit CallReturnValue(abi.decode(returnData, (string)));
- }
-
// sendValue's tests require the contract to hold Ether
receive () external payable { }
uint256[49] private __gap;
diff --git a/contracts/utils/AddressUpgradeable.sol b/contracts/utils/AddressUpgradeable.sol
index 89241895..99c1ce78 100644
--- a/contracts/utils/AddressUpgradeable.sol
+++ b/contracts/utils/AddressUpgradeable.sol
@@ -144,30 +144,6 @@ library AddressUpgradeable {
return _verifyCallResult(success, returndata, errorMessage);
}
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
- * but performing a delegate call.
- *
- * _Available since v3.4._
- */
- function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
- return functionDelegateCall(target, data, "Address: low-level delegate call failed");
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
- * but performing a delegate call.
- *
- * _Available since v3.4._
- */
- function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
- require(isContract(target), "Address: delegate call to non-contract");
-
- // solhint-disable-next-line avoid-low-level-calls
- (bool success, bytes memory returndata) = target.delegatecall(data);
- return _verifyCallResult(success, returndata, errorMessage);
- }
-
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
diff --git a/contracts/utils/MulticallUpgradeable.sol b/contracts/utils/MulticallUpgradeable.sol
index 62d5047c..a535dfc5 100644
--- a/contracts/utils/MulticallUpgradeable.sol
+++ b/contracts/utils/MulticallUpgradeable.sol
@@ -21,9 +21,37 @@ abstract contract MulticallUpgradeable is Initializable {
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint i = 0; i < data.length; i++) {
- results[i] = AddressUpgradeable.functionDelegateCall(address(this), data[i]);
+ results[i] = _functionDelegateCall(address(this), data[i]);
}
return results;
}
+
+ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
+ require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
+
+ // solhint-disable-next-line avoid-low-level-calls
+ (bool success, bytes memory returndata) = target.delegatecall(data);
+ return _verifyCallResult(success, returndata, "Address: low-level delegate call failed");
+ }
+
+ function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
+ 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
+
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let returndata_size := mload(returndata)
+ revert(add(32, returndata), returndata_size)
+ }
+ } else {
+ revert(errorMessage);
+ }
+ }
+ }
+
uint256[50] private __gap;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment