ERC2771Context.sol 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.0.0) (metatx/ERC2771Context.sol)
  3. pragma solidity ^0.8.20;
  4. import {Context} from "../utils/Context.sol";
  5. /**
  6. * @dev Context variant with ERC-2771 support.
  7. *
  8. * WARNING: Avoid using this pattern in contracts that rely in a specific calldata length as they'll
  9. * be affected by any forwarder whose `msg.data` is suffixed with the `from` address according to the ERC-2771
  10. * specification adding the address size in bytes (20) to the calldata size. An example of an unexpected
  11. * behavior could be an unintended fallback (or another function) invocation while trying to invoke the `receive`
  12. * function only accessible if `msg.data.length == 0`.
  13. */
  14. abstract contract ERC2771Context is Context {
  15. /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
  16. address private immutable _trustedForwarder;
  17. /**
  18. * @dev Initializes the contract with a trusted forwarder, which will be able to
  19. * invoke functions on this contract on behalf of other accounts.
  20. *
  21. * NOTE: The trusted forwarder can be replaced by overriding {trustedForwarder}.
  22. */
  23. /// @custom:oz-upgrades-unsafe-allow constructor
  24. constructor(address trustedForwarder_) {
  25. _trustedForwarder = trustedForwarder_;
  26. }
  27. /**
  28. * @dev Returns the address of the trusted forwarder.
  29. */
  30. function trustedForwarder() public view virtual returns (address) {
  31. return _trustedForwarder;
  32. }
  33. /**
  34. * @dev Indicates whether any particular address is the trusted forwarder.
  35. */
  36. function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
  37. return forwarder == trustedForwarder();
  38. }
  39. /**
  40. * @dev Override for `msg.sender`. Defaults to the original `msg.sender` whenever
  41. * a call is not performed by the trusted forwarder or the calldata length is less than
  42. * 20 bytes (an address length).
  43. */
  44. function _msgSender() internal view virtual override returns (address sender) {
  45. if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {
  46. // The assembly code is more direct than the Solidity version using `abi.decode`.
  47. /// @solidity memory-safe-assembly
  48. assembly {
  49. sender := shr(96, calldataload(sub(calldatasize(), 20)))
  50. }
  51. } else {
  52. return super._msgSender();
  53. }
  54. }
  55. /**
  56. * @dev Override for `msg.data`. Defaults to the original `msg.data` whenever
  57. * a call is not performed by the trusted forwarder or the calldata length is less than
  58. * 20 bytes (an address length).
  59. */
  60. function _msgData() internal view virtual override returns (bytes calldata) {
  61. if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {
  62. return msg.data[:msg.data.length - 20];
  63. } else {
  64. return super._msgData();
  65. }
  66. }
  67. }