From a3967a4dc9f10934b3297ea87f20efcf13b4a916 Mon Sep 17 00:00:00 2001 From: Jonas Bostoen Date: Tue, 21 Jan 2025 15:24:00 +0100 Subject: [PATCH] feat(contracts/symbiotic): pull in changes --- .../contracts/BoltSymbioticMiddlewareV1.sol | 9 +++- .../holesky/contracts/OperatorsRegistryV1.sol | 46 +++++++++++++------ .../interfaces/IBoltRestakingMiddlewareV1.sol | 14 ++++++ .../interfaces/IOperatorsRegistryV1.sol | 2 +- .../src/holesky/lib/OperatorsLibV1.sol | 2 +- .../test/holesky/OperatorsRegistryV1.t.sol | 2 +- .../test/holesky/SymbioticMiddleware.t.sol | 6 +-- 7 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 smart-contracts/src/holesky/interfaces/IBoltRestakingMiddlewareV1.sol diff --git a/smart-contracts/src/holesky/contracts/BoltSymbioticMiddlewareV1.sol b/smart-contracts/src/holesky/contracts/BoltSymbioticMiddlewareV1.sol index 51255ca..04bb13c 100644 --- a/smart-contracts/src/holesky/contracts/BoltSymbioticMiddlewareV1.sol +++ b/smart-contracts/src/holesky/contracts/BoltSymbioticMiddlewareV1.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -22,6 +22,7 @@ import {INetworkMiddlewareService} from "@symbiotic/core/interfaces/service/INet import {PauseableEnumerableSet} from "@symbiotic/middleware-sdk/libraries/PauseableEnumerableSet.sol"; import {IOperatorsRegistryV1} from "../interfaces/IOperatorsRegistryV1.sol"; +import {IBoltRestakingMiddlewareV1} from "../interfaces/IBoltRestakingMiddlewareV1.sol"; /** * @title SymbioticMiddlewareV1 @@ -35,7 +36,7 @@ import {IOperatorsRegistryV1} from "../interfaces/IOperatorsRegistryV1.sol"; * For more information on extensions, see . * All public view functions are implemented in the `BaseMiddlewareReader`: */ -contract BoltSymbioticMiddlewareV1 is OwnableUpgradeable, UUPSUpgradeable { +contract BoltSymbioticMiddlewareV1 is IBoltRestakingMiddlewareV1, OwnableUpgradeable, UUPSUpgradeable { using Subnetwork for address; using EnumerableSet for EnumerableSet.AddressSet; using EnumerableMap for EnumerableMap.AddressToAddressMap; @@ -46,6 +47,9 @@ contract BoltSymbioticMiddlewareV1 is OwnableUpgradeable, UUPSUpgradeable { // Most of these constants replicate view methods in the BaseMiddlewareReader. // See for more information. + /// @notice The name hash of this middleware. + bytes32 public NAME_HASH; + /// @notice The timestamp of the first epoch (when this contract gets initialized). uint48 public START_TIMESTAMP; @@ -147,6 +151,7 @@ contract BoltSymbioticMiddlewareV1 is OwnableUpgradeable, UUPSUpgradeable { OPERATOR_REGISTRY = operatorRegistry; OPERATOR_NET_OPTIN = operatorNetOptin; START_TIMESTAMP = _now(); + NAME_HASH = keccak256("SYMBIOTIC"); } function _authorizeUpgrade( diff --git a/smart-contracts/src/holesky/contracts/OperatorsRegistryV1.sol b/smart-contracts/src/holesky/contracts/OperatorsRegistryV1.sol index f752d54..25b68fd 100644 --- a/smart-contracts/src/holesky/contracts/OperatorsRegistryV1.sol +++ b/smart-contracts/src/holesky/contracts/OperatorsRegistryV1.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; +import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; import {IOperatorsRegistryV1} from "../interfaces/IOperatorsRegistryV1.sol"; +import {IBoltRestakingMiddlewareV1} from "../interfaces/IBoltRestakingMiddlewareV1.sol"; import {OperatorsLibV1} from "../lib/OperatorsLibV1.sol"; /// @title OperatorsRegistryV1 @@ -12,14 +14,20 @@ import {OperatorsLibV1} from "../lib/OperatorsLibV1.sol"; contract OperatorsRegistryV1 is OwnableUpgradeable, UUPSUpgradeable, IOperatorsRegistryV1 { using OperatorsLibV1 for OperatorsLibV1.OperatorMap; + /// @notice The start timestamp of the contract, used as reference for time-based operations + uint48 public START_TIMESTAMP; + + /// @notice The duration of an epoch in seconds, used for delaying opt-in/out operations + uint48 public EPOCH_DURATION; + /// @notice The set of bolt operators, indexed by their signer address OperatorsLibV1.OperatorMap private OPERATORS; /// @notice the address of the EigenLayer restaking middleware - address public EIGENLAYER_RESTAKING_MIDDLEWARE; + IBoltRestakingMiddlewareV1 public EIGENLAYER_RESTAKING_MIDDLEWARE; /// @notice The address of the Symbiotic restaking middleware - address public SYMBIOTIC_RESTAKING_MIDDLEWARE; + IBoltRestakingMiddlewareV1 public SYMBIOTIC_RESTAKING_MIDDLEWARE; /** * @dev This empty reserved space is put in place to allow future versions to add new @@ -29,16 +37,17 @@ contract OperatorsRegistryV1 is OwnableUpgradeable, UUPSUpgradeable, IOperatorsR * * Total storage slots: 50 */ - uint256[45] private __gap; + uint256[43] private __gap; // ========= Initializer & Proxy functionality ========= // /// @notice Initialize the contract /// @param owner The address of the owner - function initialize( - address owner - ) public initializer { + function initialize(address owner, uint48 epochDuration) public initializer { __Ownable_init(owner); + + START_TIMESTAMP = uint48(block.timestamp); + EPOCH_DURATION = epochDuration; } /// @notice Upgrade the contract @@ -59,15 +68,23 @@ contract OperatorsRegistryV1 is OwnableUpgradeable, UUPSUpgradeable, IOperatorsR _; } + // ========= Public helpers ========= // + + /// @notice Returns the timestamp of when the current epoch started + function getCurrentEpochStartTimestamp() public view returns (uint48) { + uint48 currentEpoch = (Time.timestamp() - START_TIMESTAMP) / EPOCH_DURATION; + return START_TIMESTAMP + currentEpoch * EPOCH_DURATION; + } + // ========= Operators functions ========= // // // The operator lifecycle looks as follows: // 1. Register, and become active immediately. The operator can then manage their - // restaking positions through the EL AllocationManager contract. - // 2. Pause, and become inactive (with a delay). The operator won't be slashable anymore, + // restaking positions through the restaking protocol. + // 2. Pause, and become inactive. After a delay, the operator won't be slashable anymore, // but they can still manage and rebalance their positions. - // 3. Unpause, and become active again (with a delay). The operator can be slashed again. - // 4. Deregister, and become inactive (with a delay). The operator won't be part of the AVS anymore. + // 3. Unpause, and become active again. After a delay, the operator can be slashed again. + // 4. Deregister, and become inactive. After a delay, the operator won't be part of the AVS anymore. /// @notice Register an operator in the registry /// @param signer The address of the operator @@ -151,8 +168,11 @@ contract OperatorsRegistryV1 is OwnableUpgradeable, UUPSUpgradeable, IOperatorsR /// @notice Update the address of a restaking middleware contract address /// @param restakingProtocol The name of the restaking protocol /// @param newMiddleware The address of the new restaking middleware - function updateRestakingMiddleware(string calldata restakingProtocol, address newMiddleware) public onlyOwner { - require(newMiddleware != address(0), "Invalid middleware address"); + function updateRestakingMiddleware( + string calldata restakingProtocol, + IBoltRestakingMiddlewareV1 newMiddleware + ) public onlyOwner { + require(address(newMiddleware) != address(0), "Invalid middleware address"); bytes32 protocolNameHash = keccak256(abi.encodePacked(restakingProtocol)); diff --git a/smart-contracts/src/holesky/interfaces/IBoltRestakingMiddlewareV1.sol b/smart-contracts/src/holesky/interfaces/IBoltRestakingMiddlewareV1.sol new file mode 100644 index 0000000..96bacc6 --- /dev/null +++ b/smart-contracts/src/holesky/interfaces/IBoltRestakingMiddlewareV1.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/// @title IBoltRestakingMiddlewareV1 +/// @notice An interface for generalized restaking protocol middlewares in Bolt +interface IBoltRestakingMiddlewareV1 { + function NAME_HASH() external view returns (bytes32); + + function getOperatorCollaterals( + address operator + ) external view returns (address[] memory, uint256[] memory); + + function getOperatorStake(address operator, address collateral) external view returns (uint256); +} diff --git a/smart-contracts/src/holesky/interfaces/IOperatorsRegistryV1.sol b/smart-contracts/src/holesky/interfaces/IOperatorsRegistryV1.sol index 343c899..b62da67 100644 --- a/smart-contracts/src/holesky/interfaces/IOperatorsRegistryV1.sol +++ b/smart-contracts/src/holesky/interfaces/IOperatorsRegistryV1.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; /// @title IOperatorsRegistryV1 /// @notice An interface for the OperatorsRegistryV1 contract diff --git a/smart-contracts/src/holesky/lib/OperatorsLibV1.sol b/smart-contracts/src/holesky/lib/OperatorsLibV1.sol index c3e248c..bd1cec7 100644 --- a/smart-contracts/src/holesky/lib/OperatorsLibV1.sol +++ b/smart-contracts/src/holesky/lib/OperatorsLibV1.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; import {PauseableEnumerableSet} from "@symbiotic/middleware-sdk/libraries/PauseableEnumerableSet.sol"; diff --git a/smart-contracts/test/holesky/OperatorsRegistryV1.t.sol b/smart-contracts/test/holesky/OperatorsRegistryV1.t.sol index bb46be8..5ddf660 100644 --- a/smart-contracts/test/holesky/OperatorsRegistryV1.t.sol +++ b/smart-contracts/test/holesky/OperatorsRegistryV1.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; import {Test, console} from "forge-std/Test.sol"; import {OperatorsRegistryV1} from "../../src/holesky/contracts/OperatorsRegistryV1.sol"; diff --git a/smart-contracts/test/holesky/SymbioticMiddleware.t.sol b/smart-contracts/test/holesky/SymbioticMiddleware.t.sol index 4cfa704..1f5d0be 100644 --- a/smart-contracts/test/holesky/SymbioticMiddleware.t.sol +++ b/smart-contracts/test/holesky/SymbioticMiddleware.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.27; import {Test, console} from "forge-std/Test.sol"; @@ -51,11 +51,11 @@ contract SymbioticMiddlewareTest is Test { vm.startPrank(admin); registry = new OperatorsRegistryV1(); - registry.initialize(admin); + registry.initialize(admin, 1 days); middleware = new BoltSymbioticMiddlewareV1(); // Set the restaking middleware - registry.updateRestakingMiddleware("SYMBIOTIC", address(middleware)); + registry.updateRestakingMiddleware("SYMBIOTIC", middleware); vm.stopPrank();