What is the usage of Context.sol within ERC-20?

When releasing the ERC-20 token,
OZ(OpenZeppelin)'s util Context.sol is inherited.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 * This contract is only required for intermediate, library-like contracts.
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;

I read that when using a meta-transaction solution such as EIP-2771, Context.sol is useful.

    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`.
            assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) }
        } else {
            return super._msgSender();

But in the case of ERC-20, why shoud I use Context.sol's _msgSender()?

 function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;

Doesn't make it more secure?

What is the usage of Context.sol within ERC-20?

Thank you in advance.

If you're not using a custom Context, with a custom implementation of _msgSender, then it's equivalent to msg.sender and you don't need to use it.

If you need your contracts to be more generic and support a potential custom Context, you should use _msgSender. This is the reason why we use it in the contracts.


Could you give an example of custom Context to explain the difference?

I am not fully sure to understand the difference, but would quite like to.