ERC2771Context.sol 1.1 KB

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