Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import {VersionedBlobParams} from "src/interfaces/IEigenDAStructs.sol";
import {MockStakeRegistry} from "./mocks/MockStakeRegistry.sol";
import {MockRegistryCoordinator} from "./mocks/MockRegistryCoordinator.sol";

import {BeforeInitialization} from "./test/BeforeInitialization.t.sol";

import {
DeploymentInitializer,
ImmutableInitParams,
Expand All @@ -44,15 +46,16 @@ import {
CalldataInitParams,
CalldataRegistryCoordinatorParams,
CalldataThresholdRegistryParams,
CalldataServiceManagerParams
CalldataServiceManagerParams,
InitParamsLib
} from "./DeploymentInitializer.sol";

import "forge-std/Script.sol";
import "forge-std/StdJson.sol";
import {console2} from "forge-std/console2.sol";

contract DeployVerifiable is Script {
// The intended owner of all the contracts after the full deployment process is completed.
address initialOwner;
using InitParamsLib for string;

// All proxies and implementations to upgrade them to, namespaced in structs.
ProxyAdmin proxyAdmin;
Expand All @@ -62,15 +65,6 @@ contract DeployVerifiable is Script {
// Contracts deployed without a proxy
IPauserRegistry pauserRegistry;

// Configuration parameters for construction of implementations
address rewardsCoordinator;
address avsDirectory;
address delegationManager;
address churnApprover;
address ejector;

uint256 initialPausedStatus;

// Inert implementation contracts used as initial implementations before the proxies are initialized
address emptyContract;
address mockStakeRegistry;
Expand All @@ -80,32 +74,17 @@ contract DeployVerifiable is Script {
DeploymentInitializer deploymentInitializer;

// Script config
string configData;

/// @dev override this if you don't want to use the environment to get the config path
function _configPath() internal view virtual returns (string memory) {
return vm.envString("DEPLOY_CONFIG_PATH");
}
string cfg;

function run() public {
// Read JSON config
configData = vm.readFile(_configPath());
initialOwner = stdJson.readAddress(configData, ".initialOwner");
rewardsCoordinator = stdJson.readAddress(configData, ".initParams.shared.rewardsCoordinator");
avsDirectory = stdJson.readAddress(configData, ".initParams.shared.avsDirectory");
delegationManager = stdJson.readAddress(configData, ".initParams.shared.delegationManager");
initialPausedStatus = stdJson.readUint(configData, ".initParams.shared.initialPausedStatus");
_initConfig();

vm.startBroadcast();
proxyAdmin = new ProxyAdmin();
emptyContract = address(new EmptyContract());
mockStakeRegistry = address(new MockStakeRegistry(IDelegationManager(delegationManager)));
pauserRegistry = IPauserRegistry(
new PauserRegistry(
stdJson.readAddressArray(configData, ".initParams.core.pauserRegistry.pausers"),
stdJson.readAddress(configData, ".initParams.core.pauserRegistry.unpauser")
)
);
mockStakeRegistry = address(new MockStakeRegistry(IDelegationManager(cfg.delegationManager())));
pauserRegistry = IPauserRegistry(new PauserRegistry(cfg.pausers(), cfg.unpauser()));

_deployInertProxies();
_deployImplementations();
Expand All @@ -116,24 +95,49 @@ contract DeployVerifiable is Script {
// Transfer ownership of proxy admin to deployment initializer
proxyAdmin.transferOwnership(address(deploymentInitializer));

_logs();

vm.stopBroadcast();

_doTests(configData);
_doTests();
}

/// @dev override this if you don't want to use the environment to get the config path
function _initConfig() internal virtual {
cfg = vm.readFile(vm.envString("DEPLOY_CONFIG_PATH"));
}

function _doTests(string memory cfg) internal {
vm.startPrank(initialOwner);
CalldataInitParams memory params = CalldataInitParamsLib.getCalldataInitParams(cfg);
function _logs() internal virtual {
console2.log("Deployment addresses:");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to learn - how does console2 differ from just regular console?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the foundry doc,

"console2.sol contains patches to console.sol that allow Forge to decode traces for calls to the console, but it is not compatible with Hardhat."

console2.log("Deployment Initializer: ", address(deploymentInitializer));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - inconsistent formatting with other log stmts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console2.log("Empty Contract Implementation", emptyContract);
console2.log("Mock Stake Registry Implementation", mockStakeRegistry);
console2.log("Mock Registry Coordinator Implementation", mockRegistryCoordinator);

console2.log(
"\n\nAll other relevant deployment addresses should be queried from the DeploymentInitializer contract."
);
}

function _doTests() internal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this not a redundant simulation with just running the script with --broadcast enabled?

Copy link
Contributor Author

@pakim249CAL pakim249CAL Mar 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How so? I don't think I understand this question. Do you mean that this whole fn is redundant? Basically this function is put into the script to run the same tests that the verifier would run to verify the deployment. That way, the deployer has some assurance that the verifier can run the BeforeVerifiableDeploymentInitialization test on the latest block on the deployed chain and have it pass.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see that makes sense - any chance we could capture this role differentiation in a smol comment? At first glance the behavior is a bit hard to decipher

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BeforeInitialization beforeTest = new BeforeInitialization();
beforeTest.doBeforeInitializationTests(
cfg, deploymentInitializer, emptyContract, mockStakeRegistry, mockRegistryCoordinator
);

vm.startPrank(cfg.initialOwner());
CalldataInitParams memory params = InitParamsLib.calldataInitParams(cfg);
deploymentInitializer.initializeDeployment(params);

// TODO: Add more tests

vm.stopPrank();
}

function _deployInertProxies() internal virtual {
proxyAdmin = new ProxyAdmin();
emptyContract = address(new EmptyContract());
mockStakeRegistry = address(new MockStakeRegistry(IDelegationManager(delegationManager)));
mockStakeRegistry = address(new MockStakeRegistry(IDelegationManager(cfg.delegationManager())));

// Deploy empty contracts to get addresses
proxies.indexRegistry = address(new TransparentUpgradeableProxy(emptyContract, address(proxyAdmin), ""));
Expand All @@ -158,7 +162,9 @@ contract DeployVerifiable is Script {
function _deployImplementations() internal virtual {
implementations.indexRegistry = address(new IndexRegistry(IRegistryCoordinator(proxies.registryCoordinator)));
implementations.stakeRegistry = address(
new StakeRegistry(IRegistryCoordinator(proxies.registryCoordinator), IDelegationManager(delegationManager))
new StakeRegistry(
IRegistryCoordinator(proxies.registryCoordinator), IDelegationManager(cfg.delegationManager())
)
);
implementations.socketRegistry = address(new SocketRegistry(IRegistryCoordinator(proxies.registryCoordinator)));
implementations.blsApkRegistry = address(new BLSApkRegistry(IRegistryCoordinator(proxies.registryCoordinator)));
Expand All @@ -177,8 +183,8 @@ contract DeployVerifiable is Script {
implementations.disperserRegistry = address(new EigenDADisperserRegistry());
implementations.serviceManager = address(
new EigenDAServiceManager(
IAVSDirectory(avsDirectory),
IRewardsCoordinator(rewardsCoordinator),
IAVSDirectory(cfg.avsDirectory()),
IRewardsCoordinator(cfg.rewardsCoordinator()),
IRegistryCoordinator(proxies.registryCoordinator),
IStakeRegistry(proxies.stakeRegistry),
IEigenDAThresholdRegistry(proxies.thresholdRegistry),
Expand All @@ -190,110 +196,16 @@ contract DeployVerifiable is Script {
}

function _immutableInitParams() internal view returns (ImmutableInitParams memory) {
ImmutableRegistryCoordinatorParams memory registryCoordinatorParams = ImmutableRegistryCoordinatorParams({
churnApprover: stdJson.readAddress(configData, ".initParams.middleware.registryCoordinator.churnApprover"),
ejector: stdJson.readAddress(configData, ".initParams.middleware.registryCoordinator.ejector")
});
ImmutablePaymentVaultParams memory paymentVaultParams = ImmutablePaymentVaultParams({
minNumSymbols: uint64(stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.minNumSymbols")),
pricePerSymbol: uint64(stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.pricePerSymbol")),
priceUpdateCooldown: uint64(
stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.priceUpdateCooldown")
),
globalSymbolsPerPeriod: uint64(
stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.globalSymbolsPerPeriod")
),
reservationPeriodInterval: uint64(
stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.reservationPeriodInterval")
),
globalRatePeriodInterval: uint64(
stdJson.readUint(configData, ".initParams.eigenDA.paymentVault.globalRatePeriodInterval")
)
});
ImmutableServiceManagerParams memory serviceManagerParams = ImmutableServiceManagerParams({
rewardsInitiator: stdJson.readAddress(configData, ".initParams.eigenDA.serviceManager.rewardsInitiator")
});

return ImmutableInitParams({
proxyAdmin: proxyAdmin,
initialOwner: initialOwner,
initialOwner: cfg.initialOwner(),
pauserRegistry: pauserRegistry,
initialPausedStatus: initialPausedStatus,
initialPausedStatus: cfg.initialPausedStatus(),
proxies: proxies,
implementations: implementations,
registryCoordinatorParams: registryCoordinatorParams,
paymentVaultParams: paymentVaultParams,
serviceManagerParams: serviceManagerParams
});
}
}

library CalldataInitParamsLib {
function operatorSetParams(string memory configData)
internal
pure
returns (IRegistryCoordinator.OperatorSetParam[] memory)
{
bytes memory operatorConfigsRaw =
stdJson.parseRaw(configData, ".initParams.middleware.registryCoordinator.operatorSetParams");
return abi.decode(operatorConfigsRaw, (IRegistryCoordinator.OperatorSetParam[]));
}

function minimumStakes(string memory configData) internal pure returns (uint96[] memory) {
bytes memory stakesConfigsRaw =
stdJson.parseRaw(configData, ".initParams.middleware.registryCoordinator.minimumStakes");
return abi.decode(stakesConfigsRaw, (uint96[]));
}

function strategyParams(string memory configData)
internal
pure
returns (IStakeRegistry.StrategyParams[][] memory)
{
bytes memory strategyConfigsRaw =
stdJson.parseRaw(configData, ".initParams.middleware.registryCoordinator.strategyParams");
return abi.decode(strategyConfigsRaw, (IStakeRegistry.StrategyParams[][]));
}

function quorumAdversaryThresholdPercentages(string memory configData) internal pure returns (bytes memory) {
return
stdJson.readBytes(configData, ".initParams.eigenDA.thresholdRegistry.quorumAdversaryThresholdPercentages");
}

function quorumConfirmationThresholdPercentages(string memory configData) internal pure returns (bytes memory) {
return stdJson.readBytes(
configData, ".initParams.eigenDA.thresholdRegistry.quorumConfirmationThresholdPercentages"
);
}

function quorumNumbersRequired(string memory configData) internal pure returns (bytes memory) {
return stdJson.readBytes(configData, ".initParams.eigenDA.thresholdRegistry.quorumNumbersRequired");
}

function versionedBlobParams(string memory configData) internal pure returns (VersionedBlobParams[] memory) {
bytes memory versionedBlobParamsRaw =
stdJson.parseRaw(configData, ".initParams.eigenDA.thresholdRegistry.versionedBlobParams");
return abi.decode(versionedBlobParamsRaw, (VersionedBlobParams[]));
}

function batchConfirmers(string memory configData) internal pure returns (address[] memory) {
return stdJson.readAddressArray(configData, ".initParams.eigenDA.serviceManager.batchConfirmers");
}

function getCalldataInitParams(string memory configData) internal pure returns (CalldataInitParams memory) {
return CalldataInitParams({
registryCoordinatorParams: CalldataRegistryCoordinatorParams({
operatorSetParams: operatorSetParams(configData),
minimumStakes: minimumStakes(configData),
strategyParams: strategyParams(configData)
}),
thresholdRegistryParams: CalldataThresholdRegistryParams({
quorumAdversaryThresholdPercentages: quorumAdversaryThresholdPercentages(configData),
quorumConfirmationThresholdPercentages: quorumConfirmationThresholdPercentages(configData),
quorumNumbersRequired: quorumNumbersRequired(configData),
versionedBlobParams: versionedBlobParams(configData)
}),
serviceManagerParams: CalldataServiceManagerParams({batchConfirmers: batchConfirmers(configData)})
registryCoordinatorParams: cfg.registryCoordinatorParams(),
paymentVaultParams: cfg.paymentVaultParams(),
serviceManagerParams: cfg.serviceManagerParams()
});
}
}
Loading
Loading