Proxy.sol 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)
  3. pragma solidity ^0.8.20;
  4. /**
  5. * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
  6. * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
  7. * be specified by overriding the virtual {_implementation} function.
  8. *
  9. * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
  10. * different contract through the {_delegate} function.
  11. *
  12. * The success and return data of the delegated call will be returned back to the caller of the proxy.
  13. */
  14. abstract contract Proxy {
  15. /**
  16. * @dev Delegates the current call to `implementation`.
  17. *
  18. * This function does not return to its internal call site, it will return directly to the external caller.
  19. */
  20. function _delegate(address implementation) internal virtual {
  21. assembly {
  22. // Copy msg.data. We take full control of memory in this inline assembly
  23. // block because it will not return to Solidity code. We overwrite the
  24. // Solidity scratch pad at memory position 0.
  25. calldatacopy(0, 0, calldatasize())
  26. // Call the implementation.
  27. // out and outsize are 0 because we don't know the size yet.
  28. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
  29. // Copy the returned data.
  30. returndatacopy(0, 0, returndatasize())
  31. switch result
  32. // delegatecall returns 0 on error.
  33. case 0 {
  34. revert(0, returndatasize())
  35. }
  36. default {
  37. return(0, returndatasize())
  38. }
  39. }
  40. }
  41. /**
  42. * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
  43. * function and {_fallback} should delegate.
  44. */
  45. function _implementation() internal view virtual returns (address);
  46. /**
  47. * @dev Delegates the current call to the address returned by `_implementation()`.
  48. *
  49. * This function does not return to its internal call site, it will return directly to the external caller.
  50. */
  51. function _fallback() internal virtual {
  52. _delegate(_implementation());
  53. }
  54. /**
  55. * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
  56. * function in the contract matches the call data.
  57. */
  58. fallback() external payable virtual {
  59. _fallback();
  60. }
  61. }