ERC2771Context.sol 1.2 KB

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