123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.9.4) (metatx/ERC2771Context.sol)
- pragma solidity ^0.8.9;
- import "../utils/Context.sol";
- /**
- * @dev Context variant with ERC2771 support.
- *
- * WARNING: The usage of `delegatecall` in this contract is dangerous and may result in context corruption.
- * Any forwarded request to this contract triggering a `delegatecall` to itself will result in an invalid {_msgSender}
- * recovery.
- */
- abstract contract ERC2771Context is Context {
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
- address private immutable _trustedForwarder;
- /// @custom:oz-upgrades-unsafe-allow constructor
- constructor(address trustedForwarder) {
- _trustedForwarder = trustedForwarder;
- }
- function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
- return forwarder == _trustedForwarder;
- }
- function _msgSender() internal view virtual override returns (address) {
- uint256 calldataLength = msg.data.length;
- uint256 contextSuffixLength = _contextSuffixLength();
- if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
- return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
- } else {
- return super._msgSender();
- }
- }
- function _msgData() internal view virtual override returns (bytes calldata) {
- uint256 calldataLength = msg.data.length;
- uint256 contextSuffixLength = _contextSuffixLength();
- if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
- return msg.data[:calldataLength - contextSuffixLength];
- } else {
- return super._msgData();
- }
- }
- /**
- * @dev ERC-2771 specifies the context as being a single address (20 bytes).
- */
- function _contextSuffixLength() internal view virtual override returns (uint256) {
- return 20;
- }
- }
|