ERC2771Context.sol 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.9.4) (metatx/ERC2771Context.sol)
  3. pragma solidity ^0.8.9;
  4. import "../utils/Context.sol";
  5. /**
  6. * @dev Context variant with ERC2771 support.
  7. *
  8. * WARNING: The usage of `delegatecall` in this contract is dangerous and may result in context corruption.
  9. * Any forwarded request to this contract triggering a `delegatecall` to itself will result in an invalid {_msgSender}
  10. * recovery.
  11. */
  12. abstract contract ERC2771Context is Context {
  13. /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
  14. address private immutable _trustedForwarder;
  15. /// @custom:oz-upgrades-unsafe-allow constructor
  16. constructor(address trustedForwarder) {
  17. _trustedForwarder = trustedForwarder;
  18. }
  19. function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
  20. return forwarder == _trustedForwarder;
  21. }
  22. function _msgSender() internal view virtual override returns (address) {
  23. uint256 calldataLength = msg.data.length;
  24. uint256 contextSuffixLength = _contextSuffixLength();
  25. if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
  26. return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
  27. } else {
  28. return super._msgSender();
  29. }
  30. }
  31. function _msgData() internal view virtual override returns (bytes calldata) {
  32. uint256 calldataLength = msg.data.length;
  33. uint256 contextSuffixLength = _contextSuffixLength();
  34. if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
  35. return msg.data[:calldataLength - contextSuffixLength];
  36. } else {
  37. return super._msgData();
  38. }
  39. }
  40. /**
  41. * @dev ERC-2771 specifies the context as being a single address (20 bytes).
  42. */
  43. function _contextSuffixLength() internal view virtual override returns (uint256) {
  44. return 20;
  45. }
  46. }