Pārlūkot izejas kodu

Replace abi.encodeWithSelector & abi.encodeWithSignature with abi.encodeCall (#4293)

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Balaji Shetty Pachai 2 gadi atpakaļ
vecāks
revīzija
4fd2f8be33

+ 4 - 0
.changeset/big-plums-cover.md

@@ -0,0 +1,4 @@
+---
+'openzeppelin-solidity': major
+---
+Use `abi.encodeCall` in place of `abi.encodeWithSelector` and `abi.encodeWithSignature` for improved type-checking of parameters

+ 1 - 1
contracts/mocks/MulticallTest.sol

@@ -12,7 +12,7 @@ contract MulticallTest {
     ) external {
         bytes[] memory calls = new bytes[](recipients.length);
         for (uint256 i = 0; i < recipients.length; i++) {
-            calls[i] = abi.encodeWithSignature("transfer(address,uint256)", recipients[i], amounts[i]);
+            calls[i] = abi.encodeCall(multicallToken.transfer, (recipients[i], amounts[i]));
         }
 
         bytes[] memory results = multicallToken.multicall(calls);

+ 1 - 1
contracts/mocks/ReentrancyMock.sol

@@ -26,7 +26,7 @@ contract ReentrancyMock is ReentrancyGuard {
     function countThisRecursive(uint256 n) public nonReentrant {
         if (n > 0) {
             _count();
-            (bool success, ) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
+            (bool success, ) = address(this).call(abi.encodeCall(this.countThisRecursive, (n - 1)));
             require(success, "ReentrancyMock: failed call");
         }
     }

+ 1 - 4
contracts/mocks/proxy/UUPSLegacy.sol

@@ -31,10 +31,7 @@ contract UUPSUpgradeableLegacyMock is UUPSUpgradeableMock {
         if (!rollbackTesting.value) {
             // Trigger rollback using upgradeTo from the new implementation
             rollbackTesting.value = true;
-            Address.functionDelegateCall(
-                newImplementation,
-                abi.encodeWithSignature("upgradeTo(address)", oldImplementation)
-            );
+            Address.functionDelegateCall(newImplementation, abi.encodeCall(this.upgradeTo, (oldImplementation)));
             rollbackTesting.value = false;
             // Check rollback was effective
             require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");

+ 1 - 1
contracts/token/ERC20/extensions/ERC4626.sol

@@ -67,7 +67,7 @@ abstract contract ERC4626 is ERC20, IERC4626 {
      */
     function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8) {
         (bool success, bytes memory encodedDecimals) = address(asset_).staticcall(
-            abi.encodeWithSelector(IERC20Metadata.decimals.selector)
+            abi.encodeCall(IERC20Metadata.decimals, ())
         );
         if (success && encodedDecimals.length >= 32) {
             uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256));

+ 4 - 4
contracts/token/ERC20/utils/SafeERC20.sol

@@ -24,7 +24,7 @@ library SafeERC20 {
      * non-reverting calls are assumed to be successful.
      */
     function safeTransfer(IERC20 token, address to, uint256 value) internal {
-        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
+        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
     }
 
     /**
@@ -32,7 +32,7 @@ library SafeERC20 {
      * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
      */
     function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
-        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
+        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
     }
 
     /**
@@ -62,10 +62,10 @@ library SafeERC20 {
      * 0 before setting it to a non-zero value.
      */
     function forceApprove(IERC20 token, address spender, uint256 value) internal {
-        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
+        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
 
         if (!_callOptionalReturnBool(token, approvalCall)) {
-            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
+            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
             _callOptionalReturn(token, approvalCall);
         }
     }

+ 1 - 1
contracts/utils/cryptography/SignatureChecker.sol

@@ -41,7 +41,7 @@ library SignatureChecker {
         bytes memory signature
     ) internal view returns (bool) {
         (bool success, bytes memory result) = signer.staticcall(
-            abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
+            abi.encodeCall(IERC1271.isValidSignature, (hash, signature))
         );
         return (success &&
             result.length >= 32 &&

+ 1 - 1
contracts/utils/introspection/ERC165Checker.sol

@@ -109,7 +109,7 @@ library ERC165Checker {
      */
     function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
         // prepare call
-        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);
+        bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId));
 
         // perform static call
         bool success;