Skip to content
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
20 changes: 20 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ This changelog tracks "core" contract deployments on the mev-commit chain. This
| July 22nd 2025, 20:10:39 UTC | BidderRegistry | BidderRegistryV2 | `v1.1.5` in `release/v1.1.x`. |
| July 22nd 2025, 20:10:39 UTC | ProviderRegistry | ProviderRegistryV2 | `v1.1.5` in `release/v1.1.x`. |

## Hoodi Testnet (L1) Contract Changelog

This changelog tracks deployments of **Hoodi Testnet** contracts. This changelog is only valid from the `main` branch.

### Current Deployments

| Contract | Proxy Address | Initial Commit |
|-----------------------|----------------------------------------------|---------------------|
| ValidatorOptInRouter | `0xa380ba6d6083a4Cb2a3B62b0a81Ea8727861c13e` | `13cf068477e6efdbb5c4fe5ce53a11af30bf8b47` in 'main' |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I will be creating a new branch for the current release. I think we should use that here.

| VanillaRegistry | `0x536f0792c5d5ed592e67a9260606c85f59c312f0` | `13cf068477e6efdbb5c4fe5ce53a11af30bf8b47` in 'main' |
| MevCommitAVS | `0xdF8649d298ad05f019eE4AdBD6210867B8AB225F` | `13cf068477e6efdbb5c4fe5ce53a11af30bf8b47` in 'main' |
| MevCommitMiddleware | `0x8E847EC4a36c8332652aB3b2B7D5c54dE29c7fde` | `13cf068477e6efdbb5c4fe5ce53a11af30bf8b47` in 'main' |

### Upgrade History

| Timestamp (UTC) | Contract | New Impl Version | Commmit |
|-----------------------------|---------------------|-----------------------|-------------------|
| N/A | | | |


## L1 Deployer CLI

> **After completing any L1 deployment, immediately record it in the “Current Deployments” table above.**
Expand Down
2 changes: 1 addition & 1 deletion contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ cache_path = 'cache_forge'
ffi = true
ast = true
build_info = true
extra_output = ["storageLayout"]
extra_output = ["storageLayout"]
9 changes: 6 additions & 3 deletions contracts/l1-deployer-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ help() {
echo " deploy-router Deploy and verify the ValidatorOptInRouter contract to L1."
echo
echo "Required Options:"
echo " --chain, -c <chain> Specify the chain to deploy to ('mainnet' or 'holesky')."
echo " --chain, -c <chain> Specify the chain to deploy to ('mainnet', 'holesky', or 'hoodi')."
echo
echo "Wallet Options (exactly one required):"
echo " --keystore Use a keystore for deployment."
Expand Down Expand Up @@ -128,8 +128,8 @@ parse_args() {
exit 1
fi
chain="$2"
if [[ "$chain" != "mainnet" && "$chain" != "holesky" ]]; then
echo "Error: Unknown chain '$chain'. Valid options are 'mainnet' or 'holesky'."
if [[ "$chain" != "mainnet" && "$chain" != "holesky" && "$chain" != "hoodi" ]]; then
echo "Error: Unknown chain '$chain'. Valid options are 'mainnet', 'holesky', or hoodi."
exit 1
fi
shift 2
Expand Down Expand Up @@ -248,6 +248,9 @@ get_chain_params() {
elif [[ "$chain" == "holesky" ]]; then
chain_id=17000
deploy_contract="DeployHolesky"
elif [[ "$chain" == "hoodi" ]]; then
chain_id=560048
deploy_contract="DeployHoodi"
fi
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,25 @@ contract DeployHolesky is BaseDeploy {
vm.stopBroadcast();
}
}

contract DeployHoodi is BaseDeploy {
address constant public VANILLA_REGISTRY = 0x536F0792c5D5Ed592e67a9260606c85F59C312F0;
address constant public MEV_COMMIT_AVS = 0xdF8649d298ad05f019eE4AdBD6210867B8AB225F;
address constant public MEV_COMMIT_MIDDLEWARE = 0x8E847EC4a36c8332652aB3b2B7D5c54dE29c7fde;

//This is the most important field. On mainnet it'll be the primev multisig.
address constant public OWNER = 0x1623fE21185c92BB43bD83741E226288B516134a;

function run() external {
require(block.chainid == 560048, "must deploy on Hoodi");

vm.startBroadcast();
deployValidatorOptInRouter(
VANILLA_REGISTRY,
MEV_COMMIT_AVS,
MEV_COMMIT_MIDDLEWARE,
OWNER
);
vm.stopBroadcast();
}
}
18 changes: 18 additions & 0 deletions contracts/scripts/validator-registry/DeployVanillaRegistry.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,21 @@ contract DeployAnvil is BaseDeploy {
vm.stopBroadcast();
}
}

contract DeployHoodi is BaseDeploy {
uint256 constant public MIN_STAKE = 0.0001 ether; // 10k vals = 1 ETH cost
address constant public SLASH_ORACLE = 0x1623fE21185c92BB43bD83741E226288B516134a;
address constant public SLASH_RECEIVER = 0x1623fE21185c92BB43bD83741E226288B516134a;
uint256 constant public UNSTAKE_PERIOD_BLOCKS = 32 * 3; // 2 epoch finalization time + settlement buffer
uint256 constant public PAYOUT_PERIOD = 10000; // 10k * 12s = 1.39 days

// This is the most important field. On mainnet it'll be the primev multisig.
address constant public OWNER = 0x1623fE21185c92BB43bD83741E226288B516134a;

function run() external {
require(block.chainid == 560048, "must deploy on Hoodi");
vm.startBroadcast();
deployVanillaRegistry(MIN_STAKE, SLASH_ORACLE, SLASH_RECEIVER, UNSTAKE_PERIOD_BLOCKS, PAYOUT_PERIOD, OWNER);
vm.stopBroadcast();
}
}
48 changes: 46 additions & 2 deletions contracts/scripts/validator-registry/avs/DeployAVS.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/
import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol";
import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol";
import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol";
import {EigenHoleskyReleaseConsts} from "./ReleaseAddrConsts.sol";
import {EigenMainnetReleaseConsts} from "./ReleaseAddrConsts.sol";
import {EigenHoodiReleaseConsts, EigenHoleskyReleaseConsts, EigenMainnetReleaseConsts} from "./ReleaseAddrConsts.sol";
import {MainnetConstants} from "../../MainnetConstants.sol";

contract BaseDeploy is Script {
Expand Down Expand Up @@ -166,3 +165,48 @@ contract DeployHolesky is BaseDeploy {
vm.stopBroadcast();
}
}

contract DeployHoodi is BaseDeploy {
// This is the most important field. On mainnet it'll be the primev multisig.
address constant public OWNER = 0x1623fE21185c92BB43bD83741E226288B516134a;

IDelegationManager constant public DELEGATION_MANAGER = IDelegationManager(EigenHoodiReleaseConsts.DELEGATION_MANAGER);
IEigenPodManager constant public EIGENPOD_MANAGER = IEigenPodManager(EigenHoodiReleaseConsts.EIGENPOD_MANAGER);
IStrategyManager constant public STRATEGY_MANAGER = IStrategyManager(EigenHoodiReleaseConsts.STRATEGY_MANAGER);
IAVSDirectory constant public AVS_DIRECTORY = IAVSDirectory(EigenHoodiReleaseConsts.AVS_DIRECTORY);
address constant public FREEZE_ORACLE = 0x1623fE21185c92BB43bD83741E226288B516134a; // Temporary freeze oracle
uint256 constant public UNFREEZE_FEE = 0.1 ether;
address constant public UNFREEZE_RECEIVER = 0x1623fE21185c92BB43bD83741E226288B516134a; // Temporary unfreezeReceiver
uint256 constant public UNFREEZE_PERIOD_BLOCKS = 12000; // ~ 1 day
uint256 constant public OPERATOR_DEREG_PERIOD_BLOCKS = 12000; // ~ 1 day
uint256 constant public VALIDATOR_DEREG_PERIOD_BLOCKS = 32 * 3; // 2 epoch finalization time + settlement buffer
uint256 constant public LST_RESTARKER_DEREG_PERIOD_BLOCKS = 12000; // ~ 1 day

function run() external {
require(block.chainid == 560048, "must deploy on Hoodi");

address[] memory restakeableStrategies = new address[](5);
restakeableStrategies[0] = EigenHoodiReleaseConsts.STRATEGY_BASE_STETH;
restakeableStrategies[1] = EigenHoodiReleaseConsts.STRATEGY_BASE_WETH;
restakeableStrategies[3] = EigenHoodiReleaseConsts.STRATEGY_BASE_EIGEN;
restakeableStrategies[4] = EigenHoodiReleaseConsts.BEACON_CHAIN_ETH;

vm.startBroadcast();
deployMevCommitAVS(
OWNER,
DELEGATION_MANAGER,
EIGENPOD_MANAGER,
STRATEGY_MANAGER,
AVS_DIRECTORY,
restakeableStrategies,
FREEZE_ORACLE,
UNFREEZE_FEE,
UNFREEZE_RECEIVER,
UNFREEZE_PERIOD_BLOCKS,
OPERATOR_DEREG_PERIOD_BLOCKS,
VALIDATOR_DEREG_PERIOD_BLOCKS,
LST_RESTARKER_DEREG_PERIOD_BLOCKS
);
vm.stopBroadcast();
}
}
26 changes: 26 additions & 0 deletions contracts/scripts/validator-registry/avs/ReleaseAddrConsts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,29 @@ library EigenHoleskyReleaseConsts {
address internal constant STRATEGY_BASE_ANKRETH = 0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac;
address internal constant BEACON_CHAIN_ETH = 0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0;
}

/// @notice Constants from https://github.com/Layr-Labs/eigenlayer-contracts?tab=readme-ov-file#current-testnet-deployment
/// @notice Last updated 07-25-2025 — for HOODI testnet
library EigenHoodiReleaseConsts {
// Core
address internal constant DELEGATION_MANAGER = 0x867837a9722C512e0862d8c2E15b8bE220E8b87d;
address internal constant STRATEGY_MANAGER = 0xeE45e76ddbEDdA2918b8C7E3035cd37Eab3b5D41;
address internal constant EIGENPOD_MANAGER = 0xcd1442415Fc5C29Aa848A49d2e232720BE07976c;
address internal constant AVS_DIRECTORY = 0xD58f6844f79eB1fbd9f7091d05f7cb30d3363926;
address internal constant REWARDS_COORDINATOR = 0x29e8572678e0c272350aa0b4B8f304E47EBcd5e7;
address internal constant ALLOCATION_MANAGER = 0x95a7431400F362F3647a69535C5666cA0133CAA0;
address internal constant PERMISSION_CONTROLLER = 0xdcCF401fD121d8C542E96BC1d0078884422aFAD2;

// Strategies - Deployed via StrategyFactory
address internal constant STRATEGY_FACTORY = 0xfB7d94501E4d4ACC264833Ef4ede70a11517422B;
address internal constant STRATEGY_BASE = 0x6d28cEC1659BC3a9BC814c3EFc1412878B406579;
address internal constant STRATEGY_BASE_STETH = 0xF8a1a66130D614c7360e868576D5E59203475FE0;
address internal constant STRATEGY_BASE_WETH = 0x24579aD4fe83aC53546E5c2D3dF5F85D6383420d;
// Special strategies
address internal constant STRATEGY_BASE_EIGEN = 0xB27b10291DBFE6576d17afF3e251c954Ae14f1D3;
// Beacon Chain ETH placeholder (not a real contract)
address internal constant BEACON_CHAIN_ETH = 0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0;
// Tokens
address internal constant EIGEN_TOKEN = 0x8ae2520954db7D80D66835cB71E692835bbA45bf;
address internal constant BACKING_EIGEN = 0x6e60888132Cc7e637488379B4B40c42b3751f63a;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
import {MevCommitMiddleware} from "../../../contracts/validator-registry/middleware/MevCommitMiddleware.sol";
import {IRegistry} from "symbiotic-core/interfaces/common/IRegistry.sol";
import {INetworkRegistry} from "symbiotic-core/interfaces/INetworkRegistry.sol";
import {SymbioticHoleskyDevnetConsts, SymbioticMainnetConsts} from "./ReleaseAddrConsts.s.sol";
import {SymbioticHoodiDevnetConsts, SymbioticHoleskyDevnetConsts, SymbioticMainnetConsts} from "./ReleaseAddrConsts.s.sol";
import {IBaseDelegator} from "symbiotic-core/interfaces/delegator/IBaseDelegator.sol";
import {INetworkMiddlewareService} from "symbiotic-core/interfaces/service/INetworkMiddlewareService.sol";
import {MainnetConstants} from "../../MainnetConstants.sol";
Expand Down Expand Up @@ -163,3 +163,64 @@ contract DeployHolesky is BaseDeploy {
vm.stopBroadcast();
}
}


contract DeployHoodi is BaseDeploy {

IRegistry constant public NETWORK_REGISTRY = IRegistry(SymbioticHoodiDevnetConsts.NETWORK_REGISTRY);
IRegistry constant public OPERATOR_REGISTRY = IRegistry(SymbioticHoodiDevnetConsts.OPERATOR_REGISTRY);
IRegistry constant public VAULT_FACTORY = IRegistry(SymbioticHoodiDevnetConsts.VAULT_FACTORY);
IRegistry constant public DELEGATOR_FACTORY = IRegistry(SymbioticHoodiDevnetConsts.DELEGATOR_FACTORY);
IRegistry constant public SLASHER_FACTORY = IRegistry(SymbioticHoodiDevnetConsts.SLASHER_FACTORY);
IRegistry constant public BURNER_ROUTER_FACTORY = IRegistry(SymbioticHoodiDevnetConsts.BURNER_ROUTER_FACTORY);

// On Hoodi, use dev keystore account. On mainnet these will be the primev multisig.
address constant public EXPECTED_MSG_SENDER = 0x1623fE21185c92BB43bD83741E226288B516134a;
address constant public OWNER = EXPECTED_MSG_SENDER;
address constant public NETWORK = EXPECTED_MSG_SENDER;
address constant public SLASH_ORACLE = EXPECTED_MSG_SENDER; // Temporary placeholder until oracle implements slashing.
address constant public SLASH_RECEIVER = EXPECTED_MSG_SENDER;
uint256 constant public MIN_BURNER_ROUTER_DELAY = 2 days;

uint96 constant public SUBNETWORK_ID = 1;
uint256 constant public VAULT1_MAX_NETWORK_LIMIT = 100000 ether;
uint256 constant public SLASH_PERIOD_SECONDS = 1 days; // compiles to seconds

function run() external {
require(block.chainid == 560048, "must deploy on Hoodi");
require(msg.sender == EXPECTED_MSG_SENDER, "incorrect msg.sender");

vm.startBroadcast();

INetworkRegistry networkRegistry = INetworkRegistry(address(NETWORK_REGISTRY));
if (!networkRegistry.isEntity(NETWORK)) {
networkRegistry.registerNetwork();
}

address mevCommitMiddlewareProxy = deployMevCommitMiddleware(
NETWORK_REGISTRY,
OPERATOR_REGISTRY,
VAULT_FACTORY,
DELEGATOR_FACTORY,
SLASHER_FACTORY,
BURNER_ROUTER_FACTORY,
NETWORK,
SLASH_PERIOD_SECONDS,
SLASH_ORACLE,
SLASH_RECEIVER,
MIN_BURNER_ROUTER_DELAY,
OWNER
);

INetworkMiddlewareService networkMiddlewareService = INetworkMiddlewareService(address(SymbioticHoodiDevnetConsts.NETWORK_MIDDLEWARE_SERVICE));
if (networkMiddlewareService.middleware(msg.sender) != address(0)) {
console.log("WARNING: overwriting existing middleware registration for network:", msg.sender);
}
networkMiddlewareService.setMiddleware(mevCommitMiddlewareProxy);

// No Hoodi Vaults in Symbiotic docs so hold off on Vault registration
// One created here but not verified or used: https://hoodi.etherscan.io/tx/0x3f9e9651b912bf9ac85bfe8e852183f062049b4410a7a94f7dffececb92140bb

vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,23 @@ library SymbioticHoleskyDevnetConsts {

address internal constant BURNER_ROUTER_FACTORY = 0x32e2AfbdAffB1e675898ABA75868d92eE1E68f3b;
}

/// @notice Constants from https://docs.symbiotic.fi/deployments/testnet#hoodi
/// @notice Last updated 07-25-2025
library SymbioticHoodiDevnetConsts {
address internal constant VAULT_FACTORY = 0x407A039D94948484D356eFB765b3c74382A050B4;
address internal constant DELEGATOR_FACTORY = 0x890CA3f95E0f40a79885B7400926544B2214B03f;
address internal constant SLASHER_FACTORY = 0xbf34bf75bb779c383267736c53a4ae86ac7bB299;
address internal constant NETWORK_REGISTRY = 0x7d03b7343BF8d5cEC7C0C27ecE084a20113D15C9;

address internal constant NETWORK_MIDDLEWARE_SERVICE = 0x62a1ddfD86b4c1636759d9286D3A0EC722D086e3;
address internal constant OPERATOR_REGISTRY = 0x6F75a4ffF97326A00e52662d82EA4FdE86a2C548;

address internal constant VAULT_OPT_IN_SERVICE = 0x95CC0a052ae33941877c9619835A233D21D57351;
address internal constant NETWORK_OPT_IN_SERVICE = 0x58973d16FFA900D11fC22e5e2B6840d9f7e13401;
address internal constant VAULT_CONFIGURATOR = 0x94c344E816A53D07fC4c7F4a18f82b6Da87CFc8f;
address internal constant DEFAULT_STAKER_REWARDS_FACTORY = 0x1eA0b919721C20dae19aBc4391850D94eDbe9b1c;
address internal constant DEFAULT_OPERATOR_REWARDS_FACTORY = 0xE7e597655C3F76117302ea6103f5F2B3F3D75c5d;

address internal constant BURNER_ROUTER_FACTORY = 0xF619c99D166224B4AC008b14Cc67ac72C2E91D8a;
}
Loading