github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/legacy/ResolvedDelegateProxy.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { AddressManager } from "src/legacy/AddressManager.sol";
     5  
     6  /// @custom:legacy
     7  /// @title ResolvedDelegateProxy
     8  /// @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to
     9  ///         resolve the implementation address. We're maintaining this contract for backwards
    10  ///         compatibility so we can manage all legacy proxies where necessary.
    11  contract ResolvedDelegateProxy {
    12      /// @notice Mapping used to store the implementation name that corresponds to this contract. A
    13      ///         mapping was originally used as a way to bypass the same issue normally solved by
    14      ///         storing the implementation address in a specific storage slot that does not conflict
    15      ///         with any other storage slot. Generally NOT a safe solution but works as long as the
    16      ///         implementation does not also keep a mapping in the first storage slot.
    17      mapping(address => string) private implementationName;
    18  
    19      /// @notice Mapping used to store the address of the AddressManager contract where the
    20      ///         implementation address will be resolved from. Same concept here as with the above
    21      ///         mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping
    22      ///         in the second storage slot.
    23      mapping(address => AddressManager) private addressManager;
    24  
    25      /// @param _addressManager  Address of the AddressManager.
    26      /// @param _implementationName implementationName of the contract to proxy to.
    27      constructor(AddressManager _addressManager, string memory _implementationName) {
    28          addressManager[address(this)] = _addressManager;
    29          implementationName[address(this)] = _implementationName;
    30      }
    31  
    32      /// @notice Fallback, performs a delegatecall to the resolved implementation address.
    33      fallback() external payable {
    34          address target = addressManager[address(this)].getAddress((implementationName[address(this)]));
    35  
    36          require(target != address(0), "ResolvedDelegateProxy: target address must be initialized");
    37  
    38          // slither-disable-next-line controlled-delegatecall
    39          (bool success, bytes memory returndata) = target.delegatecall(msg.data);
    40  
    41          if (success == true) {
    42              assembly {
    43                  return(add(returndata, 0x20), mload(returndata))
    44              }
    45          } else {
    46              assembly {
    47                  revert(add(returndata, 0x20), mload(returndata))
    48              }
    49          }
    50      }
    51  }