ERC2771Context.sol 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637
  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 { sender := shr(96, calldataload(sub(calldatasize(), 20))) }
  19. } else {
  20. return super._msgSender();
  21. }
  22. }
  23. function _msgData() internal view virtual override returns (bytes calldata) {
  24. if (isTrustedForwarder(msg.sender)) {
  25. return msg.data[:msg.data.length-20];
  26. } else {
  27. return super._msgData();
  28. }
  29. }
  30. }