1. pragma solidity ^0.4.18;
    2. /**
    3. * @title Proxy
    4. * @dev Gives the possibility to delegate any call to a foreign implementation.
    5. */
    6. contract Proxy {
    7. /**
    8. * @dev Tells the address of the implementation where every call will be delegated.
    9. * @return address of the implementation to which it will be delegated
    10. */
    11. function implementation() public view returns (address);
    12. /**
    13. * @dev Fallback function allowing to perform a delegatecall to the given implementation.
    14. * This function will return whatever the implementation call returns
    15. */
    16. function () payable public {
    17. address _impl = implementation();
    18. require(_impl != address(0));
    19. assembly {
    20. let ptr := mload(0x40)
    21. calldatacopy(ptr, 0, calldatasize)
    22. let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
    23. let size := returndatasize
    24. returndatacopy(ptr, 0, size)
    25. switch result
    26. case 0 { revert(ptr, size) }
    27. default { return(ptr, size) }
    28. }
    29. }
    30. }

    // 当前版本

    1. // SPDX-License-Identifier: MIT
    2. pragma solidity ^0.8.0;
    3. /**
    4. * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
    5. * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
    6. * be specified by overriding the virtual {_implementation} function.
    7. *
    8. * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
    9. * different contract through the {_delegate} function.
    10. *
    11. * The success and return data of the delegated call will be returned back to the caller of the proxy.
    12. */
    13. abstract contract Proxy {
    14. /**
    15. * @dev Delegates the current call to `implementation`.
    16. *
    17. * This function does not return to its internall call site, it will return directly to the external caller.
    18. */
    19. // implementation 应该传入新合约的地址
    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 overriden so it returns the address to which the fallback function
    43. * 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 internall call site, it will return directly to the external caller.
    50. */
    51. function _fallback() internal virtual {
    52. _beforeFallback();
    53. _delegate(_implementation());
    54. }
    55. /**
    56. * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
    57. * function in the contract matches the call data.
    58. */
    59. fallback() external payable virtual {
    60. _fallback();
    61. }
    62. /**
    63. * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
    64. * is empty.
    65. */
    66. receive() external payable virtual {
    67. _fallback();
    68. }
    69. /**
    70. * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
    71. * call, or as part of the Solidity `fallback` or `receive` functions.
    72. *
    73. * If overriden should call `super._beforeFallback()`.
    74. */
    75. function _beforeFallback() internal virtual {}
    76. }

    Proxy.sol - 图1