ERC2771Context.sol 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.1.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. * WARNING: The usage of `delegatecall` in this contract is dangerous and may result in context corruption.
  15. * Any forwarded request to this contract triggering a `delegatecall` to itself will result in an invalid {_msgSender}
  16. * recovery.
  17. */
  18. abstract contract ERC2771Context is Context {
  19. /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
  20. address private immutable _trustedForwarder;
  21. /**
  22. * @dev Initializes the contract with a trusted forwarder, which will be able to
  23. * invoke functions on this contract on behalf of other accounts.
  24. *
  25. * NOTE: The trusted forwarder can be replaced by overriding {trustedForwarder}.
  26. */
  27. /// @custom:oz-upgrades-unsafe-allow constructor
  28. constructor(address trustedForwarder_) {
  29. _trustedForwarder = trustedForwarder_;
  30. }
  31. /**
  32. * @dev Returns the address of the trusted forwarder.
  33. */
  34. function trustedForwarder() public view virtual returns (address) {
  35. return _trustedForwarder;
  36. }
  37. /**
  38. * @dev Indicates whether any particular address is the trusted forwarder.
  39. */
  40. function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
  41. return forwarder == trustedForwarder();
  42. }
  43. /**
  44. * @dev Override for `msg.sender`. Defaults to the original `msg.sender` whenever
  45. * a call is not performed by the trusted forwarder or the calldata length is less than
  46. * 20 bytes (an address length).
  47. */
  48. function _msgSender() internal view virtual override returns (address) {
  49. uint256 calldataLength = msg.data.length;
  50. uint256 contextSuffixLength = _contextSuffixLength();
  51. if (calldataLength >= contextSuffixLength && isTrustedForwarder(msg.sender)) {
  52. unchecked {
  53. return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
  54. }
  55. } else {
  56. return super._msgSender();
  57. }
  58. }
  59. /**
  60. * @dev Override for `msg.data`. Defaults to the original `msg.data` whenever
  61. * a call is not performed by the trusted forwarder or the calldata length is less than
  62. * 20 bytes (an address length).
  63. */
  64. function _msgData() internal view virtual override returns (bytes calldata) {
  65. uint256 calldataLength = msg.data.length;
  66. uint256 contextSuffixLength = _contextSuffixLength();
  67. if (calldataLength >= contextSuffixLength && isTrustedForwarder(msg.sender)) {
  68. unchecked {
  69. return msg.data[:calldataLength - contextSuffixLength];
  70. }
  71. } else {
  72. return super._msgData();
  73. }
  74. }
  75. /**
  76. * @dev ERC-2771 specifies the context as being a single address (20 bytes).
  77. */
  78. function _contextSuffixLength() internal view virtual override returns (uint256) {
  79. return 20;
  80. }
  81. }