Avoid returndatacopy in ERC2771Forwarder by calling via assembly (#4458)
This commit is contained in:
@ -7,6 +7,12 @@ import {Context} from "../utils/Context.sol";
|
||||
|
||||
/**
|
||||
* @dev Context variant with ERC2771 support.
|
||||
*
|
||||
* WARNING: Avoid using this pattern in contracts that rely in a specific calldata length as they'll
|
||||
* be affected by any forwarder whose `msg.data` is suffixed with the `from` address according to the ERC2771
|
||||
* specification adding the address size in bytes (20) to the calldata size. An example of an unexpected
|
||||
* behavior could be an unintended fallback (or another function) invocation while trying to invoke the `receive`
|
||||
* function only accessible if `msg.data.length == 0`.
|
||||
*/
|
||||
abstract contract ERC2771Context is Context {
|
||||
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
|
||||
|
||||
@ -251,11 +251,19 @@ contract ERC2771Forwarder is EIP712, Nonces {
|
||||
// Nonce should be used before the call to prevent reusing by reentrancy
|
||||
uint256 currentNonce = _useNonce(signer);
|
||||
|
||||
(success, ) = request.to.call{gas: request.gas, value: request.value}(
|
||||
abi.encodePacked(request.data, request.from)
|
||||
);
|
||||
uint256 reqGas = request.gas;
|
||||
address to = request.to;
|
||||
uint256 value = request.value;
|
||||
bytes memory data = abi.encodePacked(request.data, request.from);
|
||||
|
||||
_checkForwardedGas(gasleft(), request);
|
||||
uint256 gasLeft;
|
||||
|
||||
assembly {
|
||||
success := call(reqGas, to, value, add(data, 0x20), mload(data), 0, 0)
|
||||
gasLeft := gas()
|
||||
}
|
||||
|
||||
_checkForwardedGas(gasLeft, request);
|
||||
|
||||
emit ExecutedForwardRequest(signer, currentNonce, success);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user