Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Params registry #387

Merged
merged 19 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 89 additions & 8 deletions script/DeployBase.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ import { CSVerifier } from "../src/CSVerifier.sol";
import { ICSVerifier } from "../src/interfaces/ICSVerifier.sol";
import { PermissionlessGate } from "../src/PermissionlessGate.sol";
import { VettedGate } from "../src/VettedGate.sol";
import { CSParametersRegistry } from "../src/CSParametersRegistry.sol";

import { ILidoLocator } from "../src/interfaces/ILidoLocator.sol";
import { IGateSealFactory } from "../src/interfaces/IGateSealFactory.sol";
import { BaseOracle } from "../src/lib/base-oracle/BaseOracle.sol";
import { ICSParametersRegistry } from "../src/interfaces/ICSParametersRegistry.sol";

import { JsonObj, Json } from "./utils/Json.sol";
import { GIndex } from "../src/lib/GIndex.sol";
import { Slot } from "../src/lib/Types.sol";

struct DeployParams {
struct DeployParamsV1 {
// Lido addresses
address lidoLocatorAddress;
address aragonAgent;
Expand Down Expand Up @@ -73,6 +75,59 @@ struct DeployParams {
address secondAdminAddress;
}

struct DeployParams {
// Lido addresses
address lidoLocatorAddress;
address aragonAgent;
address easyTrackEVMScriptExecutor;
address proxyAdmin;
// Oracle
uint256 secondsPerSlot;
uint256 slotsPerEpoch;
uint256 clGenesisTime;
uint256 oracleReportEpochsPerFrame;
uint256 fastLaneLengthSlots;
uint256 consensusVersion;
address[] oracleMembers;
uint256 hashConsensusQuorum;
// Verifier
GIndex gIHistoricalSummaries;
GIndex gIFirstWithdrawal;
GIndex gIFirstValidator;
uint256 verifierSupportedEpoch;
// Accounting
uint256 maxCurveLength;
uint256[] bondCurve;
uint256 minBondLockPeriod;
uint256 maxBondLockPeriod;
uint256 bondLockPeriod;
address setResetBondCurveAddress;
address chargePenaltyRecipient;
// Module
bytes32 moduleType;
uint256 minSlashingPenaltyQuotient;
uint256 maxKeysPerOperatorEA;
address elRewardsStealingReporter;
// CSParameters
uint256 keyRemovalCharge;
uint256 elRewardsStealingAdditionalFine;
uint256 avgPerfLeewayBP;
uint256 rewardShareBP;
uint256 strikesLifetimeFrames;
uint256 strikesThreshold;
uint256 priorityQueueLimit;
// VettedGate
bytes32 vettedGateTreeRoot;
uint256[] vettedGateBondCurve;
// GateSeal
address gateSealFactory;
address sealingCommittee;
uint256 sealDuration;
uint256 sealExpiryTimestamp;
// Testnet stuff
address secondAdminAddress;
}

abstract contract DeployBase is Script {
string internal gitRef;
DeployParams internal config;
Expand All @@ -91,6 +146,7 @@ abstract contract DeployBase is Script {
PermissionlessGate public permissionlessGate;
VettedGate public vettedGate;
HashConsensus public hashConsensus;
CSParametersRegistry public parametersRegistry;

error ChainIdMismatch(uint256 actual, uint256 expected);
error HashConsensusMismatch();
Expand Down Expand Up @@ -138,14 +194,17 @@ abstract contract DeployBase is Script {

vm.startBroadcast(pk);
{
CSParametersRegistry parametersRegistryImpl = new CSParametersRegistry();
parametersRegistry = CSParametersRegistry(
_deployProxy(config.proxyAdmin, address(parametersRegistryImpl))
);

CSModule csmImpl = new CSModule({
moduleType: config.moduleType,
minSlashingPenaltyQuotient: config.minSlashingPenaltyQuotient,
elRewardsStealingAdditionalFine: config
.elRewardsStealingAdditionalFine,
maxKeysPerOperatorEA: config.maxKeysPerOperatorEA,
maxKeyRemovalCharge: config.maxKeyRemovalCharge,
lidoLocator: config.lidoLocatorAddress
lidoLocator: config.lidoLocatorAddress,
parametersRegistry: address(parametersRegistry)
});
csm = CSModule(_deployProxy(config.proxyAdmin, address(csmImpl)));

Expand Down Expand Up @@ -199,6 +258,20 @@ abstract contract DeployBase is Script {
admin: deployer
});

parametersRegistry.initialize({
admin: deployer,
skhomuti marked this conversation as resolved.
Show resolved Hide resolved
data: ICSParametersRegistry.InitializationData({
keyRemovalCharge: config.keyRemovalCharge,
elRewardsStealingAdditionalFine: config
.elRewardsStealingAdditionalFine,
priorityQueueLimit: config.priorityQueueLimit,
rewardShare: config.rewardShareBP,
performanceLeeway: config.avgPerfLeewayBP,
strikesLifetime: config.strikesLifetimeFrames,
strikesThreshold: config.strikesThreshold
})
});

accounting.initialize({
bondCurve: config.bondCurve,
admin: deployer,
Expand All @@ -221,7 +294,6 @@ abstract contract DeployBase is Script {

csm.initialize({
_accounting: address(accounting),
_keyRemovalCharge: config.keyRemovalCharge,
admin: deployer
});
permissionlessGate = new PermissionlessGate(address(csm));
Expand Down Expand Up @@ -262,8 +334,7 @@ abstract contract DeployBase is Script {
admin: address(deployer),
feeDistributorContract: address(feeDistributor),
consensusContract: address(hashConsensus),
consensusVersion: config.consensusVersion,
_avgPerfLeewayBP: config.avgPerfLeewayBP
consensusVersion: config.consensusVersion
});

address[] memory sealables = new address[](5);
Expand Down Expand Up @@ -312,6 +383,15 @@ abstract contract DeployBase is Script {
csm.grantRole(csm.DEFAULT_ADMIN_ROLE(), config.aragonAgent);
csm.revokeRole(csm.DEFAULT_ADMIN_ROLE(), deployer);

parametersRegistry.grantRole(
parametersRegistry.DEFAULT_ADMIN_ROLE(),
config.aragonAgent
);
parametersRegistry.revokeRole(
parametersRegistry.DEFAULT_ADMIN_ROLE(),
deployer
);

vettedGate.grantRole(
vettedGate.DEFAULT_ADMIN_ROLE(),
config.aragonAgent
Expand Down Expand Up @@ -355,6 +435,7 @@ abstract contract DeployBase is Script {
deployJson.set("ChainId", chainId);
deployJson.set("PermissionlessGate", address(permissionlessGate));
deployJson.set("VettedGate", address(vettedGate));
deployJson.set("CSParametersRegistry", address(parametersRegistry));
deployJson.set("CSModule", address(csm));
deployJson.set("CSAccounting", address(accounting));
deployJson.set("CSFeeOracle", address(oracle));
Expand Down
12 changes: 8 additions & 4 deletions script/DeployHolesky.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ contract DeployHolesky is DeployBase {
config.oracleReportEpochsPerFrame = 225 * 7; // 7 days
config.fastLaneLengthSlots = 0;
config.consensusVersion = 1;
config.avgPerfLeewayBP = 500;
config.oracleMembers = new address[](10);
config.oracleMembers[0] = 0x12A1D74F8697b9f4F1eEBb0a9d0FB6a751366399;
config.oracleMembers[1] = 0xD892c09b556b547c80B7d8c8cB8d75bf541B2284;
Expand Down Expand Up @@ -67,14 +66,19 @@ contract DeployHolesky is DeployBase {
// Module
config.moduleType = "community-onchain-v1";
config.minSlashingPenaltyQuotient = 32;
config.elRewardsStealingAdditionalFine = 0.1 ether;
config.maxKeysPerOperatorEA = 10;
config.maxKeyRemovalCharge = 0.1 ether;
config.keyRemovalCharge = 0.05 ether;
config
.elRewardsStealingReporter = 0xc4DAB3a3ef68C6DFd8614a870D64D475bA44F164; // Dev team EOA
config
.chargePenaltyRecipient = 0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d; // locator.treasury()
// CSParameters
config.keyRemovalCharge = 0.05 ether;
config.elRewardsStealingAdditionalFine = 0.1 ether;
config.avgPerfLeewayBP = 500;
config.rewardShareBP = 10000;
config.strikesLifetimeFrames = 6;
config.strikesThreshold = 3;
config.priorityQueueLimit = 0;
// VettedGate
config
.vettedGateTreeRoot = 0xc9a9c1576cf4f3213ad9075b72a1f1b147914a252ad927fa4ca3460ff0723ca9;
Expand Down
41 changes: 37 additions & 4 deletions script/DeployImplementationsBase.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import { CSFeeOracle } from "../src/CSFeeOracle.sol";
import { CSVerifier } from "../src/CSVerifier.sol";
import { PermissionlessGate } from "../src/PermissionlessGate.sol";
import { VettedGate } from "../src/VettedGate.sol";
import { CSParametersRegistry } from "../src/CSParametersRegistry.sol";
import { ICSEarlyAdoption } from "../src/interfaces/ICSEarlyAdoption.sol";
import { ICSParametersRegistry } from "../src/interfaces/ICSParametersRegistry.sol";
import { ICSVerifier } from "../src/interfaces/ICSVerifier.sol";

import { JsonObj, Json } from "./utils/Json.sol";
Expand All @@ -40,14 +42,30 @@ abstract contract DeployImplementationsBase is DeployBase {

vm.startBroadcast(pk);
{
CSParametersRegistry parametersRegistryImpl = new CSParametersRegistry();
parametersRegistry = CSParametersRegistry(
_deployProxy(config.proxyAdmin, address(parametersRegistryImpl))
);
parametersRegistry.initialize({
admin: deployer,
data: ICSParametersRegistry.InitializationData({
keyRemovalCharge: config.keyRemovalCharge,
elRewardsStealingAdditionalFine: config
.elRewardsStealingAdditionalFine,
priorityQueueLimit: config.priorityQueueLimit,
rewardShare: config.rewardShareBP,
performanceLeeway: config.avgPerfLeewayBP,
strikesLifetime: config.strikesLifetimeFrames,
strikesThreshold: config.strikesThreshold
})
});

CSModule csmImpl = new CSModule({
moduleType: config.moduleType,
minSlashingPenaltyQuotient: config.minSlashingPenaltyQuotient,
elRewardsStealingAdditionalFine: config
.elRewardsStealingAdditionalFine,
maxKeysPerOperatorEA: config.maxKeysPerOperatorEA,
maxKeyRemovalCharge: config.maxKeyRemovalCharge,
lidoLocator: config.lidoLocatorAddress
lidoLocator: config.lidoLocatorAddress,
parametersRegistry: address(parametersRegistry)
});

CSAccounting accountingImpl = new CSAccounting({
Expand Down Expand Up @@ -121,16 +139,31 @@ abstract contract DeployImplementationsBase is DeployBase {
);
verifier.revokeRole(verifier.DEFAULT_ADMIN_ROLE(), deployer);

parametersRegistry.grantRole(
parametersRegistry.DEFAULT_ADMIN_ROLE(),
config.aragonAgent
);
parametersRegistry.revokeRole(
parametersRegistry.DEFAULT_ADMIN_ROLE(),
deployer
);

JsonObj memory deployJson = Json.newObj();
deployJson.set("PermissionlessGate", address(permissionlessGate));
deployJson.set("VettedGate", address(vettedGate));
deployJson.set(
"CSParametersRegistryImpl",
address(parametersRegistryImpl)
);
deployJson.set("CSParametersRegistry", address(parametersRegistry));
deployJson.set("CSModuleImpl", address(csmImpl));
deployJson.set("CSAccountingImpl", address(accountingImpl));
deployJson.set("CSFeeOracleImpl", address(oracleImpl));
deployJson.set("CSFeeDistributorImpl", address(feeDistributorImpl));
deployJson.set("CSVerifier", address(verifier));
deployJson.set("HashConsensus", address(hashConsensus));
deployJson.set("GateSeal", address(gateSeal));
deployJson.set("DeployParams", abi.encode(config));
deployJson.set("git-ref", gitRef);
vm.writeJson(
deployJson.str,
Expand Down
12 changes: 8 additions & 4 deletions script/DeployMainnet.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ contract DeployMainnet is DeployBase {
config.oracleReportEpochsPerFrame = 225 * 28; // 28 days
config.fastLaneLengthSlots = 1800;
config.consensusVersion = 1;
config.avgPerfLeewayBP = 500;
config.oracleMembers = new address[](9);
config.oracleMembers[0] = 0x140Bd8FbDc884f48dA7cb1c09bE8A2fAdfea776E; // Chorus One
config.oracleMembers[1] = 0xA7410857ABbf75043d61ea54e07D57A6EB6EF186; // Kyber Network
Expand Down Expand Up @@ -65,12 +64,17 @@ contract DeployMainnet is DeployBase {
// Module
config.moduleType = "community-onchain-v1"; // Just a unique type name to be used by the off-chain tooling
config.minSlashingPenaltyQuotient = 32;
config.elRewardsStealingAdditionalFine = 0.1 ether;
config.maxKeysPerOperatorEA = 12; // 12 EA vals will result in approx 16 ETH worth of bond
config.maxKeyRemovalCharge = 0.1 ether;
config.keyRemovalCharge = 0.05 ether;
config
.elRewardsStealingReporter = 0xC52fC3081123073078698F1EAc2f1Dc7Bd71880f; // CSM Committee MS
// CSParameters
config.keyRemovalCharge = 0.05 ether;
config.elRewardsStealingAdditionalFine = 0.1 ether;
config.avgPerfLeewayBP = 500;
config.rewardShareBP = 10000;
config.strikesLifetimeFrames = 6;
config.strikesThreshold = 3;
config.priorityQueueLimit = 0;
// VettedGate
config
.vettedGateTreeRoot = 0x359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c2; // See the first value in artifacts/mainnet/early-adoption/merkle-tree.json
Expand Down
6 changes: 5 additions & 1 deletion script/fork-helpers/NodeOperators.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ contract NodeOperators is
uint256 lockedAfter = accounting.getActualLockedBond(noId);
assertEq(
lockedAfter,
lockedBefore + amount + csm.EL_REWARDS_STEALING_ADDITIONAL_FINE()
lockedBefore +
amount +
csm.PARAMETERS_REGISTRY().getElRewardsStealingAdditionalFine(
accounting.getBondCurveId(noId)
)
);
}

Expand Down
25 changes: 3 additions & 22 deletions src/CSFeeOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@ contract CSFeeOracle is
/// @notice An ACL role granting the permission to recover assets
bytes32 public constant RECOVERER_ROLE = keccak256("RECOVERER_ROLE");

uint256 internal constant MAX_BP = 10000;

ICSFeeDistributor public feeDistributor;

/// @notice DEPRECATED. Parameter was migrated to CSParametersRegistry
/// @notice Leeway in basis points is used to determine the under-performing validators threshold.
/// `threshold` = `avgPerfBP` - `avgPerfLeewayBP`, where `avgPerfBP` is an average
/// performance over the network computed by the off-chain oracle.
uint256 public avgPerfLeewayBP;
uint256 internal _avgPerfLeewayBP;

constructor(
uint256 secondsPerSlot,
Expand All @@ -48,8 +47,7 @@ contract CSFeeOracle is
address admin,
address feeDistributorContract,
address consensusContract,
uint256 consensusVersion,
uint256 _avgPerfLeewayBP
uint256 consensusVersion
) external {
if (admin == address(0)) revert ZeroAdminAddress();

Expand All @@ -58,7 +56,6 @@ contract CSFeeOracle is
BaseOracle._initialize(consensusContract, consensusVersion, 0);
/// @dev _setFeeDistributorContract() reverts if zero address
_setFeeDistributorContract(feeDistributorContract);
_setPerformanceLeeway(_avgPerfLeewayBP);
}

/// @inheritdoc ICSFeeOracle
Expand All @@ -68,13 +65,6 @@ contract CSFeeOracle is
_setFeeDistributorContract(feeDistributorContract);
}

/// @inheritdoc ICSFeeOracle
function setPerformanceLeeway(
uint256 valueBP
) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setPerformanceLeeway(valueBP);
}

/// @inheritdoc ICSFeeOracle
function submitReportData(
ReportData calldata data,
Expand Down Expand Up @@ -118,15 +108,6 @@ contract CSFeeOracle is
emit FeeDistributorContractSet(feeDistributorContract);
}

function _setPerformanceLeeway(uint256 valueBP) internal {
if (valueBP > MAX_BP) {
revert InvalidPerfLeeway();
}

avgPerfLeewayBP = valueBP;
emit PerfLeewaySet(valueBP);
}

/// @dev Called in `submitConsensusReport` after a consensus is reached.
function _handleConsensusReport(
ConsensusReport memory /* report */,
Expand Down
Loading