From 12b09de1e2a444200f2ffe4e6e09e5696763cc0f Mon Sep 17 00:00:00 2001 From: wadealexc Date: Mon, 30 Oct 2023 20:37:34 +0000 Subject: [PATCH] fix: fix compilation issues and tests --- src/BLSPubkeyRegistry.sol | 4 +- src/BLSRegistryCoordinatorWithIndices.sol | 26 +- src/IndexRegistry.sol | 13 +- src/StakeRegistry.sol | 23 +- src/StakeRegistryStorage.sol | 32 +- src/VoteWeigherBaseStorage.sol | 50 - src/interfaces/IBLSPubkeyRegistry.sol | 6 + src/interfaces/IIndexRegistry.sol | 6 + src/interfaces/IRegistryCoordinator.sol | 3 + src/interfaces/IStakeRegistry.sol | 92 +- src/interfaces/IVoteWeigher.sol | 97 -- test/EigenLayerDeployer.t.sol | 1 - ...SRegistryCoordinatorWithIndicesHarness.sol | 4 + test/harnesses/StakeRegistryHarness.sol | 8 +- test/mocks/RegistryCoordinatorMock.sol | 1 + test/mocks/StakeRegistryMock.sol | 51 ++ test/unit/BLSOperatorStateRetrieverUnit.t.sol | 8 +- test/unit/BLSPubkeyRegistryUnit.t.sol | 45 +- ...LSRegistryCoordinatorWithIndicesUnit.t.sol | 12 +- test/unit/IndexRegistryUnit.t.sol | 84 +- test/unit/StakeRegistryUnit.t.sol | 104 ++- test/unit/VoteWeigherBaseUnit.t.sol | 851 +++++++++--------- test/utils/MockAVSDeployer.sol | 74 +- 23 files changed, 845 insertions(+), 750 deletions(-) delete mode 100644 src/VoteWeigherBaseStorage.sol delete mode 100644 src/interfaces/IVoteWeigher.sol diff --git a/src/BLSPubkeyRegistry.sol b/src/BLSPubkeyRegistry.sol index f37f8b53..988266fc 100644 --- a/src/BLSPubkeyRegistry.sol +++ b/src/BLSPubkeyRegistry.sol @@ -94,10 +94,10 @@ contract BLSPubkeyRegistry is BLSPubkeyRegistryStorage { } /** - * @notice Creates a new quorum by pushing its first apk update + * @notice Initializes a new quorum by pushing its first apk update * @param quorumNumber The number of the new quorum */ - function createQuorum(uint8 quorumNumber) public virtual onlyRegistryCoordinator { + function initializeQuorum(uint8 quorumNumber) public virtual onlyRegistryCoordinator { require(quorumApkUpdates[quorumNumber].length == 0, "BLSPubkeyRegistry.createQuorum: quorum already exists"); quorumApkUpdates[quorumNumber].push(ApkUpdate({ diff --git a/src/BLSRegistryCoordinatorWithIndices.sol b/src/BLSRegistryCoordinatorWithIndices.sol index eb98f5b1..02d96711 100644 --- a/src/BLSRegistryCoordinatorWithIndices.sol +++ b/src/BLSRegistryCoordinatorWithIndices.sol @@ -15,7 +15,6 @@ import "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; import "src/interfaces/ISocketUpdater.sol"; import "src/interfaces/IServiceManager.sol"; import "src/interfaces/IBLSPubkeyRegistry.sol"; -import "src/interfaces/IVoteWeigher.sol"; import "src/interfaces/IStakeRegistry.sol"; import "src/interfaces/IIndexRegistry.sol"; import "src/interfaces/IRegistryCoordinator.sol"; @@ -50,11 +49,11 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr /// @notice the Service Manager for the service that this contract is coordinating IServiceManager public immutable serviceManager; /// @notice the BLS Pubkey Registry contract that will keep track of operators' BLS public keys - BLSPubkeyRegistry public immutable blsPubkeyRegistry; + IBLSPubkeyRegistry public immutable blsPubkeyRegistry; /// @notice the Stake Registry contract that will keep track of operators' stakes - StakeRegistry public immutable stakeRegistry; + IStakeRegistry public immutable stakeRegistry; /// @notice the Index Registry contract that will keep track of operators' indexes - IndexRegistry public immutable indexRegistry; + IIndexRegistry public immutable indexRegistry; /// @notice the current number of quorums supported by the registry coordinator uint8 public quorumCount; @@ -113,7 +112,7 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr uint256 _initialPausedStatus, OperatorSetParam[] memory _operatorSetParams, uint96[] memory _minimumStakes, - IVoteWeigher.StrategyAndWeightingMultiplier[][] memory _strategyParams + IStakeRegistry.StrategyAndWeightingMultiplier[][] memory _strategyParams ) external initializer { require( _operatorSetParams.length == _minimumStakes.length && _minimumStakes.length == _strategyParams.length, @@ -342,7 +341,7 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr function createQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategyParams + IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategyParams ) external virtual onlyServiceManagerOwner { _createQuorum(operatorSetParams, minimumStake, strategyParams); } @@ -388,12 +387,7 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr bytes calldata quorumNumbers, BN254.G1Point memory pubkey, string memory socket - ) internal virtual returns(uint32[] memory) { - // require( - // slasher.contractCanSlashOperatorUntilBlock(operator, address(serviceManager)) == type(uint32).max, - // "StakeRegistry._registerOperator: operator must be opted into slashing by the serviceManager" - // ); - + ) internal virtual returns(uint32[] memory) { // get the quorum bitmap from the quorum numbers uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); require(quorumBitmap <= MAX_QUORUM_BITMAP, "BLSRegistryCoordinatorWithIndices._registerOperatorWithCoordinator: quorumBitmap exceeds of max bitmap size"); @@ -553,7 +547,7 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr function _createQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategyParams + IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategyParams ) internal { // Increment the total quorum count. Fails if we're already at the max uint8 prevQuorumCount = quorumCount; @@ -565,9 +559,9 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr // Initialize the quorum here and in each registry _setOperatorSetParams(quorumNumber, operatorSetParams); - stakeRegistry.createQuorum(quorumNumber, minimumStake, strategyParams); - indexRegistry.createQuorum(quorumNumber); - blsPubkeyRegistry.createQuorum(quorumNumber); + stakeRegistry.initializeQuorum(quorumNumber, minimumStake, strategyParams); + indexRegistry.initializeQuorum(quorumNumber); + blsPubkeyRegistry.initializeQuorum(quorumNumber); } function _setOperatorSetParams(uint8 quorumNumber, OperatorSetParam memory operatorSetParams) internal { diff --git a/src/IndexRegistry.sol b/src/IndexRegistry.sol index 5ce053f8..fbca8dd1 100644 --- a/src/IndexRegistry.sol +++ b/src/IndexRegistry.sol @@ -86,6 +86,7 @@ contract IndexRegistry is IndexRegistryStorage { for (uint256 i = 0; i < quorumNumbers.length; i++) { uint8 quorumNumber = uint8(quorumNumbers[i]); uint32 indexOfOperatorToRemove = operatorIdToIndex[quorumNumber][operatorId]; + uint256 historyLength = _totalOperatorsHistory[quorumNumber].length; _processOperatorRemoval({ operatorId: operatorId, quorumNumber: quorumNumber, @@ -99,10 +100,10 @@ contract IndexRegistry is IndexRegistryStorage { } /** - * @notice Creates a new quorum by pushing its first quorum update + * @notice Initialize a quorum by pushing its first quorum update * @param quorumNumber The number of the new quorum */ - function createQuorum(uint8 quorumNumber) public virtual onlyRegistryCoordinator { + function initializeQuorum(uint8 quorumNumber) public virtual onlyRegistryCoordinator { require(_totalOperatorsHistory[quorumNumber].length == 0, "IndexRegistry.createQuorum: quorum already exists"); _totalOperatorsHistory[quorumNumber].push(QuorumUpdate({ @@ -133,10 +134,10 @@ contract IndexRegistry is IndexRegistryStorage { * @param index the latest index of that operator in the list of operators registered for this quorum */ function _updateOperatorIdToIndexHistory(bytes32 operatorId, uint8 quorumNumber, uint32 index) internal { - OperatorUpdate memory latestOperatorUpdate; - latestOperatorUpdate.operatorId = operatorId; - latestOperatorUpdate.fromBlockNumber = uint32(block.number); - _indexToOperatorIdHistory[quorumNumber][index].push(latestOperatorUpdate); + _indexToOperatorIdHistory[quorumNumber][index].push(OperatorUpdate({ + operatorId: operatorId, + fromBlockNumber: uint32(block.number) + })); operatorIdToIndex[quorumNumber][operatorId] = index; diff --git a/src/StakeRegistry.sol b/src/StakeRegistry.sol index a4cc29db..1c25e0da 100644 --- a/src/StakeRegistry.sol +++ b/src/StakeRegistry.sol @@ -7,7 +7,6 @@ import "src/interfaces/IServiceManager.sol"; import "src/interfaces/IStakeRegistry.sol"; import "src/interfaces/IRegistryCoordinator.sol"; import "src/StakeRegistryStorage.sol"; -import "src/VoteWeigherBaseStorage.sol"; /** * @title A `Registry` that keeps track of stakes of operators for up to 256 quorums. @@ -18,7 +17,7 @@ import "src/VoteWeigherBaseStorage.sol"; * It allows an additional functionality (in addition to registering and deregistering) to update the stake of an operator. * @author Layr Labs, Inc. */ -contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { +contract StakeRegistry is StakeRegistryStorage { modifier onlyRegistryCoordinator() { require( @@ -42,7 +41,7 @@ contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { IRegistryCoordinator _registryCoordinator, IDelegationManager _delegationManager, IServiceManager _serviceManager - ) VoteWeigherBaseStorage(_delegationManager, _serviceManager) StakeRegistryStorage(_registryCoordinator) {} + ) StakeRegistryStorage(_registryCoordinator, _delegationManager, _serviceManager) {} /******************************************************************************* EXTERNAL FUNCTIONS @@ -187,15 +186,21 @@ contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { } } - /// @notice Create a new quorum and add the strategies and their associated weights to the quorum. - function createQuorum( + /// @notice Initialize a new quorum and push its first history update + function initializeQuorum( uint8 quorumNumber, uint96 minimumStake, StrategyAndWeightingMultiplier[] memory strategyParams ) public virtual onlyRegistryCoordinator { - require(_totalStakeHistory[quorumNumber].length == 0, "StakeRegistry.createQuorum: quorum already exists"); + require(_totalStakeHistory[quorumNumber].length == 0, "StakeRegistry.initializeQuorum: quorum already exists"); _addStrategyParams(quorumNumber, strategyParams); _setMinimumStakeForQuorum(quorumNumber, minimumStake); + + _totalStakeHistory[quorumNumber].push(OperatorStakeUpdate({ + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0, + stake: 0 + })); } function setMinimumStakeForQuorum( @@ -211,7 +216,7 @@ contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { * @dev This function has no check to make sure that the strategies for a single quorum have the same underlying asset. This is a concious choice, * since a middleware may want, e.g., a stablecoin quorum that accepts USDC, USDT, DAI, etc. as underlying assets and trades them as "equivalent". */ - function addStrategyParams( + function addStrategies( uint8 quorumNumber, StrategyAndWeightingMultiplier[] memory strategyParams ) public virtual onlyServiceManagerOwner quorumExists(quorumNumber) { @@ -223,7 +228,7 @@ contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise * the removal of lower index entries will cause a shift in the indices of the other strategies to remove */ - function removeStrategyParams( + function removeStrategies( uint8 quorumNumber, uint256[] memory indicesToRemove ) public virtual onlyServiceManagerOwner quorumExists(quorumNumber) { @@ -492,7 +497,7 @@ contract StakeRegistry is VoteWeigherBaseStorage, StakeRegistryStorage { * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. * @dev this method DOES NOT check that the quorum exists */ - function _weightOfOperatorForQuorum(uint8 quorumNumber, address operator) internal view returns (uint96) { + function _weightOfOperatorForQuorum(uint8 quorumNumber, address operator) internal virtual view returns (uint96) { uint96 weight; uint256 stratsLength = strategiesConsideredAndMultipliersLength(quorumNumber); StrategyAndWeightingMultiplier memory strategyAndMultiplier; diff --git a/src/StakeRegistryStorage.sol b/src/StakeRegistryStorage.sol index 6459a659..e63af496 100644 --- a/src/StakeRegistryStorage.sol +++ b/src/StakeRegistryStorage.sol @@ -2,6 +2,8 @@ pragma solidity =0.8.12; import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; +import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; + import {IServiceManager} from "src/interfaces/IServiceManager.sol"; import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; @@ -12,6 +14,20 @@ import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; * @notice This storage contract is separate from the logic to simplify the upgrade process. */ abstract contract StakeRegistryStorage is IStakeRegistry { + + /// @notice Constant used as a divisor in calculating weights. + uint256 public constant WEIGHTING_DIVISOR = 1e18; + /// @notice Maximum length of dynamic arrays in the `strategiesConsideredAndMultipliers` mapping. + uint8 public constant MAX_WEIGHING_FUNCTION_LENGTH = 32; + /// @notice Constant used as a divisor in dealing with BIPS amounts. + uint256 internal constant MAX_BIPS = 10000; + + /// @notice The address of the Delegation contract for EigenLayer. + IDelegationManager public immutable delegation; + + /// @notice The ServiceManager contract for this middleware, where tasks are created / initiated. + IServiceManager public immutable serviceManager; + /// @notice the coordinator contract that this registry is associated with IRegistryCoordinator public immutable registryCoordinator; @@ -25,11 +41,23 @@ abstract contract StakeRegistryStorage is IStakeRegistry { /// @notice mapping from operator's operatorId to the history of their stake updates mapping(bytes32 => mapping(uint8 => OperatorStakeUpdate[])) internal operatorIdToStakeHistory; - constructor(IRegistryCoordinator _registryCoordinator) { + /** + * @notice mapping from quorum number to the list of strategies considered and their + * corresponding multipliers for that specific quorum + */ + mapping(uint8 => StrategyAndWeightingMultiplier[]) public strategiesConsideredAndMultipliers; + + constructor( + IRegistryCoordinator _registryCoordinator, + IDelegationManager _delegationManager, + IServiceManager _serviceManager + ) { registryCoordinator = _registryCoordinator; + delegation = _delegationManager; + serviceManager = _serviceManager; } // storage gap for upgradeability // slither-disable-next-line shadowing-state - uint256[65] private __GAP; + uint256[64] private __GAP; } diff --git a/src/VoteWeigherBaseStorage.sol b/src/VoteWeigherBaseStorage.sol deleted file mode 100644 index 45d53655..00000000 --- a/src/VoteWeigherBaseStorage.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.8.12; - -import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; -import "src/interfaces/IServiceManager.sol"; -import "src/interfaces/IVoteWeigher.sol"; - -import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; - -/** - * @title Storage variables for the `VoteWeigherBase` contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice This storage contract is separate from the logic to simplify the upgrade process. - */ -abstract contract VoteWeigherBaseStorage is Initializable, IVoteWeigher { - /// @notice Constant used as a divisor in calculating weights. - uint256 public constant WEIGHTING_DIVISOR = 1e18; - /// @notice Maximum length of dynamic arrays in the `strategiesConsideredAndMultipliers` mapping. - uint8 public constant MAX_WEIGHING_FUNCTION_LENGTH = 32; - /// @notice Constant used as a divisor in dealing with BIPS amounts. - uint256 internal constant MAX_BIPS = 10000; - - /// @notice The address of the Delegation contract for EigenLayer. - IDelegationManager public immutable delegation; - - /// @notice The ServiceManager contract for this middleware, where tasks are created / initiated. - IServiceManager public immutable serviceManager; - - /** - * @notice mapping from quorum number to the list of strategies considered and their - * corresponding multipliers for that specific quorum - */ - mapping(uint8 => StrategyAndWeightingMultiplier[]) public strategiesConsideredAndMultipliers; - - constructor( - IDelegationManager _delegationManager, - IServiceManager _serviceManager - ) { - delegation = _delegationManager; - serviceManager = _serviceManager; - // disable initializers so that the implementation contract cannot be initialized - _disableInitializers(); - } - - // storage gap for upgradeability - // slither-disable-next-line shadowing-state - uint256[49] private __GAP; -} diff --git a/src/interfaces/IBLSPubkeyRegistry.sol b/src/interfaces/IBLSPubkeyRegistry.sol index 42ec2251..01a0d75a 100644 --- a/src/interfaces/IBLSPubkeyRegistry.sol +++ b/src/interfaces/IBLSPubkeyRegistry.sol @@ -62,6 +62,12 @@ interface IBLSPubkeyRegistry is IRegistry { */ function deregisterOperator(address operator, bytes calldata quorumNumbers, BN254.G1Point memory pubkey) external; + /** + * @notice Initializes a new quorum by pushing its first apk update + * @param quorumNumber The number of the new quorum + */ + function initializeQuorum(uint8 quorumNumber) external; + /// @notice Returns the current APK for the provided `quorumNumber ` function getApkForQuorum(uint8 quorumNumber) external view returns (BN254.G1Point memory); diff --git a/src/interfaces/IIndexRegistry.sol b/src/interfaces/IIndexRegistry.sol index 52b7fc2f..e7eaaf00 100644 --- a/src/interfaces/IIndexRegistry.sol +++ b/src/interfaces/IIndexRegistry.sol @@ -60,6 +60,12 @@ interface IIndexRegistry is IRegistry { */ function deregisterOperator(bytes32 operatorId, bytes calldata quorumNumbers) external; + /** + * @notice Initialize a quorum by pushing its first quorum update + * @param quorumNumber The number of the new quorum + */ + function initializeQuorum(uint8 quorumNumber) external; + /// @notice Returns the _indexToOperatorIdHistory entry for the specified `operatorIndex` and `quorumNumber` at the specified `index` function getOperatorIndexUpdateOfIndexForQuorumAtIndex(uint32 operatorIndex, uint8 quorumNumber, uint32 index) external view returns (OperatorUpdate memory); diff --git a/src/interfaces/IRegistryCoordinator.sol b/src/interfaces/IRegistryCoordinator.sol index 3ee5b1a9..21320b2d 100644 --- a/src/interfaces/IRegistryCoordinator.sol +++ b/src/interfaces/IRegistryCoordinator.sol @@ -45,6 +45,9 @@ interface IRegistryCoordinator { uint192 quorumBitmap; } + /// @notice Returns the number of quorums the registry coordinator has created + function quorumCount() external view returns (uint8); + /// @notice Returns the operator struct for the given `operator` function getOperator(address operator) external view returns (Operator memory); diff --git a/src/interfaces/IStakeRegistry.sol b/src/interfaces/IStakeRegistry.sol index e24bf6dd..f7998fac 100644 --- a/src/interfaces/IStakeRegistry.sol +++ b/src/interfaces/IStakeRegistry.sol @@ -1,20 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; +import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; + import {IRegistry} from "./IRegistry.sol"; +import {IServiceManager} from "./IServiceManager.sol"; /** * @title Interface for a `Registry` that keeps track of stakes of operators for up to 256 quorums. * @author Layr Labs, Inc. */ interface IStakeRegistry is IRegistry { - // EVENTS - /// @notice emitted whenever the stake of `operator` is updated - event StakeUpdate( - bytes32 indexed operatorId, - uint8 quorumNumber, - uint96 stake - ); // DATA STRUCTURES @@ -29,8 +26,33 @@ interface IStakeRegistry is IRegistry { uint96 stake; } + /** + * @notice In weighing a particular strategy, the amount of underlying asset for that strategy is + * multiplied by its multiplier, then divided by WEIGHTING_DIVISOR + */ + struct StrategyAndWeightingMultiplier { + IStrategy strategy; + uint96 multiplier; + } + // EVENTS + + /// @notice emitted whenever the stake of `operator` is updated + event StakeUpdate( + bytes32 indexed operatorId, + uint8 quorumNumber, + uint96 stake + ); + /// @notice emitted when the minimum stake for a quorum is updated event MinimumStakeForQuorumUpdated(uint8 indexed quorumNumber, uint96 minimumStake); + /// @notice emitted when a new quorum is created + event QuorumCreated(uint8 indexed quorumNumber); + /// @notice emitted when `strategy` has been added to the array at `strategiesConsideredAndMultipliers[quorumNumber]` + event StrategyAddedToQuorum(uint8 indexed quorumNumber, IStrategy strategy); + /// @notice emitted when `strategy` has removed from the array at `strategiesConsideredAndMultipliers[quorumNumber]` + event StrategyRemovedFromQuorum(uint8 indexed quorumNumber, IStrategy strategy); + /// @notice emitted when `strategy` has its `multiplier` updated in the array at `strategiesConsideredAndMultipliers[quorumNumber]` + event StrategyMultiplierUpdated(uint8 indexed quorumNumber, IStrategy strategy, uint256 multiplier); /** * @notice Registers the `operator` with `operatorId` for the specified `quorumNumbers`. @@ -60,9 +82,65 @@ interface IStakeRegistry is IRegistry { */ function deregisterOperator(bytes32 operatorId, bytes memory quorumNumbers) external; + /** + * @notice Initialize a new quorum created by the registry coordinator by setting strategies, weights, and minimum stake + */ + function initializeQuorum(uint8 quorumNumber, uint96 minimumStake, StrategyAndWeightingMultiplier[] memory strategyParams) external; + + /// @notice Adds new strategies and the associated multipliers to the @param quorumNumber. + function addStrategies( + uint8 quorumNumber, + StrategyAndWeightingMultiplier[] memory strategyParams + ) external; + + /** + * @notice This function is used for removing strategies and their associated weights from the + * mapping strategiesConsideredAndMultipliers for a specific @param quorumNumber. + * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise + * the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove + */ + function removeStrategies(uint8 quorumNumber, uint256[] calldata indicesToRemove) external; + + /** + * @notice This function is used for modifying the weights of strategies that are already in the + * mapping strategiesConsideredAndMultipliers for a specific + * @param quorumNumber is the quorum number to change the strategy for + * @param strategyIndices are the indices of the strategies to change + * @param newMultipliers are the new multipliers for the strategies + */ + function modifyStrategyParams( + uint8 quorumNumber, + uint256[] calldata strategyIndices, + uint96[] calldata newMultipliers + ) external; + + /// @notice Constant used as a divisor in calculating weights. + function WEIGHTING_DIVISOR() external pure returns (uint256); + + /// @notice Returns the EigenLayer delegation manager contract. + function delegation() external view returns (IDelegationManager); + + /// @notice Returns the AVS service manager contract. + function serviceManager() external view returns (IServiceManager); + /// @notice In order to register for a quorum i, an operator must have at least `minimumStakeForQuorum[i]` function minimumStakeForQuorum(uint256 quorumNumber) external view returns (uint96); + /// @notice Returns the length of the dynamic array stored in `strategiesConsideredAndMultipliers[quorumNumber]`. + function strategiesConsideredAndMultipliersLength(uint8 quorumNumber) external view returns (uint256); + + /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` + function strategyAndWeightingMultiplierForQuorumByIndex( + uint8 quorumNumber, + uint256 index + ) external view returns (StrategyAndWeightingMultiplier memory); + + /** + * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. + * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` + */ + function weightOfOperatorForQuorum(uint8 quorumNumber, address operator) external view returns (uint96); + /** * @notice Returns the entire `operatorIdToStakeHistory[operatorId][quorumNumber]` array. * @param operatorId The id of the operator of interest. diff --git a/src/interfaces/IVoteWeigher.sol b/src/interfaces/IVoteWeigher.sol deleted file mode 100644 index 15af7ca3..00000000 --- a/src/interfaces/IVoteWeigher.sol +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import {IServiceManager} from "./IServiceManager.sol"; -import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; -import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; -import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; - -/** - * @title Interface for a `VoteWeigher`-type contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice Note that `NUMBER_OF_QUORUMS` is expected to remain constant, as suggested by its uppercase formatting. - */ -interface IVoteWeigher { - /// @notice emitted when a new quorum is created - event QuorumCreated(uint8 indexed quorumNumber); - /// @notice emitted when `strategy` has been added to the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyAddedToQuorum(uint8 indexed quorumNumber, IStrategy strategy); - /// @notice emitted when `strategy` has removed from the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyRemovedFromQuorum(uint8 indexed quorumNumber, IStrategy strategy); - /// @notice emitted when `strategy` has its `multiplier` updated in the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyMultiplierUpdated(uint8 indexed quorumNumber, IStrategy strategy, uint256 multiplier); - - /** - * @notice In weighing a particular strategy, the amount of underlying asset for that strategy is - * multiplied by its multiplier, then divided by WEIGHTING_DIVISOR - */ - struct StrategyAndWeightingMultiplier { - IStrategy strategy; - uint96 multiplier; - } - - /// @notice Constant used as a divisor in calculating weights. - function WEIGHTING_DIVISOR() external pure returns (uint256); - - /// @notice Returns the EigenLayer strategy manager contract. - function strategyManager() external view returns (IStrategyManager); - - /// @notice Returns the EigenLayer slasher contract. - function slasher() external view returns (ISlasher); - - /// @notice Returns the EigenLayer delegation manager contract. - function delegation() external view returns (IDelegationManager); - - /// @notice Returns the AVS service manager contract. - function serviceManager() external view returns (IServiceManager); - - /** - * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. - * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` - */ - function weightOfOperatorForQuorum(uint8 quorumNumber, address operator) external view returns (uint96); - - /// @notice Number of quorums that are being used by the middleware. - function quorumCount() external view returns (uint16); - - /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` - function strategyAndWeightingMultiplierForQuorumByIndex( - uint8 quorumNumber, - uint256 index - ) external view returns (StrategyAndWeightingMultiplier memory); - - /// @notice Create a new quorum and add the strategies and their associated weights to the quorum. - function createQuorum(StrategyAndWeightingMultiplier[] memory _strategiesConsideredAndMultipliers) external; - - /// @notice Adds new strategies and the associated multipliers to the @param quorumNumber. - function addStrategiesConsideredAndMultipliers( - uint8 quorumNumber, - StrategyAndWeightingMultiplier[] memory _newStrategiesConsideredAndMultipliers - ) external; - - /** - * @notice This function is used for removing strategies and their associated weights from the - * mapping strategiesConsideredAndMultipliers for a specific @param quorumNumber. - * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise - * the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove - */ - function removeStrategiesConsideredAndMultipliers(uint8 quorumNumber, uint256[] calldata indicesToRemove) external; - - /** - * @notice This function is used for modifying the weights of strategies that are already in the - * mapping strategiesConsideredAndMultipliers for a specific - * @param quorumNumber is the quorum number to change the strategy for - * @param strategyIndices are the indices of the strategies to change - * @param newMultipliers are the new multipliers for the strategies - */ - function modifyStrategyWeights( - uint8 quorumNumber, - uint256[] calldata strategyIndices, - uint96[] calldata newMultipliers - ) external; - - /// @notice Returns the length of the dynamic array stored in `strategiesConsideredAndMultipliers[quorumNumber]`. - function strategiesConsideredAndMultipliersLength(uint8 quorumNumber) external view returns (uint256); -} diff --git a/test/EigenLayerDeployer.t.sol b/test/EigenLayerDeployer.t.sol index bb8d94c5..d33f523a 100644 --- a/test/EigenLayerDeployer.t.sol +++ b/test/EigenLayerDeployer.t.sol @@ -10,7 +10,6 @@ import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import {StakeRegistry} from "src/StakeRegistry.sol"; -import {IVoteWeigher} from "src/interfaces/IVoteWeigher.sol"; import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; import {IBeaconChainOracle} from "eigenlayer-contracts/src/contracts/interfaces/IBeaconChainOracle.sol"; diff --git a/test/harnesses/BLSRegistryCoordinatorWithIndicesHarness.sol b/test/harnesses/BLSRegistryCoordinatorWithIndicesHarness.sol index c4105dae..85600b72 100644 --- a/test/harnesses/BLSRegistryCoordinatorWithIndicesHarness.sol +++ b/test/harnesses/BLSRegistryCoordinatorWithIndicesHarness.sol @@ -14,6 +14,10 @@ contract BLSRegistryCoordinatorWithIndicesHarness is BLSRegistryCoordinatorWithI ) BLSRegistryCoordinatorWithIndices(_slasher, _serviceManager, _stakeRegistry, _blsPubkeyRegistry, _indexRegistry) { } + function setQuorumCount(uint8 count) external { + quorumCount = count; + } + function setOperatorId(address operator, bytes32 operatorId) external { _operators[operator].operatorId = operatorId; } diff --git a/test/harnesses/StakeRegistryHarness.sol b/test/harnesses/StakeRegistryHarness.sol index 235674c7..32bce297 100644 --- a/test/harnesses/StakeRegistryHarness.sol +++ b/test/harnesses/StakeRegistryHarness.sol @@ -9,9 +9,9 @@ contract StakeRegistryHarness is StakeRegistry { constructor( IRegistryCoordinator _registryCoordinator, - IStrategyManager _strategyManager, + IDelegationManager _delegationManager, IServiceManager _serviceManager - ) StakeRegistry(_registryCoordinator, _strategyManager, _serviceManager) { + ) StakeRegistry(_registryCoordinator, _delegationManager, _serviceManager) { } function recordOperatorStakeUpdate(bytes32 operatorId, uint8 quorumNumber, uint96 newStake) external returns(int256) { @@ -31,6 +31,10 @@ contract StakeRegistryHarness is StakeRegistry { return __weightOfOperatorForQuorum[quorumNumber][operator]; } + function _weightOfOperatorForQuorum(uint8 quorumNumber, address operator) internal override view returns(uint96) { + return __weightOfOperatorForQuorum[quorumNumber][operator]; + } + // mocked function so we can set this arbitrarily without having to mock other elements function setOperatorWeight(uint8 quorumNumber, address operator, uint96 weight) external { __weightOfOperatorForQuorum[quorumNumber][operator] = weight; diff --git a/test/mocks/RegistryCoordinatorMock.sol b/test/mocks/RegistryCoordinatorMock.sol index 92322c62..a17ecfe8 100644 --- a/test/mocks/RegistryCoordinatorMock.sol +++ b/test/mocks/RegistryCoordinatorMock.sol @@ -6,6 +6,7 @@ import "src/interfaces/IRegistryCoordinator.sol"; contract RegistryCoordinatorMock is IRegistryCoordinator { + function quorumCount() external view returns (uint8) {} /// @notice Returns the bitmap of the quorums the operator is registered for. function operatorIdToQuorumBitmap(bytes32 pubkeyHash) external view returns (uint256){} diff --git a/test/mocks/StakeRegistryMock.sol b/test/mocks/StakeRegistryMock.sol index 8b6e932f..3861d07a 100644 --- a/test/mocks/StakeRegistryMock.sol +++ b/test/mocks/StakeRegistryMock.sol @@ -40,9 +40,60 @@ contract StakeRegistryMock is IStakeRegistry { */ function deregisterOperator(bytes32 operatorId, bytes memory quorumNumbers) external {} + /** + * @notice Initialize a new quorum created by the registry coordinator by setting strategies, weights, and minimum stake + */ + function initializeQuorum(uint8 quorumNumber, uint96 minimumStake, StrategyAndWeightingMultiplier[] memory strategyParams) external {} + + /// @notice Adds new strategies and the associated multipliers to the @param quorumNumber. + function addStrategies( + uint8 quorumNumber, + StrategyAndWeightingMultiplier[] memory strategyParams + ) external {} + + /** + * @notice This function is used for removing strategies and their associated weights from the + * mapping strategiesConsideredAndMultipliers for a specific @param quorumNumber. + * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise + * the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove + */ + function removeStrategies(uint8 quorumNumber, uint256[] calldata indicesToRemove) external {} + + /** + * @notice This function is used for modifying the weights of strategies that are already in the + * mapping strategiesConsideredAndMultipliers for a specific + * @param quorumNumber is the quorum number to change the strategy for + * @param strategyIndices are the indices of the strategies to change + * @param newMultipliers are the new multipliers for the strategies + */ + function modifyStrategyParams( + uint8 quorumNumber, + uint256[] calldata strategyIndices, + uint96[] calldata newMultipliers + ) external {} + + function delegation() external view returns (IDelegationManager) {} + function serviceManager() external view returns (IServiceManager) {} + + function WEIGHTING_DIVISOR() external pure returns (uint256) {} + + function strategiesConsideredAndMultipliersLength(uint8 quorumNumber) external view returns (uint256) {} + /// @notice In order to register for a quorum i, an operator must have at least `minimumStakeForQuorum[i]` function minimumStakeForQuorum(uint256 quorumNumber) external view returns (uint96) {} + /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` + function strategyAndWeightingMultiplierForQuorumByIndex( + uint8 quorumNumber, + uint256 index + ) external view returns (StrategyAndWeightingMultiplier memory) {} + + /** + * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. + * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` + */ + function weightOfOperatorForQuorum(uint8 quorumNumber, address operator) external view returns (uint96) {} + /** * @notice Returns the entire `operatorIdToStakeHistory[operatorId][quorumNumber]` array. * @param operatorId The id of the operator of interest. diff --git a/test/unit/BLSOperatorStateRetrieverUnit.t.sol b/test/unit/BLSOperatorStateRetrieverUnit.t.sol index 791803a2..6842bf16 100644 --- a/test/unit/BLSOperatorStateRetrieverUnit.t.sol +++ b/test/unit/BLSOperatorStateRetrieverUnit.t.sol @@ -108,8 +108,8 @@ contract BLSOperatorStateRetrieverUnitTests is MockAVSDeployer { // assert the indices are the number of registered operators for the quorum minus 1 for (uint8 i = 0; i < allInclusiveQuorumNumbers.length; i++) { uint8 quorumNumber = uint8(allInclusiveQuorumNumbers[i]); - assertEq(checkSignaturesIndices.quorumApkIndices[i], expectedOperatorOverallIndices[quorumNumber].length - 1, "quorumApkIndex should be the number of registered operators for the quorum minus 1"); - assertEq(checkSignaturesIndices.totalStakeIndices[i], expectedOperatorOverallIndices[quorumNumber].length - 1, "totalStakeIndex should be the number of registered operators for the quorum minus 1"); + assertEq(checkSignaturesIndices.quorumApkIndices[i], expectedOperatorOverallIndices[quorumNumber].length, "quorumApkIndex should be the number of registered operators for the quorum"); + assertEq(checkSignaturesIndices.totalStakeIndices[i], expectedOperatorOverallIndices[quorumNumber].length, "totalStakeIndex should be the number of registered operators for the quorum"); } } @@ -151,8 +151,8 @@ contract BLSOperatorStateRetrieverUnitTests is MockAVSDeployer { // assert the indices are the number of registered operators for the quorum minus 1 for (uint8 i = 0; i < allInclusiveQuorumNumbers.length; i++) { uint8 quorumNumber = uint8(allInclusiveQuorumNumbers[i]); - assertEq(checkSignaturesIndices.quorumApkIndices[i], expectedOperatorOverallIndices[quorumNumber].length - 1, "quorumApkIndex should be the number of registered operators for the quorum minus 1"); - assertEq(checkSignaturesIndices.totalStakeIndices[i], expectedOperatorOverallIndices[quorumNumber].length - 1, "totalStakeIndex should be the number of registered operators for the quorum minus 1"); + assertEq(checkSignaturesIndices.quorumApkIndices[i], expectedOperatorOverallIndices[quorumNumber].length, "quorumApkIndex should be the number of registered operators for the quorum"); + assertEq(checkSignaturesIndices.totalStakeIndices[i], expectedOperatorOverallIndices[quorumNumber].length, "totalStakeIndex should be the number of registered operators for the quorum"); } // assert the quorum bitmap and stake indices are zero because there have been no kicks or stake updates diff --git a/test/unit/BLSPubkeyRegistryUnit.t.sol b/test/unit/BLSPubkeyRegistryUnit.t.sol index 99247971..4b5d7f35 100644 --- a/test/unit/BLSPubkeyRegistryUnit.t.sol +++ b/test/unit/BLSPubkeyRegistryUnit.t.sol @@ -26,10 +26,16 @@ contract BLSPubkeyRegistryUnitTests is Test { uint8 internal defaultQuorumNumber = 0; + // Track initialized quorums so we can filter these out when fuzzing + mapping(uint8 => bool) initializedQuorums; + function setUp() external { registryCoordinator = new RegistryCoordinatorMock(); pkCompendium = new BLSPublicKeyCompendiumMock(); blsPubkeyRegistry = new BLSPubkeyRegistry(registryCoordinator, pkCompendium); + + // Initialize a quorum + _initializeQuorum(defaultQuorumNumber); } function testConstructorArgs() public view { @@ -99,19 +105,23 @@ contract BLSPubkeyRegistryUnitTests is Test { bytes memory quorumNumbers = new bytes(2); quorumNumbers[0] = bytes1(quorumNumber1); quorumNumbers[1] = bytes1(quorumNumber2); + if (!initializedQuorums[quorumNumber1]) { + _initializeFuzzedQuorum(quorumNumber1); + } + if (!initializedQuorums[quorumNumber2]) { + _initializeFuzzedQuorum(quorumNumber2); + } BN254.G1Point[] memory quorumApksBefore = new BN254.G1Point[](quorumNumbers.length); for(uint8 i = 0; i < quorumNumbers.length; i++){ quorumApksBefore[i] = blsPubkeyRegistry.getApkForQuorum(uint8(quorumNumbers[i])); } - cheats.startPrank(defaultOperator); + cheats.prank(defaultOperator); pkCompendium.registerPublicKey(defaultPubKey); - cheats.stopPrank(); - cheats.startPrank(address(registryCoordinator)); + cheats.prank(address(registryCoordinator)); blsPubkeyRegistry.registerOperator(defaultOperator, quorumNumbers, defaultPubKey); - cheats.stopPrank(); //check quorum apk updates for(uint8 i = 0; i < quorumNumbers.length; i++){ @@ -148,6 +158,8 @@ contract BLSPubkeyRegistryUnitTests is Test { bytes memory quorumNumbers = new bytes(2); quorumNumbers[0] = bytes1(quorumNumber1); quorumNumbers[1] = bytes1(quorumNumber2); + _initializeFuzzedQuorum(quorumNumber1); + _initializeFuzzedQuorum(quorumNumber2); testQuorumApkUpdates(quorumNumber1, quorumNumber2); @@ -200,19 +212,20 @@ contract BLSPubkeyRegistryUnitTests is Test { testRegisterOperatorBLSPubkey(defaultOperator, pk); quorumApk = quorumApk.plus(BN254.hashToG1(pk)); quorumApkHash = bytes24(BN254.hashG1Point(quorumApk)); - require(quorumApkHash == blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, uint32(block.number + blockGap) , i), "incorrect quorum aok updates"); + require(quorumApkHash == blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, uint32(block.number + blockGap) , i + 1), "incorrect quorum aok updates"); cheats.roll(block.number + 100); if(_generateRandomNumber(i) % 2 == 0){ _deregisterOperator(pk); quorumApk = quorumApk.plus(BN254.hashToG1(pk).negate()); quorumApkHash = bytes24(BN254.hashG1Point(quorumApk)); - require(quorumApkHash == blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, uint32(block.number + blockGap) , i + 1), "incorrect quorum aok updates"); + require(quorumApkHash == blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, uint32(block.number + blockGap) , i + 2), "incorrect quorum aok updates"); cheats.roll(block.number + 100); i++; } } } + /// TODO - fix test function testIncorrectBlockNumberForQuorumApkUpdates(uint256 numRegistrants, uint32 indexToCheck, uint32 wrongBlockNumber) external { cheats.assume(numRegistrants > 0 && numRegistrants < 100); cheats.assume(indexToCheck < numRegistrants - 1); @@ -225,15 +238,33 @@ contract BLSPubkeyRegistryUnitTests is Test { cheats.roll(block.number + 100); } if(wrongBlockNumber < startingBlockNumber + indexToCheck*100){ + emit log_named_uint("index too recent: ", indexToCheck); cheats.expectRevert(bytes("BLSPubkeyRegistry._validateApkHashForQuorumAtBlockNumber: index too recent")); blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, wrongBlockNumber, indexToCheck); } - if (wrongBlockNumber >= startingBlockNumber + (indexToCheck+1)*100){ + if (wrongBlockNumber >= startingBlockNumber + (indexToCheck+1)*100){ + emit log_named_uint("index not latest: ", indexToCheck); cheats.expectRevert(bytes("BLSPubkeyRegistry._validateApkHashForQuorumAtBlockNumber: not latest apk update")); blsPubkeyRegistry.getApkHashForQuorumAtBlockNumberFromIndex(defaultQuorumNumber, wrongBlockNumber, indexToCheck); } } + function _initializeQuorum( + uint8 quorumNumber + ) internal { + cheats.prank(address(registryCoordinator)); + + blsPubkeyRegistry.initializeQuorum(quorumNumber); + initializedQuorums[quorumNumber] = true; + } + + function _initializeFuzzedQuorum( + uint8 quorumNumber + ) internal { + cheats.assume(!initializedQuorums[quorumNumber]); + _initializeQuorum(quorumNumber); + } + function _getRandomPk(uint256 seed) internal view returns (bytes32) { return keccak256(abi.encodePacked(block.timestamp, seed)); } diff --git a/test/unit/BLSRegistryCoordinatorWithIndicesUnit.t.sol b/test/unit/BLSRegistryCoordinatorWithIndicesUnit.t.sol index 9244d5f6..3941445e 100644 --- a/test/unit/BLSRegistryCoordinatorWithIndicesUnit.t.sol +++ b/test/unit/BLSRegistryCoordinatorWithIndicesUnit.t.sol @@ -58,7 +58,15 @@ contract BLSRegistryCoordinatorWithIndicesUnit is MockAVSDeployer { // make sure the contract intializers are disabled cheats.expectRevert(bytes("Initializable: contract is already initialized")); - registryCoordinator.initialize(churnApprover, ejector, operatorSetParams, pauserRegistry, 0/*initialPausedStatus*/); + registryCoordinator.initialize( + churnApprover, + ejector, + pauserRegistry, + 0/*initialPausedStatus*/, + operatorSetParams, + new uint96[](0), + new IStakeRegistry.StrategyAndWeightingMultiplier[][](0) + ); } function testSetOperatorSetParams_NotServiceManagerOwner_Reverts() public { @@ -135,7 +143,7 @@ contract BLSRegistryCoordinatorWithIndicesUnit is MockAVSDeployer { bytes memory quorumNumbersNotCreated = new bytes(1); quorumNumbersNotCreated[0] = 0x0B; cheats.prank(defaultOperator); - cheats.expectRevert("StakeRegistry._registerOperator: greatest quorumNumber must be less than quorumCount"); + cheats.expectRevert("BLSPubkeyRegistry._processQuorumApkUpdate: quorum does not exist"); registryCoordinator.registerOperatorWithCoordinator(quorumNumbersNotCreated, defaultPubKey, defaultSocket); } diff --git a/test/unit/IndexRegistryUnit.t.sol b/test/unit/IndexRegistryUnit.t.sol index ba63a11e..9d26c18e 100644 --- a/test/unit/IndexRegistryUnit.t.sol +++ b/test/unit/IndexRegistryUnit.t.sol @@ -20,12 +20,20 @@ contract IndexRegistryUnitTests is Test { bytes32 operatorId2 = bytes32(uint256(35)); bytes32 operatorId3 = bytes32(uint256(36)); + // Track initialized quorums so we can filter these out when fuzzing + mapping(uint8 => bool) initializedQuorums; + // Test 0 length operators in operators to remove function setUp() public { // deploy the contract registryCoordinatorMock = new RegistryCoordinatorMock(); indexRegistry = new IndexRegistry(registryCoordinatorMock); bitmapUtilsWrapper = new BitmapUtilsWrapper(); + + // Initialize quorums and add to fuzz filter + _initializeQuorum(defaultQuorumNumber); + _initializeQuorum(defaultQuorumNumber + 1); + _initializeQuorum(defaultQuorumNumber + 2); } function testConstructor() public { @@ -72,7 +80,7 @@ contract IndexRegistryUnitTests is Test { // Check _totalOperatorsHistory updates IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(1, 0); + .getQuorumUpdateAtIndex(1, 1); require( quorumUpdate.numOperators == 1, "IndexRegistry.registerOperator: totalOperatorsHistory num operators not 1" @@ -117,7 +125,7 @@ contract IndexRegistryUnitTests is Test { // Check _totalOperatorsHistory updates IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(2, 0); + .getQuorumUpdateAtIndex(2, 1); require( quorumUpdate.numOperators == 1, "IndexRegistry.registerOperator: totalOperatorsHistory num operators not 1" @@ -160,7 +168,7 @@ contract IndexRegistryUnitTests is Test { // Check _totalOperatorsHistory updates for quorum 1 IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(1, 0); + .getQuorumUpdateAtIndex(1, 1); require( quorumUpdate.numOperators == 1, "IndexRegistry.registerOperator: totalOperatorsHistory numOperators not 1" @@ -183,7 +191,7 @@ contract IndexRegistryUnitTests is Test { ); // Check _totalOperatorsHistory updates for quorum 2 - quorumUpdate = indexRegistry.getQuorumUpdateAtIndex(2, 0); + quorumUpdate = indexRegistry.getQuorumUpdateAtIndex(2, 1); require( quorumUpdate.numOperators == 1, "IndexRegistry.registerOperator: totalOperatorsHistory num operators not 1" @@ -227,7 +235,7 @@ contract IndexRegistryUnitTests is Test { // Check _totalOperatorsHistory updates IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(1, 1); + .getQuorumUpdateAtIndex(1, 2); require( quorumUpdate.numOperators == 2, "IndexRegistry.registerOperator: totalOperatorsHistory num operators not 2" @@ -264,7 +272,7 @@ contract IndexRegistryUnitTests is Test { // Check total operators IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(defaultQuorumNumber, 1); + .getQuorumUpdateAtIndex(defaultQuorumNumber, 2); require(quorumUpdate.fromBlockNumber == block.number, "fromBlockNumber not set correctly"); require(quorumUpdate.numOperators == 0, "incorrect total number of operators"); require(indexRegistry.totalOperatorsForQuorum(1) == 0, "operator not deregistered correctly"); @@ -299,7 +307,7 @@ contract IndexRegistryUnitTests is Test { // Check total operators for removed quorums for (uint256 i = 0; i < quorumsToRemove.length; i++) { IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(uint8(quorumsToRemove[i]), 3); // 4 updates total + .getQuorumUpdateAtIndex(uint8(quorumsToRemove[i]), 4); // 5 updates total require(quorumUpdate.fromBlockNumber == block.number, "fromBlockNumber not set correctly"); require(quorumUpdate.numOperators == 2, "incorrect total number of operators"); require( @@ -359,7 +367,7 @@ contract IndexRegistryUnitTests is Test { uint32 prevTotal = indexRegistry.getTotalOperatorsForQuorumAtBlockNumberByIndex( defaultQuorumNumber, uint32(block.number - 10), - 0 + 1 ); require(prevTotal == 1, "IndexRegistry.getTotalOperatorsForQuorumAtBlockNumberByIndex: prev total not 1"); @@ -367,7 +375,7 @@ contract IndexRegistryUnitTests is Test { uint32 currentTotal = indexRegistry.getTotalOperatorsForQuorumAtBlockNumberByIndex( defaultQuorumNumber, uint32(block.number), - 1 + 2 ); require(currentTotal == 2, "IndexRegistry.getTotalOperatorsForQuorumAtBlockNumberByIndex: current total not 2"); } @@ -463,13 +471,10 @@ contract IndexRegistryUnitTests is Test { * 5. operator is not already registerd for any quorums being registered for */ function testFuzzRegisterOperatorMultipleQuorums(bytes memory quorumNumbers) public { - // Validate quorumNumbers - cheats.assume(quorumNumbers.length > 0); - cheats.assume(bitmapUtilsWrapper.isArrayStrictlyAscendingOrdered(quorumNumbers)); - uint256 bitmap = bitmapUtilsWrapper.orderedBytesArrayToBitmap(quorumNumbers); - cheats.assume(bitmap <= type(uint192).max); + // Initialize quorum numbers, skipping invalid tests + _initializeFuzzedQuorums(quorumNumbers); - // Register operator + // Register for quorums cheats.prank(address(registryCoordinatorMock)); uint32[] memory numOperatorsPerQuorum = indexRegistry.registerOperator(operatorId1, quorumNumbers); @@ -500,7 +505,7 @@ contract IndexRegistryUnitTests is Test { // Check _totalOperatorsHistory updates IIndexRegistry.QuorumUpdate memory quorumUpdate; for (uint256 i = 0; i < quorumNumbers.length; i++) { - quorumUpdate = indexRegistry.getQuorumUpdateAtIndex(uint8(quorumNumbers[i]), 0); + quorumUpdate = indexRegistry.getQuorumUpdateAtIndex(uint8(quorumNumbers[i]), 1); require( quorumUpdate.numOperators == 1, "IndexRegistry.registerOperator: totalOperatorsHistory num operators not 1" @@ -516,12 +521,9 @@ contract IndexRegistryUnitTests is Test { } } - function testFuzzRegsiterMultipleOperatorsMultipleQuorums(bytes memory quorumNumbers) public { - // Validate quorumNumbers - cheats.assume(quorumNumbers.length > 0); - cheats.assume(bitmapUtilsWrapper.isArrayStrictlyAscendingOrdered(quorumNumbers)); - uint256 bitmap = bitmapUtilsWrapper.orderedBytesArrayToBitmap(quorumNumbers); - cheats.assume(bitmap <= type(uint192).max); + function testFuzzRegisterMultipleOperatorsMultipleQuorums(bytes memory quorumNumbers) public { + // Initialize quorum numbers, skipping invalid tests + _initializeFuzzedQuorums(quorumNumbers); // Register operators 1,2,3 _registerOperator(operatorId1, quorumNumbers); @@ -537,7 +539,7 @@ contract IndexRegistryUnitTests is Test { for (uint256 i = 0; i < quorumNumbers.length; i++) { quorumUpdate = indexRegistry.getQuorumUpdateAtIndex( uint8(quorumNumbers[i]), - uint32(numOperators - 1) + uint32(numOperators) ); require( quorumUpdate.numOperators == numOperators, @@ -563,13 +565,11 @@ contract IndexRegistryUnitTests is Test { } function testFuzzDeregisterOperator(bytes memory quorumsToAdd, uint256 bitsToFlip) public { - // Validate quorumsToAdd - cheats.assume(quorumsToAdd.length > 0); - cheats.assume(bitmapUtilsWrapper.isArrayStrictlyAscendingOrdered(quorumsToAdd)); - uint256 bitmap = bitmapUtilsWrapper.orderedBytesArrayToBitmap(quorumsToAdd); - cheats.assume(bitmap <= type(uint192).max); - - // Format quorumsToRemove + // Initialize quorum numbers, skipping invalid tests + _initializeFuzzedQuorums(quorumsToAdd); + uint bitmap = bitmapUtilsWrapper.orderedBytesArrayToBitmap(quorumsToAdd); + + // Format bitsToFlip = bound(bitsToFlip, 1, quorumsToAdd.length); uint256 bitsFlipped = 0; uint256 bitPosition = 0; @@ -605,7 +605,7 @@ contract IndexRegistryUnitTests is Test { // Check total operators for removed quorums for (uint256 i = 0; i < quorumsToRemove.length; i++) { IIndexRegistry.QuorumUpdate memory quorumUpdate = indexRegistry - .getQuorumUpdateAtIndex(uint8(quorumsToRemove[i]), 2); // 3 updates total + .getQuorumUpdateAtIndex(uint8(quorumsToRemove[i]), 3); // 4 updates total require(quorumUpdate.fromBlockNumber == block.number, "fromBlockNumber not set correctly"); require(quorumUpdate.numOperators == 1, "incorrect total number of operators"); require( @@ -623,6 +623,28 @@ contract IndexRegistryUnitTests is Test { } } + function _initializeQuorum(uint8 quorumNumber) internal { + cheats.prank(address(registryCoordinatorMock)); + + // Initialize quorum and mark registered + indexRegistry.initializeQuorum(quorumNumber); + initializedQuorums[quorumNumber] = true; + } + + function _initializeFuzzedQuorums(bytes memory quorumNumbers) internal { + cheats.assume(quorumNumbers.length > 0); + cheats.assume(bitmapUtilsWrapper.isArrayStrictlyAscendingOrdered(quorumNumbers)); + uint256 bitmap = bitmapUtilsWrapper.orderedBytesArrayToBitmap(quorumNumbers); + cheats.assume(bitmap <= type(uint192).max); + + // Initialize quorums and add to fuzz filter + for (uint i = 0; i < quorumNumbers.length; i++) { + uint8 quorumNumber = uint8(quorumNumbers[i]); + cheats.assume(!initializedQuorums[quorumNumber]); + _initializeQuorum(quorumNumber); + } + } + function _registerOperator(bytes32 operatorId, bytes memory quorumNumbers) internal { cheats.prank(address(registryCoordinatorMock)); indexRegistry.registerOperator(operatorId, quorumNumbers); diff --git a/test/unit/StakeRegistryUnit.t.sol b/test/unit/StakeRegistryUnit.t.sol index bee91582..c1663087 100644 --- a/test/unit/StakeRegistryUnit.t.sol +++ b/test/unit/StakeRegistryUnit.t.sol @@ -12,10 +12,10 @@ import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.s import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; import {IServiceManager} from "src/interfaces/IServiceManager.sol"; -import {IVoteWeigher} from "src/interfaces/IVoteWeigher.sol"; import {IIndexRegistry} from "src/interfaces/IIndexRegistry.sol"; import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; +import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; import {BitmapUtils} from "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; @@ -56,12 +56,19 @@ contract StakeRegistryUnitTests is Test { address public pubkeyRegistry = address(uint160(uint256(keccak256("pubkeyRegistry")))); address public indexRegistry = address(uint160(uint256(keccak256("indexRegistry")))); + uint256 churnApproverPrivateKey = uint256(keccak256("churnApproverPrivateKey")); + address churnApprover = cheats.addr(churnApproverPrivateKey); + address ejector = address(uint160(uint256(keccak256("ejector")))); + address defaultOperator = address(uint160(uint256(keccak256("defaultOperator")))); bytes32 defaultOperatorId = keccak256("defaultOperatorId"); uint8 defaultQuorumNumber = 0; uint8 numQuorums = 192; uint8 maxQuorumsToRegisterFor = 4; + // Track initialized quorums so we can filter these out when fuzzing + mapping(uint8 => bool) initializedQuorums; + uint256 gasUsed; /// @notice emitted whenever the stake of `operator` is updated @@ -111,57 +118,47 @@ contract StakeRegistryUnitTests is Test { serviceManagerMock = new ServiceManagerMock(slasher); stakeRegistryImplementation = new StakeRegistryHarness( IRegistryCoordinator(address(registryCoordinator)), - strategyManagerMock, + delegationMock, IServiceManager(address(serviceManagerMock)) ); - - // setup the dummy minimum stake for quorum - uint96[] memory minimumStakeForQuorum = new uint96[](maxQuorumsToRegisterFor); - for (uint256 i = 0; i < minimumStakeForQuorum.length; i++) { - minimumStakeForQuorum[i] = uint96(i+1); - } - - // setup the dummy quorum strategies - IVoteWeigher.StrategyAndWeightingMultiplier[][] memory quorumStrategiesConsideredAndMultipliers = - new IVoteWeigher.StrategyAndWeightingMultiplier[][](maxQuorumsToRegisterFor); - for (uint256 i = 0; i < quorumStrategiesConsideredAndMultipliers.length; i++) { - quorumStrategiesConsideredAndMultipliers[i] = new IVoteWeigher.StrategyAndWeightingMultiplier[](1); - quorumStrategiesConsideredAndMultipliers[i][0] = IVoteWeigher.StrategyAndWeightingMultiplier( - IStrategy(address(uint160(i))), - uint96(i+1) - ); - } - stakeRegistry = StakeRegistryHarness( address( new TransparentUpgradeableProxy( address(stakeRegistryImplementation), address(proxyAdmin), - abi.encodeWithSelector( - StakeRegistry.initialize.selector, - minimumStakeForQuorum, - quorumStrategiesConsideredAndMultipliers - ) + "" ) ) ); - cheats.stopPrank(); - } - function testCorrectConstruction() public { - // make sure the contract intializers are disabled - cheats.expectRevert(bytes("Initializable: contract is already initialized")); - stakeRegistryImplementation.initialize(new uint96[](0), new IVoteWeigher.StrategyAndWeightingMultiplier[][](0)); + // Initialize quorums with dummy minimum stake and strategies + for (uint i = 0; i < maxQuorumsToRegisterFor; i++) { + uint96 minimumStake = uint96(i + 1); + IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategyParams = + new IStakeRegistry.StrategyAndWeightingMultiplier[](1); + strategyParams[0] = IStakeRegistry.StrategyAndWeightingMultiplier( + IStrategy(address(uint160(i))), + uint96(i+1) + ); + + _initializeQuorum(uint8(defaultQuorumNumber + i), minimumStake, strategyParams); + } + + // Update the reg coord quorum count so updateStakes works + registryCoordinator.setQuorumCount(maxQuorumsToRegisterFor); } function testSetMinimumStakeForQuorum_NotFromServiceManager_Reverts() public { - cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); + cheats.expectRevert("StakeRegistry.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); stakeRegistry.setMinimumStakeForQuorum(defaultQuorumNumber, 0); } function testSetMinimumStakeForQuorum_Valid(uint8 quorumNumber, uint96 minimumStakeForQuorum) public { + // filter out non-initialized quorums + cheats.assume(initializedQuorums[quorumNumber]); + // set the minimum stake for quorum cheats.prank(serviceManagerOwner); stakeRegistry.setMinimumStakeForQuorum(quorumNumber, minimumStakeForQuorum); @@ -177,18 +174,6 @@ contract StakeRegistryUnitTests is Test { stakeRegistry.registerOperator(defaultOperator, defaultOperatorId, quorumNumbers); } - function testRegisterOperator_MoreQuorumsThanQuorumCount_Reverts() public { - bytes memory quorumNumbers = new bytes(maxQuorumsToRegisterFor+1); - for (uint i = 0; i < quorumNumbers.length; i++) { - quorumNumbers[i] = bytes1(uint8(i)); - } - - // expect that it reverts when you register - cheats.expectRevert("StakeRegistry._registerOperator: greatest quorumNumber must be less than quorumCount"); - cheats.prank(address(registryCoordinator)); - stakeRegistry.registerOperator(defaultOperator, defaultOperatorId, quorumNumbers); - } - function testRegisterOperator_LessThanMinimumStakeForQuorum_Reverts( uint96[] memory stakesForQuorum ) public { @@ -205,7 +190,7 @@ contract StakeRegistryUnitTests is Test { stakesForQuorum[stakesForQuorum.length - 1] = stakeRegistry.minimumStakeForQuorum(uint8(quorumNumbers.length - 1)) - 1; // expect that it reverts when you register - cheats.expectRevert("StakeRegistry._registerOperator: Operator does not meet minimum stake requirement for quorum"); + cheats.expectRevert("StakeRegistry.registerOperator: Operator does not meet minimum stake requirement for quorum"); cheats.prank(address(registryCoordinator)); stakeRegistry.registerOperator(defaultOperator, defaultOperatorId, quorumNumbers); } @@ -244,7 +229,7 @@ contract StakeRegistryUnitTests is Test { // check that the operator has 0 stake updates in the quorum numbers they did not register for assertEq(stakeRegistry.getLengthOfOperatorIdStakeHistoryForQuorum(defaultOperatorId, i), 0); // make the analogous check for total stake history - assertEq(stakeRegistry.getLengthOfTotalStakeHistoryForQuorum(i), 0); + assertEq(stakeRegistry.getLengthOfTotalStakeHistoryForQuorum(i), 1); } } } @@ -322,10 +307,9 @@ contract StakeRegistryUnitTests is Test { // make sure that the stake update is as expected IStakeRegistry.OperatorStakeUpdate memory totalStakeUpdate = - stakeRegistry.getTotalStakeUpdateForQuorumFromIndex(i, historyLength-1); + stakeRegistry.getTotalStakeUpdateForQuorumFromIndex(i, historyLength-1); assertEq(totalStakeUpdate.stake, cumulativeStake); - assertEq(totalStakeUpdate.updateBlockNumber, cumulativeBlockNumber); // make sure that the next update block number of the previous stake update is as expected if (historyLength >= 2) { IStakeRegistry.OperatorStakeUpdate memory prevTotalStakeUpdate = @@ -421,7 +405,7 @@ contract StakeRegistryUnitTests is Test { quorumNumberIndex++; } else if (quorumBitmap >> i & 1 == 1) { assertEq(stakeRegistry.getLengthOfOperatorIdStakeHistoryForQuorum(operatorIdToDeregister, i), 1, "testDeregisterFirstOperator_Valid_8"); - assertEq(stakeRegistry.getLengthOfTotalStakeHistoryForQuorum(i), numOperatorsInQuorum[i], "testDeregisterFirstOperator_Valid_9"); + assertEq(stakeRegistry.getLengthOfTotalStakeHistoryForQuorum(i), numOperatorsInQuorum[i] + 1, "testDeregisterFirstOperator_Valid_9"); quorumNumberIndex++; } else { // check that the operator has 0 stake updates in the quorum numbers they did not register for @@ -503,8 +487,15 @@ contract StakeRegistryUnitTests is Test { cheats.roll(intialBlockNumber); bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); + for (uint i = 0; i < stakesForQuorum.length; i++) { + emit log_named_uint("quorum", uint8(quorumNumbers[i])); + emit log_named_uint("stake", uint96(stakesForQuorum[i])); + } + for(uint i = 0; i < stakesForQuorum.length; i++) { stakeRegistry.setOperatorWeight(uint8(quorumNumbers[i]), defaultOperator, stakesForQuorum[i] + 1); + emit log_named_uint("updating quorum", uint8(quorumNumbers[i])); + emit log_named_uint("to stake", uint96(stakesForQuorum[i] + 1)); } address[] memory operators = new address[](1); @@ -512,11 +503,24 @@ contract StakeRegistryUnitTests is Test { stakeRegistry.updateStakes(operators); for(uint i = 0; i < quorumNumbers.length; i++) { - StakeRegistry.OperatorStakeUpdate memory operatorStakeUpdate = stakeRegistry.getStakeUpdateForQuorumFromOperatorIdAndIndex(uint8(quorumNumbers[i]), defaultOperatorId, 1); + StakeRegistry.OperatorStakeUpdate memory operatorStakeUpdate = stakeRegistry.getMostRecentStakeUpdateByOperatorId(defaultOperatorId, uint8(quorumNumbers[i])); + emit log_named_uint("quorum", uint8(quorumNumbers[i])); + emit log_named_uint("most recent stake", operatorStakeUpdate.stake); assertEq(operatorStakeUpdate.stake, stakesForQuorum[i] + 1); } } + function _initializeQuorum( + uint8 quorumNumber, + uint96 minimumStake, + IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategyParams + ) internal { + cheats.prank(address(registryCoordinator)); + + stakeRegistry.initializeQuorum(quorumNumber, minimumStake, strategyParams); + initializedQuorums[quorumNumber] = true; + } + // utility function for registering an operator with a valid quorumBitmap and stakesForQuorum using provided randomness function _registerOperatorRandomValid( address operator, diff --git a/test/unit/VoteWeigherBaseUnit.t.sol b/test/unit/VoteWeigherBaseUnit.t.sol index ca5cef44..8a604ce5 100644 --- a/test/unit/VoteWeigherBaseUnit.t.sol +++ b/test/unit/VoteWeigherBaseUnit.t.sol @@ -11,7 +11,7 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; import {IServiceManager} from "src/interfaces/IServiceManager.sol"; -import {IVoteWeigher} from "src/interfaces/IVoteWeigher.sol"; +import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; import {StakeRegistry} from "src/StakeRegistry.sol"; import {RegistryCoordinatorMock} from "test/mocks/RegistryCoordinatorMock.sol"; @@ -91,429 +91,430 @@ contract VoteWeigherBaseUnitTests is Test { assertEq(address(voteWeigherImplementation.serviceManager()), address(serviceManager)); } - function testCreateQuorum_Valid(IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) public { - strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); - // create a quorum from the serviceManagerOwner - // get the quorum count before the quorum is created - uint8 quorumCountBefore = uint8(voteWeigher.quorumCount()); - cheats.prank(serviceManagerOwner); - // expect each strategy to be added to the quorum - for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { - cheats.expectEmit(true, true, true, true, address(voteWeigher)); - emit StrategyAddedToQuorum(quorumCountBefore, strategiesAndWeightingMultipliers[i].strategy); - } - // created quorum will have quorum number of the count before it was created - cheats.expectEmit(true, true, true, true, address(voteWeigher)); - emit QuorumCreated(quorumCountBefore); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + /// TODO - migrate tests to registry coordinator + // function testCreateQuorum_Valid(IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) public { + // strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); + // // create a quorum from the serviceManagerOwner + // // get the quorum count before the quorum is created + // uint8 quorumCountBefore = uint8(voteWeigher.quorumCount()); + // cheats.prank(serviceManagerOwner); + // // expect each strategy to be added to the quorum + // for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { + // cheats.expectEmit(true, true, true, true, address(voteWeigher)); + // emit StrategyAddedToQuorum(quorumCountBefore, strategiesAndWeightingMultipliers[i].strategy); + // } + // // created quorum will have quorum number of the count before it was created + // cheats.expectEmit(true, true, true, true, address(voteWeigher)); + // emit QuorumCreated(quorumCountBefore); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - assertEq(voteWeigher.quorumCount(), quorumCountBefore + 1); - // check that all of the weights are correct - for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { - IVoteWeigher.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumCountBefore, i); - assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); - assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); - } - } - - function testCreateQuorum_FromNotServiceManagerOwner_Reverts( - address notServiceManagerOwner, - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers - ) public fuzzedAddress(notServiceManagerOwner) { - cheats.assume(notServiceManagerOwner != serviceManagerOwner); - cheats.prank(notServiceManagerOwner); - cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testCreateQuorum_StrategiesAndWeightingMultipliers_LengthGreaterThanMaxAllowed_Reverts( - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers - ) public { - strategiesAndWeightingMultipliers = _removeDuplicates(strategiesAndWeightingMultipliers); - strategiesAndWeightingMultipliers = _replaceZeroWeights(strategiesAndWeightingMultipliers); - - cheats.assume(strategiesAndWeightingMultipliers.length > voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); - cheats.prank(serviceManagerOwner); - cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: exceed MAX_WEIGHING_FUNCTION_LENGTH"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testCreateQuorum_StrategiesAndWeightingMultipliers_WithDuplicateStrategies_Reverts( - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, - uint256 indexFromDuplicate, - uint256 indexToDuplicate - ) public { - cheats.assume(strategiesAndWeightingMultipliers.length <= voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); - cheats.assume(strategiesAndWeightingMultipliers.length > 1); - strategiesAndWeightingMultipliers = _replaceZeroWeights(strategiesAndWeightingMultipliers); - - // plant a duplicate strategy - indexToDuplicate = indexToDuplicate % strategiesAndWeightingMultipliers.length; - indexFromDuplicate = indexFromDuplicate % strategiesAndWeightingMultipliers.length; - cheats.assume(indexToDuplicate != indexFromDuplicate); - strategiesAndWeightingMultipliers[indexToDuplicate].strategy = strategiesAndWeightingMultipliers[indexFromDuplicate].strategy; - - cheats.prank(serviceManagerOwner); - cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: cannot add same strategy 2x"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testCreateQuorum_EmptyStrategiesAndWeightingMultipliers_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers; - cheats.prank(serviceManagerOwner); - cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: no strategies provided"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testCreateQuorum_StrategiesAndWeightingMultipliers_WithZeroWeight( - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, - uint256 indexForZeroMultiplier - ) public { - strategiesAndWeightingMultipliers = _removeDuplicates(strategiesAndWeightingMultipliers); - cheats.assume(strategiesAndWeightingMultipliers.length <= voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); - cheats.assume(strategiesAndWeightingMultipliers.length > 0); - //plant a zero weight - strategiesAndWeightingMultipliers[indexForZeroMultiplier % strategiesAndWeightingMultipliers.length].multiplier = 0; - - cheats.prank(serviceManagerOwner); - cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: cannot add strategy with zero weight"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testCreateQuorum_MoreThanMaxQuorums_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - uint256 maxQuorums = voteWeigher.MAX_QUORUM_COUNT(); + // assertEq(voteWeigher.quorumCount(), quorumCountBefore + 1); + // // check that all of the weights are correct + // for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { + // IStakeRegistry.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumCountBefore, i); + // assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); + // assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); + // } + // } + + // function testCreateQuorum_FromNotServiceManagerOwner_Reverts( + // address notServiceManagerOwner, + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers + // ) public fuzzedAddress(notServiceManagerOwner) { + // cheats.assume(notServiceManagerOwner != serviceManagerOwner); + // cheats.prank(notServiceManagerOwner); + // cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testCreateQuorum_StrategiesAndWeightingMultipliers_LengthGreaterThanMaxAllowed_Reverts( + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers + // ) public { + // strategiesAndWeightingMultipliers = _removeDuplicates(strategiesAndWeightingMultipliers); + // strategiesAndWeightingMultipliers = _replaceZeroWeights(strategiesAndWeightingMultipliers); + + // cheats.assume(strategiesAndWeightingMultipliers.length > voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); + // cheats.prank(serviceManagerOwner); + // cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: exceed MAX_WEIGHING_FUNCTION_LENGTH"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testCreateQuorum_StrategiesAndWeightingMultipliers_WithDuplicateStrategies_Reverts( + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, + // uint256 indexFromDuplicate, + // uint256 indexToDuplicate + // ) public { + // cheats.assume(strategiesAndWeightingMultipliers.length <= voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); + // cheats.assume(strategiesAndWeightingMultipliers.length > 1); + // strategiesAndWeightingMultipliers = _replaceZeroWeights(strategiesAndWeightingMultipliers); + + // // plant a duplicate strategy + // indexToDuplicate = indexToDuplicate % strategiesAndWeightingMultipliers.length; + // indexFromDuplicate = indexFromDuplicate % strategiesAndWeightingMultipliers.length; + // cheats.assume(indexToDuplicate != indexFromDuplicate); + // strategiesAndWeightingMultipliers[indexToDuplicate].strategy = strategiesAndWeightingMultipliers[indexFromDuplicate].strategy; + + // cheats.prank(serviceManagerOwner); + // cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: cannot add same strategy 2x"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testCreateQuorum_EmptyStrategiesAndWeightingMultipliers_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers; + // cheats.prank(serviceManagerOwner); + // cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: no strategies provided"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testCreateQuorum_StrategiesAndWeightingMultipliers_WithZeroWeight( + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, + // uint256 indexForZeroMultiplier + // ) public { + // strategiesAndWeightingMultipliers = _removeDuplicates(strategiesAndWeightingMultipliers); + // cheats.assume(strategiesAndWeightingMultipliers.length <= voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); + // cheats.assume(strategiesAndWeightingMultipliers.length > 0); + // //plant a zero weight + // strategiesAndWeightingMultipliers[indexForZeroMultiplier % strategiesAndWeightingMultipliers.length].multiplier = 0; + + // cheats.prank(serviceManagerOwner); + // cheats.expectRevert("VoteWeigherBase._addStrategiesConsideredAndMultipliers: cannot add strategy with zero weight"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testCreateQuorum_MoreThanMaxQuorums_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + // uint256 maxQuorums = voteWeigher.MAX_QUORUM_COUNT(); - cheats.startPrank(serviceManagerOwner); - for (uint i = 0; i < maxQuorums; i++) { - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - assertEq(voteWeigher.quorumCount(), maxQuorums); - - cheats.expectRevert("VoteWeigherBase._createQuorum: number of quorums cannot exceed MAX_QUORUM_COUNT"); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - } - - function testAddStrategiesConsideredAndMultipliers_Valid( - uint256 randomSplit, - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers - ) public { - strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); - // make sure there is at least 2 strategies - cheats.assume(strategiesAndWeightingMultipliers.length > 1); - // we need at least 1 strategy in each side of the split - randomSplit = randomSplit % (strategiesAndWeightingMultipliers.length - 1) + 1; - // create 2 arrays, 1 with the first randomSplit elements and 1 with the rest - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers1 = new IVoteWeigher.StrategyAndWeightingMultiplier[](randomSplit); - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers2 = new IVoteWeigher.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length - randomSplit); - for (uint256 i = 0; i < strategiesAndWeightingMultipliers.length; i++) { - if (i < randomSplit) { - strategiesAndWeightingMultipliers1[i] = strategiesAndWeightingMultipliers[i]; - } else { - strategiesAndWeightingMultipliers2[i - randomSplit] = strategiesAndWeightingMultipliers[i]; - } - } - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - // create quorum with the first randomSplit elements - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers1); - - // add the rest of the strategies - for (uint i = 0; i < strategiesAndWeightingMultipliers2.length; i++) { - cheats.expectEmit(true, true, true, true, address(voteWeigher)); - emit StrategyAddedToQuorum(quorumNumber, strategiesAndWeightingMultipliers2[i].strategy); - } - voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber, strategiesAndWeightingMultipliers2); - - // check that the quorum was created and strategies were added correctly - for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { - IVoteWeigher.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); - assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); - assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); - } - } - - function testAddStrategiesConsideredAndMultipliers_NotFromServiceManagerOwner_Reverts( - address notServiceManagerOwner - ) public fuzzedAddress(notServiceManagerOwner) { - cheats.assume(notServiceManagerOwner != serviceManagerOwner); - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - // create quorum with all but the last element - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.prank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // add the last element - cheats.prank(notServiceManagerOwner); - cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); - voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber, strategiesAndWeightingMultipliers); - } - - function testAddStrategiesConsideredAndMultipliers_ForNonexistentQuorum_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - // create quorum with all but the last element - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // add the last element - cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); - voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber+1, strategiesAndWeightingMultipliers); - } - - // this test generates a psudorandom descending order array of indices to remove - // removes them, and checks that the strategies were removed correctly by computing - // a local copy of the strategies when the removal algorithm is applied and comparing - function testRemoveStrategiesConsideredAndMultipliers_Valid( - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, - uint256 randomness - ) public { - strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); - // generate a bunch of random array of valid descending order indices - uint256[] memory indicesToRemove = _generateRandomUniqueIndices(randomness, strategiesAndWeightingMultipliers.length); - - // create the quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // remove certain strategies - // make sure events are emmitted - for (uint i = 0; i < indicesToRemove.length; i++) { - cheats.expectEmit(true, true, true, true, address(voteWeigher)); - emit StrategyRemovedFromQuorum(quorumNumber, strategiesAndWeightingMultipliers[indicesToRemove[i]].strategy); - } - voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, indicesToRemove); + // cheats.startPrank(serviceManagerOwner); + // for (uint i = 0; i < maxQuorums; i++) { + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + // assertEq(voteWeigher.quorumCount(), maxQuorums); + + // cheats.expectRevert("VoteWeigherBase._createQuorum: number of quorums cannot exceed MAX_QUORUM_COUNT"); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + // } + + // function testAddStrategiesConsideredAndMultipliers_Valid( + // uint256 randomSplit, + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers + // ) public { + // strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); + // // make sure there is at least 2 strategies + // cheats.assume(strategiesAndWeightingMultipliers.length > 1); + // // we need at least 1 strategy in each side of the split + // randomSplit = randomSplit % (strategiesAndWeightingMultipliers.length - 1) + 1; + // // create 2 arrays, 1 with the first randomSplit elements and 1 with the rest + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers1 = new IStakeRegistry.StrategyAndWeightingMultiplier[](randomSplit); + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers2 = new IStakeRegistry.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length - randomSplit); + // for (uint256 i = 0; i < strategiesAndWeightingMultipliers.length; i++) { + // if (i < randomSplit) { + // strategiesAndWeightingMultipliers1[i] = strategiesAndWeightingMultipliers[i]; + // } else { + // strategiesAndWeightingMultipliers2[i - randomSplit] = strategiesAndWeightingMultipliers[i]; + // } + // } + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // // create quorum with the first randomSplit elements + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers1); + + // // add the rest of the strategies + // for (uint i = 0; i < strategiesAndWeightingMultipliers2.length; i++) { + // cheats.expectEmit(true, true, true, true, address(voteWeigher)); + // emit StrategyAddedToQuorum(quorumNumber, strategiesAndWeightingMultipliers2[i].strategy); + // } + // voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber, strategiesAndWeightingMultipliers2); + + // // check that the quorum was created and strategies were added correctly + // for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { + // IStakeRegistry.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); + // assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); + // assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); + // } + // } + + // function testAddStrategiesConsideredAndMultipliers_NotFromServiceManagerOwner_Reverts( + // address notServiceManagerOwner + // ) public fuzzedAddress(notServiceManagerOwner) { + // cheats.assume(notServiceManagerOwner != serviceManagerOwner); + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // // create quorum with all but the last element + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.prank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // add the last element + // cheats.prank(notServiceManagerOwner); + // cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); + // voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber, strategiesAndWeightingMultipliers); + // } + + // function testAddStrategiesConsideredAndMultipliers_ForNonexistentQuorum_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // // create quorum with all but the last element + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // add the last element + // cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); + // voteWeigher.addStrategiesConsideredAndMultipliers(quorumNumber+1, strategiesAndWeightingMultipliers); + // } + + // // this test generates a psudorandom descending order array of indices to remove + // // removes them, and checks that the strategies were removed correctly by computing + // // a local copy of the strategies when the removal algorithm is applied and comparing + // function testRemoveStrategiesConsideredAndMultipliers_Valid( + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, + // uint256 randomness + // ) public { + // strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); + // // generate a bunch of random array of valid descending order indices + // uint256[] memory indicesToRemove = _generateRandomUniqueIndices(randomness, strategiesAndWeightingMultipliers.length); + + // // create the quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // remove certain strategies + // // make sure events are emmitted + // for (uint i = 0; i < indicesToRemove.length; i++) { + // cheats.expectEmit(true, true, true, true, address(voteWeigher)); + // emit StrategyRemovedFromQuorum(quorumNumber, strategiesAndWeightingMultipliers[indicesToRemove[i]].strategy); + // } + // voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, indicesToRemove); - // check that the strategies that were not removed are still there - // get all strategies and multipliers form the contracts - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliersFromContract = new IVoteWeigher.StrategyAndWeightingMultiplier[](voteWeigher.strategiesConsideredAndMultipliersLength(quorumNumber)); - for (uint256 i = 0; i < strategiesAndWeightingMultipliersFromContract.length; i++) { - strategiesAndWeightingMultipliersFromContract[i] = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); - } - - // remove indicesToRemove from local strategiesAndWeightingMultipliers - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliersLocal = new IVoteWeigher.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length - indicesToRemove.length); + // // check that the strategies that were not removed are still there + // // get all strategies and multipliers form the contracts + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliersFromContract = new IStakeRegistry.StrategyAndWeightingMultiplier[](voteWeigher.strategiesConsideredAndMultipliersLength(quorumNumber)); + // for (uint256 i = 0; i < strategiesAndWeightingMultipliersFromContract.length; i++) { + // strategiesAndWeightingMultipliersFromContract[i] = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); + // } + + // // remove indicesToRemove from local strategiesAndWeightingMultipliers + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliersLocal = new IStakeRegistry.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length - indicesToRemove.length); - // run the removal algorithm locally - uint256 endIndex = strategiesAndWeightingMultipliers.length - 1; - for (uint256 i = 0; i < indicesToRemove.length; i++) { - strategiesAndWeightingMultipliers[indicesToRemove[i]] = strategiesAndWeightingMultipliers[endIndex]; - if (endIndex > 0) { - endIndex--; - } - } - for (uint256 i = 0; i < strategiesAndWeightingMultipliersLocal.length; i++) { - strategiesAndWeightingMultipliersLocal[i] = strategiesAndWeightingMultipliers[i]; - } - - // check that the arrays are the same - assertEq(strategiesAndWeightingMultipliersFromContract.length, strategiesAndWeightingMultipliersLocal.length); - for (uint256 i = 0; i < strategiesAndWeightingMultipliersFromContract.length; i++) { - assertEq(address(strategiesAndWeightingMultipliersFromContract[i].strategy), address(strategiesAndWeightingMultipliersLocal[i].strategy)); - assertEq(strategiesAndWeightingMultipliersFromContract[i].multiplier, strategiesAndWeightingMultipliersLocal[i].multiplier); - } - - } - - function testRemoveStrategiesConsideredAndMultipliers_NotFromServiceManagerOwner_Reverts( - address notServiceManagerOwner - ) public fuzzedAddress(notServiceManagerOwner) { - cheats.assume(notServiceManagerOwner != serviceManagerOwner); - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - uint256[] memory indicesToRemove = new uint256[](1); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.prank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // remove certain strategies - cheats.prank(notServiceManagerOwner); - cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); - voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, indicesToRemove); - } - - function testRemoveStrategiesConsideredAndMultipliers_ForNonexistentQuorum_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - uint256[] memory indicesToRemove = new uint256[](1); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // remove strategies from a non-existent quorum - cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); - voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber + 1, indicesToRemove); - } - - function testRemoveStrategiesConsideredAndMultipliers_EmptyIndicesToRemove_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // remove no strategies - cheats.expectRevert("VoteWeigherBase.removeStrategiesConsideredAndMultipliers: no indices to remove provided"); - voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, new uint256[](0)); - } - - function testModifyStrategyWeights_NotFromServiceManagerOwner_Reverts( - address notServiceManagerOwner - ) public fuzzedAddress(notServiceManagerOwner) { - cheats.assume(notServiceManagerOwner != serviceManagerOwner); - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - uint256[] memory strategyIndices = new uint256[](1); - uint96[] memory newWeights = new uint96[](1); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.prank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // modify certain strategies - cheats.prank(notServiceManagerOwner); - cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); - voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); - } - - function testModifyStrategyWeights_Valid( - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, - uint96[] memory newWeights, - uint256 randomness - ) public { - strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); - uint256[] memory strategyIndices = _generateRandomUniqueIndices(randomness, strategiesAndWeightingMultipliers.length); - - // trim the provided weights to the length of the strategyIndices and extend if it is shorter - uint96[] memory newWeightsTrim = new uint96[](strategyIndices.length); - for (uint256 i = 0; i < strategyIndices.length; i++) { - if(i < newWeights.length) { - newWeightsTrim[i] = newWeights[i]; - } else { - newWeightsTrim[i] = strategiesAndWeightingMultipliers[strategyIndices[i]].multiplier - 1; - } - } - newWeights = newWeightsTrim; - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // modify certain strategies - for (uint i = 0; i < strategyIndices.length; i++) { - cheats.expectEmit(true, true, true, true, address(voteWeigher)); - emit StrategyMultiplierUpdated(quorumNumber, strategiesAndWeightingMultipliers[strategyIndices[i]].strategy, newWeights[i]); - } - voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); - - // convert the strategies and weighting multipliers to the modified - for (uint i = 0; i < strategyIndices.length; i++) { - strategiesAndWeightingMultipliers[strategyIndices[i]].multiplier = newWeights[i]; - } - // make sure the quorum strategies and weights have changed - for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { - IVoteWeigher.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); - assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); - assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); - } - } - - function testModifyStrategyWeights_ForNonexistentQuorum_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - uint256[] memory strategyIndices = new uint256[](1); - uint96[] memory newWeights = new uint96[](1); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // modify certain strategies of a non-existent quorum - cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); - voteWeigher.modifyStrategyWeights(quorumNumber + 1, strategyIndices, newWeights); - } - - function testModifyStrategyWeights_InconsistentStrategyAndWeightArrayLengths_Reverts( - uint256[] memory strategyIndices, - uint96[] memory newWeights - ) public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - // make sure the arrays are of different lengths - cheats.assume(strategyIndices.length != newWeights.length); - cheats.assume(strategyIndices.length > 0); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // modify certain strategies - cheats.expectRevert("VoteWeigherBase.modifyStrategyWeights: input length mismatch"); - voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); - } - - function testModifyStrategyWeights_EmptyStrategyIndicesAndWeights_Reverts() public { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndWeightingMultipliers); - - // modify no strategies - cheats.expectRevert("VoteWeigherBase.modifyStrategyWeights: no strategy indices provided"); - voteWeigher.modifyStrategyWeights(quorumNumber, new uint256[](0), new uint96[](0)); - } - - function testWeightOfOperatorForQuorum( - address operator, - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndMultipliers, - uint96[] memory shares - ) public { - strategiesAndMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndMultipliers); - cheats.assume(shares.length >= strategiesAndMultipliers.length); - for (uint i = 0; i < strategiesAndMultipliers.length; i++) { - if(uint256(shares[i]) * uint256(strategiesAndMultipliers[i].multiplier) > type(uint96).max) { - strategiesAndMultipliers[i].multiplier = 1; - } - } - - // set the operator shares - for (uint i = 0; i < strategiesAndMultipliers.length; i++) { - delegationMock.setOperatorShares(operator, strategiesAndMultipliers[i].strategy, shares[i]); - } - - // create a valid quorum - uint8 quorumNumber = uint8(voteWeigher.quorumCount()); - cheats.startPrank(serviceManagerOwner); - voteWeigher.createQuorum(strategiesAndMultipliers); - - // make sure the weight of the operator is correct - uint256 expectedWeight = 0; - for (uint i = 0; i < strategiesAndMultipliers.length; i++) { - expectedWeight += shares[i] * strategiesAndMultipliers[i].multiplier / voteWeigher.WEIGHTING_DIVISOR(); - } - - assertEq(voteWeigher.weightOfOperatorForQuorum(quorumNumber, operator), expectedWeight); - } - - function _removeDuplicates(IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) + // // run the removal algorithm locally + // uint256 endIndex = strategiesAndWeightingMultipliers.length - 1; + // for (uint256 i = 0; i < indicesToRemove.length; i++) { + // strategiesAndWeightingMultipliers[indicesToRemove[i]] = strategiesAndWeightingMultipliers[endIndex]; + // if (endIndex > 0) { + // endIndex--; + // } + // } + // for (uint256 i = 0; i < strategiesAndWeightingMultipliersLocal.length; i++) { + // strategiesAndWeightingMultipliersLocal[i] = strategiesAndWeightingMultipliers[i]; + // } + + // // check that the arrays are the same + // assertEq(strategiesAndWeightingMultipliersFromContract.length, strategiesAndWeightingMultipliersLocal.length); + // for (uint256 i = 0; i < strategiesAndWeightingMultipliersFromContract.length; i++) { + // assertEq(address(strategiesAndWeightingMultipliersFromContract[i].strategy), address(strategiesAndWeightingMultipliersLocal[i].strategy)); + // assertEq(strategiesAndWeightingMultipliersFromContract[i].multiplier, strategiesAndWeightingMultipliersLocal[i].multiplier); + // } + + // } + + // function testRemoveStrategiesConsideredAndMultipliers_NotFromServiceManagerOwner_Reverts( + // address notServiceManagerOwner + // ) public fuzzedAddress(notServiceManagerOwner) { + // cheats.assume(notServiceManagerOwner != serviceManagerOwner); + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // uint256[] memory indicesToRemove = new uint256[](1); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.prank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // remove certain strategies + // cheats.prank(notServiceManagerOwner); + // cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); + // voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, indicesToRemove); + // } + + // function testRemoveStrategiesConsideredAndMultipliers_ForNonexistentQuorum_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // uint256[] memory indicesToRemove = new uint256[](1); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // remove strategies from a non-existent quorum + // cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); + // voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber + 1, indicesToRemove); + // } + + // function testRemoveStrategiesConsideredAndMultipliers_EmptyIndicesToRemove_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // remove no strategies + // cheats.expectRevert("VoteWeigherBase.removeStrategiesConsideredAndMultipliers: no indices to remove provided"); + // voteWeigher.removeStrategiesConsideredAndMultipliers(quorumNumber, new uint256[](0)); + // } + + // function testModifyStrategyWeights_NotFromServiceManagerOwner_Reverts( + // address notServiceManagerOwner + // ) public fuzzedAddress(notServiceManagerOwner) { + // cheats.assume(notServiceManagerOwner != serviceManagerOwner); + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // uint256[] memory strategyIndices = new uint256[](1); + // uint96[] memory newWeights = new uint96[](1); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.prank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // modify certain strategies + // cheats.prank(notServiceManagerOwner); + // cheats.expectRevert("VoteWeigherBase.onlyServiceManagerOwner: caller is not the owner of the serviceManager"); + // voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); + // } + + // function testModifyStrategyWeights_Valid( + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers, + // uint96[] memory newWeights, + // uint256 randomness + // ) public { + // strategiesAndWeightingMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndWeightingMultipliers); + // uint256[] memory strategyIndices = _generateRandomUniqueIndices(randomness, strategiesAndWeightingMultipliers.length); + + // // trim the provided weights to the length of the strategyIndices and extend if it is shorter + // uint96[] memory newWeightsTrim = new uint96[](strategyIndices.length); + // for (uint256 i = 0; i < strategyIndices.length; i++) { + // if(i < newWeights.length) { + // newWeightsTrim[i] = newWeights[i]; + // } else { + // newWeightsTrim[i] = strategiesAndWeightingMultipliers[strategyIndices[i]].multiplier - 1; + // } + // } + // newWeights = newWeightsTrim; + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // modify certain strategies + // for (uint i = 0; i < strategyIndices.length; i++) { + // cheats.expectEmit(true, true, true, true, address(voteWeigher)); + // emit StrategyMultiplierUpdated(quorumNumber, strategiesAndWeightingMultipliers[strategyIndices[i]].strategy, newWeights[i]); + // } + // voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); + + // // convert the strategies and weighting multipliers to the modified + // for (uint i = 0; i < strategyIndices.length; i++) { + // strategiesAndWeightingMultipliers[strategyIndices[i]].multiplier = newWeights[i]; + // } + // // make sure the quorum strategies and weights have changed + // for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { + // IStakeRegistry.StrategyAndWeightingMultiplier memory strategyAndWeightingMultiplier = voteWeigher.strategyAndWeightingMultiplierForQuorumByIndex(quorumNumber, i); + // assertEq(address(strategyAndWeightingMultiplier.strategy), address(strategiesAndWeightingMultipliers[i].strategy)); + // assertEq(strategyAndWeightingMultiplier.multiplier, strategiesAndWeightingMultipliers[i].multiplier); + // } + // } + + // function testModifyStrategyWeights_ForNonexistentQuorum_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // uint256[] memory strategyIndices = new uint256[](1); + // uint96[] memory newWeights = new uint96[](1); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // modify certain strategies of a non-existent quorum + // cheats.expectRevert("VoteWeigherBase.validQuorumNumber: quorumNumber is not valid"); + // voteWeigher.modifyStrategyWeights(quorumNumber + 1, strategyIndices, newWeights); + // } + + // function testModifyStrategyWeights_InconsistentStrategyAndWeightArrayLengths_Reverts( + // uint256[] memory strategyIndices, + // uint96[] memory newWeights + // ) public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // // make sure the arrays are of different lengths + // cheats.assume(strategyIndices.length != newWeights.length); + // cheats.assume(strategyIndices.length > 0); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // modify certain strategies + // cheats.expectRevert("VoteWeigherBase.modifyStrategyWeights: input length mismatch"); + // voteWeigher.modifyStrategyWeights(quorumNumber, strategyIndices, newWeights); + // } + + // function testModifyStrategyWeights_EmptyStrategyIndicesAndWeights_Reverts() public { + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = _defaultStrategiesAndWeightingMultipliers(); + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndWeightingMultipliers); + + // // modify no strategies + // cheats.expectRevert("VoteWeigherBase.modifyStrategyWeights: no strategy indices provided"); + // voteWeigher.modifyStrategyWeights(quorumNumber, new uint256[](0), new uint96[](0)); + // } + + // function testWeightOfOperatorForQuorum( + // address operator, + // IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndMultipliers, + // uint96[] memory shares + // ) public { + // strategiesAndMultipliers = _convertToValidStrategiesAndWeightingMultipliers(strategiesAndMultipliers); + // cheats.assume(shares.length >= strategiesAndMultipliers.length); + // for (uint i = 0; i < strategiesAndMultipliers.length; i++) { + // if(uint256(shares[i]) * uint256(strategiesAndMultipliers[i].multiplier) > type(uint96).max) { + // strategiesAndMultipliers[i].multiplier = 1; + // } + // } + + // // set the operator shares + // for (uint i = 0; i < strategiesAndMultipliers.length; i++) { + // delegationMock.setOperatorShares(operator, strategiesAndMultipliers[i].strategy, shares[i]); + // } + + // // create a valid quorum + // uint8 quorumNumber = uint8(voteWeigher.quorumCount()); + // cheats.startPrank(serviceManagerOwner); + // voteWeigher.createQuorum(strategiesAndMultipliers); + + // // make sure the weight of the operator is correct + // uint256 expectedWeight = 0; + // for (uint i = 0; i < strategiesAndMultipliers.length; i++) { + // expectedWeight += shares[i] * strategiesAndMultipliers[i].multiplier / voteWeigher.WEIGHTING_DIVISOR(); + // } + + // assertEq(voteWeigher.weightOfOperatorForQuorum(quorumNumber, operator), expectedWeight); + // } + + function _removeDuplicates(IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) internal - returns(IVoteWeigher.StrategyAndWeightingMultiplier[] memory) + returns(IStakeRegistry.StrategyAndWeightingMultiplier[] memory) { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory deduplicatedStrategiesAndWeightingMultipliers = new IVoteWeigher.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length); + IStakeRegistry.StrategyAndWeightingMultiplier[] memory deduplicatedStrategiesAndWeightingMultipliers = new IStakeRegistry.StrategyAndWeightingMultiplier[](strategiesAndWeightingMultipliers.length); uint256 numUniqueStrategies = 0; // check for duplicates for (uint i = 0; i < strategiesAndWeightingMultipliers.length; i++) { @@ -530,14 +531,14 @@ contract VoteWeigherBaseUnitTests is Test { strategyInCurrentArray[strategiesAndWeightingMultipliers[i].strategy] = false; } - IVoteWeigher.StrategyAndWeightingMultiplier[] memory trimmedStrategiesAndWeightingMultipliers = new IVoteWeigher.StrategyAndWeightingMultiplier[](numUniqueStrategies); + IStakeRegistry.StrategyAndWeightingMultiplier[] memory trimmedStrategiesAndWeightingMultipliers = new IStakeRegistry.StrategyAndWeightingMultiplier[](numUniqueStrategies); for (uint i = 0; i < numUniqueStrategies; i++) { trimmedStrategiesAndWeightingMultipliers[i] = deduplicatedStrategiesAndWeightingMultipliers[i]; } return trimmedStrategiesAndWeightingMultipliers; } - function _replaceZeroWeights(IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) internal pure returns(IVoteWeigher.StrategyAndWeightingMultiplier[] memory) { + function _replaceZeroWeights(IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) internal pure returns(IStakeRegistry.StrategyAndWeightingMultiplier[] memory) { for (uint256 i = 0; i < strategiesAndWeightingMultipliers.length; i++) { if (strategiesAndWeightingMultipliers[i].multiplier == 0) { strategiesAndWeightingMultipliers[i].multiplier = 1; @@ -571,20 +572,20 @@ contract VoteWeigherBaseUnitTests is Test { return trimmedRandomIndices; } - function _convertToValidStrategiesAndWeightingMultipliers(IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) internal returns (IVoteWeigher.StrategyAndWeightingMultiplier[] memory) { + function _convertToValidStrategiesAndWeightingMultipliers(IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers) internal returns (IStakeRegistry.StrategyAndWeightingMultiplier[] memory) { strategiesAndWeightingMultipliers = _removeDuplicates(strategiesAndWeightingMultipliers); cheats.assume(strategiesAndWeightingMultipliers.length <= voteWeigher.MAX_WEIGHING_FUNCTION_LENGTH()); cheats.assume(strategiesAndWeightingMultipliers.length > 0); return _replaceZeroWeights(strategiesAndWeightingMultipliers); } - function _defaultStrategiesAndWeightingMultipliers() internal pure returns (IVoteWeigher.StrategyAndWeightingMultiplier[] memory) { - IVoteWeigher.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = new IVoteWeigher.StrategyAndWeightingMultiplier[](2); - strategiesAndWeightingMultipliers[0] = IVoteWeigher.StrategyAndWeightingMultiplier({ + function _defaultStrategiesAndWeightingMultipliers() internal pure returns (IStakeRegistry.StrategyAndWeightingMultiplier[] memory) { + IStakeRegistry.StrategyAndWeightingMultiplier[] memory strategiesAndWeightingMultipliers = new IStakeRegistry.StrategyAndWeightingMultiplier[](2); + strategiesAndWeightingMultipliers[0] = IStakeRegistry.StrategyAndWeightingMultiplier({ strategy: IStrategy(address(uint160(uint256(keccak256("strategy1"))))), multiplier: 1.04 ether }); - strategiesAndWeightingMultipliers[1] = IVoteWeigher.StrategyAndWeightingMultiplier({ + strategiesAndWeightingMultipliers[1] = IStakeRegistry.StrategyAndWeightingMultiplier({ strategy: IStrategy(address(uint160(uint256(keccak256("strategy2"))))), multiplier: 1.69 ether }); diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 456e3bd8..6fc84bf1 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -24,7 +24,6 @@ import {IndexRegistry} from "src/IndexRegistry.sol"; import {IServiceManager} from "src/interfaces/IServiceManager.sol"; import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; -import {IVoteWeigher} from "src/interfaces/IVoteWeigher.sol"; import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; import {IIndexRegistry} from "src/interfaces/IIndexRegistry.sol"; import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; @@ -196,14 +195,38 @@ contract MockAVSDeployer is Test { ) ); + cheats.stopPrank(); + cheats.startPrank(proxyAdminOwner); + stakeRegistryImplementation = new StakeRegistryHarness( IRegistryCoordinator(registryCoordinator), - strategyManagerMock, + delegationMock, IServiceManager(address(serviceManagerMock)) ); - cheats.stopPrank(); - cheats.startPrank(proxyAdminOwner); + proxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(stakeRegistry))), + address(stakeRegistryImplementation) + ); + + blsPubkeyRegistryImplementation = new BLSPubkeyRegistry( + registryCoordinator, + BLSPublicKeyCompendium(address(pubkeyCompendium)) + ); + + proxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(blsPubkeyRegistry))), + address(blsPubkeyRegistryImplementation) + ); + + indexRegistryImplementation = new IndexRegistry( + registryCoordinator + ); + + proxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(indexRegistry))), + address(indexRegistryImplementation) + ); // setup the dummy minimum stake for quorum uint96[] memory minimumStakeForQuorum = new uint96[](numQuorumsToAdd); @@ -212,26 +235,16 @@ contract MockAVSDeployer is Test { } // setup the dummy quorum strategies - IVoteWeigher.StrategyAndWeightingMultiplier[][] memory quorumStrategiesConsideredAndMultipliers = - new IVoteWeigher.StrategyAndWeightingMultiplier[][](numQuorumsToAdd); + IStakeRegistry.StrategyAndWeightingMultiplier[][] memory quorumStrategiesConsideredAndMultipliers = + new IStakeRegistry.StrategyAndWeightingMultiplier[][](numQuorumsToAdd); for (uint256 i = 0; i < quorumStrategiesConsideredAndMultipliers.length; i++) { - quorumStrategiesConsideredAndMultipliers[i] = new IVoteWeigher.StrategyAndWeightingMultiplier[](1); - quorumStrategiesConsideredAndMultipliers[i][0] = IVoteWeigher.StrategyAndWeightingMultiplier( + quorumStrategiesConsideredAndMultipliers[i] = new IStakeRegistry.StrategyAndWeightingMultiplier[](1); + quorumStrategiesConsideredAndMultipliers[i][0] = IStakeRegistry.StrategyAndWeightingMultiplier( IStrategy(address(uint160(i))), uint96(i+1) ); } - proxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(stakeRegistry))), - address(stakeRegistryImplementation), - abi.encodeWithSelector( - StakeRegistry.initialize.selector, - minimumStakeForQuorum, - quorumStrategiesConsideredAndMultipliers - ) - ); - registryCoordinatorImplementation = new BLSRegistryCoordinatorWithIndicesHarness( slasher, serviceManagerMock, @@ -257,32 +270,15 @@ contract MockAVSDeployer is Test { BLSRegistryCoordinatorWithIndices.initialize.selector, churnApprover, ejector, - operatorSetParams, pauserRegistry, - 0/*initialPausedStatus*/ + 0/*initialPausedStatus*/, + operatorSetParams, + minimumStakeForQuorum, + quorumStrategiesConsideredAndMultipliers ) ); } - blsPubkeyRegistryImplementation = new BLSPubkeyRegistry( - registryCoordinator, - BLSPublicKeyCompendium(address(pubkeyCompendium)) - ); - - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(blsPubkeyRegistry))), - address(blsPubkeyRegistryImplementation) - ); - - indexRegistryImplementation = new IndexRegistry( - registryCoordinator - ); - - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(indexRegistry))), - address(indexRegistryImplementation) - ); - operatorStateRetriever = new BLSOperatorStateRetriever(); cheats.stopPrank();