diff --git a/contracts/script/GenerateUnitTestHashes.s.sol b/contracts/script/GenerateUnitTestHashes.s.sol index 7537372035..0418b48fc0 100644 --- a/contracts/script/GenerateUnitTestHashes.s.sol +++ b/contracts/script/GenerateUnitTestHashes.s.sol @@ -23,7 +23,7 @@ contract GenerateHashes is Script { quorumBlobParam[0] = IEigenDAServiceManager.QuorumBlobParam({ quorumNumber: 0, adversaryThresholdPercentage: 80, - quorumThresholdPercentage: 100, + confirmationThresholdPercentage: 100, chunkLength: 10 }); @@ -40,7 +40,7 @@ contract GenerateHashes is Script { quorumBlobParam[0] = IEigenDAServiceManager.QuorumBlobParam({ quorumNumber: 1, adversaryThresholdPercentage: 80, - quorumThresholdPercentage: 100, + confirmationThresholdPercentage: 100, chunkLength: 10 }); diff --git a/contracts/src/core/EigenDAServiceManager.sol b/contracts/src/core/EigenDAServiceManager.sol index 6099f6976b..3e44cfab21 100644 --- a/contracts/src/core/EigenDAServiceManager.sol +++ b/contracts/src/core/EigenDAServiceManager.sol @@ -80,10 +80,10 @@ contract EigenDAServiceManager is EigenDAServiceManagerStorage, ServiceManagerBa "EigenDAServiceManager.confirmBatch: specified referenceBlockNumber is too far in past" ); - //make sure that the quorumNumbers and quorumThresholdPercentages are of the same length + //make sure that the quorumNumbers and confirmationThresholdPercentages are of the same length require( - batchHeader.quorumNumbers.length == batchHeader.quorumThresholdPercentages.length, - "EigenDAServiceManager.confirmBatch: quorumNumbers and quorumThresholdPercentages must be of the same length" + batchHeader.quorumNumbers.length == batchHeader.confirmationThresholdPercentages.length, + "EigenDAServiceManager.confirmBatch: quorumNumbers and confirmationThresholdPercentages must be of the same length" ); // calculate reducedBatchHeaderHash which nodes signed @@ -101,12 +101,12 @@ contract EigenDAServiceManager is EigenDAServiceManagerStorage, ServiceManagerBa ); // check that signatories own at least a threshold percentage of each quourm - for (uint i = 0; i < batchHeader.quorumThresholdPercentages.length; i++) { - // we don't check that the quorumThresholdPercentages are not >100 because a greater value would trivially fail the check, implying + for (uint i = 0; i < batchHeader.confirmationThresholdPercentages.length; i++) { + // we don't check that the confirmationThresholdPercentages are not >100 because a greater value would trivially fail the check, implying // signed stake > total stake require( quorumStakeTotals.signedStakeForQuorum[i] * THRESHOLD_DENOMINATOR >= - quorumStakeTotals.totalStakeForQuorum[i] * uint8(batchHeader.quorumThresholdPercentages[i]), + quorumStakeTotals.totalStakeForQuorum[i] * uint8(batchHeader.confirmationThresholdPercentages[i]), "EigenDAServiceManager.confirmBatch: signatories do not own at least threshold percentage of a quorum" ); } diff --git a/contracts/src/core/EigenDAServiceManagerStorage.sol b/contracts/src/core/EigenDAServiceManagerStorage.sol index 5cd23d7e59..a5b687c675 100644 --- a/contracts/src/core/EigenDAServiceManagerStorage.sol +++ b/contracts/src/core/EigenDAServiceManagerStorage.sol @@ -26,7 +26,10 @@ abstract contract EigenDAServiceManagerStorage is IEigenDAServiceManager { */ uint32 public constant BLOCK_STALE_MEASURE = 150; + /// @notice The quorum adversary threshold percentages bytes public constant quorumAdversaryThresholdPercentages = hex"2121"; + + /// @notice The quorum confirmation threshold percentages bytes public constant quorumConfirmationThresholdPercentages = hex"4242"; /// @notice The current batchId diff --git a/contracts/src/interfaces/IEigenDAServiceManager.sol b/contracts/src/interfaces/IEigenDAServiceManager.sol index d17ee4cbd3..0b540e6941 100644 --- a/contracts/src/interfaces/IEigenDAServiceManager.sol +++ b/contracts/src/interfaces/IEigenDAServiceManager.sol @@ -27,7 +27,7 @@ interface IEigenDAServiceManager is IServiceManager { struct QuorumBlobParam { uint8 quorumNumber; uint8 adversaryThresholdPercentage; - uint8 quorumThresholdPercentage; + uint8 confirmationThresholdPercentage; uint32 chunkLength; // the length of the chunks in the quorum } @@ -45,7 +45,7 @@ interface IEigenDAServiceManager is IServiceManager { struct BatchHeader { bytes32 blobHeadersRoot; bytes quorumNumbers; // each byte is a different quorum number - bytes quorumThresholdPercentages; // every bytes is an amount less than 100 specifying the percentage of stake + bytes confirmationThresholdPercentages; // every bytes is an amount less than 100 specifying the percentage of stake // the must have signed in the corresponding quorum in `quorumNumbers` uint32 referenceBlockNumber; } diff --git a/contracts/src/libraries/EigenDARollupUtils.sol b/contracts/src/libraries/EigenDARollupUtils.sol index 1880023f4c..0d8dd7e092 100644 --- a/contracts/src/libraries/EigenDARollupUtils.sol +++ b/contracts/src/libraries/EigenDARollupUtils.sol @@ -57,12 +57,13 @@ library EigenDARollupUtils { "EigenDARollupUtils.verifyBlob: quorumNumber does not match" ); - // make sure that the adversaryThresholdPercentage is less than the given quorumThresholdPercentage + // make sure that the adversaryThresholdPercentage is less than the given confirmationThresholdPercentage require(blobHeader.quorumBlobParams[i].adversaryThresholdPercentage - < blobHeader.quorumBlobParams[i].quorumThresholdPercentage, + < blobHeader.quorumBlobParams[i].confirmationThresholdPercentage, "EigenDARollupUtils.verifyBlob: adversaryThresholdPercentage is not valid" ); + // make sure that the adversaryThresholdPercentage is at least the given quorumAdversaryThresholdPercentage uint8 _adversaryThresholdPercentage = getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); if(_adversaryThresholdPercentage > 0){ require(blobHeader.quorumBlobParams[i].adversaryThresholdPercentage >= _adversaryThresholdPercentage, @@ -70,15 +71,21 @@ library EigenDARollupUtils { ); } - // make sure that the stake signed for is greater than the given quorumThresholdPercentage - require(uint8(blobVerificationProof.batchMetadata.batchHeader.quorumThresholdPercentages[uint8(blobVerificationProof.quorumThresholdIndexes[i])]) - >= blobHeader.quorumBlobParams[i].quorumThresholdPercentage, - "EigenDARollupUtils.verifyBlob: quorumThresholdPercentage is not met" + // make sure that the stake signed for is greater than the given confirmationThresholdPercentage + require(uint8(blobVerificationProof.batchMetadata.batchHeader.confirmationThresholdPercentages[uint8(blobVerificationProof.quorumThresholdIndexes[i])]) + >= blobHeader.quorumBlobParams[i].confirmationThresholdPercentage, + "EigenDARollupUtils.verifyBlob: confirmationThresholdPercentage is not met" ); } } + /** + * @notice gets the adversary threshold percentage for a given quorum + * @param eigenDAServiceManager the contract in which the batch was confirmed + * @param quorumNumber the quorum number to get the adversary threshold percentage for + * @dev returns 0 if the quorumNumber is not found + */ function getQuorumAdversaryThreshold( IEigenDAServiceManager eigenDAServiceManager, uint256 quorumNumber diff --git a/contracts/test/unit/EigenDABlobUtils.t.sol b/contracts/test/unit/EigenDABlobUtils.t.sol index 11d1071d3f..64387197d4 100644 --- a/contracts/test/unit/EigenDABlobUtils.t.sol +++ b/contracts/test/unit/EigenDABlobUtils.t.sol @@ -79,10 +79,10 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); bytes memory secondBlobHash = abi.encodePacked(blobHeader[1].hashBlobHeader()); batchHeader.blobHeadersRoot = keccak256(abi.encodePacked(keccak256(firstBlobHash), keccak256(secondBlobHash))); - // add dummy quorum numbers and quorum threshold percentages making sure quorumThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage + // add dummy quorum numbers and quorum threshold percentages making sure confirmationThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage for (uint i = 0; i < blobHeader[1].quorumBlobParams.length; i++) { batchHeader.quorumNumbers = abi.encodePacked(batchHeader.quorumNumbers, blobHeader[1].quorumBlobParams[i].quorumNumber); - batchHeader.quorumThresholdPercentages = abi.encodePacked(batchHeader.quorumThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); + batchHeader.confirmationThresholdPercentages = abi.encodePacked(batchHeader.confirmationThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); } batchHeader.referenceBlockNumber = uint32(block.number); @@ -165,10 +165,10 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); bytes memory secondBlobHash = abi.encodePacked(blobHeader[1].hashBlobHeader()); batchHeader.blobHeadersRoot = keccak256(abi.encodePacked(keccak256(firstBlobHash), keccak256(secondBlobHash))); - // add dummy quorum numbers and quorum threshold percentages making sure quorumThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage + // add dummy quorum numbers and quorum threshold percentages making sure confirmationThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage for (uint i = 0; i < blobHeader[1].quorumBlobParams.length; i++) { batchHeader.quorumNumbers = abi.encodePacked(batchHeader.quorumNumbers, blobHeader[1].quorumBlobParams[i].quorumNumber); - batchHeader.quorumThresholdPercentages = abi.encodePacked(batchHeader.quorumThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); + batchHeader.confirmationThresholdPercentages = abi.encodePacked(batchHeader.confirmationThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); } batchHeader.referenceBlockNumber = uint32(block.number); @@ -211,10 +211,10 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); bytes memory secondBlobHash = abi.encodePacked(blobHeader[1].hashBlobHeader()); batchHeader.blobHeadersRoot = keccak256(abi.encodePacked(keccak256(firstBlobHash), keccak256(secondBlobHash))); - // add dummy quorum numbers and quorum threshold percentages making sure quorumThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage + // add dummy quorum numbers and quorum threshold percentages making sure confirmationThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage for (uint i = 0; i < blobHeader[1].quorumBlobParams.length; i++) { batchHeader.quorumNumbers = abi.encodePacked(batchHeader.quorumNumbers, blobHeader[1].quorumBlobParams[i].quorumNumber); - batchHeader.quorumThresholdPercentages = abi.encodePacked(batchHeader.quorumThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); + batchHeader.confirmationThresholdPercentages = abi.encodePacked(batchHeader.confirmationThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); } batchHeader.referenceBlockNumber = uint32(block.number); @@ -256,10 +256,10 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); bytes memory secondBlobHash = abi.encodePacked(blobHeader[1].hashBlobHeader()); batchHeader.blobHeadersRoot = keccak256(abi.encodePacked(keccak256(firstBlobHash), keccak256(secondBlobHash))); - // add dummy quorum numbers and quorum threshold percentages making sure quorumThresholdPercentage = 100 + // add dummy quorum numbers and quorum threshold percentages making sure confirmationThresholdPercentage = 100 for (uint i = 0; i < blobHeader[1].quorumBlobParams.length; i++) { batchHeader.quorumNumbers = abi.encodePacked(batchHeader.quorumNumbers, blobHeader[1].quorumBlobParams[i].quorumNumber); - batchHeader.quorumThresholdPercentages = abi.encodePacked(batchHeader.quorumThresholdPercentages, blobHeader[1].quorumBlobParams[i].quorumThresholdPercentage - 1); + batchHeader.confirmationThresholdPercentages = abi.encodePacked(batchHeader.confirmationThresholdPercentages, blobHeader[1].quorumBlobParams[i].confirmationThresholdPercentage - 1); } batchHeader.referenceBlockNumber = uint32(block.number); @@ -286,7 +286,7 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { blobVerificationProof.quorumThresholdIndexes[i] = bytes1(uint8(i)); } - cheats.expectRevert("EigenDARollupUtils.verifyBlob: quorumThresholdPercentage is not met"); + cheats.expectRevert("EigenDARollupUtils.verifyBlob: confirmationThresholdPercentage is not met"); eigenDABlobUtilsHarness.verifyBlob(blobHeader[1], eigenDAServiceManager, blobVerificationProof); } @@ -313,7 +313,7 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { quorumNumbersUsed[blobHeader.quorumBlobParams[i].quorumNumber] = true; blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); blobHeader.quorumBlobParams[i].chunkLength = uint32(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].chunkLength", i)))); - blobHeader.quorumBlobParams[i].quorumThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; + blobHeader.quorumBlobParams[i].confirmationThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; } // mark all quorum numbers as unused for (uint i = 0; i < numQuorumsBlobParams; i++) { diff --git a/contracts/test/unit/EigenDAServiceManagerUnit.t.sol b/contracts/test/unit/EigenDAServiceManagerUnit.t.sol index 301b43b5d9..d8ea5835ea 100644 --- a/contracts/test/unit/EigenDAServiceManagerUnit.t.sol +++ b/contracts/test/unit/EigenDAServiceManagerUnit.t.sol @@ -171,9 +171,9 @@ contract EigenDAServiceManagerUnit is BLSMockAVSDeployer { function testConfirmBatch_Revert_LengthMismatch(uint256 pseudoRandomNumber) public { (IEigenDAServiceManager.BatchHeader memory batchHeader, BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature) = _getHeaderandNonSigners(0, pseudoRandomNumber, 100); - batchHeader.quorumThresholdPercentages = new bytes(0); + batchHeader.confirmationThresholdPercentages = new bytes(0); - cheats.expectRevert(bytes("EigenDAServiceManager.confirmBatch: quorumNumbers and quorumThresholdPercentages must be of the same length")); + cheats.expectRevert(bytes("EigenDAServiceManager.confirmBatch: quorumNumbers and confirmationThresholdPercentages must be of the same length")); cheats.prank(confirmer, confirmer); eigenDAServiceManager.confirmBatch( batchHeader, @@ -204,9 +204,9 @@ contract EigenDAServiceManagerUnit is BLSMockAVSDeployer { IEigenDAServiceManager.BatchHeader memory batchHeader; batchHeader.blobHeadersRoot = keccak256(abi.encodePacked("blobHeadersRoot", pseudoRandomNumber)); batchHeader.quorumNumbers = quorumNumbers; - batchHeader.quorumThresholdPercentages = new bytes(quorumNumbers.length); + batchHeader.confirmationThresholdPercentages = new bytes(quorumNumbers.length); for (uint256 i = 0; i < quorumNumbers.length; i++) { - batchHeader.quorumThresholdPercentages[i] = bytes1(threshold); + batchHeader.confirmationThresholdPercentages[i] = bytes1(threshold); } batchHeader.referenceBlockNumber = referenceBlockNumber; return batchHeader; diff --git a/contracts/test/unit/MockRollup.t.sol b/contracts/test/unit/MockRollup.t.sol index cf3f13f275..64c38f1eec 100644 --- a/contracts/test/unit/MockRollup.t.sol +++ b/contracts/test/unit/MockRollup.t.sol @@ -122,10 +122,10 @@ contract MockRollupTest is BLSMockAVSDeployer { bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); bytes memory secondBlobHash = abi.encodePacked(blobHeader[1].hashBlobHeader()); batchHeader.blobHeadersRoot = keccak256(abi.encodePacked(keccak256(firstBlobHash), keccak256(secondBlobHash))); - // add dummy quorum numbers and quorum threshold percentages making sure quorumThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage + // add dummy quorum numbers and quorum threshold percentages making sure confirmationThresholdPercentage = adversaryThresholdPercentage + defaultCodingRatioPercentage for (uint i = 0; i < blobHeader[1].quorumBlobParams.length; i++) { batchHeader.quorumNumbers = abi.encodePacked(batchHeader.quorumNumbers, blobHeader[1].quorumBlobParams[i].quorumNumber); - batchHeader.quorumThresholdPercentages = abi.encodePacked(batchHeader.quorumThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); + batchHeader.confirmationThresholdPercentages = abi.encodePacked(batchHeader.confirmationThresholdPercentages, blobHeader[1].quorumBlobParams[i].adversaryThresholdPercentage + defaultCodingRatioPercentage); } batchHeader.referenceBlockNumber = uint32(block.number); @@ -174,7 +174,7 @@ contract MockRollupTest is BLSMockAVSDeployer { quorumNumbersUsed[blobHeader.quorumBlobParams[i].quorumNumber] = true; blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); blobHeader.quorumBlobParams[i].chunkLength = uint32(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].chunkLength", i)))); - blobHeader.quorumBlobParams[i].quorumThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; + blobHeader.quorumBlobParams[i].confirmationThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; } // mark all quorum numbers as unused for (uint i = 0; i < numQuorumsBlobParams; i++) { @@ -185,8 +185,8 @@ contract MockRollupTest is BLSMockAVSDeployer { } function testGetQuorumAdversaryThreshold () public { - require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 0) == 50, "getQuorumAdversaryThreshold failed"); - require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 1) == 50, "getQuorumAdversaryThreshold failed"); + require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 0) == 33, "getQuorumAdversaryThreshold failed"); + require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 1) == 33, "getQuorumAdversaryThreshold failed"); } } \ No newline at end of file