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 }