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
79 changes: 79 additions & 0 deletions src/contracts/core/ProtocolRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";
import "./ProtocolRegistryStorage.sol";

contract ProtocolRegistry is Initializable, OwnableUpgradeable, ProtocolRegistryStorage {
using ShortStringsUpgradeable for *;

/**
*
* INITIALIZING FUNCTIONS
*
*/
constructor() {
_disableInitializers();
}

/// @inheritdoc IProtocolRegistry
function initialize(
address initialOwner
) external initializer {
_transferOwnership(initialOwner);
}

/**
*
* INITIALIZING FUNCTIONS
*
*/

/// @inheritdoc IProtocolRegistry
function setVersion(address addr, string calldata semver) external onlyOwner {
_setVersion(addr, semver);
}

/// @inheritdoc IProtocolRegistry
function setVersions(address[] calldata addresses, string calldata semver) external onlyOwner {
for (uint256 i = 0; i < addresses.length; ++i) {
_setVersion(addresses[i], semver);
}
}

/// @inheritdoc IProtocolRegistry
function setVersions(address[] calldata addresses, string[] calldata semvers) external onlyOwner {
require(addresses.length == semvers.length, InputArrayLengthMismatch());
for (uint256 i = 0; i < addresses.length; ++i) {
_setVersion(addresses[i], semvers[i]);
}
}

/// @dev Internal function to set the version for a given address.
function _setVersion(address addr, string calldata semver) internal {
_semver[addr] = semver.toShortString();
emit VersionSet(addr, semver);
}

/**
*
* VIEW FUNCTIONS
*
*/

/// @inheritdoc IProtocolRegistry
function version(
address addr
) external view returns (string memory) {
return _semver[addr].toString();
}

/// @inheritdoc IProtocolRegistry
function majorVersion(
address addr
) external view returns (string memory) {
bytes memory v = bytes(_semver[addr].toString());
return string(abi.encodePacked(v[0]));
}
}
17 changes: 17 additions & 0 deletions src/contracts/core/ProtocolRegistryStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import "@openzeppelin-upgrades/contracts/utils/ShortStringsUpgradeable.sol";
import "../interfaces/IProtocolRegistry.sol";

abstract contract ProtocolRegistryStorage is IProtocolRegistry {
/// @notice Mapping from an address to its semantic version.
mapping(address addr => ShortString semver) internal _semver;

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
68 changes: 68 additions & 0 deletions src/contracts/interfaces/IProtocolRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

interface IProtocolRegistryErrors {
/// @notice Thrown when two array parameters have mismatching lengths.
error InputArrayLengthMismatch();
}

interface IProtocolRegistryTypes {}

interface IProtocolRegistryEvents is IProtocolRegistryTypes {
/// @notice Emitted when the version is set for a given address.
/// @param addr The address for which the version is set.
/// @param semver The semantic version string set for the address.
event VersionSet(address indexed addr, string semver);
}

interface IProtocolRegistry is IProtocolRegistryErrors, IProtocolRegistryEvents {
/**
* @notice Initializes the ProtocolRegistry with the initial owner.
* @param initialOwner The address to set as the initial owner.
*/
function initialize(
address initialOwner
) external;

/**
* @notice Sets the semantic version for a single address.
* @dev Only callable by the contract owner.
* @param addr The address for which to set the version.
* @param semver The semantic version string to set for the address.
*/
function setVersion(address addr, string calldata semver) external;

/**
* @notice Sets the same semantic version for each address in the provided array.
* @dev Only callable by the contract owner.
* @param addresses The addresses for which to set the version.
* @param semver The semantic version string to set for all addresses.
*/
function setVersions(address[] calldata addresses, string calldata semver) external;

/**
* @notice Sets a distinct semantic version for each address in the provided array.
* @dev Only callable by the contract owner.
* @param addresses The addresses for which to set the version.
* @param semvers The semantic version strings to set, one for each address.
*/
function setVersions(address[] calldata addresses, string[] calldata semvers) external;

/**
* @notice Returns the semantic version string for a given address.
* @param addr The address to query.
* @return The semantic version string associated with the address.
*/
function version(
address addr
) external view returns (string memory);

/**
* @notice Returns the major version string for a given address.
* @param addr The address to query.
* @return The major version string associated with the address.
*/
function majorVersion(
address addr
) external view returns (string memory);
}
4 changes: 1 addition & 3 deletions src/test/harnesses/EigenPodHarness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import "../../contracts/pods/EigenPod.sol";
import "forge-std/Test.sol";

contract EigenPodHarness is EigenPod {
constructor(IETHPOSDeposit _ethPOS, IEigenPodManager _eigenPodManager)
EigenPod(_ethPOS, _eigenPodManager)
{}
constructor(IETHPOSDeposit _ethPOS, IEigenPodManager _eigenPodManager) EigenPod(_ethPOS, _eigenPodManager) {}

function getActiveValidatorCount() public view returns (uint) {
return activeValidatorCount;
Expand Down
9 changes: 3 additions & 6 deletions src/test/harnesses/EigenPodManagerWrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import "../../contracts/pods/EigenPodManager.sol";

///@notice This contract exposes a manual setter for podShares in order to initialize podShares as negative
contract EigenPodManagerWrapper is EigenPodManager {
constructor(
IETHPOSDeposit _ethPOS,
IBeacon _eigenPodBeacon,
IDelegationManager _delegationManager,
IPauserRegistry _pauserRegistry
) EigenPodManager(_ethPOS, _eigenPodBeacon, _delegationManager, _pauserRegistry) {}
constructor(IETHPOSDeposit _ethPOS, IBeacon _eigenPodBeacon, IDelegationManager _delegationManager, IPauserRegistry _pauserRegistry)
EigenPodManager(_ethPOS, _eigenPodBeacon, _delegationManager, _pauserRegistry)
{}

function setPodOwnerShares(address owner, IEigenPod pod) external {
ownerToPod[owner] = pod;
Expand Down
10 changes: 2 additions & 8 deletions src/test/integration/IntegrationDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
/// Deploy an implementation contract for each contract in the system
function _deployImplementations() public {
allocationManagerImplementation = new AllocationManager(
delegationManager,
eigenStrategy,
eigenLayerPauserReg,
permissionController,
DEALLOCATION_DELAY,
ALLOCATION_CONFIGURATION_DELAY
delegationManager, eigenStrategy, eigenLayerPauserReg, permissionController, DEALLOCATION_DELAY, ALLOCATION_CONFIGURATION_DELAY
);
permissionControllerImplementation = new PermissionController();
delegationManagerImplementation = new DelegationManager(
Expand Down Expand Up @@ -363,8 +358,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
})
);
avsDirectoryImplementation = new AVSDirectory(delegationManager, eigenLayerPauserReg, version);
eigenPodManagerImplementation =
new EigenPodManager(DEPOSIT_CONTRACT, eigenPodBeacon, delegationManager, eigenLayerPauserReg);
eigenPodManagerImplementation = new EigenPodManager(DEPOSIT_CONTRACT, eigenPodBeacon, delegationManager, eigenLayerPauserReg);
strategyFactoryImplementation = new StrategyFactory(strategyManager, eigenLayerPauserReg);

// Beacon implementations
Expand Down
3 changes: 1 addition & 2 deletions src/test/unit/BN254CertificateVerifierUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ contract BN254CertificateVerifierUnitTests is
defaultOperatorSetConfig = OperatorSetConfig({owner: operatorSetOwner, maxStalenessPeriod: defaultMaxStaleness});

// Deploy Contracts
bn254CertificateVerifierImplementation =
new BN254CertificateVerifier(IOperatorTableUpdater(address(operatorTableUpdaterMock)));
bn254CertificateVerifierImplementation = new BN254CertificateVerifier(IOperatorTableUpdater(address(operatorTableUpdaterMock)));
verifier = BN254CertificateVerifier(
address(new TransparentUpgradeableProxy(address(bn254CertificateVerifierImplementation), address(eigenLayerProxyAdmin), ""))
);
Expand Down
15 changes: 6 additions & 9 deletions src/test/unit/EigenPodManagerUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ contract EigenPodManagerUnitTests_ShareUpdateTests is EigenPodManagerUnitTests {
super.setUp();

// Upgrade eigenPodManager to wrapper
eigenPodManagerWrapper = new EigenPodManagerWrapper(
ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry
);
eigenPodManagerWrapper =
new EigenPodManagerWrapper(ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry);
eigenLayerProxyAdmin.upgrade(ITransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerWrapper));
}

Expand Down Expand Up @@ -424,9 +423,8 @@ contract EigenPodManagerUnitTests_WithdrawSharesAsTokensTests is EigenPodManager
super.setUp();

// Upgrade eigenPodManager to wrapper
eigenPodManagerWrapper = new EigenPodManagerWrapper(
ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry
);
eigenPodManagerWrapper =
new EigenPodManagerWrapper(ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry);
eigenLayerProxyAdmin.upgrade(ITransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerWrapper));
}
/**
Expand Down Expand Up @@ -545,9 +543,8 @@ contract EigenPodManagerUnitTests_BeaconChainETHBalanceUpdateTests is EigenPodMa
super.setUp();

// Upgrade eigenPodManager to wrapper
eigenPodManagerWrapper = new EigenPodManagerWrapper(
ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry
);
eigenPodManagerWrapper =
new EigenPodManagerWrapper(ethPOSMock, eigenPodBeacon, IDelegationManager(address(delegationManagerMock)), pauserRegistry);
eigenLayerProxyAdmin.upgrade(ITransparentUpgradeableProxy(payable(address(eigenPodManager))), address(eigenPodManagerWrapper));
}

Expand Down
15 changes: 5 additions & 10 deletions src/test/unit/TaskMailboxUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1249,8 +1249,7 @@ contract TaskMailboxUnitTests_submitResult is TaskMailboxUnitTests {

// Deploy a new TaskMailbox with the failing verifier using proxy pattern
ProxyAdmin proxyAdmin = new ProxyAdmin();
TaskMailbox taskMailboxImpl =
new TaskMailbox(address(mockFailingVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TaskMailbox taskMailboxImpl = new TaskMailbox(address(mockFailingVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(taskMailboxImpl),
address(proxyAdmin),
Expand Down Expand Up @@ -3270,8 +3269,7 @@ contract TaskMailboxUnitTests_Upgradeable is TaskMailboxUnitTests {

function test_Implementation_CannotBeInitialized() public {
// Deploy a new implementation
TaskMailbox newImpl =
new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TaskMailbox newImpl = new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);

// Try to initialize the implementation directly, should revert
vm.expectRevert("Initializable: contract is already initialized");
Expand All @@ -3282,8 +3280,7 @@ contract TaskMailboxUnitTests_Upgradeable is TaskMailboxUnitTests {
address newOwner = address(0x1234);

// Deploy new implementation with different version
TaskMailbox newImpl =
new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TaskMailbox newImpl = new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);

// Upgrade proxy to new implementation
proxyAdmin.upgrade(ITransparentUpgradeableProxy(address(taskMailbox)), address(newImpl));
Expand All @@ -3296,8 +3293,7 @@ contract TaskMailboxUnitTests_Upgradeable is TaskMailboxUnitTests {
address attacker = address(0x9999);

// Deploy new implementation
TaskMailbox newImpl =
new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TaskMailbox newImpl = new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);

// Try to upgrade from non-owner, should revert
vm.prank(attacker);
Expand Down Expand Up @@ -3331,8 +3327,7 @@ contract TaskMailboxUnitTests_Upgradeable is TaskMailboxUnitTests {
assertEq(address(retrievedConfig.taskHook), address(config.taskHook));

// Deploy new implementation
TaskMailbox newImpl =
new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);
TaskMailbox newImpl = new TaskMailbox(address(mockBN254CertificateVerifier), address(mockECDSACertificateVerifier), MAX_TASK_SLA);

// Upgrade
vm.prank(address(this)); // proxyAdmin owner
Expand Down