Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

m2-mainnet Contracts Update #158

Merged
merged 41 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ab4cd8f
start
0x0aa0 Nov 22, 2023
c94e852
temp comment scripts
0x0aa0 Nov 28, 2023
0f1a5ca
sm interface
0x0aa0 Jan 5, 2024
e150030
batch confirmer permission
0x0aa0 Jan 5, 2024
69a8ae3
mock rollup reorg
0x0aa0 Jan 8, 2024
3ce4a72
optimistic confirmation
0x0aa0 Jan 10, 2024
6bb3fa7
use ServiceManagerBase
0x0aa0 Jan 10, 2024
c933aa9
update DASM interface
0x0aa0 Jan 10, 2024
f64bf6f
nit
0x0aa0 Jan 10, 2024
e45bb7c
optimistic confirmation
0x0aa0 Jan 10, 2024
6f2788e
Merge branch 'nitro' of https://github.com/Layr-Labs/eigenda into nitro
0x0aa0 Jan 10, 2024
63d0351
nsss calldata
0x0aa0 Jan 12, 2024
5a3c1e8
Merge branch 'master' into m2-mainnet-contracts
0x0aa0 Jan 12, 2024
b105c4a
rm fee
0x0aa0 Jan 12, 2024
41c0064
Updated assignments commitments rebase (#176)
mooselumph Jan 13, 2024
112c739
fix rollup
0x0aa0 Jan 14, 2024
44de9d8
rm op
0x0aa0 Jan 14, 2024
aa8620b
fix scripts
0x0aa0 Jan 14, 2024
7e8d345
fin
0x0aa0 Jan 14, 2024
3c38f51
Update transactor for M2 mainnet contracts (#194)
mooselumph Jan 25, 2024
8ccb524
Update deployment code for M2 mainnet contracts (#193)
mooselumph Jan 25, 2024
ca28ca1
Update indexer M2 mainnet contracts (#195)
mooselumph Jan 25, 2024
aa7b912
Component updates for M2 mainnet contracts (#196)
mooselumph Jan 25, 2024
165e760
Plumb the kickparams for register operator with churn call (#212)
jianoaix Jan 26, 2024
d06dec1
fix(breaking): add storage gap to da service manager storage (#215)
stevennevins Jan 29, 2024
0f83d13
Update subgraphs for m2 contract changes (#192)
mooselumph Jan 29, 2024
5e911e0
Make Churner work on v2 smart contracts (#213)
jianoaix Jan 30, 2024
8bea4a7
Update contract submodules (#224)
0x0aa0 Jan 31, 2024
d104c9d
Update eigenda batch metadata subgraph (#221)
mooselumph Jan 31, 2024
0efdbf0
Merge master into m2 mainnet contracts (#220)
mooselumph Jan 31, 2024
6916ee0
Merge master
mooselumph Jan 31, 2024
48edabb
Update bindings and protoc
mooselumph Jan 31, 2024
f47fbd0
Merge master again
mooselumph Feb 1, 2024
d703d8f
update eigenlayer-contracts submodule (#229)
0x0aa0 Feb 1, 2024
a31bc9e
update eigenlayer-middleware submodule
0x0aa0 Feb 1, 2024
f534540
Add AVS directory (#227)
mooselumph Feb 1, 2024
d950176
Churner fixes for m2 mainnet contracts (#231)
mooselumph Feb 1, 2024
5966e34
Goerli deploy script (#214)
0x0aa0 Feb 2, 2024
c91f47b
Fix unit tests and lint (#234)
mooselumph Feb 2, 2024
8c7be10
fix: integration script (#235)
0x0aa0 Feb 2, 2024
723c9bb
M2 mainnet contracts fix integ tests (#237)
mooselumph Feb 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 55 additions & 125 deletions contracts/src/core/EigenDAServiceManager.sol
Original file line number Diff line number Diff line change
@@ -1,58 +1,40 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";
import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";

import {IDelegationManager} from "eigenlayer-core/contracts/interfaces/IDelegationManager.sol";
import {BytesLib} from "eigenlayer-core/contracts/libraries/BytesLib.sol";
import {Merkle} from "eigenlayer-core/contracts/libraries/Merkle.sol";
import {Pausable} from "eigenlayer-core/contracts/permissions/Pausable.sol";
import {IDelegationManager} from "eigenlayer-core/contracts/interfaces/IDelegationManager.sol";
import {IStrategyManager} from "eigenlayer-core/contracts/interfaces/IStrategyManager.sol";
import {ISlasher} from "eigenlayer-core/contracts/interfaces/ISlasher.sol";
import {IPauserRegistry} from "eigenlayer-core/contracts/interfaces/IPauserRegistry.sol";
import {ISignatureUtils} from "eigenlayer-core/contracts/interfaces/ISignatureUtils.sol";

import {BLSSignatureChecker, IRegistryCoordinator} from "eigenlayer-middleware/BLSSignatureChecker.sol";
import {IServiceManager} from "eigenlayer-middleware/interfaces/IServiceManager.sol";
import {ServiceManagerBase} from "eigenlayer-middleware/ServiceManagerBase.sol";
import {BLSSignatureChecker} from "eigenlayer-middleware/BLSSignatureChecker.sol";
import {IRegistryCoordinator} from "eigenlayer-middleware/interfaces/IRegistryCoordinator.sol";
import {IStakeRegistry} from "eigenlayer-middleware/interfaces/IStakeRegistry.sol";
import {BitmapUtils} from "eigenlayer-middleware/libraries/BitmapUtils.sol";

import {EigenDAServiceManagerStorage} from "./EigenDAServiceManagerStorage.sol";
import {EigenDAHasher} from "../libraries/EigenDAHasher.sol";


/**b
/**
* @title Primary entrypoint for procuring services from EigenDA.
* @author Layr Labs, Inc.
* @notice This contract is used for:
* - initializing the data store by the disperser
* - confirming the data store by the disperser with inferred aggregated signatures of the quorum
* - freezing operators as the result of various "challenges"
*/
contract EigenDAServiceManager is Initializable, OwnableUpgradeable, EigenDAServiceManagerStorage, BLSSignatureChecker, Pausable {
using BytesLib for bytes;
contract EigenDAServiceManager is EigenDAServiceManagerStorage, ServiceManagerBase, BLSSignatureChecker, Pausable {
using EigenDAHasher for BatchHeader;
using EigenDAHasher for ReducedBatchHeader;

uint8 internal constant PAUSED_CONFIRM_BATCH = 0;

/**
* @notice The EigenLayer delegation contract for this EigenDA which is primarily used by
* delegators to delegate their stake to operators who would serve as EigenDA
* nodes and so on.
* @dev For more details, see DelegationManager.sol.
*/
IDelegationManager public immutable delegationManager;

IStrategyManager public immutable strategyManager;

ISlasher public immutable slasher;

/// @notice when applied to a function, ensures that the function is only callable by the `registryCoordinator`.
modifier onlyRegistryCoordinator() {
require(msg.sender == address(registryCoordinator), "onlyRegistryCoordinator: not from registry coordinator");
_;
}
IStrategyManager public immutable _strategyManager;
ISlasher public immutable _slasher;

/// @notice when applied to a function, ensures that the function is only callable by the `batchConfirmer`.
modifier onlyBatchConfirmer() {
Expand All @@ -61,16 +43,17 @@ contract EigenDAServiceManager is Initializable, OwnableUpgradeable, EigenDAServ
}

constructor(
IRegistryCoordinator _registryCoordinator,
IStrategyManager _strategyManager,
IDelegationManager _delegationMananger,
ISlasher _slasher
IDelegationManager __delegationMananger,
IRegistryCoordinator __registryCoordinator,
IStrategyManager __strategyManager,
IStakeRegistry __stakeRegistry,
ISlasher __slasher
)
BLSSignatureChecker(_registryCoordinator)
BLSSignatureChecker(__registryCoordinator)
ServiceManagerBase(__delegationMananger, __registryCoordinator, __stakeRegistry)
{
strategyManager = _strategyManager;
delegationManager = _delegationMananger;
slasher = _slasher;
_strategyManager = __strategyManager;
_slasher = __slasher;
_disableInitializers();
}

Expand All @@ -84,7 +67,7 @@ contract EigenDAServiceManager is Initializable, OwnableUpgradeable, EigenDAServ
{
_initializePauser(_pauserRegistry, UNPAUSE_ALL);
_transferOwnership(_initialOwner);
batchConfirmer = _batchConfirmer;
_setBatchConfirmer(_batchConfirmer);
}

/**
Expand Down Expand Up @@ -140,42 +123,53 @@ contract EigenDAServiceManager is Initializable, OwnableUpgradeable, EigenDAServ
bytes32 batchHeaderHash = batchHeader.hashBatchHeader();
batchIdToBatchMetadataHash[batchIdMemory] = EigenDAHasher.hashBatchHashedMetadata(batchHeaderHash, signatoryRecordHash, fee, uint32(block.number));

emit BatchConfirmed(reducedBatchHeaderHash, batchIdMemory, fee);
emit BatchConfirmed(reducedBatchHeaderHash, batchIdMemory, fee, false);

// increment the batchId
batchId = batchIdMemory + 1;
}

/**
* @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator registration with the AVS
* @param operator The address of the operator to register.
* @param operatorSignature The signature, salt, and expiry of the operator's signature.
*/
function registerOperatorToAVS(
address operator,
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
) external {
delegationManager.registerOperatorToAVS(operator, operatorSignature);
}
/// @notice This function is used for submitting data availabilty certificates optimistically
function confirmBatchOptimistically(
BatchHeader calldata batchHeader
) external onlyWhenNotPaused(PAUSED_CONFIRM_BATCH) onlyBatchConfirmer() {
// make sure the information needed to derive the non-signers and batch is in calldata to avoid emitting events
require(tx.origin == msg.sender, "EigenDAServiceManager.confirmBatch: header and nonsigner data must be in calldata");
// make sure the stakes against which the Batch is being confirmed are not stale
require(
batchHeader.referenceBlockNumber <= block.number, "EigenDAServiceManager.confirmBatch: specified referenceBlockNumber is in future"
);

/**
* @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator deregistration from the AVS
* @param operator The address of the operator to deregister.
*/
function deregisterOperatorFromAVS(address operator) external {
delegationManager.deregisterOperatorFromAVS(operator);
}
require(
(batchHeader.referenceBlockNumber + BLOCK_STALE_MEASURE) >= uint32(block.number),
"EigenDAServiceManager.confirmBatch: specified referenceBlockNumber is too far in past"
);

/**
* @notice Sets the metadata URI for the AVS
* @param _metadataURI is the metadata URI for the AVS
*/
function setMetadataURI(string memory _metadataURI) external onlyOwner() {
metadataURI = _metadataURI;
// calculate reducedBatchHeaderHash which nodes signed
bytes32 reducedBatchHeaderHash = batchHeader.hashBatchHeaderToReducedBatchHeader();

// store the metadata hash
uint96 fee = 0;
uint32 batchIdMemory = batchIdOptimistic;
bytes32 batchHeaderHash = batchHeader.hashBatchHeader();
batchIdToBatchMetadataHashOptimistic[batchIdMemory] = EigenDAHasher.hashBatchHashedMetadata(batchHeaderHash, fee, uint32(block.number));
0x0aa0 marked this conversation as resolved.
Show resolved Hide resolved

emit BatchConfirmed(reducedBatchHeaderHash, batchIdMemory, fee, true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might mess up our indexing to add another param, so another event might be preferrable.

@mooselumph wdyt


// increment the batchId
batchIdOptimistic = batchIdMemory + 1;
}

/// @notice This function is used for changing the batch confirmer
function setBatchConfirmer(address _batchConfirmer) external onlyOwner() {
_setBatchConfirmer(_batchConfirmer);
}

/// @notice changes the batch confirmer
function _setBatchConfirmer(address _batchConfirmer) internal {
address previousBatchConfirmer = batchConfirmer;
batchConfirmer = _batchConfirmer;
emit BatchConfirmerChanged(previousBatchConfirmer, batchConfirmer);
}

/// @notice Returns the current batchId
Expand All @@ -188,68 +182,4 @@ contract EigenDAServiceManager is Initializable, OwnableUpgradeable, EigenDAServ
return uint32(block.number) + STORE_DURATION_BLOCKS + BLOCK_STALE_MEASURE;
}

/**
* @notice Returns the list of strategies that the operator has potentially restaked on the AVS
* @param operator The address of the operator to get restaked strategies for
* @dev This function is intended to be called off-chain
* @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness
* of each element in the returned array. The off-chain service should do that validation separately
*/
function getOperatorRestakedStrategies(address operator) external view returns (address[] memory) {
bytes32 operatorId = registryCoordinator.getOperatorId(operator);
uint256 quorumBitmap = registryCoordinator.getCurrentQuorumBitmap(operatorId);
bytes memory quorumBytesArray = BitmapUtils.bitmapToBytesArray(quorumBitmap);

uint256 strategiesLength;
for (uint i = 0; i < quorumBytesArray.length; i++) {
uint8 quorumNumber = uint8(quorumBytesArray[i]);
strategiesLength += stakeRegistry.strategyParamsLength(quorumNumber);
}

address[] memory restakedStrategies = new address[](strategiesLength);
uint256 index;
for (uint i = 0; i < quorumBytesArray.length; i++) {
uint8 quorumNumber = uint8(quorumBytesArray[i]);
uint256 strategyParamsLength = stakeRegistry.strategyParamsLength(quorumNumber);
for (uint j = 0; j < strategyParamsLength; j++) {
IStakeRegistry.StrategyParams memory strategyParams = stakeRegistry.strategyParamsByIndex(quorumNumber, j);
restakedStrategies[index] = address(strategyParams.strategy);
++index;
}
}

return restakedStrategies;
}

/**
* @notice Returns the list of strategies that the AVS supports for restaking
* @dev This function is intended to be called off-chain
* @dev No guarantee is made on uniqueness of each element in the returned array.
* The off-chain service should do that validabution separately
*/
function getRestakeableStrategies() external view returns (address[] memory) {
uint256 quorumBitmap;
uint256 strategiesLength;
for (uint8 i = 0; i < type(uint8).max; i++) {
if(stakeRegistry.minimumStakeForQuorum(i) > 0) {
quorumBitmap = BitmapUtils.setBit(quorumBitmap, i);
strategiesLength += stakeRegistry.strategyParamsLength(i);
}
}

bytes memory quorumBytesArray = BitmapUtils.bitmapToBytesArray(quorumBitmap);
address[] memory restakedStrategies = new address[](strategiesLength);
uint256 index;
for (uint i = 0; i < quorumBytesArray.length; i++) {
uint8 quorumNumber = uint8(quorumBytesArray[i]);
uint256 strategyParamsLength = stakeRegistry.strategyParamsLength(quorumNumber);
for (uint j = 0; j < strategyParamsLength; j++) {
IStakeRegistry.StrategyParams memory strategyParams = stakeRegistry.strategyParamsByIndex(quorumNumber, j);
restakedStrategies[index] = address(strategyParams.strategy);
++index;
}
}

return restakedStrategies;
}
}
8 changes: 6 additions & 2 deletions contracts/src/core/EigenDAServiceManagerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ abstract contract EigenDAServiceManagerStorage is IEigenDAServiceManager {
/// @notice mapping between the batchId to the hash of the metadata of the corresponding Batch
mapping(uint32 => bytes32) public batchIdToBatchMetadataHash;

/// @notice The current batchIdOptimistic
uint32 public batchIdOptimistic;

/// @notice mapping between the batchIdOptimistic to the hash of the metadata of the corresponding Optimistic Batch
mapping(uint32 => bytes32) public batchIdToBatchMetadataHashOptimistic;

/// @notice address that is permissioned to confirm batches
address public batchConfirmer;

/// @notice metadata URI for the EigenDA AVS
string public metadataURI;
}
29 changes: 22 additions & 7 deletions contracts/src/interfaces/IEigenDAServiceManager.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import {IDelegationManager} from "eigenlayer-core/contracts/interfaces/IDelegationManager.sol";
import {IServiceManager} from "eigenlayer-middleware/interfaces/IServiceManager.sol";
import {IDelayedService} from "eigenlayer-middleware/interfaces/IDelayedService.sol";
import {BLSSignatureChecker} from "eigenlayer-middleware/BLSSignatureChecker.sol";
import {IDelegationManager} from "eigenlayer-core/contracts/interfaces/IDelegationManager.sol";
import {BN254} from "eigenlayer-middleware/libraries/BN254.sol";

interface IEigenDAServiceManager is IServiceManager, IDelayedService {
Expand All @@ -15,13 +15,14 @@ interface IEigenDAServiceManager is IServiceManager, IDelayedService {
* @param batchHeaderHash The hash of the batch header
* @param batchId The ID for the Batch inside of the specified duration (i.e. *not* the globalBatchId)
*/
event BatchConfirmed(bytes32 indexed batchHeaderHash, uint32 batchId, uint96 fee);

event FeePerBytePerTimeSet(uint256 previousValue, uint256 newValue);
event BatchConfirmed(bytes32 indexed batchHeaderHash, uint32 batchId, uint96 fee, bool optimistic);

event PaymentManagerSet(address previousAddress, address newAddress);

event FeeSetterChanged(address previousAddress, address newAddress);
/**
* @notice Emitted when the batch confirmer is changed.
* @param previousAddress The address of the previous batch confirmer
* @param newAddress The address of the new batch confirmer
*/
event BatchConfirmerChanged(address previousAddress, address newAddress);

// STRUCTS

Expand Down Expand Up @@ -84,4 +85,18 @@ interface IEigenDAServiceManager is IServiceManager, IDelayedService {
BatchHeader calldata batchHeader,
BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature
) external;

/// @notice This function is used for submitting data availabilty certificates optimistically
function confirmBatchOptimistically(
BatchHeader calldata batchHeader
) external;

/// @notice This function is used for changing the batch confirmer
function setBatchConfirmer(address _batchConfirmer) external;

/// @notice Returns the current batchId
function taskNumber() external view returns (uint32);

/// @notice Returns the block until which operators must serve.
function latestServeUntilBlock() external view returns (uint32);
}
14 changes: 14 additions & 0 deletions contracts/src/libraries/EigenDAHasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ library EigenDAHasher {
return keccak256(abi.encodePacked(batchHeaderHash, signatoryRecordHash, fee, blockNumber));
}

/**
* @notice hashes the given metdata into the commitment that will be stored in the contract
* @param batchHeaderHash the hash of the batchHeader
* @param fee the fee paid in paymentToken for the batch
* @param blockNumber the block number at which the batch was confirmed
*/
function hashBatchHashedMetadata(
bytes32 batchHeaderHash,
uint96 fee,
0x0aa0 marked this conversation as resolved.
Show resolved Hide resolved
uint32 blockNumber
) internal pure returns(bytes32) {
return keccak256(abi.encodePacked(batchHeaderHash, fee, blockNumber));
}

/**
* @notice given the a batchHeader in the provided metdata, calculates the hash of the batchMetadata
* @param batchMetadata the metadata of the batch
Expand Down
3 changes: 2 additions & 1 deletion contracts/test/unit/EigenDABlobUtils.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer {
_setUpBLSMockAVSDeployer();

eigenDAServiceManagerImplementation = new EigenDAServiceManager(
delegationMock,
registryCoordinator,
strategyManagerMock,
delegationMock,
stakeRegistry,
slasher
);

Expand Down
9 changes: 5 additions & 4 deletions contracts/test/unit/EigenDAServiceManagerUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,18 @@ contract EigenDAServiceManagerUnit is BLSMockAVSDeployer {

uint256 feePerBytePerTime = 0;

event BatchConfirmed(bytes32 indexed batchHeaderHash, uint32 batchId, uint96 fee);
event BatchConfirmed(bytes32 indexed batchHeaderHash, uint32 batchId, uint96 fee, bool optimistic);
event FeePerBytePerTimeSet(uint256 previousValue, uint256 newValue);
event FeeSetterChanged(address previousAddress, address newAddress);

function setUp() virtual public {
_setUpBLSMockAVSDeployer();

eigenDAServiceManagerImplementation = new EigenDAServiceManager(
delegationMock,
registryCoordinator,
strategyManagerMock,
delegationMock,
stakeRegistry,
slasher
);

Expand Down Expand Up @@ -64,7 +65,7 @@ contract EigenDAServiceManagerUnit is BLSMockAVSDeployer {

cheats.prank(confirmer, confirmer);
cheats.expectEmit(true, true, true, true, address(eigenDAServiceManager));
emit BatchConfirmed(batchHeaderHash, batchIdToConfirm, 0);
emit BatchConfirmed(batchHeaderHash, batchIdToConfirm, 0, false);
uint256 gasBefore = gasleft();
eigenDAServiceManager.confirmBatch(
batchHeader,
Expand Down Expand Up @@ -144,7 +145,7 @@ contract EigenDAServiceManagerUnit is BLSMockAVSDeployer {

cheats.prank(confirmer, confirmer);
cheats.expectEmit(true, true, true, true, address(eigenDAServiceManager));
emit BatchConfirmed(batchHeaderHash, batchIdToConfirm, 0);
emit BatchConfirmed(batchHeaderHash, batchIdToConfirm, 0, false);
uint256 gasBefore = gasleft();
eigenDAServiceManager.confirmBatch(
batchHeader,
Expand Down
Loading
Loading