From 0653a46712105d810d80c8760c1c1140be077331 Mon Sep 17 00:00:00 2001 From: shotaronowhere <10378902+shotaronowhere@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:10:51 -0700 Subject: [PATCH] fix: revert stakeroot calculation changes --- src/contracts/core/StakeRootCompendium.sol | 63 +++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/src/contracts/core/StakeRootCompendium.sol b/src/contracts/core/StakeRootCompendium.sol index 80f2889154..c85220142b 100644 --- a/src/contracts/core/StakeRootCompendium.sol +++ b/src/contracts/core/StakeRootCompendium.sol @@ -502,18 +502,27 @@ contract StakeRootCompendium is StakeRootCompendiumStorage { /// @inheritdoc IStakeRootCompendium function getStakeRoot( - uint32[] calldata operatorSetIdsInStakeTree, + OperatorSet[] calldata operatorSetsInStakeTree, bytes32[] calldata operatorSetRoots ) external view returns (bytes32) { - // TODO: This fn should revert if mismatched parameters are passed in due to out of bounds - // array access, see if these checks can be removed. - require(operatorSets.length == operatorSetIdsInStakeTree.length, InputArrayLengthMismatch()); - require(operatorSetIdsInStakeTree.length == operatorSetRoots.length, InputArrayLengthMismatch()); - - for (uint256 i = 0; i < operatorSetIdsInStakeTree.length; i++) { - require(operatorSets[i].operatorSetId == operatorSetIdsInStakeTree[i], InputCorrelatedVariableMismatch()); + require( + operatorSets.length == operatorSetsInStakeTree.length, + "StakeRootCompendium.getStakeRoot: operatorSets vs. operatorSetsInStakeTree length mismatch" + ); + require( + operatorSetsInStakeTree.length == operatorSetRoots.length, + "StakeRootCompendium.getStakeRoot: operatorSetsInStakeTree vs. operatorSetRoots mismatch" + ); + for (uint256 i = 0; i < operatorSetsInStakeTree.length; i++) { + require( + operatorSets[i].avs == operatorSetsInStakeTree[i].avs, + "StakeRootCompendium.getStakeRoot: operatorSets vs. operatorSetsInStakeTree avs mismatch" + ); + require( + operatorSets[i].operatorSetId == operatorSetsInStakeTree[i].operatorSetId, + "StakeRootCompendium.getStakeRoot: operatorSets vs. operatorSetsInStakeTree operatorSetId mismatch" + ); } - return Merkle.merkleizeKeccak256(operatorSetRoots); } @@ -523,17 +532,18 @@ contract StakeRootCompendium is StakeRootCompendiumStorage { uint256 startOperatorIndex, uint256 numOperators ) external view returns (OperatorSet memory, address[] memory, OperatorLeaf[] memory) { - require(operatorSetIndex < operatorSets.length, OperatorSetIndexOutOfBounds()); + require( + operatorSetIndex < operatorSets.length, + "StakeRootCompendium.getOperatorSetLeaves: operator set index out of bounds" + ); OperatorSet memory operatorSet = operatorSets[operatorSetIndex]; - address[] memory operators = - avsDirectory.getOperatorsInOperatorSet(operatorSet, startOperatorIndex, numOperators); + address[] memory operators = avsDirectory.getOperatorsInOperatorSet(operatorSet, startOperatorIndex, numOperators); (IStrategy[] memory strategies, uint256[] memory multipliers) = _getStrategiesAndMultipliers(operatorSet); OperatorLeaf[] memory operatorLeaves = new OperatorLeaf[](operators.length); for (uint256 i = 0; i < operatorLeaves.length; i++) { // calculate the weighted sum of the operator's shares for the strategies given the multipliers - (uint256 delegatedStake, uint256 slashableStake) = - _getStakes(operatorSet, strategies, multipliers, operators[i]); + (uint256 delegatedStake, uint256 slashableStake) = _getStakes(operatorSet, strategies, multipliers, operators[i]); operatorLeaves[i] = OperatorLeaf({ delegatedStake: delegatedStake, @@ -547,27 +557,30 @@ contract StakeRootCompendium is StakeRootCompendiumStorage { /// @inheritdoc IStakeRootCompendium function getOperatorSetRoot( OperatorSet calldata operatorSet, - address[] calldata operators, OperatorLeaf[] calldata operatorLeaves ) external view returns (bytes32) { - require(avsDirectory.isOperatorSet(operatorSet.avs, operatorSet.operatorSetId), OperatorSetMustExist()); require( - operatorLeaves.length == avsDirectory.getNumOperatorsInOperatorSet(operatorSet), OperatorSetSizeMismatch() + avsDirectory.isOperatorSet(operatorSet.avs, operatorSet.operatorSetId), + "StakeRootCompendium.getOperatorSetRoot: operator set does not exist" + ); + require( + operatorLeaves.length == avsDirectory.getNumOperatorsInOperatorSet(operatorSet), + "AVSSyncTree.getOperatorSetRoot: operator set size mismatch" ); uint256 totalDelegatedStake; uint256 totalSlashableStake; - address prevOperator; + bytes32 prevExtraData; bytes32[] memory operatorLeavesHashes = new bytes32[](operatorLeaves.length); for (uint256 i = 0; i < operatorLeaves.length; i++) { - require( - uint160(prevOperator) < uint160(operators[i]), "AVSSyncTree.getOperatorSetRoot: operators not sorted" - ); - prevOperator = operators[i]; + require(uint256(prevExtraData) < uint256(operatorLeaves[i].extraData), "StakeRootCompendium.getOperatorSetRoot: extraData not sorted"); + prevExtraData = operatorLeaves[i].extraData; operatorLeavesHashes[i] = keccak256( abi.encodePacked( - operatorLeaves[i].delegatedStake, operatorLeaves[i].slashableStake, operatorLeaves[i].extraData + operatorLeaves[i].delegatedStake, + operatorLeaves[i].slashableStake, + operatorLeaves[i].extraData ) ); @@ -581,8 +594,8 @@ contract StakeRootCompendium is StakeRootCompendiumStorage { operatorTreeRoot, keccak256( abi.encodePacked( - totalDelegatedStake, - totalSlashableStake, + totalDelegatedStake, + totalSlashableStake, operatorSetExtraDatas[operatorSet.avs][operatorSet.operatorSetId] ) )