ERC2771Context.sol 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0) (metatx/ERC2771Context.sol)
  3. pragma solidity ^0.8.9;
  4. import "../utils/Context.sol";
  5. /**
  6. * @dev Context variant with ERC2771 support.
  7. */
  8. abstract contract ERC2771Context is Context {
  9. /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
  10. address private immutable _trustedForwarder;
  11. /// @custom:oz-upgrades-unsafe-allow constructor
  12. constructor(address trustedForwarder) {
  13. _trustedForwarder = trustedForwarder;
  14. }
  15. function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
  16. return forwarder == _trustedForwarder;
  17. }
  18. function _msgSender() internal view virtual override returns (address sender) {
  19. if (isTrustedForwarder(msg.sender)) {
  20. // The assembly code is more direct than the Solidity version using `abi.decode`.
  21. assembly {
  22. sender := shr(96, calldataload(sub(calldatasize(), 20)))
  23. }
  24. } else {
  25. return super._msgSender();
  26. }
  27. }
  28. function _msgData() internal view virtual override returns (bytes calldata) {
  29. if (isTrustedForwarder(msg.sender)) {
  30. return msg.data[:msg.data.length - 20];
  31. } else {
  32. return super._msgData();
  33. }
  34. }
  35. }