mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 09:50:01 +00:00
In this PR:
1. Implement application-specific functionalities in the
`DataHavenServiceManager` contract:
1. Registering of 3 operator sets: Validators, BSPs and MSPs.
2. Allowlisted sign up of operators.
3. Integration with Snowbridge to send message of new validator set.
2. Basic testing of the above functionalities.
3. Tests now use less mocked contracts (especially from EigenLayer).
4. Refactor of `SignUpOperator` script, which now supports the three
kinds of Operator sets.
164 lines
6.7 KiB
Solidity
164 lines
6.7 KiB
Solidity
// SPDX-License-Identifier: UNLICENSED
|
|
pragma solidity ^0.8.27;
|
|
|
|
// EigenLayer imports
|
|
import {IAllocationManagerTypes} from
|
|
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
|
|
import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol";
|
|
|
|
// OpenZeppelin imports
|
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
|
// Testing imports
|
|
import {Script} from "forge-std/Script.sol";
|
|
import {console} from "forge-std/console.sol";
|
|
import {Logging} from "../utils/Logging.sol";
|
|
import {ELScriptStorage} from "../utils/ELScriptStorage.s.sol";
|
|
import {DHScriptStorage} from "../utils/DHScriptStorage.s.sol";
|
|
import {Accounts} from "../utils/Accounts.sol";
|
|
|
|
/**
|
|
* @title SignUpOperatorBase
|
|
* @notice Base contract for signing up different types of operators (Validators, BSPs, MSPs)
|
|
*/
|
|
abstract contract SignUpOperatorBase is Script, ELScriptStorage, DHScriptStorage, Accounts {
|
|
// Progress indicator
|
|
uint16 public deploymentStep = 0;
|
|
uint16 public totalSteps = 3; // Total major steps
|
|
|
|
function _logProgress() internal {
|
|
deploymentStep++;
|
|
Logging.logProgress(deploymentStep, totalSteps);
|
|
}
|
|
|
|
/**
|
|
* @notice Abstract method to be implemented by derived contracts to get the operator set ID
|
|
* @return The operator set ID for the specific type (Validator, BSP, MSP)
|
|
*/
|
|
function _getOperatorSetId() internal view virtual returns (uint32);
|
|
|
|
/**
|
|
* @notice Abstract method to be implemented by derived contracts to add operator to allowlist
|
|
*/
|
|
function _addToAllowlist() internal virtual;
|
|
|
|
/**
|
|
* @notice Abstract method to get the operator type name (for logging)
|
|
* @return The name of the operator type
|
|
*/
|
|
function _getOperatorTypeName() internal view virtual returns (string memory);
|
|
|
|
function run() public {
|
|
string memory network = vm.envOr("NETWORK", string("anvil"));
|
|
Logging.logHeader(string.concat("SIGN UP DATAHAVEN ", _getOperatorTypeName()));
|
|
console.log("| Network: %s", network);
|
|
console.log("| Timestamp: %s", vm.toString(block.timestamp));
|
|
Logging.logFooter();
|
|
|
|
// Read addresses of latest deployment of EigenLayer contracts, for the given network.
|
|
_loadELContracts(network);
|
|
Logging.logInfo(string.concat("Loaded EigenLayer contracts for network: ", network));
|
|
|
|
// Read addresses of latest deployment of DataHaven contracts, for the given network.
|
|
_loadDHContracts(network);
|
|
Logging.logInfo(string.concat("Loaded DataHaven contracts for network: ", network));
|
|
|
|
_logProgress();
|
|
|
|
// STEP 1: Stake tokens into strategies
|
|
Logging.logSection("Staking Tokens into Strategies");
|
|
|
|
// Get the deployed strategies and deposit some of the operator's balance into them.
|
|
for (uint256 i = 0; i < deployedStrategies.length; i++) {
|
|
IERC20 linkedToken = StrategyBase(deployedStrategies[i]).underlyingToken();
|
|
|
|
// Check that the operator has a balance of the linked token.
|
|
uint256 balance = linkedToken.balanceOf(_operator);
|
|
Logging.logInfo(
|
|
string.concat(
|
|
"Strategy ",
|
|
vm.toString(i),
|
|
" underlying token: ",
|
|
vm.toString(address(linkedToken)),
|
|
" - Operator balance: ",
|
|
vm.toString(balance)
|
|
)
|
|
);
|
|
|
|
require(balance > 0, "Operator does not have a balance of the linked token");
|
|
|
|
// Stake some of the operator's balance as stake for the strategy.
|
|
vm.startBroadcast(_operatorPrivateKey);
|
|
uint256 balanceToStake = balance / 10;
|
|
linkedToken.approve(address(strategyManager), balanceToStake);
|
|
strategyManager.depositIntoStrategy(deployedStrategies[i], linkedToken, balanceToStake);
|
|
vm.stopBroadcast();
|
|
|
|
Logging.logStep(
|
|
string.concat(
|
|
"Staked ", vm.toString(balanceToStake), " tokens for strategy ", vm.toString(i)
|
|
)
|
|
);
|
|
}
|
|
_logProgress();
|
|
|
|
// STEP 2: Register as an operator in EigenLayer
|
|
Logging.logSection("Registering as EigenLayer Operator");
|
|
|
|
// Register the operator as an operator.
|
|
// We don't set a delegation approver, so that there is no need to sign any messages.
|
|
address initDelegationApprover = address(0);
|
|
uint32 allocationDelay = 0;
|
|
string memory metadataURI = "";
|
|
vm.broadcast(_operatorPrivateKey);
|
|
delegation.registerAsOperator(initDelegationApprover, allocationDelay, metadataURI);
|
|
Logging.logStep(
|
|
string.concat("Registered operator in EigenLayer: ", vm.toString(_operator))
|
|
);
|
|
|
|
// Check the staked balance of the operator.
|
|
Logging.logSection("Operator Shares Information");
|
|
for (uint256 i = 0; i < deployedStrategies.length; i++) {
|
|
uint256 operatorShares = delegation.operatorShares(_operator, deployedStrategies[i]);
|
|
Logging.logInfo(
|
|
string.concat(
|
|
"Operator shares for strategy ",
|
|
vm.toString(i),
|
|
": ",
|
|
vm.toString(operatorShares)
|
|
)
|
|
);
|
|
}
|
|
_logProgress();
|
|
|
|
// STEP 3: Register as a DataHaven operator of specific type
|
|
Logging.logSection(string.concat("Registering as DataHaven ", _getOperatorTypeName()));
|
|
|
|
// Add the operator to the appropriate allowlist of the DataHaven service.
|
|
_addToAllowlist();
|
|
Logging.logStep(
|
|
string.concat(
|
|
"Added operator to ", _getOperatorTypeName(), " allowlist of DataHaven service"
|
|
)
|
|
);
|
|
|
|
// Register the operator as operator for the DataHaven service.
|
|
uint32[] memory operatorSetIds = new uint32[](1);
|
|
operatorSetIds[0] = _getOperatorSetId();
|
|
IAllocationManagerTypes.RegisterParams memory registerParams = IAllocationManagerTypes
|
|
.RegisterParams({avs: address(serviceManager), operatorSetIds: operatorSetIds, data: ""});
|
|
|
|
vm.broadcast(_operatorPrivateKey);
|
|
allocationManager.registerForOperatorSets(_operator, registerParams);
|
|
Logging.logStep(
|
|
string.concat("Registered ", _getOperatorTypeName(), " in DataHaven service")
|
|
);
|
|
|
|
Logging.logHeader("OPERATOR SETUP COMPLETE");
|
|
Logging.logInfo(string.concat(_getOperatorTypeName(), ": ", vm.toString(_operator)));
|
|
Logging.logInfo(
|
|
string.concat("Successfully configured ", _getOperatorTypeName(), " for DataHaven")
|
|
);
|
|
Logging.logFooter();
|
|
}
|
|
}
|