ETH Price: $1,975.58 (+0.68%)

Transaction Decoder

Block:
24509326 at Feb-22-2026 02:09:35 AM +UTC
Transaction Fee:
0.0000191212285275 ETH $0.04
Gas Used:
622,875 Gas / 0.03069834 Gwei

Emitted Events:

1161 L1ChugSplashProxy.0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23( 0x35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23, 0x0000000000000000000000008988b981aca6889a2a0336bafaaa7cc34898eb77, 0x0000000000000000000000008988b981aca6889a2a0336bafaaa7cc34898eb77, 00000000000000000000000000000000000000000000000001225b8f3976a88b, 0000000000000000000000000000000000000000000000000000000000000040, 000000000000000000000000000000000000000000000000000000000000000b, 7375706572627269646765000000000000000000000000000000000000000000 )
1162 L1ChugSplashProxy.0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5( 0x2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af5, 0x0000000000000000000000008988b981aca6889a2a0336bafaaa7cc34898eb77, 0x0000000000000000000000008988b981aca6889a2a0336bafaaa7cc34898eb77, 00000000000000000000000000000000000000000000000001225b8f3976a88b, 0000000000000000000000000000000000000000000000000000000000000040, 000000000000000000000000000000000000000000000000000000000000000b, 7375706572627269646765000000000000000000000000000000000000000000 )
1163 Proxy.0xb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32( 0xb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32, 0x000000000000000000000000977f82a600a1414e583f7f13623f1ac5d58b1c0b, 0x0000000000000000000000004200000000000000000000000000000000000007, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 000000000000000000000000000000000000000000000000000000000000020d, 00000000000000000000000000000000000000000000000001225b8f3976a88b, 00000000000000000000000000000000000000000000000001225b8f3976a88b, 000000000007e17600d764ad0b00010000000000000000000000000000000000, 0000000000000000000007fc2a0000000000000000000000003154cf16ccdb4c, 6d922629664174b904d80f2c3500000000000000000000000042000000000000, 0000000000000000000000001000000000000000000000000000000000000000, 000000000001225b8f3976a88b00000000000000000000000000000000000000, 00000000000000000000030d4000000000000000000000000000000000000000, 000000000000000000000000c000000000000000000000000000000000000000, 000000000000000000000000c41635f5fd0000000000000000000000008988b9, 81aca6889a2a0336bafaaa7cc34898eb770000000000000000000000008988b9, 81aca6889a2a0336bafaaa7cc34898eb77000000000000000000000000000000, 00000000000000000001225b8f3976a88b000000000000000000000000000000, 0000000000000000000000000000000080000000000000000000000000000000, 000000000000000000000000000000000b737570657262726964676500000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
1164 ResolvedDelegateProxy.0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a( 0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a, 0x0000000000000000000000004200000000000000000000000000000000000010, 0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c35, 0000000000000000000000000000000000000000000000000000000000000080, 000100000000000000000000000000000000000000000000000000000007fc2a, 0000000000000000000000000000000000000000000000000000000000030d40, 00000000000000000000000000000000000000000000000000000000000000c4, 1635f5fd0000000000000000000000008988b981aca6889a2a0336bafaaa7cc3, 4898eb770000000000000000000000008988b981aca6889a2a0336bafaaa7cc3, 4898eb7700000000000000000000000000000000000000000000000001225b8f, 3976a88b00000000000000000000000000000000000000000000000000000000, 0000008000000000000000000000000000000000000000000000000000000000, 0000000b73757065726272696467650000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
1165 ResolvedDelegateProxy.0x8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d546( 0x8ebb2ec2465bdb2a06a66fc37a0963af8a2a6a1479d81d56fdb8cbb98096d546, 0x0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c35, 00000000000000000000000000000000000000000000000001225b8f3976a88b )

Account State Difference:

  Address   Before After State Difference Code
(quasarbuilder)
21.077969176925259233 Eth21.077969220526509233 Eth0.00000004360125
0x49048044...fAF74E97e
(Base: Base Portal)
797,182.116457360953899624 Eth797,182.198185774902518515 Eth0.081728413948618891
0x866E82a6...5d58b0Afa
0x8988b981...34898eb77
0.091746782377618891 Eth
Nonce: 1
0.0099992472004725 Eth
Nonce: 2
0.081747535177146391

Execution Trace

ETH 0.081728413948618891 L1ChugSplashProxy.e11013dd( )
  • ProxyAdmin.STATICCALL( )
  • ETH 0.081728413948618891 0x61525eaacddb97d9184afc205827e6a4fd0bf62a.e11013dd( )
    • ETH 0.081728413948618891 ResolvedDelegateProxy.3dbb202b( )
      • AddressManager.getAddress( _name=OVM_L1CrossDomainMessenger ) => ( 0xb686F13AfF1e427a1f993F29ab0F2E7383729FE0 )
      • ETH 0.081728413948618891 0xb686f13aff1e427a1f993f29ab0f2e7383729fe0.3dbb202b( )
        • ETH 0.081728413948618891 Proxy.e9e05c42( )
          • ETH 0.081728413948618891 0x97cebbf8959e2a5476fbe9b98a21806ec234609b.e9e05c42( )
            • Proxy.47af267b( )
            • Proxy.47af267b( )
            • Proxy.STATICCALL( )
              File 1 of 6: L1ChugSplashProxy
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              /**
               * @title IL1ChugSplashDeployer
               */
              interface IL1ChugSplashDeployer {
                  function isUpgrading() external view returns (bool);
              }
              /**
               * @custom:legacy
               * @title L1ChugSplashProxy
               * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added
               *         functions `setCode` and `setStorage` for changing the code or storage of the contract.
               *
               *         Note for future developers: do NOT make anything in this contract 'public' unless you
               *         know what you're doing. Anything public can potentially have a function signature that
               *         conflicts with a signature attached to the implementation contract. Public functions
               *         SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good
               *         reason not to have that modifier. And there almost certainly is not a good reason to not
               *         have that modifier. Beware!
               */
              contract L1ChugSplashProxy {
                  /**
                   * @notice "Magic" prefix. When prepended to some arbitrary bytecode and used to create a
                   *         contract, the appended bytecode will be deployed as given.
                   */
                  bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;
                  /**
                   * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                   */
                  bytes32 internal constant IMPLEMENTATION_KEY =
                      0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                  /**
                   * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
                   */
                  bytes32 internal constant OWNER_KEY =
                      0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                  /**
                   * @notice Blocks a function from being called when the parent signals that the system should
                   *         be paused via an isUpgrading function.
                   */
                  modifier onlyWhenNotPaused() {
                      address owner = _getOwner();
                      // We do a low-level call because there's no guarantee that the owner actually *is* an
                      // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and
                      // it turns out that it isn't the right type of contract.
                      (bool success, bytes memory returndata) = owner.staticcall(
                          abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)
                      );
                      // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we
                      // can just continue as normal. We also expect that the return value is exactly 32 bytes
                      // long. If this isn't the case then we can safely ignore the result.
                      if (success && returndata.length == 32) {
                          // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the
                          // case that the isUpgrading function returned something other than 0 or 1. But we only
                          // really care about the case where this value is 0 (= false).
                          uint256 ret = abi.decode(returndata, (uint256));
                          require(ret == 0, "L1ChugSplashProxy: system is currently being upgraded");
                      }
                      _;
                  }
                  /**
                   * @notice Makes a proxy call instead of triggering the given function when the caller is
                   *         either the owner or the zero address. Caller can only ever be the zero address if
                   *         this function is being called off-chain via eth_call, which is totally fine and can
                   *         be convenient for client-side tooling. Avoids situations where the proxy and
                   *         implementation share a sighash and the proxy function ends up being called instead
                   *         of the implementation one.
                   *
                   *         Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If
                   *         there's a way for someone to send a transaction with msg.sender == address(0) in any
                   *         real context then we have much bigger problems. Primary reason to include this
                   *         additional allowed sender is because the owner address can be changed dynamically
                   *         and we do not want clients to have to keep track of the current owner in order to
                   *         make an eth_call that doesn't trigger the proxied contract.
                   */
                  // slither-disable-next-line incorrect-modifier
                  modifier proxyCallIfNotOwner() {
                      if (msg.sender == _getOwner() || msg.sender == address(0)) {
                          _;
                      } else {
                          // This WILL halt the call frame on completion.
                          _doProxyCall();
                      }
                  }
                  /**
                   * @param _owner Address of the initial contract owner.
                   */
                  constructor(address _owner) {
                      _setOwner(_owner);
                  }
                  // slither-disable-next-line locked-ether
                  receive() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  // slither-disable-next-line locked-ether
                  fallback() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  /**
                   * @notice Sets the code that should be running behind this proxy.
                   *
                   *         Note: This scheme is a bit different from the standard proxy scheme where one would
                   *         typically deploy the code separately and then set the implementation address. We're
                   *         doing it this way because it gives us a lot more freedom on the client side. Can
                   *         only be triggered by the contract owner.
                   *
                   * @param _code New contract code to run inside this contract.
                   */
                  function setCode(bytes memory _code) external proxyCallIfNotOwner {
                      // Get the code hash of the current implementation.
                      address implementation = _getImplementation();
                      // If the code hash matches the new implementation then we return early.
                      if (keccak256(_code) == _getAccountCodeHash(implementation)) {
                          return;
                      }
                      // Create the deploycode by appending the magic prefix.
                      bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);
                      // Deploy the code and set the new implementation address.
                      address newImplementation;
                      assembly {
                          newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))
                      }
                      // Check that the code was actually deployed correctly. I'm not sure if you can ever
                      // actually fail this check. Should only happen if the contract creation from above runs
                      // out of gas but this parent execution thread does NOT run out of gas. Seems like we
                      // should be doing this check anyway though.
                      require(
                          _getAccountCodeHash(newImplementation) == keccak256(_code),
                          "L1ChugSplashProxy: code was not correctly deployed"
                      );
                      _setImplementation(newImplementation);
                  }
                  /**
                   * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to
                   *         perform upgrades in a more transparent way. Only callable by the owner.
                   *
                   * @param _key   Storage key to modify.
                   * @param _value New value for the storage key.
                   */
                  function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {
                      assembly {
                          sstore(_key, _value)
                      }
                  }
                  /**
                   * @notice Changes the owner of the proxy contract. Only callable by the owner.
                   *
                   * @param _owner New owner of the proxy contract.
                   */
                  function setOwner(address _owner) external proxyCallIfNotOwner {
                      _setOwner(_owner);
                  }
                  /**
                   * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by
                   *         making an eth_call and setting the "from" address to address(0).
                   *
                   * @return Owner address.
                   */
                  function getOwner() external proxyCallIfNotOwner returns (address) {
                      return _getOwner();
                  }
                  /**
                   * @notice Queries the implementation address. Can only be called by the owner OR by making an
                   *         eth_call and setting the "from" address to address(0).
                   *
                   * @return Implementation address.
                   */
                  function getImplementation() external proxyCallIfNotOwner returns (address) {
                      return _getImplementation();
                  }
                  /**
                   * @notice Sets the implementation address.
                   *
                   * @param _implementation New implementation address.
                   */
                  function _setImplementation(address _implementation) internal {
                      assembly {
                          sstore(IMPLEMENTATION_KEY, _implementation)
                      }
                  }
                  /**
                   * @notice Changes the owner of the proxy contract.
                   *
                   * @param _owner New owner of the proxy contract.
                   */
                  function _setOwner(address _owner) internal {
                      assembly {
                          sstore(OWNER_KEY, _owner)
                      }
                  }
                  /**
                   * @notice Performs the proxy call via a delegatecall.
                   */
                  function _doProxyCall() internal onlyWhenNotPaused {
                      address implementation = _getImplementation();
                      require(implementation != address(0), "L1ChugSplashProxy: implementation is not set yet");
                      assembly {
                          // Copy calldata into memory at 0x0....calldatasize.
                          calldatacopy(0x0, 0x0, calldatasize())
                          // Perform the delegatecall, make sure to pass all available gas.
                          let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)
                          // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
                          // overwrite the calldata that we just copied into memory but that doesn't really
                          // matter because we'll be returning in a second anyway.
                          returndatacopy(0x0, 0x0, returndatasize())
                          // Success == 0 means a revert. We'll revert too and pass the data up.
                          if iszero(success) {
                              revert(0x0, returndatasize())
                          }
                          // Otherwise we'll just return and pass the data up.
                          return(0x0, returndatasize())
                      }
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function _getImplementation() internal view returns (address) {
                      address implementation;
                      assembly {
                          implementation := sload(IMPLEMENTATION_KEY)
                      }
                      return implementation;
                  }
                  /**
                   * @notice Queries the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function _getOwner() internal view returns (address) {
                      address owner;
                      assembly {
                          owner := sload(OWNER_KEY)
                      }
                      return owner;
                  }
                  /**
                   * @notice Gets the code hash for a given account.
                   *
                   * @param _account Address of the account to get a code hash for.
                   *
                   * @return Code hash for the account.
                   */
                  function _getAccountCodeHash(address _account) internal view returns (bytes32) {
                      bytes32 codeHash;
                      assembly {
                          codeHash := extcodehash(_account)
                      }
                      return codeHash;
                  }
              }
              

              File 2 of 6: Proxy
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              /**
               * @title Proxy
               * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or
               *         if the caller is address(0), meaning that the call originated from an off-chain
               *         simulation.
               */
              contract Proxy {
                  /**
                   * @notice The storage slot that holds the address of the implementation.
                   *         bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                   */
                  bytes32 internal constant IMPLEMENTATION_KEY =
                      0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                  /**
                   * @notice The storage slot that holds the address of the owner.
                   *         bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
                   */
                  bytes32 internal constant OWNER_KEY =
                      0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                  /**
                   * @notice An event that is emitted each time the implementation is changed. This event is part
                   *         of the EIP-1967 specification.
                   *
                   * @param implementation The address of the implementation contract
                   */
                  event Upgraded(address indexed implementation);
                  /**
                   * @notice An event that is emitted each time the owner is upgraded. This event is part of the
                   *         EIP-1967 specification.
                   *
                   * @param previousAdmin The previous owner of the contract
                   * @param newAdmin      The new owner of the contract
                   */
                  event AdminChanged(address previousAdmin, address newAdmin);
                  /**
                   * @notice A modifier that reverts if not called by the owner or by address(0) to allow
                   *         eth_call to interact with this proxy without needing to use low-level storage
                   *         inspection. We assume that nobody is able to trigger calls from address(0) during
                   *         normal EVM execution.
                   */
                  modifier proxyCallIfNotAdmin() {
                      if (msg.sender == _getAdmin() || msg.sender == address(0)) {
                          _;
                      } else {
                          // This WILL halt the call frame on completion.
                          _doProxyCall();
                      }
                  }
                  /**
                   * @notice Sets the initial admin during contract deployment. Admin address is stored at the
                   *         EIP-1967 admin storage slot so that accidental storage collision with the
                   *         implementation is not possible.
                   *
                   * @param _admin Address of the initial contract admin. Admin as the ability to access the
                   *               transparent proxy interface.
                   */
                  constructor(address _admin) {
                      _changeAdmin(_admin);
                  }
                  // slither-disable-next-line locked-ether
                  receive() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  // slither-disable-next-line locked-ether
                  fallback() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  /**
                   * @notice Set the implementation contract address. The code at the given address will execute
                   *         when this contract is called.
                   *
                   * @param _implementation Address of the implementation contract.
                   */
                  function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {
                      _setImplementation(_implementation);
                  }
                  /**
                   * @notice Set the implementation and call a function in a single transaction. Useful to ensure
                   *         atomic execution of initialization-based upgrades.
                   *
                   * @param _implementation Address of the implementation contract.
                   * @param _data           Calldata to delegatecall the new implementation with.
                   */
                  function upgradeToAndCall(address _implementation, bytes calldata _data)
                      public
                      payable
                      virtual
                      proxyCallIfNotAdmin
                      returns (bytes memory)
                  {
                      _setImplementation(_implementation);
                      (bool success, bytes memory returndata) = _implementation.delegatecall(_data);
                      require(success, "Proxy: delegatecall to new implementation contract failed");
                      return returndata;
                  }
                  /**
                   * @notice Changes the owner of the proxy contract. Only callable by the owner.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {
                      _changeAdmin(_admin);
                  }
                  /**
                   * @notice Gets the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function admin() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getAdmin();
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function implementation() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getImplementation();
                  }
                  /**
                   * @notice Sets the implementation address.
                   *
                   * @param _implementation New implementation address.
                   */
                  function _setImplementation(address _implementation) internal {
                      assembly {
                          sstore(IMPLEMENTATION_KEY, _implementation)
                      }
                      emit Upgraded(_implementation);
                  }
                  /**
                   * @notice Changes the owner of the proxy contract.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function _changeAdmin(address _admin) internal {
                      address previous = _getAdmin();
                      assembly {
                          sstore(OWNER_KEY, _admin)
                      }
                      emit AdminChanged(previous, _admin);
                  }
                  /**
                   * @notice Performs the proxy call via a delegatecall.
                   */
                  function _doProxyCall() internal {
                      address impl = _getImplementation();
                      require(impl != address(0), "Proxy: implementation not initialized");
                      assembly {
                          // Copy calldata into memory at 0x0....calldatasize.
                          calldatacopy(0x0, 0x0, calldatasize())
                          // Perform the delegatecall, make sure to pass all available gas.
                          let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)
                          // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
                          // overwrite the calldata that we just copied into memory but that doesn't really
                          // matter because we'll be returning in a second anyway.
                          returndatacopy(0x0, 0x0, returndatasize())
                          // Success == 0 means a revert. We'll revert too and pass the data up.
                          if iszero(success) {
                              revert(0x0, returndatasize())
                          }
                          // Otherwise we'll just return and pass the data up.
                          return(0x0, returndatasize())
                      }
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function _getImplementation() internal view returns (address) {
                      address impl;
                      assembly {
                          impl := sload(IMPLEMENTATION_KEY)
                      }
                      return impl;
                  }
                  /**
                   * @notice Queries the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function _getAdmin() internal view returns (address) {
                      address owner;
                      assembly {
                          owner := sload(OWNER_KEY)
                      }
                      return owner;
                  }
              }
              

              File 3 of 6: ResolvedDelegateProxy
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              import { AddressManager } from "./AddressManager.sol";
              /**
               * @custom:legacy
               * @title ResolvedDelegateProxy
               * @notice ResolvedDelegateProxy is a legacy proxy contract that makes use of the AddressManager to
               *         resolve the implementation address. We're maintaining this contract for backwards
               *         compatibility so we can manage all legacy proxies where necessary.
               */
              contract ResolvedDelegateProxy {
                  /**
                   * @notice Mapping used to store the implementation name that corresponds to this contract. A
                   *         mapping was originally used as a way to bypass the same issue normally solved by
                   *         storing the implementation address in a specific storage slot that does not conflict
                   *         with any other storage slot. Generally NOT a safe solution but works as long as the
                   *         implementation does not also keep a mapping in the first storage slot.
                   */
                  mapping(address => string) private implementationName;
                  /**
                   * @notice Mapping used to store the address of the AddressManager contract where the
                   *         implementation address will be resolved from. Same concept here as with the above
                   *         mapping. Also generally unsafe but fine if the implementation doesn't keep a mapping
                   *         in the second storage slot.
                   */
                  mapping(address => AddressManager) private addressManager;
                  /**
                   * @param _addressManager  Address of the AddressManager.
                   * @param _implementationName implementationName of the contract to proxy to.
                   */
                  constructor(AddressManager _addressManager, string memory _implementationName) {
                      addressManager[address(this)] = _addressManager;
                      implementationName[address(this)] = _implementationName;
                  }
                  /**
                   * @notice Fallback, performs a delegatecall to the resolved implementation address.
                   */
                  // solhint-disable-next-line no-complex-fallback
                  fallback() external payable {
                      address target = addressManager[address(this)].getAddress(
                          (implementationName[address(this)])
                      );
                      require(target != address(0), "ResolvedDelegateProxy: target address must be initialized");
                      // slither-disable-next-line controlled-delegatecall
                      (bool success, bytes memory returndata) = target.delegatecall(msg.data);
                      if (success == true) {
                          assembly {
                              return(add(returndata, 0x20), mload(returndata))
                          }
                      } else {
                          assembly {
                              revert(add(returndata, 0x20), mload(returndata))
                          }
                      }
                  }
              }
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
              /**
               * @custom:legacy
               * @title AddressManager
               * @notice AddressManager is a legacy contract that was used in the old version of the Optimism
               *         system to manage a registry of string names to addresses. We now use a more standard
               *         proxy system instead, but this contract is still necessary for backwards compatibility
               *         with several older contracts.
               */
              contract AddressManager is Ownable {
                  /**
                   * @notice Mapping of the hashes of string names to addresses.
                   */
                  mapping(bytes32 => address) private addresses;
                  /**
                   * @notice Emitted when an address is modified in the registry.
                   *
                   * @param name       String name being set in the registry.
                   * @param newAddress Address set for the given name.
                   * @param oldAddress Address that was previously set for the given name.
                   */
                  event AddressSet(string indexed name, address newAddress, address oldAddress);
                  /**
                   * @notice Changes the address associated with a particular name.
                   *
                   * @param _name    String name to associate an address with.
                   * @param _address Address to associate with the name.
                   */
                  function setAddress(string memory _name, address _address) external onlyOwner {
                      bytes32 nameHash = _getNameHash(_name);
                      address oldAddress = addresses[nameHash];
                      addresses[nameHash] = _address;
                      emit AddressSet(_name, _address, oldAddress);
                  }
                  /**
                   * @notice Retrieves the address associated with a given name.
                   *
                   * @param _name Name to retrieve an address for.
                   *
                   * @return Address associated with the given name.
                   */
                  function getAddress(string memory _name) external view returns (address) {
                      return addresses[_getNameHash(_name)];
                  }
                  /**
                   * @notice Computes the hash of a name.
                   *
                   * @param _name Name to compute a hash for.
                   *
                   * @return Hash of the given name.
                   */
                  function _getNameHash(string memory _name) internal pure returns (bytes32) {
                      return keccak256(abi.encodePacked(_name));
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
              pragma solidity ^0.8.0;
              import "../utils/Context.sol";
              /**
               * @dev Contract module which provides a basic access control mechanism, where
               * there is an account (an owner) that can be granted exclusive access to
               * specific functions.
               *
               * By default, the owner account will be the one that deploys the contract. This
               * can later be changed with {transferOwnership}.
               *
               * This module is used through inheritance. It will make available the modifier
               * `onlyOwner`, which can be applied to your functions to restrict their use to
               * the owner.
               */
              abstract contract Ownable is Context {
                  address private _owner;
                  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                  /**
                   * @dev Initializes the contract setting the deployer as the initial owner.
                   */
                  constructor() {
                      _transferOwnership(_msgSender());
                  }
                  /**
                   * @dev Throws if called by any account other than the owner.
                   */
                  modifier onlyOwner() {
                      _checkOwner();
                      _;
                  }
                  /**
                   * @dev Returns the address of the current owner.
                   */
                  function owner() public view virtual returns (address) {
                      return _owner;
                  }
                  /**
                   * @dev Throws if the sender is not the owner.
                   */
                  function _checkOwner() internal view virtual {
                      require(owner() == _msgSender(), "Ownable: caller is not the owner");
                  }
                  /**
                   * @dev Leaves the contract without owner. It will not be possible to call
                   * `onlyOwner` functions anymore. Can only be called by the current owner.
                   *
                   * NOTE: Renouncing ownership will leave the contract without an owner,
                   * thereby removing any functionality that is only available to the owner.
                   */
                  function renounceOwnership() public virtual onlyOwner {
                      _transferOwnership(address(0));
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Can only be called by the current owner.
                   */
                  function transferOwnership(address newOwner) public virtual onlyOwner {
                      require(newOwner != address(0), "Ownable: new owner is the zero address");
                      _transferOwnership(newOwner);
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Internal function without access restriction.
                   */
                  function _transferOwnership(address newOwner) internal virtual {
                      address oldOwner = _owner;
                      _owner = newOwner;
                      emit OwnershipTransferred(oldOwner, newOwner);
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
              pragma solidity ^0.8.0;
              /**
               * @dev Provides information about the current execution context, including the
               * sender of the transaction and its data. While these are generally available
               * via msg.sender and msg.data, they should not be accessed in such a direct
               * manner, since when dealing with meta-transactions the account sending and
               * paying for execution may not be the actual sender (as far as an application
               * is concerned).
               *
               * This contract is only required for intermediate, library-like contracts.
               */
              abstract contract Context {
                  function _msgSender() internal view virtual returns (address) {
                      return msg.sender;
                  }
                  function _msgData() internal view virtual returns (bytes calldata) {
                      return msg.data;
                  }
              }
              

              File 4 of 6: ProxyAdmin
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
              import { Proxy } from "./Proxy.sol";
              import { AddressManager } from "../legacy/AddressManager.sol";
              import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
              /**
               * @title IStaticERC1967Proxy
               * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.
               */
              interface IStaticERC1967Proxy {
                  function implementation() external view returns (address);
                  function admin() external view returns (address);
              }
              /**
               * @title IStaticL1ChugSplashProxy
               * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.
               */
              interface IStaticL1ChugSplashProxy {
                  function getImplementation() external view returns (address);
                  function getOwner() external view returns (address);
              }
              /**
               * @title ProxyAdmin
               * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,
               *         based on the OpenZeppelin implementation. It has backwards compatibility logic to work
               *         with the various types of proxies that have been deployed by Optimism in the past.
               */
              contract ProxyAdmin is Ownable {
                  /**
                   * @notice The proxy types that the ProxyAdmin can manage.
                   *
                   * @custom:value ERC1967    Represents an ERC1967 compliant transparent proxy interface.
                   * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).
                   * @custom:value RESOLVED   Represents the ResolvedDelegate proxy (legacy).
                   */
                  enum ProxyType {
                      ERC1967,
                      CHUGSPLASH,
                      RESOLVED
                  }
                  /**
                   * @notice A mapping of proxy types, used for backwards compatibility.
                   */
                  mapping(address => ProxyType) public proxyType;
                  /**
                   * @notice A reverse mapping of addresses to names held in the AddressManager. This must be
                   *         manually kept up to date with changes in the AddressManager for this contract
                   *         to be able to work as an admin for the ResolvedDelegateProxy type.
                   */
                  mapping(address => string) public implementationName;
                  /**
                   * @notice The address of the address manager, this is required to manage the
                   *         ResolvedDelegateProxy type.
                   */
                  AddressManager public addressManager;
                  /**
                   * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.
                   */
                  bool internal upgrading;
                  /**
                   * @param _owner Address of the initial owner of this contract.
                   */
                  constructor(address _owner) Ownable() {
                      _transferOwnership(_owner);
                  }
                  /**
                   * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)
                   *         proxy types.
                   *
                   * @param _address Address of the proxy.
                   * @param _type    Type of the proxy.
                   */
                  function setProxyType(address _address, ProxyType _type) external onlyOwner {
                      proxyType[_address] = _type;
                  }
                  /**
                   * @notice Sets the implementation name for a given address. Only required for
                   *         ResolvedDelegateProxy type proxies that have an implementation name.
                   *
                   * @param _address Address of the ResolvedDelegateProxy.
                   * @param _name    Name of the implementation for the proxy.
                   */
                  function setImplementationName(address _address, string memory _name) external onlyOwner {
                      implementationName[_address] = _name;
                  }
                  /**
                   * @notice Set the address of the AddressManager. This is required to manage legacy
                   *         ResolvedDelegateProxy type proxy contracts.
                   *
                   * @param _address Address of the AddressManager.
                   */
                  function setAddressManager(AddressManager _address) external onlyOwner {
                      addressManager = _address;
                  }
                  /**
                   * @custom:legacy
                   * @notice Set an address in the address manager. Since only the owner of the AddressManager
                   *         can directly modify addresses and the ProxyAdmin will own the AddressManager, this
                   *         gives the owner of the ProxyAdmin the ability to modify addresses directly.
                   *
                   * @param _name    Name to set within the AddressManager.
                   * @param _address Address to attach to the given name.
                   */
                  function setAddress(string memory _name, address _address) external onlyOwner {
                      addressManager.setAddress(_name, _address);
                  }
                  /**
                   * @custom:legacy
                   * @notice Set the upgrading status for the Chugsplash proxy type.
                   *
                   * @param _upgrading Whether or not the system is upgrading.
                   */
                  function setUpgrading(bool _upgrading) external onlyOwner {
                      upgrading = _upgrading;
                  }
                  /**
                   * @custom:legacy
                   * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.
                   *
                   * @return Whether or not there is an upgrade going on. May not actually tell you whether an
                   *         upgrade is going on, since we don't currently plan to use this variable for anything
                   *         other than a legacy indicator to fix a UX bug in the ChugSplash proxy.
                   */
                  function isUpgrading() external view returns (bool) {
                      return upgrading;
                  }
                  /**
                   * @notice Returns the implementation of the given proxy address.
                   *
                   * @param _proxy Address of the proxy to get the implementation of.
                   *
                   * @return Address of the implementation of the proxy.
                   */
                  function getProxyImplementation(address _proxy) external view returns (address) {
                      ProxyType ptype = proxyType[_proxy];
                      if (ptype == ProxyType.ERC1967) {
                          return IStaticERC1967Proxy(_proxy).implementation();
                      } else if (ptype == ProxyType.CHUGSPLASH) {
                          return IStaticL1ChugSplashProxy(_proxy).getImplementation();
                      } else if (ptype == ProxyType.RESOLVED) {
                          return addressManager.getAddress(implementationName[_proxy]);
                      } else {
                          revert("ProxyAdmin: unknown proxy type");
                      }
                  }
                  /**
                   * @notice Returns the admin of the given proxy address.
                   *
                   * @param _proxy Address of the proxy to get the admin of.
                   *
                   * @return Address of the admin of the proxy.
                   */
                  function getProxyAdmin(address payable _proxy) external view returns (address) {
                      ProxyType ptype = proxyType[_proxy];
                      if (ptype == ProxyType.ERC1967) {
                          return IStaticERC1967Proxy(_proxy).admin();
                      } else if (ptype == ProxyType.CHUGSPLASH) {
                          return IStaticL1ChugSplashProxy(_proxy).getOwner();
                      } else if (ptype == ProxyType.RESOLVED) {
                          return addressManager.owner();
                      } else {
                          revert("ProxyAdmin: unknown proxy type");
                      }
                  }
                  /**
                   * @notice Updates the admin of the given proxy address.
                   *
                   * @param _proxy    Address of the proxy to update.
                   * @param _newAdmin Address of the new proxy admin.
                   */
                  function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {
                      ProxyType ptype = proxyType[_proxy];
                      if (ptype == ProxyType.ERC1967) {
                          Proxy(_proxy).changeAdmin(_newAdmin);
                      } else if (ptype == ProxyType.CHUGSPLASH) {
                          L1ChugSplashProxy(_proxy).setOwner(_newAdmin);
                      } else if (ptype == ProxyType.RESOLVED) {
                          addressManager.transferOwnership(_newAdmin);
                      } else {
                          revert("ProxyAdmin: unknown proxy type");
                      }
                  }
                  /**
                   * @notice Changes a proxy's implementation contract.
                   *
                   * @param _proxy          Address of the proxy to upgrade.
                   * @param _implementation Address of the new implementation address.
                   */
                  function upgrade(address payable _proxy, address _implementation) public onlyOwner {
                      ProxyType ptype = proxyType[_proxy];
                      if (ptype == ProxyType.ERC1967) {
                          Proxy(_proxy).upgradeTo(_implementation);
                      } else if (ptype == ProxyType.CHUGSPLASH) {
                          L1ChugSplashProxy(_proxy).setStorage(
                              // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                              0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,
                              bytes32(uint256(uint160(_implementation)))
                          );
                      } else if (ptype == ProxyType.RESOLVED) {
                          string memory name = implementationName[_proxy];
                          addressManager.setAddress(name, _implementation);
                      } else {
                          // It should not be possible to retrieve a ProxyType value which is not matched by
                          // one of the previous conditions.
                          assert(false);
                      }
                  }
                  /**
                   * @notice Changes a proxy's implementation contract and delegatecalls the new implementation
                   *         with some given data. Useful for atomic upgrade-and-initialize calls.
                   *
                   * @param _proxy          Address of the proxy to upgrade.
                   * @param _implementation Address of the new implementation address.
                   * @param _data           Data to trigger the new implementation with.
                   */
                  function upgradeAndCall(
                      address payable _proxy,
                      address _implementation,
                      bytes memory _data
                  ) external payable onlyOwner {
                      ProxyType ptype = proxyType[_proxy];
                      if (ptype == ProxyType.ERC1967) {
                          Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);
                      } else {
                          // reverts if proxy type is unknown
                          upgrade(_proxy, _implementation);
                          (bool success, ) = _proxy.call{ value: msg.value }(_data);
                          require(success, "ProxyAdmin: call to proxy after upgrade failed");
                      }
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
              pragma solidity ^0.8.0;
              import "../utils/Context.sol";
              /**
               * @dev Contract module which provides a basic access control mechanism, where
               * there is an account (an owner) that can be granted exclusive access to
               * specific functions.
               *
               * By default, the owner account will be the one that deploys the contract. This
               * can later be changed with {transferOwnership}.
               *
               * This module is used through inheritance. It will make available the modifier
               * `onlyOwner`, which can be applied to your functions to restrict their use to
               * the owner.
               */
              abstract contract Ownable is Context {
                  address private _owner;
                  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                  /**
                   * @dev Initializes the contract setting the deployer as the initial owner.
                   */
                  constructor() {
                      _transferOwnership(_msgSender());
                  }
                  /**
                   * @dev Throws if called by any account other than the owner.
                   */
                  modifier onlyOwner() {
                      _checkOwner();
                      _;
                  }
                  /**
                   * @dev Returns the address of the current owner.
                   */
                  function owner() public view virtual returns (address) {
                      return _owner;
                  }
                  /**
                   * @dev Throws if the sender is not the owner.
                   */
                  function _checkOwner() internal view virtual {
                      require(owner() == _msgSender(), "Ownable: caller is not the owner");
                  }
                  /**
                   * @dev Leaves the contract without owner. It will not be possible to call
                   * `onlyOwner` functions anymore. Can only be called by the current owner.
                   *
                   * NOTE: Renouncing ownership will leave the contract without an owner,
                   * thereby removing any functionality that is only available to the owner.
                   */
                  function renounceOwnership() public virtual onlyOwner {
                      _transferOwnership(address(0));
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Can only be called by the current owner.
                   */
                  function transferOwnership(address newOwner) public virtual onlyOwner {
                      require(newOwner != address(0), "Ownable: new owner is the zero address");
                      _transferOwnership(newOwner);
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Internal function without access restriction.
                   */
                  function _transferOwnership(address newOwner) internal virtual {
                      address oldOwner = _owner;
                      _owner = newOwner;
                      emit OwnershipTransferred(oldOwner, newOwner);
                  }
              }
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              /**
               * @title Proxy
               * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or
               *         if the caller is address(0), meaning that the call originated from an off-chain
               *         simulation.
               */
              contract Proxy {
                  /**
                   * @notice The storage slot that holds the address of the implementation.
                   *         bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                   */
                  bytes32 internal constant IMPLEMENTATION_KEY =
                      0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                  /**
                   * @notice The storage slot that holds the address of the owner.
                   *         bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
                   */
                  bytes32 internal constant OWNER_KEY =
                      0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                  /**
                   * @notice An event that is emitted each time the implementation is changed. This event is part
                   *         of the EIP-1967 specification.
                   *
                   * @param implementation The address of the implementation contract
                   */
                  event Upgraded(address indexed implementation);
                  /**
                   * @notice An event that is emitted each time the owner is upgraded. This event is part of the
                   *         EIP-1967 specification.
                   *
                   * @param previousAdmin The previous owner of the contract
                   * @param newAdmin      The new owner of the contract
                   */
                  event AdminChanged(address previousAdmin, address newAdmin);
                  /**
                   * @notice A modifier that reverts if not called by the owner or by address(0) to allow
                   *         eth_call to interact with this proxy without needing to use low-level storage
                   *         inspection. We assume that nobody is able to trigger calls from address(0) during
                   *         normal EVM execution.
                   */
                  modifier proxyCallIfNotAdmin() {
                      if (msg.sender == _getAdmin() || msg.sender == address(0)) {
                          _;
                      } else {
                          // This WILL halt the call frame on completion.
                          _doProxyCall();
                      }
                  }
                  /**
                   * @notice Sets the initial admin during contract deployment. Admin address is stored at the
                   *         EIP-1967 admin storage slot so that accidental storage collision with the
                   *         implementation is not possible.
                   *
                   * @param _admin Address of the initial contract admin. Admin as the ability to access the
                   *               transparent proxy interface.
                   */
                  constructor(address _admin) {
                      _changeAdmin(_admin);
                  }
                  // slither-disable-next-line locked-ether
                  receive() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  // slither-disable-next-line locked-ether
                  fallback() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  /**
                   * @notice Set the implementation contract address. The code at the given address will execute
                   *         when this contract is called.
                   *
                   * @param _implementation Address of the implementation contract.
                   */
                  function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {
                      _setImplementation(_implementation);
                  }
                  /**
                   * @notice Set the implementation and call a function in a single transaction. Useful to ensure
                   *         atomic execution of initialization-based upgrades.
                   *
                   * @param _implementation Address of the implementation contract.
                   * @param _data           Calldata to delegatecall the new implementation with.
                   */
                  function upgradeToAndCall(address _implementation, bytes calldata _data)
                      public
                      payable
                      virtual
                      proxyCallIfNotAdmin
                      returns (bytes memory)
                  {
                      _setImplementation(_implementation);
                      (bool success, bytes memory returndata) = _implementation.delegatecall(_data);
                      require(success, "Proxy: delegatecall to new implementation contract failed");
                      return returndata;
                  }
                  /**
                   * @notice Changes the owner of the proxy contract. Only callable by the owner.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {
                      _changeAdmin(_admin);
                  }
                  /**
                   * @notice Gets the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function admin() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getAdmin();
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function implementation() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getImplementation();
                  }
                  /**
                   * @notice Sets the implementation address.
                   *
                   * @param _implementation New implementation address.
                   */
                  function _setImplementation(address _implementation) internal {
                      assembly {
                          sstore(IMPLEMENTATION_KEY, _implementation)
                      }
                      emit Upgraded(_implementation);
                  }
                  /**
                   * @notice Changes the owner of the proxy contract.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function _changeAdmin(address _admin) internal {
                      address previous = _getAdmin();
                      assembly {
                          sstore(OWNER_KEY, _admin)
                      }
                      emit AdminChanged(previous, _admin);
                  }
                  /**
                   * @notice Performs the proxy call via a delegatecall.
                   */
                  function _doProxyCall() internal {
                      address impl = _getImplementation();
                      require(impl != address(0), "Proxy: implementation not initialized");
                      assembly {
                          // Copy calldata into memory at 0x0....calldatasize.
                          calldatacopy(0x0, 0x0, calldatasize())
                          // Perform the delegatecall, make sure to pass all available gas.
                          let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)
                          // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
                          // overwrite the calldata that we just copied into memory but that doesn't really
                          // matter because we'll be returning in a second anyway.
                          returndatacopy(0x0, 0x0, returndatasize())
                          // Success == 0 means a revert. We'll revert too and pass the data up.
                          if iszero(success) {
                              revert(0x0, returndatasize())
                          }
                          // Otherwise we'll just return and pass the data up.
                          return(0x0, returndatasize())
                      }
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function _getImplementation() internal view returns (address) {
                      address impl;
                      assembly {
                          impl := sload(IMPLEMENTATION_KEY)
                      }
                      return impl;
                  }
                  /**
                   * @notice Queries the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function _getAdmin() internal view returns (address) {
                      address owner;
                      assembly {
                          owner := sload(OWNER_KEY)
                      }
                      return owner;
                  }
              }
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
              /**
               * @custom:legacy
               * @title AddressManager
               * @notice AddressManager is a legacy contract that was used in the old version of the Optimism
               *         system to manage a registry of string names to addresses. We now use a more standard
               *         proxy system instead, but this contract is still necessary for backwards compatibility
               *         with several older contracts.
               */
              contract AddressManager is Ownable {
                  /**
                   * @notice Mapping of the hashes of string names to addresses.
                   */
                  mapping(bytes32 => address) private addresses;
                  /**
                   * @notice Emitted when an address is modified in the registry.
                   *
                   * @param name       String name being set in the registry.
                   * @param newAddress Address set for the given name.
                   * @param oldAddress Address that was previously set for the given name.
                   */
                  event AddressSet(string indexed name, address newAddress, address oldAddress);
                  /**
                   * @notice Changes the address associated with a particular name.
                   *
                   * @param _name    String name to associate an address with.
                   * @param _address Address to associate with the name.
                   */
                  function setAddress(string memory _name, address _address) external onlyOwner {
                      bytes32 nameHash = _getNameHash(_name);
                      address oldAddress = addresses[nameHash];
                      addresses[nameHash] = _address;
                      emit AddressSet(_name, _address, oldAddress);
                  }
                  /**
                   * @notice Retrieves the address associated with a given name.
                   *
                   * @param _name Name to retrieve an address for.
                   *
                   * @return Address associated with the given name.
                   */
                  function getAddress(string memory _name) external view returns (address) {
                      return addresses[_getNameHash(_name)];
                  }
                  /**
                   * @notice Computes the hash of a name.
                   *
                   * @param _name Name to compute a hash for.
                   *
                   * @return Hash of the given name.
                   */
                  function _getNameHash(string memory _name) internal pure returns (bytes32) {
                      return keccak256(abi.encodePacked(_name));
                  }
              }
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              /**
               * @title IL1ChugSplashDeployer
               */
              interface IL1ChugSplashDeployer {
                  function isUpgrading() external view returns (bool);
              }
              /**
               * @custom:legacy
               * @title L1ChugSplashProxy
               * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added
               *         functions `setCode` and `setStorage` for changing the code or storage of the contract.
               *
               *         Note for future developers: do NOT make anything in this contract 'public' unless you
               *         know what you're doing. Anything public can potentially have a function signature that
               *         conflicts with a signature attached to the implementation contract. Public functions
               *         SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good
               *         reason not to have that modifier. And there almost certainly is not a good reason to not
               *         have that modifier. Beware!
               */
              contract L1ChugSplashProxy {
                  /**
                   * @notice "Magic" prefix. When prepended to some arbitrary bytecode and used to create a
                   *         contract, the appended bytecode will be deployed as given.
                   */
                  bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;
                  /**
                   * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                   */
                  bytes32 internal constant IMPLEMENTATION_KEY =
                      0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                  /**
                   * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
                   */
                  bytes32 internal constant OWNER_KEY =
                      0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                  /**
                   * @notice Blocks a function from being called when the parent signals that the system should
                   *         be paused via an isUpgrading function.
                   */
                  modifier onlyWhenNotPaused() {
                      address owner = _getOwner();
                      // We do a low-level call because there's no guarantee that the owner actually *is* an
                      // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and
                      // it turns out that it isn't the right type of contract.
                      (bool success, bytes memory returndata) = owner.staticcall(
                          abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)
                      );
                      // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we
                      // can just continue as normal. We also expect that the return value is exactly 32 bytes
                      // long. If this isn't the case then we can safely ignore the result.
                      if (success && returndata.length == 32) {
                          // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the
                          // case that the isUpgrading function returned something other than 0 or 1. But we only
                          // really care about the case where this value is 0 (= false).
                          uint256 ret = abi.decode(returndata, (uint256));
                          require(ret == 0, "L1ChugSplashProxy: system is currently being upgraded");
                      }
                      _;
                  }
                  /**
                   * @notice Makes a proxy call instead of triggering the given function when the caller is
                   *         either the owner or the zero address. Caller can only ever be the zero address if
                   *         this function is being called off-chain via eth_call, which is totally fine and can
                   *         be convenient for client-side tooling. Avoids situations where the proxy and
                   *         implementation share a sighash and the proxy function ends up being called instead
                   *         of the implementation one.
                   *
                   *         Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If
                   *         there's a way for someone to send a transaction with msg.sender == address(0) in any
                   *         real context then we have much bigger problems. Primary reason to include this
                   *         additional allowed sender is because the owner address can be changed dynamically
                   *         and we do not want clients to have to keep track of the current owner in order to
                   *         make an eth_call that doesn't trigger the proxied contract.
                   */
                  // slither-disable-next-line incorrect-modifier
                  modifier proxyCallIfNotOwner() {
                      if (msg.sender == _getOwner() || msg.sender == address(0)) {
                          _;
                      } else {
                          // This WILL halt the call frame on completion.
                          _doProxyCall();
                      }
                  }
                  /**
                   * @param _owner Address of the initial contract owner.
                   */
                  constructor(address _owner) {
                      _setOwner(_owner);
                  }
                  // slither-disable-next-line locked-ether
                  receive() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  // slither-disable-next-line locked-ether
                  fallback() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  /**
                   * @notice Sets the code that should be running behind this proxy.
                   *
                   *         Note: This scheme is a bit different from the standard proxy scheme where one would
                   *         typically deploy the code separately and then set the implementation address. We're
                   *         doing it this way because it gives us a lot more freedom on the client side. Can
                   *         only be triggered by the contract owner.
                   *
                   * @param _code New contract code to run inside this contract.
                   */
                  function setCode(bytes memory _code) external proxyCallIfNotOwner {
                      // Get the code hash of the current implementation.
                      address implementation = _getImplementation();
                      // If the code hash matches the new implementation then we return early.
                      if (keccak256(_code) == _getAccountCodeHash(implementation)) {
                          return;
                      }
                      // Create the deploycode by appending the magic prefix.
                      bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);
                      // Deploy the code and set the new implementation address.
                      address newImplementation;
                      assembly {
                          newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))
                      }
                      // Check that the code was actually deployed correctly. I'm not sure if you can ever
                      // actually fail this check. Should only happen if the contract creation from above runs
                      // out of gas but this parent execution thread does NOT run out of gas. Seems like we
                      // should be doing this check anyway though.
                      require(
                          _getAccountCodeHash(newImplementation) == keccak256(_code),
                          "L1ChugSplashProxy: code was not correctly deployed"
                      );
                      _setImplementation(newImplementation);
                  }
                  /**
                   * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to
                   *         perform upgrades in a more transparent way. Only callable by the owner.
                   *
                   * @param _key   Storage key to modify.
                   * @param _value New value for the storage key.
                   */
                  function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {
                      assembly {
                          sstore(_key, _value)
                      }
                  }
                  /**
                   * @notice Changes the owner of the proxy contract. Only callable by the owner.
                   *
                   * @param _owner New owner of the proxy contract.
                   */
                  function setOwner(address _owner) external proxyCallIfNotOwner {
                      _setOwner(_owner);
                  }
                  /**
                   * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by
                   *         making an eth_call and setting the "from" address to address(0).
                   *
                   * @return Owner address.
                   */
                  function getOwner() external proxyCallIfNotOwner returns (address) {
                      return _getOwner();
                  }
                  /**
                   * @notice Queries the implementation address. Can only be called by the owner OR by making an
                   *         eth_call and setting the "from" address to address(0).
                   *
                   * @return Implementation address.
                   */
                  function getImplementation() external proxyCallIfNotOwner returns (address) {
                      return _getImplementation();
                  }
                  /**
                   * @notice Sets the implementation address.
                   *
                   * @param _implementation New implementation address.
                   */
                  function _setImplementation(address _implementation) internal {
                      assembly {
                          sstore(IMPLEMENTATION_KEY, _implementation)
                      }
                  }
                  /**
                   * @notice Changes the owner of the proxy contract.
                   *
                   * @param _owner New owner of the proxy contract.
                   */
                  function _setOwner(address _owner) internal {
                      assembly {
                          sstore(OWNER_KEY, _owner)
                      }
                  }
                  /**
                   * @notice Performs the proxy call via a delegatecall.
                   */
                  function _doProxyCall() internal onlyWhenNotPaused {
                      address implementation = _getImplementation();
                      require(implementation != address(0), "L1ChugSplashProxy: implementation is not set yet");
                      assembly {
                          // Copy calldata into memory at 0x0....calldatasize.
                          calldatacopy(0x0, 0x0, calldatasize())
                          // Perform the delegatecall, make sure to pass all available gas.
                          let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)
                          // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
                          // overwrite the calldata that we just copied into memory but that doesn't really
                          // matter because we'll be returning in a second anyway.
                          returndatacopy(0x0, 0x0, returndatasize())
                          // Success == 0 means a revert. We'll revert too and pass the data up.
                          if iszero(success) {
                              revert(0x0, returndatasize())
                          }
                          // Otherwise we'll just return and pass the data up.
                          return(0x0, returndatasize())
                      }
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function _getImplementation() internal view returns (address) {
                      address implementation;
                      assembly {
                          implementation := sload(IMPLEMENTATION_KEY)
                      }
                      return implementation;
                  }
                  /**
                   * @notice Queries the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function _getOwner() internal view returns (address) {
                      address owner;
                      assembly {
                          owner := sload(OWNER_KEY)
                      }
                      return owner;
                  }
                  /**
                   * @notice Gets the code hash for a given account.
                   *
                   * @param _account Address of the account to get a code hash for.
                   *
                   * @return Code hash for the account.
                   */
                  function _getAccountCodeHash(address _account) internal view returns (bytes32) {
                      bytes32 codeHash;
                      assembly {
                          codeHash := extcodehash(_account)
                      }
                      return codeHash;
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
              pragma solidity ^0.8.0;
              /**
               * @dev Provides information about the current execution context, including the
               * sender of the transaction and its data. While these are generally available
               * via msg.sender and msg.data, they should not be accessed in such a direct
               * manner, since when dealing with meta-transactions the account sending and
               * paying for execution may not be the actual sender (as far as an application
               * is concerned).
               *
               * This contract is only required for intermediate, library-like contracts.
               */
              abstract contract Context {
                  function _msgSender() internal view virtual returns (address) {
                      return msg.sender;
                  }
                  function _msgData() internal view virtual returns (bytes calldata) {
                      return msg.data;
                  }
              }
              

              File 5 of 6: AddressManager
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
              /**
               * @custom:legacy
               * @title AddressManager
               * @notice AddressManager is a legacy contract that was used in the old version of the Optimism
               *         system to manage a registry of string names to addresses. We now use a more standard
               *         proxy system instead, but this contract is still necessary for backwards compatibility
               *         with several older contracts.
               */
              contract AddressManager is Ownable {
                  /**
                   * @notice Mapping of the hashes of string names to addresses.
                   */
                  mapping(bytes32 => address) private addresses;
                  /**
                   * @notice Emitted when an address is modified in the registry.
                   *
                   * @param name       String name being set in the registry.
                   * @param newAddress Address set for the given name.
                   * @param oldAddress Address that was previously set for the given name.
                   */
                  event AddressSet(string indexed name, address newAddress, address oldAddress);
                  /**
                   * @notice Changes the address associated with a particular name.
                   *
                   * @param _name    String name to associate an address with.
                   * @param _address Address to associate with the name.
                   */
                  function setAddress(string memory _name, address _address) external onlyOwner {
                      bytes32 nameHash = _getNameHash(_name);
                      address oldAddress = addresses[nameHash];
                      addresses[nameHash] = _address;
                      emit AddressSet(_name, _address, oldAddress);
                  }
                  /**
                   * @notice Retrieves the address associated with a given name.
                   *
                   * @param _name Name to retrieve an address for.
                   *
                   * @return Address associated with the given name.
                   */
                  function getAddress(string memory _name) external view returns (address) {
                      return addresses[_getNameHash(_name)];
                  }
                  /**
                   * @notice Computes the hash of a name.
                   *
                   * @param _name Name to compute a hash for.
                   *
                   * @return Hash of the given name.
                   */
                  function _getNameHash(string memory _name) internal pure returns (bytes32) {
                      return keccak256(abi.encodePacked(_name));
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
              pragma solidity ^0.8.0;
              import "../utils/Context.sol";
              /**
               * @dev Contract module which provides a basic access control mechanism, where
               * there is an account (an owner) that can be granted exclusive access to
               * specific functions.
               *
               * By default, the owner account will be the one that deploys the contract. This
               * can later be changed with {transferOwnership}.
               *
               * This module is used through inheritance. It will make available the modifier
               * `onlyOwner`, which can be applied to your functions to restrict their use to
               * the owner.
               */
              abstract contract Ownable is Context {
                  address private _owner;
                  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                  /**
                   * @dev Initializes the contract setting the deployer as the initial owner.
                   */
                  constructor() {
                      _transferOwnership(_msgSender());
                  }
                  /**
                   * @dev Throws if called by any account other than the owner.
                   */
                  modifier onlyOwner() {
                      _checkOwner();
                      _;
                  }
                  /**
                   * @dev Returns the address of the current owner.
                   */
                  function owner() public view virtual returns (address) {
                      return _owner;
                  }
                  /**
                   * @dev Throws if the sender is not the owner.
                   */
                  function _checkOwner() internal view virtual {
                      require(owner() == _msgSender(), "Ownable: caller is not the owner");
                  }
                  /**
                   * @dev Leaves the contract without owner. It will not be possible to call
                   * `onlyOwner` functions anymore. Can only be called by the current owner.
                   *
                   * NOTE: Renouncing ownership will leave the contract without an owner,
                   * thereby removing any functionality that is only available to the owner.
                   */
                  function renounceOwnership() public virtual onlyOwner {
                      _transferOwnership(address(0));
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Can only be called by the current owner.
                   */
                  function transferOwnership(address newOwner) public virtual onlyOwner {
                      require(newOwner != address(0), "Ownable: new owner is the zero address");
                      _transferOwnership(newOwner);
                  }
                  /**
                   * @dev Transfers ownership of the contract to a new account (`newOwner`).
                   * Internal function without access restriction.
                   */
                  function _transferOwnership(address newOwner) internal virtual {
                      address oldOwner = _owner;
                      _owner = newOwner;
                      emit OwnershipTransferred(oldOwner, newOwner);
                  }
              }
              // SPDX-License-Identifier: MIT
              // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
              pragma solidity ^0.8.0;
              /**
               * @dev Provides information about the current execution context, including the
               * sender of the transaction and its data. While these are generally available
               * via msg.sender and msg.data, they should not be accessed in such a direct
               * manner, since when dealing with meta-transactions the account sending and
               * paying for execution may not be the actual sender (as far as an application
               * is concerned).
               *
               * This contract is only required for intermediate, library-like contracts.
               */
              abstract contract Context {
                  function _msgSender() internal view virtual returns (address) {
                      return msg.sender;
                  }
                  function _msgData() internal view virtual returns (bytes calldata) {
                      return msg.data;
                  }
              }
              

              File 6 of 6: Proxy
              // SPDX-License-Identifier: MIT
              pragma solidity 0.8.15;
              /**
               * @title Proxy
               * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or
               *         if the caller is address(0), meaning that the call originated from an off-chain
               *         simulation.
               */
              contract Proxy {
                  /**
                   * @notice The storage slot that holds the address of the implementation.
                   *         bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
                   */
                  bytes32 internal constant IMPLEMENTATION_KEY =
                      0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                  /**
                   * @notice The storage slot that holds the address of the owner.
                   *         bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
                   */
                  bytes32 internal constant OWNER_KEY =
                      0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                  /**
                   * @notice An event that is emitted each time the implementation is changed. This event is part
                   *         of the EIP-1967 specification.
                   *
                   * @param implementation The address of the implementation contract
                   */
                  event Upgraded(address indexed implementation);
                  /**
                   * @notice An event that is emitted each time the owner is upgraded. This event is part of the
                   *         EIP-1967 specification.
                   *
                   * @param previousAdmin The previous owner of the contract
                   * @param newAdmin      The new owner of the contract
                   */
                  event AdminChanged(address previousAdmin, address newAdmin);
                  /**
                   * @notice A modifier that reverts if not called by the owner or by address(0) to allow
                   *         eth_call to interact with this proxy without needing to use low-level storage
                   *         inspection. We assume that nobody is able to trigger calls from address(0) during
                   *         normal EVM execution.
                   */
                  modifier proxyCallIfNotAdmin() {
                      if (msg.sender == _getAdmin() || msg.sender == address(0)) {
                          _;
                      } else {
                          // This WILL halt the call frame on completion.
                          _doProxyCall();
                      }
                  }
                  /**
                   * @notice Sets the initial admin during contract deployment. Admin address is stored at the
                   *         EIP-1967 admin storage slot so that accidental storage collision with the
                   *         implementation is not possible.
                   *
                   * @param _admin Address of the initial contract admin. Admin as the ability to access the
                   *               transparent proxy interface.
                   */
                  constructor(address _admin) {
                      _changeAdmin(_admin);
                  }
                  // slither-disable-next-line locked-ether
                  receive() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  // slither-disable-next-line locked-ether
                  fallback() external payable {
                      // Proxy call by default.
                      _doProxyCall();
                  }
                  /**
                   * @notice Set the implementation contract address. The code at the given address will execute
                   *         when this contract is called.
                   *
                   * @param _implementation Address of the implementation contract.
                   */
                  function upgradeTo(address _implementation) public virtual proxyCallIfNotAdmin {
                      _setImplementation(_implementation);
                  }
                  /**
                   * @notice Set the implementation and call a function in a single transaction. Useful to ensure
                   *         atomic execution of initialization-based upgrades.
                   *
                   * @param _implementation Address of the implementation contract.
                   * @param _data           Calldata to delegatecall the new implementation with.
                   */
                  function upgradeToAndCall(address _implementation, bytes calldata _data)
                      public
                      payable
                      virtual
                      proxyCallIfNotAdmin
                      returns (bytes memory)
                  {
                      _setImplementation(_implementation);
                      (bool success, bytes memory returndata) = _implementation.delegatecall(_data);
                      require(success, "Proxy: delegatecall to new implementation contract failed");
                      return returndata;
                  }
                  /**
                   * @notice Changes the owner of the proxy contract. Only callable by the owner.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function changeAdmin(address _admin) public virtual proxyCallIfNotAdmin {
                      _changeAdmin(_admin);
                  }
                  /**
                   * @notice Gets the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function admin() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getAdmin();
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function implementation() public virtual proxyCallIfNotAdmin returns (address) {
                      return _getImplementation();
                  }
                  /**
                   * @notice Sets the implementation address.
                   *
                   * @param _implementation New implementation address.
                   */
                  function _setImplementation(address _implementation) internal {
                      assembly {
                          sstore(IMPLEMENTATION_KEY, _implementation)
                      }
                      emit Upgraded(_implementation);
                  }
                  /**
                   * @notice Changes the owner of the proxy contract.
                   *
                   * @param _admin New owner of the proxy contract.
                   */
                  function _changeAdmin(address _admin) internal {
                      address previous = _getAdmin();
                      assembly {
                          sstore(OWNER_KEY, _admin)
                      }
                      emit AdminChanged(previous, _admin);
                  }
                  /**
                   * @notice Performs the proxy call via a delegatecall.
                   */
                  function _doProxyCall() internal {
                      address impl = _getImplementation();
                      require(impl != address(0), "Proxy: implementation not initialized");
                      assembly {
                          // Copy calldata into memory at 0x0....calldatasize.
                          calldatacopy(0x0, 0x0, calldatasize())
                          // Perform the delegatecall, make sure to pass all available gas.
                          let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)
                          // Copy returndata into memory at 0x0....returndatasize. Note that this *will*
                          // overwrite the calldata that we just copied into memory but that doesn't really
                          // matter because we'll be returning in a second anyway.
                          returndatacopy(0x0, 0x0, returndatasize())
                          // Success == 0 means a revert. We'll revert too and pass the data up.
                          if iszero(success) {
                              revert(0x0, returndatasize())
                          }
                          // Otherwise we'll just return and pass the data up.
                          return(0x0, returndatasize())
                      }
                  }
                  /**
                   * @notice Queries the implementation address.
                   *
                   * @return Implementation address.
                   */
                  function _getImplementation() internal view returns (address) {
                      address impl;
                      assembly {
                          impl := sload(IMPLEMENTATION_KEY)
                      }
                      return impl;
                  }
                  /**
                   * @notice Queries the owner of the proxy contract.
                   *
                   * @return Owner address.
                   */
                  function _getAdmin() internal view returns (address) {
                      address owner;
                      assembly {
                          owner := sload(OWNER_KEY)
                      }
                      return owner;
                  }
              }