github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity ^0.8.0;
     3  
     4  import { console2 as console } from "forge-std/console2.sol";
     5  
     6  import { Script } from "forge-std/Script.sol";
     7  import { Artifacts } from "scripts/Artifacts.s.sol";
     8  import { PeripheryDeployConfig } from "scripts/PeripheryDeployConfig.s.sol";
     9  
    10  import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
    11  import { Proxy } from "src/universal/Proxy.sol";
    12  
    13  import { Faucet } from "src/periphery/faucet/Faucet.sol";
    14  import { Drippie } from "src/periphery/drippie/Drippie.sol";
    15  import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
    16  import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol";
    17  import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol";
    18  import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
    19  import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
    20  import { Config } from "scripts/Config.sol";
    21  
    22  /// @title DeployPeriphery
    23  /// @notice Script used to deploy periphery contracts.
    24  contract DeployPeriphery is Script, Artifacts {
    25      PeripheryDeployConfig cfg;
    26  
    27      /// @notice The name of the script, used to ensure the right deploy artifacts
    28      ///         are used.
    29      function name() public pure returns (string memory name_) {
    30          name_ = "DeployPeriphery";
    31      }
    32  
    33      function setUp() public override {
    34          Artifacts.setUp();
    35  
    36          string memory path = string.concat(vm.projectRoot(), "/periphery-deploy-config/", deploymentContext, ".json");
    37          cfg = new PeripheryDeployConfig(path);
    38  
    39          console.log("Deployment context: %s", deploymentContext);
    40      }
    41  
    42      /// @notice Deploy all of the periphery contracts
    43      function run() public {
    44          console.log("Deploying all periphery contracts");
    45  
    46          deployProxies();
    47          deployImplementations();
    48  
    49          initializeFaucet();
    50          installFaucetAuthModulesConfigs();
    51  
    52          if (cfg.installOpChainFaucetsDrips()) {
    53              installOpChainFaucetsDrippieConfigs();
    54          }
    55  
    56          if (cfg.archivePreviousOpChainFaucetsDrips()) {
    57              archivePreviousOpChainFaucetsDrippieConfigs();
    58          }
    59      }
    60  
    61      /// @notice Deploy all of the proxies
    62      function deployProxies() public {
    63          deployProxyAdmin();
    64  
    65          deployFaucetProxy();
    66      }
    67  
    68      /// @notice Deploy all of the implementations
    69      function deployImplementations() public {
    70          deployFaucet();
    71          deployFaucetDrippie();
    72          deployCheckTrue();
    73          deployCheckBalanceLow();
    74          deployCheckGelatoLow();
    75          deployOnChainAuthModule();
    76          deployOffChainAuthModule();
    77      }
    78  
    79      /// @notice Modifier that wraps a function in broadcasting.
    80      modifier broadcast() {
    81          vm.startBroadcast();
    82          _;
    83          vm.stopBroadcast();
    84      }
    85  
    86      /// @notice Deploy the ProxyAdmin
    87      function deployProxyAdmin() public broadcast returns (address addr_) {
    88          bytes32 salt = keccak256(bytes("ProxyAdmin"));
    89          bytes32 initCodeHash = keccak256(abi.encodePacked(type(ProxyAdmin).creationCode, abi.encode(msg.sender)));
    90          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
    91          if (preComputedAddress.code.length > 0) {
    92              console.log("ProxyAdmin already deployed at %s", preComputedAddress);
    93              save("ProxyAdmin", preComputedAddress);
    94              addr_ = preComputedAddress;
    95          } else {
    96              ProxyAdmin admin = new ProxyAdmin{ salt: salt }({ _owner: msg.sender });
    97              require(admin.owner() == msg.sender);
    98  
    99              save("ProxyAdmin", address(admin));
   100              console.log("ProxyAdmin deployed at %s", address(admin));
   101  
   102              addr_ = address(admin);
   103          }
   104      }
   105  
   106      /// @notice Deploy the FaucetProxy
   107      function deployFaucetProxy() public broadcast returns (address addr_) {
   108          bytes32 salt = keccak256(bytes("FaucetProxy"));
   109          address proxyAdmin = mustGetAddress("ProxyAdmin");
   110          bytes32 initCodeHash = keccak256(abi.encodePacked(type(Proxy).creationCode, abi.encode(proxyAdmin)));
   111          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   112          if (preComputedAddress.code.length > 0) {
   113              console.log("FaucetProxy already deployed at %s", preComputedAddress);
   114              save("FaucetProxy", preComputedAddress);
   115              addr_ = preComputedAddress;
   116          } else {
   117              Proxy proxy = new Proxy{ salt: salt }({ _admin: proxyAdmin });
   118              require(EIP1967Helper.getAdmin(address(proxy)) == proxyAdmin);
   119  
   120              save("FaucetProxy", address(proxy));
   121              console.log("FaucetProxy deployed at %s", address(proxy));
   122  
   123              addr_ = address(proxy);
   124          }
   125      }
   126  
   127      /// @notice Deploy the faucet contract.
   128      function deployFaucet() public broadcast returns (address addr_) {
   129          bytes32 salt = keccak256(bytes("Faucet"));
   130          bytes32 initCodeHash = keccak256(abi.encodePacked(type(Faucet).creationCode, abi.encode(cfg.faucetAdmin())));
   131          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   132          if (preComputedAddress.code.length > 0) {
   133              console.log("Faucet already deployed at %s", preComputedAddress);
   134              save("Faucet", preComputedAddress);
   135              addr_ = preComputedAddress;
   136          } else {
   137              Faucet faucet = new Faucet{ salt: salt }(cfg.faucetAdmin());
   138              require(faucet.ADMIN() == cfg.faucetAdmin());
   139  
   140              save("Faucet", address(faucet));
   141              console.log("Faucet deployed at %s", address(faucet));
   142  
   143              addr_ = address(faucet);
   144          }
   145      }
   146  
   147      /// @notice Deploy drippie contract.
   148      function deployFaucetDrippie() public broadcast returns (address addr_) {
   149          bytes32 salt = keccak256(bytes("FaucetDrippie"));
   150          bytes32 initCodeHash =
   151              keccak256(abi.encodePacked(type(Drippie).creationCode, abi.encode(cfg.faucetDrippieOwner())));
   152          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   153          if (preComputedAddress.code.length > 0) {
   154              console.log("FaucetDrippie already deployed at %s", preComputedAddress);
   155              save("FaucetDrippie", preComputedAddress);
   156              addr_ = preComputedAddress;
   157          } else {
   158              Drippie drippie = new Drippie{ salt: salt }(cfg.faucetDrippieOwner());
   159  
   160              save("FaucetDrippie", address(drippie));
   161              console.log("FaucetDrippie deployed at %s", address(drippie));
   162  
   163              addr_ = address(drippie);
   164          }
   165      }
   166  
   167      /// @notice Deploy CheckTrue contract.
   168      function deployCheckTrue() public broadcast returns (address addr_) {
   169          bytes32 salt = keccak256(bytes("CheckTrue"));
   170          bytes32 initCodeHash = keccak256(abi.encodePacked(type(CheckTrue).creationCode));
   171          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   172          if (preComputedAddress.code.length > 0) {
   173              console.log("CheckTrue already deployed at %s", preComputedAddress);
   174              save("CheckTrue", preComputedAddress);
   175              addr_ = preComputedAddress;
   176          } else {
   177              CheckTrue checkTrue = new CheckTrue{ salt: salt }();
   178  
   179              save("CheckTrue", address(checkTrue));
   180              console.log("CheckTrue deployed at %s", address(checkTrue));
   181  
   182              addr_ = address(checkTrue);
   183          }
   184      }
   185  
   186      /// @notice Deploy CheckBalanceLow contract.
   187      function deployCheckBalanceLow() public broadcast returns (address addr_) {
   188          bytes32 salt = keccak256(bytes("CheckBalanceLow"));
   189          bytes32 initCodeHash = keccak256(abi.encodePacked(type(CheckBalanceLow).creationCode));
   190          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   191          if (preComputedAddress.code.length > 0) {
   192              console.log("CheckBalanceLow already deployed at %s", preComputedAddress);
   193              save("CheckBalanceLow", preComputedAddress);
   194              addr_ = preComputedAddress;
   195          } else {
   196              CheckBalanceLow checkBalanceLow = new CheckBalanceLow{ salt: salt }();
   197  
   198              save("CheckBalanceLow", address(checkBalanceLow));
   199              console.log("CheckBalanceLow deployed at %s", address(checkBalanceLow));
   200  
   201              addr_ = address(checkBalanceLow);
   202          }
   203      }
   204  
   205      /// @notice Deploy CheckGelatoLow contract.
   206      function deployCheckGelatoLow() public broadcast returns (address addr_) {
   207          bytes32 salt = keccak256(bytes("CheckGelatoLow"));
   208          bytes32 initCodeHash = keccak256(abi.encodePacked(type(CheckGelatoLow).creationCode));
   209          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   210          if (preComputedAddress.code.length > 0) {
   211              console.log("CheckGelatoLow already deployed at %s", preComputedAddress);
   212              save("CheckGelatoLow", preComputedAddress);
   213              addr_ = preComputedAddress;
   214          } else {
   215              CheckGelatoLow checkGelatoLow = new CheckGelatoLow{ salt: salt }();
   216  
   217              save("CheckGelatoLow", address(checkGelatoLow));
   218              console.log("CheckGelatoLow deployed at %s", address(checkGelatoLow));
   219  
   220              addr_ = address(checkGelatoLow);
   221          }
   222      }
   223  
   224      /// @notice Initialize the Faucet
   225      function initializeFaucet() public broadcast {
   226          ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
   227          address faucetProxy = mustGetAddress("FaucetProxy");
   228          address faucet = mustGetAddress("Faucet");
   229          address implementationAddress = proxyAdmin.getProxyImplementation(faucetProxy);
   230          if (implementationAddress == faucet) {
   231              console.log("Faucet proxy implementation already set");
   232          } else {
   233              proxyAdmin.upgrade({ _proxy: payable(faucetProxy), _implementation: faucet });
   234          }
   235  
   236          require(Faucet(payable(faucetProxy)).ADMIN() == Faucet(payable(faucet)).ADMIN());
   237      }
   238  
   239      /// @notice installs the drip configs in the faucet drippie contract.
   240      function installFaucetDrippieConfigs() public {
   241          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   242          console.log("Installing faucet drips at %s", address(drippie));
   243          installFaucetDripV1();
   244          installFaucetDripV2();
   245          installFaucetAdminDripV1();
   246          installFaucetGelatoBalanceV1();
   247  
   248          console.log("Faucet drip configs successfully installed");
   249      }
   250  
   251      /// @notice installs drip configs that deposit funds to all OP Chain faucets. This function
   252      /// should only be called on an L1 testnet.
   253      function installOpChainFaucetsDrippieConfigs() public {
   254          uint256 drippieOwnerPrivateKey = Config.drippieOwnerPrivateKey();
   255          vm.startBroadcast(drippieOwnerPrivateKey);
   256  
   257          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   258          console.log("Installing OP Chain faucet drips at %s", address(drippie));
   259          installSmallOpChainFaucetsDrips();
   260          installLargeOpChainFaucetsDrips();
   261          installSmallOpChainAdminWalletDrips();
   262          installLargeOpChainAdminWalletDrips();
   263  
   264          vm.stopBroadcast();
   265  
   266          console.log("OP chain faucet drip configs successfully installed");
   267      }
   268  
   269      /// @notice archives the previous OP Chain drip configs.
   270      function archivePreviousOpChainFaucetsDrippieConfigs() public {
   271          uint256 drippieOwnerPrivateKey = Config.drippieOwnerPrivateKey();
   272          vm.startBroadcast(drippieOwnerPrivateKey);
   273  
   274          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   275          console.log("Archiving OP Chain faucet drips at %s", address(drippie));
   276          archivePreviousSmallOpChainFaucetsDrips();
   277          archivePreviousLargeOpChainFaucetsDrips();
   278  
   279          vm.stopBroadcast();
   280  
   281          console.log("OP chain faucet drip configs successfully installed");
   282      }
   283  
   284      /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval.
   285      function installSmallOpChainFaucetsDrips() public {
   286          address faucetProxy = mustGetAddress("FaucetProxy");
   287          uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
   288          for (uint256 i = 0; i < arrayLength; i++) {
   289              address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
   290              _installDepositEthToDrip(
   291                  faucetProxy,
   292                  l1BridgeAddress,
   293                  cfg.smallOpChainFaucetDripValue(),
   294                  cfg.smallOpChainFaucetDripInterval(),
   295                  _faucetDripName(l1BridgeAddress, cfg.dripVersion())
   296              );
   297          }
   298      }
   299  
   300      /// @notice installs drips that send funds to the admin wallets for small OP chain faucets
   301      /// on the scheduled interval.
   302      function installSmallOpChainAdminWalletDrips() public {
   303          require(
   304              cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(),
   305              "installSmallOpChainAdminWalletDrips: Only handles identical admin wallet addresses"
   306          );
   307          address adminWallet = cfg.faucetOnchainAuthModuleAdmin();
   308          uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
   309          for (uint256 i = 0; i < arrayLength; i++) {
   310              address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
   311              _installDepositEthToDrip(
   312                  adminWallet,
   313                  l1BridgeAddress,
   314                  cfg.opChainAdminWalletDripValue(),
   315                  cfg.opChainAdminWalletDripInterval(),
   316                  _adminWalletDripName(l1BridgeAddress, cfg.dripVersion())
   317              );
   318          }
   319      }
   320  
   321      /// @notice installs drips that send funds to the admin wallets for large OP chain faucets
   322      /// on the scheduled interval.
   323      function installLargeOpChainAdminWalletDrips() public {
   324          require(
   325              cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(),
   326              "installLargeOpChainAdminWalletDrips: Only handles identical admin wallet addresses"
   327          );
   328          address adminWallet = cfg.faucetOnchainAuthModuleAdmin();
   329          uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
   330          for (uint256 i = 0; i < arrayLength; i++) {
   331              address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
   332              _installDepositEthToDrip(
   333                  adminWallet,
   334                  l1BridgeAddress,
   335                  cfg.opChainAdminWalletDripValue(),
   336                  cfg.opChainAdminWalletDripInterval(),
   337                  _adminWalletDripName(l1BridgeAddress, cfg.dripVersion())
   338              );
   339          }
   340      }
   341  
   342      /// @notice installs drips that send funds to large OP chain faucets on the scheduled interval.
   343      function installLargeOpChainFaucetsDrips() public {
   344          address faucetProxy = mustGetAddress("FaucetProxy");
   345          uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
   346          for (uint256 i = 0; i < arrayLength; i++) {
   347              address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
   348              _installDepositEthToDrip(
   349                  faucetProxy,
   350                  l1BridgeAddress,
   351                  cfg.largeOpChainFaucetDripValue(),
   352                  cfg.largeOpChainFaucetDripInterval(),
   353                  _faucetDripName(l1BridgeAddress, cfg.dripVersion())
   354              );
   355          }
   356      }
   357  
   358      /// @notice installs the FaucetDripV1 drip on the faucet drippie contract.
   359      function installFaucetDripV1() public broadcast {
   360          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   361          string memory dripName = "FaucetDripV1";
   362          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
   363              console.log("installing %s", dripName);
   364              Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
   365              actions[0] =
   366                  Drippie.DripAction({ target: mustGetAddress("FaucetProxy"), data: "", value: cfg.faucetDripV1Value() });
   367              drippie.create({
   368                  _name: dripName,
   369                  _config: Drippie.DripConfig({
   370                      reentrant: false,
   371                      interval: cfg.faucetDripV1Interval(),
   372                      dripcheck: CheckBalanceLow(mustGetAddress("CheckBalanceLow")),
   373                      checkparams: abi.encode(
   374                          CheckBalanceLow.Params({ target: mustGetAddress("FaucetProxy"), threshold: cfg.faucetDripV1Threshold() })
   375                          ),
   376                      actions: actions
   377                  })
   378              });
   379              console.log("%s installed successfully", dripName);
   380          } else {
   381              console.log("%s already installed.", dripName);
   382          }
   383  
   384          _activateIfPausedDrip(drippie, dripName);
   385      }
   386  
   387      /// @notice installs the FaucetDripV2 drip on the faucet drippie contract.
   388      function installFaucetDripV2() public broadcast {
   389          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   390          string memory dripName = "FaucetDripV2";
   391          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
   392              console.log("installing %s", dripName);
   393              Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
   394              actions[0] =
   395                  Drippie.DripAction({ target: mustGetAddress("FaucetProxy"), data: "", value: cfg.faucetDripV2Value() });
   396              drippie.create({
   397                  _name: dripName,
   398                  _config: Drippie.DripConfig({
   399                      reentrant: false,
   400                      interval: cfg.faucetDripV2Interval(),
   401                      dripcheck: CheckBalanceLow(mustGetAddress("CheckBalanceLow")),
   402                      checkparams: abi.encode(
   403                          CheckBalanceLow.Params({ target: mustGetAddress("FaucetProxy"), threshold: cfg.faucetDripV2Threshold() })
   404                          ),
   405                      actions: actions
   406                  })
   407              });
   408              console.log("%s installed successfully", dripName);
   409          } else {
   410              console.log("%s already installed.", dripName);
   411          }
   412  
   413          _activateIfPausedDrip(drippie, dripName);
   414      }
   415  
   416      /// @notice installs the FaucetAdminDripV1 drip on the faucet drippie contract.
   417      function installFaucetAdminDripV1() public broadcast {
   418          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   419          string memory dripName = "FaucetAdminDripV1";
   420          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
   421              console.log("installing %s", dripName);
   422              Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
   423              actions[0] = Drippie.DripAction({
   424                  target: mustGetAddress("FaucetProxy"),
   425                  data: "",
   426                  value: cfg.faucetAdminDripV1Value()
   427              });
   428              drippie.create({
   429                  _name: dripName,
   430                  _config: Drippie.DripConfig({
   431                      reentrant: false,
   432                      interval: cfg.faucetAdminDripV1Interval(),
   433                      dripcheck: CheckBalanceLow(mustGetAddress("CheckBalanceLow")),
   434                      checkparams: abi.encode(
   435                          CheckBalanceLow.Params({
   436                              target: mustGetAddress("FaucetProxy"),
   437                              threshold: cfg.faucetAdminDripV1Threshold()
   438                          })
   439                          ),
   440                      actions: actions
   441                  })
   442              });
   443              console.log("%s installed successfully", dripName);
   444          } else {
   445              console.log("%s already installed.", dripName);
   446          }
   447  
   448          _activateIfPausedDrip(drippie, dripName);
   449      }
   450  
   451      /// @notice installs the GelatoBalanceV1 drip on the faucet drippie contract.
   452      function installFaucetGelatoBalanceV1() public broadcast {
   453          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   454          string memory dripName = "GelatoBalanceV2";
   455          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
   456              console.log("installing %s", dripName);
   457              Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
   458              actions[0] = Drippie.DripAction({
   459                  target: payable(cfg.faucetGelatoTreasury()),
   460                  data: abi.encodeWithSignature(
   461                      "depositFunds(address,address,uint256)",
   462                      cfg.faucetGelatoRecipient(),
   463                      // Gelato represents ETH as 0xeeeee....eeeee
   464                      0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE,
   465                      cfg.faucetGelatoBalanceV1Value()
   466                      ),
   467                  value: cfg.faucetGelatoBalanceV1Value()
   468              });
   469              drippie.create({
   470                  _name: dripName,
   471                  _config: Drippie.DripConfig({
   472                      reentrant: false,
   473                      interval: cfg.faucetGelatoBalanceV1DripInterval(),
   474                      dripcheck: CheckGelatoLow(mustGetAddress("CheckGelatoLow")),
   475                      checkparams: abi.encode(
   476                          CheckGelatoLow.Params({
   477                              recipient: cfg.faucetGelatoRecipient(),
   478                              threshold: cfg.faucetGelatoThreshold(),
   479                              treasury: cfg.faucetGelatoTreasury()
   480                          })
   481                          ),
   482                      actions: actions
   483                  })
   484              });
   485              console.log("%s installed successfully", dripName);
   486          } else {
   487              console.log("%s already installed.", dripName);
   488          }
   489  
   490          _activateIfPausedDrip(drippie, dripName);
   491      }
   492  
   493      function archivePreviousSmallOpChainFaucetsDrips() public {
   494          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   495          uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
   496          for (uint256 i = 0; i < arrayLength; i++) {
   497              address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
   498              _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
   499              _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
   500              _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
   501              _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
   502          }
   503      }
   504  
   505      function archivePreviousLargeOpChainFaucetsDrips() public {
   506          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   507          uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
   508          for (uint256 i = 0; i < arrayLength; i++) {
   509              address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
   510              _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
   511              _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
   512              _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion()));
   513              _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion()));
   514          }
   515      }
   516  
   517      function _activateIfPausedDrip(Drippie drippie, string memory dripName) internal {
   518          require(
   519              drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE
   520                  || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED,
   521              "attempting to activate a drip that is not currently paused or activated"
   522          );
   523          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) {
   524              console.log("%s is paused, activating", dripName);
   525              drippie.status(dripName, Drippie.DripStatus.ACTIVE);
   526              console.log("%s activated", dripName);
   527              require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE);
   528          } else {
   529              console.log("%s already activated", dripName);
   530          }
   531      }
   532  
   533      function _pauseIfActivatedDrip(Drippie drippie, string memory dripName) internal {
   534          require(
   535              drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE
   536                  || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED,
   537              "attempting to pause a drip that is not currently paused or activated"
   538          );
   539          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE) {
   540              console.log("%s is active, pausing", dripName);
   541              drippie.status(dripName, Drippie.DripStatus.PAUSED);
   542              console.log("%s paused", dripName);
   543              require(drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED);
   544          } else {
   545              console.log("%s already paused", dripName);
   546          }
   547      }
   548  
   549      function _archiveIfPausedDrip(Drippie drippie, string memory dripName) internal {
   550          require(
   551              drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED
   552                  || drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED,
   553              "attempting to archive a drip that is not currently paused or archived"
   554          );
   555          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) {
   556              console.log("%s is paused, archiving", dripName);
   557              drippie.status(dripName, Drippie.DripStatus.ARCHIVED);
   558              console.log("%s archived", dripName);
   559              require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED);
   560          } else {
   561              console.log("%s already archived", dripName);
   562          }
   563      }
   564  
   565      /// @notice deploys the On-Chain Authentication Module
   566      function deployOnChainAuthModule() public broadcast returns (address addr_) {
   567          string memory moduleName = "OnChainAuthModule";
   568          string memory version = "1";
   569          bytes32 salt = keccak256(bytes("OnChainAuthModule"));
   570          bytes32 initCodeHash = keccak256(
   571              abi.encodePacked(
   572                  type(AdminFaucetAuthModule).creationCode,
   573                  abi.encode(cfg.faucetOnchainAuthModuleAdmin(), moduleName, version)
   574              )
   575          );
   576          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   577          if (preComputedAddress.code.length > 0) {
   578              console.log("OnChainAuthModule already deployed at %s", preComputedAddress);
   579              save("OnChainAuthModule", preComputedAddress);
   580              addr_ = preComputedAddress;
   581          } else {
   582              AdminFaucetAuthModule onChainAuthModule =
   583                  new AdminFaucetAuthModule{ salt: salt }(cfg.faucetOnchainAuthModuleAdmin(), moduleName, version);
   584              require(onChainAuthModule.ADMIN() == cfg.faucetOnchainAuthModuleAdmin());
   585  
   586              save("OnChainAuthModule", address(onChainAuthModule));
   587              console.log("OnChainAuthModule deployed at %s", address(onChainAuthModule));
   588  
   589              addr_ = address(onChainAuthModule);
   590          }
   591      }
   592  
   593      /// @notice deploys the Off-Chain Authentication Module
   594      function deployOffChainAuthModule() public broadcast returns (address addr_) {
   595          string memory moduleName = "OffChainAuthModule";
   596          string memory version = "1";
   597          bytes32 salt = keccak256(bytes("OffChainAuthModule"));
   598          bytes32 initCodeHash = keccak256(
   599              abi.encodePacked(
   600                  type(AdminFaucetAuthModule).creationCode,
   601                  abi.encode(cfg.faucetOffchainAuthModuleAdmin(), moduleName, version)
   602              )
   603          );
   604          address preComputedAddress = computeCreate2Address(salt, initCodeHash);
   605          if (preComputedAddress.code.length > 0) {
   606              console.logBytes32(initCodeHash);
   607              console.log("OffChainAuthModule already deployed at %s", preComputedAddress);
   608              save("OffChainAuthModule", preComputedAddress);
   609              addr_ = preComputedAddress;
   610          } else {
   611              AdminFaucetAuthModule offChainAuthModule =
   612                  new AdminFaucetAuthModule{ salt: salt }(cfg.faucetOffchainAuthModuleAdmin(), moduleName, version);
   613              require(offChainAuthModule.ADMIN() == cfg.faucetOffchainAuthModuleAdmin());
   614  
   615              save("OffChainAuthModule", address(offChainAuthModule));
   616              console.log("OffChainAuthModule deployed at %s", address(offChainAuthModule));
   617  
   618              addr_ = address(offChainAuthModule);
   619          }
   620      }
   621  
   622      /// @notice installs the OnChain AuthModule on the Faucet contract.
   623      function installOnChainAuthModule() public broadcast {
   624          string memory moduleName = "OnChainAuthModule";
   625          Faucet faucet = Faucet(mustGetAddress("FaucetProxy"));
   626          AdminFaucetAuthModule onChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName));
   627          if (faucet.isModuleEnabled(onChainAuthModule)) {
   628              console.log("%s already installed.", moduleName);
   629          } else {
   630              console.log("Installing %s", moduleName);
   631              Faucet.ModuleConfig memory myModuleConfig = Faucet.ModuleConfig({
   632                  name: moduleName,
   633                  enabled: true,
   634                  ttl: cfg.faucetOnchainAuthModuleTtl(),
   635                  amount: cfg.faucetOnchainAuthModuleAmount()
   636              });
   637              faucet.configure(onChainAuthModule, myModuleConfig);
   638              console.log("%s installed successfully", moduleName);
   639          }
   640      }
   641  
   642      /// @notice installs the OffChain AuthModule on the Faucet contract.
   643      function installOffChainAuthModule() public broadcast {
   644          string memory moduleName = "OffChainAuthModule";
   645          Faucet faucet = Faucet(mustGetAddress("FaucetProxy"));
   646          AdminFaucetAuthModule offChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName));
   647          if (faucet.isModuleEnabled(offChainAuthModule)) {
   648              console.log("%s already installed.", moduleName);
   649          } else {
   650              console.log("Installing %s", moduleName);
   651              Faucet.ModuleConfig memory myModuleConfig = Faucet.ModuleConfig({
   652                  name: moduleName,
   653                  enabled: true,
   654                  ttl: cfg.faucetOffchainAuthModuleTtl(),
   655                  amount: cfg.faucetOffchainAuthModuleAmount()
   656              });
   657              faucet.configure(offChainAuthModule, myModuleConfig);
   658              console.log("%s installed successfully", moduleName);
   659          }
   660      }
   661  
   662      /// @notice installs all of the auth module in the faucet contract.
   663      function installFaucetAuthModulesConfigs() public {
   664          Faucet faucet = Faucet(mustGetAddress("FaucetProxy"));
   665          console.log("Installing auth modules at %s", address(faucet));
   666          installOnChainAuthModule();
   667          installOffChainAuthModule();
   668  
   669          console.log("Faucet Auth Module configs successfully installed");
   670      }
   671  
   672      function _faucetDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) {
   673          string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-drip-", vm.toString(_l1Bridge));
   674          string memory versionSuffix = string.concat("-", vm.toString(version));
   675          return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix);
   676      }
   677  
   678      function _adminWalletDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) {
   679          string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-admin-drip-", vm.toString(_l1Bridge));
   680          string memory versionSuffix = string.concat("-", vm.toString(version));
   681          return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix);
   682      }
   683  
   684      function _installDepositEthToDrip(
   685          address _depositTo,
   686          address _l1Bridge,
   687          uint256 _dripValue,
   688          uint256 _dripInterval,
   689          string memory dripName
   690      )
   691          internal
   692      {
   693          Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
   694          if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) {
   695              console.log("installing %s", dripName);
   696              Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
   697              actions[0] = Drippie.DripAction({
   698                  target: payable(_l1Bridge),
   699                  data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", _depositTo, 200000, ""),
   700                  value: _dripValue
   701              });
   702              drippie.create({
   703                  _name: dripName,
   704                  _config: Drippie.DripConfig({
   705                      reentrant: false,
   706                      interval: _dripInterval,
   707                      dripcheck: CheckTrue(mustGetAddress("CheckTrue")),
   708                      checkparams: abi.encode(""),
   709                      actions: actions
   710                  })
   711              });
   712              console.log("%s installed successfully", dripName);
   713          } else {
   714              console.log("%s already installed.", dripName);
   715          }
   716  
   717          _activateIfPausedDrip(drippie, dripName);
   718      }
   719  }