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 }