Commit 03289ebf authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat: add ops drippie deployments (#10541)

Updates the periphery deploy to also deploy a Drippie contract to
be used for standard operational drips.
parent a533f524
...@@ -23,3 +23,6 @@ ...@@ -23,3 +23,6 @@
[submodule "packages/contracts-bedrock/lib/lib-keccak"] [submodule "packages/contracts-bedrock/lib/lib-keccak"]
path = packages/contracts-bedrock/lib/lib-keccak path = packages/contracts-bedrock/lib/lib-keccak
url = https://github.com/ethereum-optimism/lib-keccak url = https://github.com/ethereum-optimism/lib-keccak
[submodule "packages/contracts-bedrock/lib/automate"]
path = packages/contracts-bedrock/lib/automate
url = https://github.com/gelatodigital/automate
...@@ -20,6 +20,7 @@ remappings = [ ...@@ -20,6 +20,7 @@ remappings = [
'ds-test/=lib/forge-std/lib/ds-test/src', 'ds-test/=lib/forge-std/lib/ds-test/src',
'safe-contracts/=lib/safe-contracts/contracts', 'safe-contracts/=lib/safe-contracts/contracts',
'kontrol-cheatcodes/=lib/kontrol-cheatcodes/src', 'kontrol-cheatcodes/=lib/kontrol-cheatcodes/src',
'gelato/=lib/automate/contracts'
] ]
extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout'] extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
bytecode_hash = 'none' bytecode_hash = 'none'
......
Subproject commit 0117585fea20ff0cd24fd17bf74a6debaa4d57d2
{ {
"faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", "create2DeploymentSalt": "0.0.2",
"gelatoAutomateContract": "0x2A6C106ae13B558BB9E2Ec64Bd2f1f7BEFF3A5E0",
"gelatoTreasuryContract": "0x7506C12a824d73D9b08564d5Afc22c949434755e",
"operationsDrippieOwner": "0x03C256F7Ae7518D0fe489F257ab4b928D37CBE16",
"operationsSequencerDripV1Target": "0x8F23BB38F531600e5d8FDDaAEC41F13FaB46E98c",
"operationsSequencerDripV1Value": 20000000000000000000,
"operationsSequencerDripV1Interval": 86400,
"operationsSequencerDripV1Threshold": 100000000000000000000,
"operationsGelatoDripV1Recipient": "0x03C256F7Ae7518D0fe489F257ab4b928D37CBE16",
"operationsGelatoDripV1Value": 1000000000000000000,
"operationsGelatoDripV1Interval": 86400,
"operationsGelatoDripV1Threshold": 500000000000000000,
"operationsSecretsDripV1Delay": 43200,
"operationsSecretsDripV1MustExist": "0x565fa8c7daa859353b5b328b97b12c7d66c5832b2a24d4e0f739a65ad266a46f",
"operationsSecretsDripV1MustNotExist": "0xbc362b01d69a85dff1793803dde67df1f338f37a36fdc73dddf27283d215e614",
"operationsSecretsDripV1Target": "0x03C256F7Ae7518D0fe489F257ab4b928D37CBE16",
"operationsSecretsDripV1Value": 1000000000000000000,
"operationsSecretsDripV1Interval": 3600,
"faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5",
"faucetDripV1Value": 20000000000000000000, "faucetDripV1Value": 20000000000000000000,
"faucetDripV1Interval": 3600, "faucetDripV1Interval": 3600,
"faucetDripV1Threshold": 100000000000000000000, "faucetDripV1Threshold": 100000000000000000000,
"faucetDripV2Value": 500000000000000000000,
"faucetDripV2Interval": 604800, "faucetDripV2Interval": 604800,
"faucetDripV2Threshold": 20000000000000000000, "faucetDripV2Threshold": 20000000000000000000,
"faucetDripV2Value": 500000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400, "faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000, "faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000, "faucetGelatoThreshold": 100000000000000000,
"smallOpChainFaucetDripValue": 34000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000,
"faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6",
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
"faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleTtl": 86400,
"faucetOffchainAuthModuleAmount": 50000000000000000, "faucetOffchainAuthModuleAmount": 50000000000000000,
"opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1",
"baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB",
"pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3",
"orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333",
"modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2",
"lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17",
"liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5", "liskL1BridgeAddress": "0x1Fb30e446eA791cd1f011675E5F3f5311b70faF5",
"installOpChainFaucetsDrips": true,
"deployDripchecks": true,
"deployFaucetContracts": false,
"deployOperationsContracts": true,
"installOpChainFaucetsDrips": false,
"archivePreviousOpChainFaucetsDrips": false, "archivePreviousOpChainFaucetsDrips": false,
"dripVersion": 3, "dripVersion": 3,
"previousDripVersion": 2, "previousDripVersion": 2
"smallOpChainFaucetDripValue": 34000000000000000000,
"smallOpChainFaucetDripInterval": 86400,
"largeOpChainFaucetDripValue": 34000000000000000000,
"largeOpChainFaucetDripInterval": 86400,
"opChainAdminWalletDripValue": 1000000000000000000,
"opChainAdminWalletDripInterval": 2592000
} }
...@@ -2,74 +2,98 @@ ...@@ -2,74 +2,98 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
import { Script } from "forge-std/Script.sol"; import { Script } from "forge-std/Script.sol";
import { IAutomate as IGelato } from "gelato/interfaces/IAutomate.sol";
import { LibDataTypes as GelatoDataTypes } from "gelato/libraries/LibDataTypes.sol";
import { LibTaskId as GelatoTaskId } from "gelato/libraries/LibTaskId.sol";
import { GelatoBytes } from "gelato/vendor/gelato/GelatoBytes.sol";
import { Config } from "scripts/Config.sol";
import { Artifacts } from "scripts/Artifacts.s.sol"; import { Artifacts } from "scripts/Artifacts.s.sol";
import { PeripheryDeployConfig } from "scripts/PeripheryDeployConfig.s.sol"; import { PeripheryDeployConfig } from "scripts/PeripheryDeployConfig.s.sol";
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { Proxy } from "src/universal/Proxy.sol"; import { Proxy } from "src/universal/Proxy.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol";
import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol";
import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol";
import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol";
import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol";
import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { Config } from "scripts/Config.sol";
/// @title DeployPeriphery /// @title DeployPeriphery
/// @notice Script used to deploy periphery contracts. /// @notice Script used to deploy periphery contracts.
contract DeployPeriphery is Script, Artifacts { contract DeployPeriphery is Script, Artifacts {
/// @notice Error emitted when an address mismatch is detected.
error AddressMismatch(string, address, address);
/// @notice Struct that contains the data for a Gelato task.
struct GelatoTaskData {
address taskCreator;
address execAddress;
bytes execData;
GelatoDataTypes.ModuleData moduleData;
address feeToken;
}
/// @notice Deployment configuration.
PeripheryDeployConfig cfg; PeripheryDeployConfig cfg;
/// @notice Sets up the deployment script. /// @notice Sets up the deployment script.
function setUp() public override { function setUp() public override {
Artifacts.setUp(); Artifacts.setUp();
string memory path = string.concat(vm.projectRoot(), "/periphery-deploy-config/", deploymentContext, ".json"); cfg = new PeripheryDeployConfig(Config.deployConfigPath());
cfg = new PeripheryDeployConfig(path); console.log("Config path: %s", Config.deployConfigPath());
console.log("Deployment context: %s", deploymentContext);
} }
/// @notice Deploy all of the periphery contracts. /// @notice Deploy all of the periphery contracts.
function run() public { function run() public {
console.log("Deploying all periphery contracts"); console.log("Deploying periphery contracts");
deployProxies(); // Optionally deploy the base dripcheck contracts.
deployImplementations(); if (cfg.deployDripchecks()) {
deployCheckTrue();
deployCheckBalanceLow();
deployCheckGelatoLow();
deployCheckSecrets();
}
initializeFaucet(); // Optionally deploy the faucet contracts.
installFaucetAuthModulesConfigs(); if (cfg.deployFaucetContracts()) {
// Deploy faucet contracts.
deployProxyAdmin();
deployFaucetProxy();
deployFaucet();
deployFaucetDrippie();
deployOnChainAuthModule();
deployOffChainAuthModule();
// Initialize the faucet.
initializeFaucet();
installFaucetAuthModulesConfigs();
// Optionally install OP Chain drip configs.
if (cfg.installOpChainFaucetsDrips()) {
installOpChainFaucetsDrippieConfigs();
}
if (cfg.installOpChainFaucetsDrips()) { // Optionally archive old drip configs.
installOpChainFaucetsDrippieConfigs(); if (cfg.archivePreviousOpChainFaucetsDrips()) {
archivePreviousOpChainFaucetsDrippieConfigs();
}
} }
if (cfg.archivePreviousOpChainFaucetsDrips()) { // Optionally deploy the operations contracts.
archivePreviousOpChainFaucetsDrippieConfigs(); if (cfg.deployOperationsContracts()) {
deployOperationsDrippie();
} }
} }
/// @notice Deploy all of the proxies.
function deployProxies() public {
deployProxyAdmin();
deployFaucetProxy();
}
/// @notice Deploy all of the implementations.
function deployImplementations() public {
deployFaucet();
deployFaucetDrippie();
deployCheckTrue();
deployCheckBalanceLow();
deployCheckGelatoLow();
deployOnChainAuthModule();
deployOffChainAuthModule();
}
/// @notice Modifier that wraps a function in broadcasting. /// @notice Modifier that wraps a function in broadcasting.
modifier broadcast() { modifier broadcast() {
vm.startBroadcast(); vm.startBroadcast();
...@@ -125,6 +149,18 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -125,6 +149,18 @@ contract DeployPeriphery is Script, Artifacts {
require(drippie.owner() == cfg.faucetDrippieOwner()); require(drippie.owner() == cfg.faucetDrippieOwner());
} }
/// @notice Deploy the Drippie contract for standard operations.
function deployOperationsDrippie() public broadcast returns (address addr_) {
addr_ = _deployCreate2({
_name: "OperationsDrippie",
_creationCode: type(Drippie).creationCode,
_constructorParams: abi.encode(cfg.operationsDrippieOwner())
});
Drippie drippie = Drippie(payable(addr_));
require(drippie.owner() == cfg.operationsDrippieOwner());
}
/// @notice Deploy On-Chain Authentication Module. /// @notice Deploy On-Chain Authentication Module.
function deployOnChainAuthModule() public broadcast returns (address addr_) { function deployOnChainAuthModule() public broadcast returns (address addr_) {
addr_ = _deployCreate2({ addr_ = _deployCreate2({
...@@ -176,6 +212,15 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -176,6 +212,15 @@ contract DeployPeriphery is Script, Artifacts {
}); });
} }
/// @notice Deploy CheckSecrets contract.
function deployCheckSecrets() public broadcast returns (address addr_) {
addr_ = _deployCreate2({
_name: "CheckSecrets",
_creationCode: type(CheckSecrets).creationCode,
_constructorParams: hex""
});
}
/// @notice Initialize the Faucet. /// @notice Initialize the Faucet.
function initializeFaucet() public broadcast { function initializeFaucet() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
...@@ -191,7 +236,17 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -191,7 +236,17 @@ contract DeployPeriphery is Script, Artifacts {
require(Faucet(payable(faucetProxy)).ADMIN() == Faucet(payable(faucet)).ADMIN()); require(Faucet(payable(faucetProxy)).ADMIN() == Faucet(payable(faucet)).ADMIN());
} }
/// @notice Installs the drip configs in the faucet drippie contract. /// @notice Installs the drip configs in the operations Drippie contract.
function installOperationsDrippieConfigs() public {
Drippie drippie = Drippie(mustGetAddress("OperationsDrippie"));
console.log("Installing operations drips at %s", address(drippie));
installOperationsSequencerDripV1();
installOperationsGelatoDripV1();
installOperationsSecretsDripV1();
console.log("Operations drip configs successfully installed");
}
/// @notice Installs the drip configs in the faucet Drippie contract.
function installFaucetDrippieConfigs() public { function installFaucetDrippieConfigs() public {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
console.log("Installing faucet drips at %s", address(drippie)); console.log("Installing faucet drips at %s", address(drippie));
...@@ -224,6 +279,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -224,6 +279,7 @@ contract DeployPeriphery is Script, Artifacts {
for (uint256 i = 0; i < cfg.getSmallFaucetsL1BridgeAddressesCount(); i++) { for (uint256 i = 0; i < cfg.getSmallFaucetsL1BridgeAddressesCount(); i++) {
address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip({ _installDepositEthToDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: _makeFaucetDripName(l1BridgeAddress, cfg.dripVersion()), _name: _makeFaucetDripName(l1BridgeAddress, cfg.dripVersion()),
_bridge: l1BridgeAddress, _bridge: l1BridgeAddress,
...@@ -239,6 +295,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -239,6 +295,7 @@ contract DeployPeriphery is Script, Artifacts {
for (uint256 i = 0; i < cfg.getLargeFaucetsL1BridgeAddressesCount(); i++) { for (uint256 i = 0; i < cfg.getLargeFaucetsL1BridgeAddressesCount(); i++) {
address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip({ _installDepositEthToDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: _makeFaucetDripName(l1BridgeAddress, cfg.dripVersion()), _name: _makeFaucetDripName(l1BridgeAddress, cfg.dripVersion()),
_bridge: l1BridgeAddress, _bridge: l1BridgeAddress,
...@@ -260,6 +317,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -260,6 +317,7 @@ contract DeployPeriphery is Script, Artifacts {
for (uint256 i = 0; i < cfg.getSmallFaucetsL1BridgeAddressesCount(); i++) { for (uint256 i = 0; i < cfg.getSmallFaucetsL1BridgeAddressesCount(); i++) {
address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip({ _installDepositEthToDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: _makeAdminWalletDripName(l1BridgeAddress, cfg.dripVersion()), _name: _makeAdminWalletDripName(l1BridgeAddress, cfg.dripVersion()),
_bridge: l1BridgeAddress, _bridge: l1BridgeAddress,
...@@ -281,6 +339,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -281,6 +339,7 @@ contract DeployPeriphery is Script, Artifacts {
for (uint256 i = 0; i < cfg.getLargeFaucetsL1BridgeAddressesCount(); i++) { for (uint256 i = 0; i < cfg.getLargeFaucetsL1BridgeAddressesCount(); i++) {
address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i);
_installDepositEthToDrip({ _installDepositEthToDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: _makeAdminWalletDripName(l1BridgeAddress, cfg.dripVersion()), _name: _makeAdminWalletDripName(l1BridgeAddress, cfg.dripVersion()),
_bridge: l1BridgeAddress, _bridge: l1BridgeAddress,
...@@ -291,9 +350,52 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -291,9 +350,52 @@ contract DeployPeriphery is Script, Artifacts {
} }
} }
/// @notice Installs the OperationsSequencerDripV1 drip on the operations drippie contract.
function installOperationsSequencerDripV1() public broadcast {
_installBalanceLowDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("OperationsDrippie")),
_name: "OperationsSequencerDripV1",
_target: cfg.operationsSequencerDripV1Target(),
_value: cfg.operationsSequencerDripV1Value(),
_interval: cfg.operationsSequencerDripV1Interval(),
_threshold: cfg.operationsSequencerDripV1Threshold()
});
}
/// @notice Installs the OperationsGelatoDripV1 drip on the operations drippie contract.
function installOperationsGelatoDripV1() public broadcast {
_installGelatoDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("OperationsDrippie")),
_name: "OperationsGelatoDripV1",
_treasury: cfg.gelatoTreasuryContract(),
_recipient: cfg.operationsGelatoDripV1Recipient(),
_value: cfg.operationsGelatoDripV1Value(),
_interval: cfg.operationsGelatoDripV1Interval(),
_threshold: cfg.operationsGelatoDripV1Threshold()
});
}
/// @notice Installs the OperationsSecretsDripV1 drip on the operations drippie contract.
function installOperationsSecretsDripV1() public broadcast {
_installSecretsDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("OperationsDrippie")),
_name: "OperationsSecretsDripV1",
_delay: cfg.operationsSecretsDripV1Delay(),
_secretHashMustExist: cfg.operationsSecretsDripV1MustExist(),
_secretHashMustNotExist: cfg.operationsSecretsDripV1MustNotExist(),
_target: cfg.operationsSecretsDripV1Target(),
_value: cfg.operationsSecretsDripV1Value(),
_interval: cfg.operationsSecretsDripV1Interval()
});
}
/// @notice Installs the FaucetDripV1 drip on the faucet drippie contract. /// @notice Installs the FaucetDripV1 drip on the faucet drippie contract.
function installFaucetDripV1() public broadcast { function installFaucetDripV1() public broadcast {
_installBalanceLowDrip({ _installBalanceLowDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: "FaucetDripV1", _name: "FaucetDripV1",
_target: mustGetAddress("FaucetProxy"), _target: mustGetAddress("FaucetProxy"),
...@@ -306,6 +408,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -306,6 +408,7 @@ contract DeployPeriphery is Script, Artifacts {
/// @notice Installs the FaucetDripV2 drip on the faucet drippie contract. /// @notice Installs the FaucetDripV2 drip on the faucet drippie contract.
function installFaucetDripV2() public broadcast { function installFaucetDripV2() public broadcast {
_installBalanceLowDrip({ _installBalanceLowDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: "FaucetDripV2", _name: "FaucetDripV2",
_target: mustGetAddress("FaucetProxy"), _target: mustGetAddress("FaucetProxy"),
...@@ -318,6 +421,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -318,6 +421,7 @@ contract DeployPeriphery is Script, Artifacts {
/// @notice Installs the FaucetAdminDripV1 drip on the faucet drippie contract. /// @notice Installs the FaucetAdminDripV1 drip on the faucet drippie contract.
function installFaucetAdminDripV1() public broadcast { function installFaucetAdminDripV1() public broadcast {
_installBalanceLowDrip({ _installBalanceLowDrip({
_gelato: IGelato(cfg.gelatoAutomateContract()),
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: "FaucetAdminDripV1", _name: "FaucetAdminDripV1",
_target: mustGetAddress("FaucetProxy"), _target: mustGetAddress("FaucetProxy"),
...@@ -329,34 +433,15 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -329,34 +433,15 @@ contract DeployPeriphery is Script, Artifacts {
/// @notice Installs the GelatoBalanceV2 drip on the faucet drippie contract. /// @notice Installs the GelatoBalanceV2 drip on the faucet drippie contract.
function installFaucetGelatoBalanceV2() public broadcast { function installFaucetGelatoBalanceV2() public broadcast {
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); _installGelatoDrip({
actions[0] = Drippie.DripAction({ _gelato: IGelato(cfg.gelatoAutomateContract()),
target: payable(cfg.faucetGelatoTreasury()),
data: abi.encodeWithSignature(
"depositFunds(address,address,uint256)",
cfg.faucetGelatoRecipient(),
// Gelato represents ETH as 0xeeeee....eeeee
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE,
cfg.faucetGelatoBalanceV1Value()
),
value: cfg.faucetGelatoBalanceV1Value()
});
_installDrip({
_drippie: Drippie(mustGetAddress("FaucetDrippie")), _drippie: Drippie(mustGetAddress("FaucetDrippie")),
_name: "GelatoBalanceV2", _name: "GelatoBalanceV2",
_config: Drippie.DripConfig({ _treasury: cfg.gelatoTreasuryContract(),
reentrant: false, _recipient: cfg.faucetGelatoRecipient(),
interval: cfg.faucetGelatoBalanceV1DripInterval(), _value: cfg.faucetGelatoBalanceV1Value(),
dripcheck: CheckGelatoLow(mustGetAddress("CheckGelatoLow")), _interval: cfg.faucetGelatoBalanceV1DripInterval(),
checkparams: abi.encode( _threshold: cfg.faucetGelatoThreshold()
CheckGelatoLow.Params({
recipient: cfg.faucetGelatoRecipient(),
threshold: cfg.faucetGelatoThreshold(),
treasury: cfg.faucetGelatoTreasury()
})
),
actions: actions
})
}); });
} }
...@@ -375,6 +460,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -375,6 +460,7 @@ contract DeployPeriphery is Script, Artifacts {
console.log("OP chain faucet drip configs successfully installed"); console.log("OP chain faucet drip configs successfully installed");
} }
/// @notice Archives the previous small OP Chain faucet drips.
function archivePreviousSmallOpChainFaucetsDrips() public { function archivePreviousSmallOpChainFaucetsDrips() public {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount();
...@@ -391,6 +477,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -391,6 +477,7 @@ contract DeployPeriphery is Script, Artifacts {
} }
} }
/// @notice Archives the previous large OP Chain faucet drips.
function archivePreviousLargeOpChainFaucetsDrips() public { function archivePreviousLargeOpChainFaucetsDrips() public {
Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); Drippie drippie = Drippie(mustGetAddress("FaucetDrippie"));
uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount();
...@@ -462,10 +549,10 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -462,10 +549,10 @@ contract DeployPeriphery is Script, Artifacts {
return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix); return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix);
} }
// @notice Deploys a contract using the CREATE2 opcode. /// @notice Deploys a contract using the CREATE2 opcode.
// @param _name The name of the contract. /// @param _name The name of the contract.
// @param _creationCode The contract creation code. /// @param _creationCode The contract creation code.
// @param _constructorParams The constructor parameters. /// @param _constructorParams The constructor parameters.
function _deployCreate2( function _deployCreate2(
string memory _name, string memory _name,
bytes memory _creationCode, bytes memory _creationCode,
...@@ -474,12 +561,17 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -474,12 +561,17 @@ contract DeployPeriphery is Script, Artifacts {
internal internal
returns (address addr_) returns (address addr_)
{ {
bytes32 salt = keccak256(bytes(_name)); bytes32 salt = keccak256(abi.encodePacked(bytes(_name), cfg.create2DeploymentSalt()));
bytes memory initCode = abi.encodePacked(_creationCode, _constructorParams); bytes memory initCode = abi.encodePacked(_creationCode, _constructorParams);
address preComputedAddress = computeCreate2Address(salt, keccak256(initCode)); address preComputedAddress = vm.computeCreate2Address(salt, keccak256(initCode));
if (preComputedAddress.code.length > 0) { if (preComputedAddress.code.length > 0) {
console.log("%s already deployed at %s", _name, preComputedAddress); console.log("%s already deployed at %s", _name, preComputedAddress);
save(_name, preComputedAddress); address savedAddress = getAddress(_name);
if (savedAddress == address(0)) {
save(_name, preComputedAddress);
} else if (savedAddress != preComputedAddress) {
revert AddressMismatch(_name, preComputedAddress, savedAddress);
}
addr_ = preComputedAddress; addr_ = preComputedAddress;
} else { } else {
assembly { assembly {
...@@ -506,14 +598,94 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -506,14 +598,94 @@ contract DeployPeriphery is Script, Artifacts {
} }
} }
/// @notice Generates the data for a Gelato task that would trigger a drip.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip.
/// @return _taskData Gelato task data.
function _makeGelatoDripTaskData(
Drippie _drippie,
string memory _name
)
internal
view
returns (GelatoTaskData memory _taskData)
{
// Get the drip interval.
uint256 dripInterval = _drippie.getDripInterval(_name);
// Set up module types.
GelatoDataTypes.Module[] memory modules = new GelatoDataTypes.Module[](2);
modules[0] = GelatoDataTypes.Module.PROXY;
modules[1] = GelatoDataTypes.Module.TRIGGER;
// Create arguments for the PROXY and TRIGGER modules.
bytes[] memory args = new bytes[](2);
args[0] = abi.encode(_name);
args[1] = abi.encode(
GelatoDataTypes.TriggerModuleData({
triggerType: GelatoDataTypes.TriggerType.TIME,
triggerConfig: abi.encode(GelatoDataTypes.Time({ nextExec: 0, interval: uint128(dripInterval) }))
})
);
// Create the task data.
_taskData = GelatoTaskData({
taskCreator: msg.sender,
execAddress: address(_drippie),
execData: abi.encodeCall(Drippie.drip, (_name)),
moduleData: GelatoDataTypes.ModuleData({ modules: modules, args: args }),
feeToken: address(0)
});
}
/// @notice Starts a gelato drip task.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip being triggered.
function _startGelatoDripTask(IGelato _gelato, Drippie _drippie, string memory _name) internal {
GelatoTaskData memory taskData = _makeGelatoDripTaskData({ _drippie: _drippie, _name: _name });
_gelato.createTask({
execAddress: taskData.execAddress,
execData: taskData.execData,
moduleData: taskData.moduleData,
feeToken: taskData.feeToken
});
}
/// @notice Pauses a gelato drip task.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip being triggered.
function _pauseGelatoDripTask(IGelato _gelato, Drippie _drippie, string memory _name) internal {
GelatoTaskData memory taskData = _makeGelatoDripTaskData({ _drippie: _drippie, _name: _name });
_gelato.cancelTask(
GelatoTaskId.getTaskId({
taskCreator: taskData.taskCreator,
execAddress: taskData.execAddress,
execSelector: GelatoBytes.memorySliceSelector(taskData.execData),
moduleData: taskData.moduleData,
feeToken: taskData.feeToken
})
);
}
/// @notice Installs a drip in the drippie contract. /// @notice Installs a drip in the drippie contract.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract. /// @param _drippie The drippie contract.
/// @param _name The name of the drip. /// @param _name The name of the drip.
/// @param _config The configuration of the drip. /// @param _config The configuration of the drip.
function _installDrip(Drippie _drippie, string memory _name, Drippie.DripConfig memory _config) internal { function _installDrip(
IGelato _gelato,
Drippie _drippie,
string memory _name,
Drippie.DripConfig memory _config
)
internal
{
if (_drippie.getDripStatus(_name) == Drippie.DripStatus.NONE) { if (_drippie.getDripStatus(_name) == Drippie.DripStatus.NONE) {
console.log("installing %s", _name); console.log("installing %s", _name);
_drippie.create(_name, _config); _drippie.create(_name, _config);
_startGelatoDripTask(_gelato, _drippie, _name);
console.log("%s installed successfully", _name); console.log("%s installed successfully", _name);
} else { } else {
console.log("%s already installed", _name); console.log("%s already installed", _name);
...@@ -524,6 +696,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -524,6 +696,7 @@ contract DeployPeriphery is Script, Artifacts {
} }
/// @notice Installs a drip that sends ETH to an address if the balance is below a threshold. /// @notice Installs a drip that sends ETH to an address if the balance is below a threshold.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract. /// @param _drippie The drippie contract.
/// @param _name The name of the drip. /// @param _name The name of the drip.
/// @param _target The target address. /// @param _target The target address.
...@@ -531,9 +704,10 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -531,9 +704,10 @@ contract DeployPeriphery is Script, Artifacts {
/// @param _interval The interval that must elapse between drips. /// @param _interval The interval that must elapse between drips.
/// @param _threshold The balance threshold. /// @param _threshold The balance threshold.
function _installBalanceLowDrip( function _installBalanceLowDrip(
IGelato _gelato,
Drippie _drippie, Drippie _drippie,
string memory _name, string memory _name,
address payable _target, address _target,
uint256 _value, uint256 _value,
uint256 _interval, uint256 _interval,
uint256 _threshold uint256 _threshold
...@@ -541,8 +715,9 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -541,8 +715,9 @@ contract DeployPeriphery is Script, Artifacts {
internal internal
{ {
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({ target: _target, data: "", value: _value }); actions[0] = Drippie.DripAction({ target: payable(_target), data: "", value: _value });
_installDrip({ _installDrip({
_gelato: _gelato,
_drippie: _drippie, _drippie: _drippie,
_name: _name, _name: _name,
_config: Drippie.DripConfig({ _config: Drippie.DripConfig({
...@@ -556,12 +731,14 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -556,12 +731,14 @@ contract DeployPeriphery is Script, Artifacts {
} }
/// @notice Installs a drip that sends ETH through the L1StandardBridge on an interval. /// @notice Installs a drip that sends ETH through the L1StandardBridge on an interval.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract. /// @param _drippie The drippie contract.
/// @param _name The name of the drip. /// @param _name The name of the drip.
/// @param _bridge The address of the bridge. /// @param _bridge The address of the bridge.
/// @param _target The target address. /// @param _target The target address.
/// @param _value The amount of ETH to send. /// @param _value The amount of ETH to send.
function _installDepositEthToDrip( function _installDepositEthToDrip(
IGelato _gelato,
Drippie _drippie, Drippie _drippie,
string memory _name, string memory _name,
address _bridge, address _bridge,
...@@ -578,6 +755,7 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -578,6 +755,7 @@ contract DeployPeriphery is Script, Artifacts {
value: _value value: _value
}); });
_installDrip({ _installDrip({
_gelato: _gelato,
_drippie: _drippie, _drippie: _drippie,
_name: _name, _name: _name,
_config: Drippie.DripConfig({ _config: Drippie.DripConfig({
...@@ -589,4 +767,93 @@ contract DeployPeriphery is Script, Artifacts { ...@@ -589,4 +767,93 @@ contract DeployPeriphery is Script, Artifacts {
}) })
}); });
} }
/// @notice Installs a drip that sends ETH to the Gelato treasury if the balance is below a
/// threshold. Balance gets deposited into the account of the recipient.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip.
/// @param _treasury The address of the Gelato treasury.
/// @param _recipient The address of the recipient.
/// @param _value The amount of ETH to send.
/// @param _interval The interval that must elapse between drips.
function _installGelatoDrip(
IGelato _gelato,
Drippie _drippie,
string memory _name,
address _treasury,
address _recipient,
uint256 _value,
uint256 _interval,
uint256 _threshold
)
internal
{
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({
target: payable(_treasury),
data: abi.encodeWithSignature("depositNative(address)", _recipient),
value: _value
});
_installDrip({
_gelato: _gelato,
_drippie: _drippie,
_name: _name,
_config: Drippie.DripConfig({
reentrant: false,
interval: _interval,
dripcheck: CheckGelatoLow(mustGetAddress("CheckGelatoLow")),
checkparams: abi.encode(
CheckGelatoLow.Params({ recipient: _recipient, threshold: _threshold, treasury: _treasury })
),
actions: actions
})
});
}
/// @notice Installs a drip that sends ETH to an account if one given secret is revealed and
/// another is not. Drip will stop if the second secret is revealed.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip.
/// @param _delay The delay before the drip starts after the first secret is revealed.
/// @param _secretHashMustExist The hash of the secret that must exist.
/// @param _secretHashMustNotExist The hash of the secret that must not exist.
/// @param _target The target address.
/// @param _value The amount of ETH to send.
/// @param _interval The interval that must elapse between drips.
function _installSecretsDrip(
IGelato _gelato,
Drippie _drippie,
string memory _name,
uint256 _delay,
bytes32 _secretHashMustExist,
bytes32 _secretHashMustNotExist,
address _target,
uint256 _value,
uint256 _interval
)
internal
{
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({ target: payable(_target), data: "", value: _value });
_installDrip({
_gelato: _gelato,
_drippie: _drippie,
_name: _name,
_config: Drippie.DripConfig({
reentrant: false,
interval: _interval,
dripcheck: CheckSecrets(mustGetAddress("CheckSecrets")),
checkparams: abi.encode(
CheckSecrets.Params({
delay: _delay,
secretHashMustExist: _secretHashMustExist,
secretHashMustNotExist: _secretHashMustNotExist
})
),
actions: actions
})
});
}
} }
...@@ -12,7 +12,31 @@ import { stdJson } from "forge-std/StdJson.sol"; ...@@ -12,7 +12,31 @@ import { stdJson } from "forge-std/StdJson.sol";
contract PeripheryDeployConfig is Script { contract PeripheryDeployConfig is Script {
string internal _json; string internal _json;
address public faucetAdmin; // General configuration.
string public create2DeploymentSalt;
// Configuration for Gelato.
address public gelatoAutomateContract;
address public gelatoTreasuryContract;
// Configuration for standard operations Drippie contract.
address public operationsDrippieOwner;
address public operationsSequencerDripV1Target;
uint256 public operationsSequencerDripV1Value;
uint256 public operationsSequencerDripV1Interval;
uint256 public operationsSequencerDripV1Threshold;
address public operationsGelatoDripV1Recipient;
uint256 public operationsGelatoDripV1Value;
uint256 public operationsGelatoDripV1Interval;
uint256 public operationsGelatoDripV1Threshold;
uint256 public operationsSecretsDripV1Delay;
bytes32 public operationsSecretsDripV1MustExist;
bytes32 public operationsSecretsDripV1MustNotExist;
address public operationsSecretsDripV1Target;
uint256 public operationsSecretsDripV1Value;
uint256 public operationsSecretsDripV1Interval;
// Configuration for the faucet Drippie contract.
address public faucetDrippieOwner; address public faucetDrippieOwner;
uint256 public faucetDripV1Value; uint256 public faucetDripV1Value;
uint256 public faucetDripV1Interval; uint256 public faucetDripV1Interval;
...@@ -23,25 +47,27 @@ contract PeripheryDeployConfig is Script { ...@@ -23,25 +47,27 @@ contract PeripheryDeployConfig is Script {
uint256 public faucetAdminDripV1Value; uint256 public faucetAdminDripV1Value;
uint256 public faucetAdminDripV1Interval; uint256 public faucetAdminDripV1Interval;
uint256 public faucetAdminDripV1Threshold; uint256 public faucetAdminDripV1Threshold;
address public faucetGelatoTreasury;
address public faucetGelatoRecipient; address public faucetGelatoRecipient;
uint256 public faucetGelatoBalanceV1DripInterval; uint256 public faucetGelatoBalanceV1DripInterval;
uint256 public faucetGelatoBalanceV1Value; uint256 public faucetGelatoBalanceV1Value;
uint256 public faucetGelatoThreshold; uint256 public faucetGelatoThreshold;
address public faucetOnchainAuthModuleAdmin;
uint256 public faucetOnchainAuthModuleTtl;
uint256 public faucetOnchainAuthModuleAmount;
address public faucetOffchainAuthModuleAdmin;
uint256 public faucetOffchainAuthModuleTtl;
uint256 public faucetOffchainAuthModuleAmount;
bool public installOpChainFaucetsDrips;
bool public archivePreviousOpChainFaucetsDrips;
uint256 public smallOpChainFaucetDripValue; uint256 public smallOpChainFaucetDripValue;
uint256 public smallOpChainFaucetDripInterval; uint256 public smallOpChainFaucetDripInterval;
uint256 public largeOpChainFaucetDripValue; uint256 public largeOpChainFaucetDripValue;
uint256 public largeOpChainFaucetDripInterval; uint256 public largeOpChainFaucetDripInterval;
uint256 public opChainAdminWalletDripValue; uint256 public opChainAdminWalletDripValue;
uint256 public opChainAdminWalletDripInterval; uint256 public opChainAdminWalletDripInterval;
// Configuration for the Faucet contract.
address public faucetAdmin;
address public faucetOnchainAuthModuleAdmin;
uint256 public faucetOnchainAuthModuleTtl;
uint256 public faucetOnchainAuthModuleAmount;
address public faucetOffchainAuthModuleAdmin;
uint256 public faucetOffchainAuthModuleTtl;
uint256 public faucetOffchainAuthModuleAmount;
// Configuration for the L1 bridges.
address public opL1BridgeAddress; address public opL1BridgeAddress;
address public baseL1BridgeAddress; address public baseL1BridgeAddress;
address public zoraL1BridgeAddress; address public zoraL1BridgeAddress;
...@@ -52,6 +78,15 @@ contract PeripheryDeployConfig is Script { ...@@ -52,6 +78,15 @@ contract PeripheryDeployConfig is Script {
address public liskL1BridgeAddress; address public liskL1BridgeAddress;
address[6] public smallFaucetsL1BridgeAddresses; address[6] public smallFaucetsL1BridgeAddresses;
address[2] public largeFaucetsL1BridgeAddresses; address[2] public largeFaucetsL1BridgeAddresses;
// Configuration booleans.
bool public deployDripchecks;
bool public deployFaucetContracts;
bool public deployOperationsContracts;
bool public installOpChainFaucetsDrips;
bool public archivePreviousOpChainFaucetsDrips;
// Configuration for the drip version.
uint256 public dripVersion; uint256 public dripVersion;
uint256 public previousDripVersion; uint256 public previousDripVersion;
...@@ -64,7 +99,31 @@ contract PeripheryDeployConfig is Script { ...@@ -64,7 +99,31 @@ contract PeripheryDeployConfig is Script {
return; return;
} }
faucetAdmin = stdJson.readAddress(_json, "$.faucetAdmin"); // General configuration.
create2DeploymentSalt = stdJson.readString(_json, "$.create2DeploymentSalt");
// Configuration for Gelato.
gelatoAutomateContract = stdJson.readAddress(_json, "$.gelatoAutomateContract");
gelatoTreasuryContract = stdJson.readAddress(_json, "$.gelatoTreasuryContract");
// Configuration for the standard operations Drippie contract.
operationsDrippieOwner = stdJson.readAddress(_json, "$.operationsDrippieOwner");
operationsSequencerDripV1Target = stdJson.readAddress(_json, "$.operationsSequencerDripV1Target");
operationsSequencerDripV1Value = stdJson.readUint(_json, "$.operationsSequencerDripV1Value");
operationsSequencerDripV1Interval = stdJson.readUint(_json, "$.operationsSequencerDripV1Interval");
operationsSequencerDripV1Threshold = stdJson.readUint(_json, "$.operationsSequencerDripV1Threshold");
operationsGelatoDripV1Recipient = stdJson.readAddress(_json, "$.operationsGelatoDripV1Recipient");
operationsGelatoDripV1Value = stdJson.readUint(_json, "$.operationsGelatoDripV1Value");
operationsGelatoDripV1Interval = stdJson.readUint(_json, "$.operationsGelatoDripV1Interval");
operationsGelatoDripV1Threshold = stdJson.readUint(_json, "$.operationsGelatoDripV1Threshold");
operationsSecretsDripV1Delay = stdJson.readUint(_json, "$.operationsSecretsDripV1Delay");
operationsSecretsDripV1MustExist = stdJson.readBytes32(_json, "$.operationsSecretsDripV1MustExist");
operationsSecretsDripV1MustNotExist = stdJson.readBytes32(_json, "$.operationsSecretsDripV1MustNotExist");
operationsSecretsDripV1Target = stdJson.readAddress(_json, "$.operationsSecretsDripV1Target");
operationsSecretsDripV1Value = stdJson.readUint(_json, "$.operationsSecretsDripV1Value");
operationsSecretsDripV1Interval = stdJson.readUint(_json, "$.operationsSecretsDripV1Interval");
// Configuration for the faucet Drippie contract.
faucetDrippieOwner = stdJson.readAddress(_json, "$.faucetDrippieOwner"); faucetDrippieOwner = stdJson.readAddress(_json, "$.faucetDrippieOwner");
faucetDripV1Value = stdJson.readUint(_json, "$.faucetDripV1Value"); faucetDripV1Value = stdJson.readUint(_json, "$.faucetDripV1Value");
faucetDripV1Interval = stdJson.readUint(_json, "$.faucetDripV1Interval"); faucetDripV1Interval = stdJson.readUint(_json, "$.faucetDripV1Interval");
...@@ -75,19 +134,27 @@ contract PeripheryDeployConfig is Script { ...@@ -75,19 +134,27 @@ contract PeripheryDeployConfig is Script {
faucetAdminDripV1Value = stdJson.readUint(_json, "$.faucetAdminDripV1Value"); faucetAdminDripV1Value = stdJson.readUint(_json, "$.faucetAdminDripV1Value");
faucetAdminDripV1Interval = stdJson.readUint(_json, "$.faucetAdminDripV1Interval"); faucetAdminDripV1Interval = stdJson.readUint(_json, "$.faucetAdminDripV1Interval");
faucetAdminDripV1Threshold = stdJson.readUint(_json, "$.faucetAdminDripV1Threshold"); faucetAdminDripV1Threshold = stdJson.readUint(_json, "$.faucetAdminDripV1Threshold");
faucetGelatoTreasury = stdJson.readAddress(_json, "$.faucetGelatoTreasury");
faucetGelatoRecipient = stdJson.readAddress(_json, "$.faucetGelatoRecipient"); faucetGelatoRecipient = stdJson.readAddress(_json, "$.faucetGelatoRecipient");
faucetGelatoBalanceV1DripInterval = stdJson.readUint(_json, "$.faucetGelatoBalanceV1DripInterval"); faucetGelatoBalanceV1DripInterval = stdJson.readUint(_json, "$.faucetGelatoBalanceV1DripInterval");
faucetGelatoBalanceV1Value = stdJson.readUint(_json, "$.faucetGelatoBalanceV1Value"); faucetGelatoBalanceV1Value = stdJson.readUint(_json, "$.faucetGelatoBalanceV1Value");
faucetGelatoThreshold = stdJson.readUint(_json, "$.faucetGelatoThreshold"); faucetGelatoThreshold = stdJson.readUint(_json, "$.faucetGelatoThreshold");
smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue");
smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval");
largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue");
largeOpChainFaucetDripInterval = stdJson.readUint(_json, "$.largeOpChainFaucetDripInterval");
opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue");
opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval");
// Configuration for the Faucet contract.
faucetAdmin = stdJson.readAddress(_json, "$.faucetAdmin");
faucetOnchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOnchainAuthModuleAdmin"); faucetOnchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOnchainAuthModuleAdmin");
faucetOnchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOnchainAuthModuleTtl"); faucetOnchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOnchainAuthModuleTtl");
faucetOnchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOnchainAuthModuleAmount"); faucetOnchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOnchainAuthModuleAmount");
faucetOffchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOffchainAuthModuleAdmin"); faucetOffchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOffchainAuthModuleAdmin");
faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl"); faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl");
faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount"); faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount");
installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips");
archivePreviousOpChainFaucetsDrips = stdJson.readBool(_json, "$.archivePreviousOpChainFaucetsDrips"); // Configuration for the L1 bridges.
opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress"); opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress");
baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress"); baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress");
zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress"); zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress");
...@@ -96,14 +163,6 @@ contract PeripheryDeployConfig is Script { ...@@ -96,14 +163,6 @@ contract PeripheryDeployConfig is Script {
liskL1BridgeAddress = stdJson.readAddress(_json, "$.liskL1BridgeAddress"); liskL1BridgeAddress = stdJson.readAddress(_json, "$.liskL1BridgeAddress");
modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress"); modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress");
lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress"); lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress");
dripVersion = stdJson.readUint(_json, "$.dripVersion");
previousDripVersion = stdJson.readUint(_json, "$.previousDripVersion");
smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue");
smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval");
largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue");
largeOpChainFaucetDripInterval = stdJson.readUint(_json, "$.largeOpChainFaucetDripInterval");
opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue");
opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval");
largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress; largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress;
largeFaucetsL1BridgeAddresses[1] = baseL1BridgeAddress; largeFaucetsL1BridgeAddresses[1] = baseL1BridgeAddress;
smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress; smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress;
...@@ -112,6 +171,17 @@ contract PeripheryDeployConfig is Script { ...@@ -112,6 +171,17 @@ contract PeripheryDeployConfig is Script {
smallFaucetsL1BridgeAddresses[3] = modeL1BridgeAddress; smallFaucetsL1BridgeAddresses[3] = modeL1BridgeAddress;
smallFaucetsL1BridgeAddresses[4] = lyraL1BridgeAddress; smallFaucetsL1BridgeAddresses[4] = lyraL1BridgeAddress;
smallFaucetsL1BridgeAddresses[5] = liskL1BridgeAddress; smallFaucetsL1BridgeAddresses[5] = liskL1BridgeAddress;
// Configuration booleans.
deployDripchecks = stdJson.readBool(_json, "$.deployDripchecks");
deployFaucetContracts = stdJson.readBool(_json, "$.deployFaucetContracts");
deployOperationsContracts = stdJson.readBool(_json, "$.deployOperationsContracts");
installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips");
archivePreviousOpChainFaucetsDrips = stdJson.readBool(_json, "$.archivePreviousOpChainFaucetsDrips");
// Configuration for the drip version.
dripVersion = stdJson.readUint(_json, "$.dripVersion");
previousDripVersion = stdJson.readUint(_json, "$.previousDripVersion");
} }
function getSmallFaucetsL1BridgeAddressesCount() public view returns (uint256 count) { function getSmallFaucetsL1BridgeAddressesCount() public view returns (uint256 count) {
......
...@@ -249,6 +249,25 @@ ...@@ -249,6 +249,25 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "getDripInterval",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
......
...@@ -251,4 +251,11 @@ contract Drippie is AssetReceiver { ...@@ -251,4 +251,11 @@ contract Drippie is AssetReceiver {
function getDripStatus(string calldata _name) public view returns (DripStatus) { function getDripStatus(string calldata _name) public view returns (DripStatus) {
return drips[_name].status; return drips[_name].status;
} }
/// @notice Returns the interval of a given drip.
/// @param _name Drip to check.
/// @return Interval of the given drip.
function getDripInterval(string calldata _name) public view returns (uint256) {
return drips[_name].config.interval;
}
} }
...@@ -4,7 +4,8 @@ pragma solidity 0.8.15; ...@@ -4,7 +4,8 @@ pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
interface IGelatoTreasury { interface IGelatoTreasury {
function userTokenBalance(address _user, address _token) external view returns (uint256); function totalDepositedAmount(address _user, address _token) external view returns (uint256);
function totalWithdrawnAmount(address _user, address _token) external view returns (uint256);
} }
/// @title CheckGelatoLow /// @title CheckGelatoLow
...@@ -24,11 +25,19 @@ contract CheckGelatoLow is IDripCheck { ...@@ -24,11 +25,19 @@ contract CheckGelatoLow is IDripCheck {
function check(bytes memory _params) external view returns (bool execute_) { function check(bytes memory _params) external view returns (bool execute_) {
Params memory params = abi.decode(_params, (Params)); Params memory params = abi.decode(_params, (Params));
// Check GelatoTreasury ETH balance is below threshold. // Gelato represents ETH as 0xeeeee....eeeee.
execute_ = IGelatoTreasury(params.treasury).userTokenBalance( address eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
params.recipient,
// Gelato represents ETH as 0xeeeee....eeeee // Get the total deposited amount.
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE uint256 deposited = IGelatoTreasury(params.treasury).totalDepositedAmount(params.recipient, eth);
) < params.threshold;
// Get the total withdrawn amount.
uint256 withdrawn = IGelatoTreasury(params.treasury).totalWithdrawnAmount(params.recipient, eth);
// Figure out the current balance.
uint256 balance = deposited - withdrawn;
// Check if the balance is below the threshold.
execute_ = balance < params.threshold;
} }
} }
...@@ -5,23 +5,26 @@ import { Test } from "forge-std/Test.sol"; ...@@ -5,23 +5,26 @@ import { Test } from "forge-std/Test.sol";
import { CheckGelatoLow, IGelatoTreasury } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; import { CheckGelatoLow, IGelatoTreasury } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
/// @title MockGelatoTreasury /// @title MockGelatoTreasury
/// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary /// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary setting of balances.
/// setting of user balances.
contract MockGelatoTreasury is IGelatoTreasury { contract MockGelatoTreasury is IGelatoTreasury {
mapping(address => mapping(address => uint256)) private tokenBalances; mapping(address => mapping(address => uint256)) private totalDeposited;
mapping(address => mapping(address => uint256)) private totalWithdrawn;
function setTokenBalance(address _user, address _token, uint256 _balance) external { function totalDepositedAmount(address _user, address _token) external view override returns (uint256) {
tokenBalances[_token][_user] = _balance; return totalDeposited[_token][_user];
} }
function userTokenBalance(address _user, address _token) external view returns (uint256) { function totalWithdrawnAmount(address _user, address _token) external view override returns (uint256) {
return tokenBalances[_token][_user]; return totalWithdrawn[_token][_user];
}
function setTotalDepositedAmount(address _user, address _token, uint256 _amount) external {
totalDeposited[_token][_user] = _amount;
} }
} }
/// @title CheckGelatoLowTest /// @title CheckGelatoLowTest
/// @notice Tests the CheckGelatoLow contract via fuzzing both the success case /// @notice Tests the CheckGelatoLow contract via fuzzing both the success and failure cases.
/// and the failure case.
contract CheckGelatoLowTest is Test { contract CheckGelatoLowTest is Test {
/// @notice An instance of the CheckGelatoLow contract. /// @notice An instance of the CheckGelatoLow contract.
CheckGelatoLow c; CheckGelatoLow c;
...@@ -44,7 +47,9 @@ contract CheckGelatoLowTest is Test { ...@@ -44,7 +47,9 @@ contract CheckGelatoLowTest is Test {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient }); CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
vm.assume(gelato.userTokenBalance(_recipient, eth) < _threshold); vm.assume(
gelato.totalDepositedAmount(_recipient, eth) - gelato.totalWithdrawnAmount(_recipient, eth) < _threshold
);
assertEq(c.check(abi.encode(p)), true); assertEq(c.check(abi.encode(p)), true);
} }
...@@ -56,7 +61,7 @@ contract CheckGelatoLowTest is Test { ...@@ -56,7 +61,7 @@ contract CheckGelatoLowTest is Test {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient }); CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
gelato.setTokenBalance(_recipient, eth, _threshold); gelato.setTotalDepositedAmount(_recipient, eth, _threshold);
assertEq(c.check(abi.encode(p)), false); assertEq(c.check(abi.encode(p)), false);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment