ERC2771Context.sol 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
  52. return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
  53. } else {
  54. return super._msgSender();
  55. }
  56. }
  57. /**
  58. * @dev Override for `msg.data`. Defaults to the original `msg.data` whenever
  59. * a call is not performed by the trusted forwarder or the calldata length is less than
  60. * 20 bytes (an address length).
  61. */
  62. function _msgData() internal view virtual override returns (bytes calldata) {
  63. uint256 calldataLength = msg.data.length;
  64. uint256 contextSuffixLength = _contextSuffixLength();
  65. if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
  66. return msg.data[:calldataLength - contextSuffixLength];
  67. } else {
  68. return super._msgData();
  69. }
  70. }
  71. /**
  72. * @dev ERC-2771 specifies the context as being a single address (20 bytes).
  73. */
  74. function _contextSuffixLength() internal view virtual override returns (uint256) {
  75. return 20;
  76. }
  77. }