// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "@openzeppelin/contracts/utils/Context.sol"; import "./ERC2771ContextStorage.sol"; abstract contract ERC2771ContextInternal is Context { function _isTrustedForwarder(address operator) internal view returns (bool) { return ERC2771ContextStorage.layout().trustedForwarder == operator; } function _msgSender() internal view virtual override returns (address sender) { if (_isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (_isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } }