diff --git a/src/bridge/ISequencerInbox.sol b/src/bridge/ISequencerInbox.sol index 0a7d1311..33a6861d 100644 --- a/src/bridge/ISequencerInbox.sol +++ b/src/bridge/ISequencerInbox.sol @@ -199,6 +199,24 @@ interface ISequencerInbox is IDelayedMessageProvider { // ---------- onlyRollupOrOwner functions ---------- + /** + * @notice Set the eigenda service manager contract + * @param newEigenDAServiceManager the new svc manager contract address + */ + function setEigenDAServiceManager(address newEigenDAServiceManager) external; + + /** + * @notice Set the rollup manager contract address + * @param newRollupManager the new rollup manager contract address + */ + function setEigenDARollupManager(address newRollupManager) external; + + /** + * @notice Set the new rollup contract address + */ + function setRollupAddress() external; + + /** * @notice Set max delay for sequencer inbox * @param maxTimeVariation_ the maximum time variation parameters diff --git a/src/bridge/SequencerInbox.sol b/src/bridge/SequencerInbox.sol index 3c0c07c1..a048b949 100644 --- a/src/bridge/SequencerInbox.sol +++ b/src/bridge/SequencerInbox.sol @@ -62,9 +62,6 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox IBridge public bridge; - IEigenDAServiceManager public immutable eigenDAServiceManager; - IRollupManager public immutable eigenDARollupManager; - /// @inheritdoc ISequencerInbox uint256 public constant HEADER_LENGTH = 40; @@ -136,11 +133,12 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox // True if the chain this SequencerInbox is deployed on uses custom fee token bool public immutable isUsingFeeToken; + address public eigenDAServiceManager; + address public eigenDARollupManager; + constructor( uint256 _maxDataSize, IReader4844 reader4844_, - IEigenDAServiceManager eigenDAServiceManager_, - IRollupManager eigenDARollupManager_, bool _isUsingFeeToken ) { maxDataSize = _maxDataSize; @@ -150,8 +148,6 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox if (reader4844_ == IReader4844(address(0))) revert InitParamZero("Reader4844"); } reader4844 = reader4844_; - eigenDAServiceManager = eigenDAServiceManager_; - eigenDARollupManager = eigenDARollupManager_; isUsingFeeToken = _isUsingFeeToken; } @@ -426,7 +422,7 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); // verify that the blob was actually included before continuing - eigenDARollupManager.verifyBlob(blobHeader, eigenDAServiceManager, blobVerificationProof); + IRollupManager(eigenDARollupManager).verifyBlob(blobHeader, IEigenDAServiceManager(eigenDAServiceManager), blobVerificationProof); // NOTE: to retrieve need the following // see: https://github.com/Layr-Labs/eigenda/blob/master/api/docs/retriever.md#blobrequest @@ -799,19 +795,25 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox emit OwnerFunctionCalled(5); } - // /// @inheritdoc ISequencerInbox - // function updateRollupAddress() external onlyRollupOwner { - // IOwnable newRollup = bridge.rollup(); - // if (rollup == newRollup) revert RollupNotChanged(); - // rollup = newRollup; - // emit OwnerFunctionCalled(6); - // } + /// @inheritdoc ISequencerInbox + function setRollupAddress() external onlyRollupOwner { + IOwnable newRollup = bridge.rollup(); + if (rollup == newRollup) revert RollupNotChanged(); + rollup = newRollup; + emit OwnerFunctionCalled(6); + } + + /// @inheritdoc ISequencerInbox + function setEigenDAServiceManager(address newEigenDAServiceManager) external onlyRollupOwner { + eigenDAServiceManager = newEigenDAServiceManager; + emit OwnerFunctionCalled(7); + } - // /// @inheritdoc ISequencerInbox - // function updateEigenDAServiceManager(address newEigenDAServiceManager) external onlyRollupOwner { - // eigenDAServiceManager = IEigenDAServiceManager(newEigenDAServiceManager); - // emit OwnerFunctionCalled(31); - // } + /// @inheritdoc ISequencerInbox + function setEigenDARollupManager(address newRollupManager) external onlyRollupOwner { + eigenDARollupManager = newRollupManager; + emit OwnerFunctionCalled(8); + } function isValidKeysetHash(bytes32 ksHash) external view returns (bool) { return dasKeySetInfo[ksHash].isValidKeyset; diff --git a/src/mocks/SequencerInboxStub.sol b/src/mocks/SequencerInboxStub.sol index 3485fdd0..bf24ab9f 100644 --- a/src/mocks/SequencerInboxStub.sol +++ b/src/mocks/SequencerInboxStub.sol @@ -18,11 +18,9 @@ contract SequencerInboxStub is SequencerInbox { ISequencerInbox.MaxTimeVariation memory maxTimeVariation_, uint256 maxDataSize_, IReader4844 reader4844_, - IEigenDAServiceManager eigenDAServiceManager_, - IRollupManager eigenDARollupManager_, bool isUsingFeeToken_ - ) SequencerInbox(maxDataSize_, reader4844_, eigenDAServiceManager_, eigenDARollupManager_, isUsingFeeToken_) { + ) SequencerInbox(maxDataSize_, reader4844_, isUsingFeeToken_) { bridge = bridge_; rollup = IOwnable(msg.sender); delayBlocks = uint64(maxTimeVariation_.delayBlocks); diff --git a/src/rollup/RollupCreator.sol b/src/rollup/RollupCreator.sol index 0a7d39b3..6f8fe195 100644 --- a/src/rollup/RollupCreator.sol +++ b/src/rollup/RollupCreator.sol @@ -43,6 +43,8 @@ contract RollupCreator is Ownable { //// @dev The address of the batch poster, not used when set to zero address address[] batchPosters; address batchPosterManager; + address eigenDAServiceManager; + address eigenDARollupManager; } BridgeCreator public bridgeCreator; @@ -196,6 +198,10 @@ contract RollupCreator is Ownable { bridgeContracts.sequencerInbox.setBatchPosterManager(deployParams.batchPosterManager); } + // Setting EigenDAServiceManager and EigenDARollupManager + bridgeContracts.sequencerInbox.setEigenDAServiceManager(deployParams.eigenDAServiceManager); + bridgeContracts.sequencerInbox.setEigenDARollupManager(deployParams.eigenDARollupManager); + // Call setValidator on the newly created rollup contract just if validator set is not empty if (deployParams.validators.length != 0) { bool[] memory _vals = new bool[](deployParams.validators.length); diff --git a/test/foundry/SequencerInbox.t.sol b/test/foundry/SequencerInbox.t.sol index b2ed88c6..ae993a6e 100644 --- a/test/foundry/SequencerInbox.t.sol +++ b/test/foundry/SequencerInbox.t.sol @@ -74,8 +74,6 @@ contract SequencerInboxTest is Test { SequencerInbox seqInboxImpl = new SequencerInbox( maxDataSize, isArbHosted ? IReader4844(address(0)) : dummyReader4844, - dummyEigenDAServiceManager, - rollupManager, false ); SequencerInbox seqInbox = SequencerInbox( @@ -356,7 +354,7 @@ contract SequencerInboxTest is Test { /* solhint-disable func-name-mixedcase */ function testConstructor() public { SequencerInbox seqInboxLogic = - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, false); + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, false); assertEq(seqInboxLogic.maxDataSize(), MAX_DATA_SIZE, "Invalid MAX_DATA_SIZE"); assertEq(seqInboxLogic.isUsingFeeToken(), false, "Invalid isUsingFeeToken"); @@ -365,7 +363,7 @@ contract SequencerInboxTest is Test { assertEq(seqInboxProxy.isUsingFeeToken(), false, "Invalid isUsingFeeToken"); SequencerInbox seqInboxLogicFeeToken = - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, true); + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, true); assertEq(seqInboxLogicFeeToken.maxDataSize(), MAX_DATA_SIZE, "Invalid MAX_DATA_SIZE"); assertEq(seqInboxLogicFeeToken.isUsingFeeToken(), true, "Invalid isUsingFeeToken"); @@ -381,7 +379,7 @@ contract SequencerInboxTest is Test { _bridge.initialize(IOwnable(address(new RollupMock(rollupOwner)))); address seqInboxLogic = address( - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, false) + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, false) ); SequencerInbox seqInboxProxy = SequencerInbox(TestUtil.deployProxy(seqInboxLogic)); seqInboxProxy.initialize(IBridge(_bridge), maxTimeVariation); @@ -399,7 +397,7 @@ contract SequencerInboxTest is Test { _bridge.initialize(IOwnable(address(new RollupMock(rollupOwner))), nativeToken); address seqInboxLogic = address( - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, true) + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, true) ); SequencerInbox seqInboxProxy = SequencerInbox(TestUtil.deployProxy(seqInboxLogic)); seqInboxProxy.initialize(IBridge(_bridge), maxTimeVariation); @@ -415,7 +413,7 @@ contract SequencerInboxTest is Test { _bridge.initialize(IOwnable(address(new RollupMock(rollupOwner)))); address seqInboxLogic = address( - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, true) + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, true) ); SequencerInbox seqInboxProxy = SequencerInbox(TestUtil.deployProxy(seqInboxLogic)); @@ -431,7 +429,7 @@ contract SequencerInboxTest is Test { _bridge.initialize(IOwnable(address(new RollupMock(rollupOwner))), nativeToken); address seqInboxLogic = address( - new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, dummyEigenDAServiceManager, rollupManager, false) + new SequencerInbox(MAX_DATA_SIZE, dummyReader4844, false) ); SequencerInbox seqInboxProxy = SequencerInbox(TestUtil.deployProxy(seqInboxLogic)); @@ -625,136 +623,134 @@ contract SequencerInboxTest is Test { quorumIndices: hex"0001" }); - // function testAddSequencerL2BatchFromEigenDA() public { - // blobHeader.commitment = commitment; - // blobHeader.dataLength = 1; - // blobHeader.quorumBlobParams.push( - // IEigenDAServiceManager.QuorumBlobParam({ - // quorumNumber: 0, - // adversaryThresholdPercentage: 33, - // confirmationThresholdPercentage: 55, - // chunkLength: 1 - // }) - // ); - // blobHeader.quorumBlobParams.push( - // IEigenDAServiceManager.QuorumBlobParam({ - // quorumNumber: 1, - // adversaryThresholdPercentage: 33, - // confirmationThresholdPercentage: 55, - // chunkLength: 1 - // }) - // ); - - // (SequencerInbox seqInbox, Bridge bridge) = deployRollup(false); - // // update the dummyEigenDAServiceManager to use the holesky serviceManager contract - // vm.prank(rollupOwner); - // seqInbox.updateEigenDAServiceManager(0xD4A7E1Bd8015057293f0D0A557088c286942e84b); - // address delayedInboxSender = address(140); - // uint8 delayedInboxKind = 3; - // bytes32 messageDataHash = RAND.Bytes32(); - - // vm.prank(dummyInbox); - // bridge.enqueueDelayedMessage(delayedInboxKind, delayedInboxSender, messageDataHash); - - // // ed is EIGEN_DA_MESSAGE_HEADER_FLAG rest is abi.encodePacked(blobHeader.commitment.X, blobHeader.commitment.Y, blobHeader.dataLength) - // bytes memory data = - // hex"ed1a78ee576b0026de661b72106bf447f5bb70881f24a3fa8b1f312992c8e165970633b392b3d3f66407d912aafcc2f0231c31918f0485e8476975edc710fcb45200000001"; - - // uint256 subMessageCount = bridge.sequencerReportedSubMessageCount(); - // uint256 sequenceNumber = bridge.sequencerMessageCount(); - // uint256 delayedMessagesRead = bridge.delayedMessageCount(); - - // expectEvents(bridge, seqInbox, data, false, false, true); - - // vm.prank(tx.origin); - - // seqInbox.addSequencerL2BatchFromEigenDA( - // sequenceNumber, - // blobVerificationProof, - // blobHeader, - // delayedMessagesRead, - // IGasRefunder(address(0)), - // subMessageCount, - // subMessageCount + 1 - // ); - // } - - // // TODO: put these in jsons later - // // create illegal commitment - // BN254.G1Point illegalCommitment = BN254.G1Point({ - // X: 11151623676041303181597631684634074376466382703418354161831688442589830350329, - // Y: 4222041728992406478862708226745479381252734858741080790666424175645694456140 - // }); - - // IEigenDAServiceManager.BlobHeader illegalBlobHeader; - - // IEigenDAServiceManager.BatchHeader illegalBatchHeader = IEigenDAServiceManager.BatchHeader({ - // blobHeadersRoot: bytes32(0), - // quorumNumbers: bytes(""), - // signedStakeForQuorums: bytes(""), - // referenceBlockNumber: 1 - // }); - - // IEigenDAServiceManager.BatchMetadata illegalBatchMetadata = IEigenDAServiceManager.BatchMetadata({ - // batchHeader: illegalBatchHeader, - // signatoryRecordHash: bytes32(0), - // confirmationBlockNumber: 1 - // }); - - // EigenDARollupUtils.BlobVerificationProof illegalBlobVerificationProof = EigenDARollupUtils - // .BlobVerificationProof({ - // batchId: 1, - // blobIndex: 1, - // batchMetadata: illegalBatchMetadata, - // inclusionProof: bytes(""), - // quorumIndices: bytes("") - // }); - - // function testAddSequencerL2BatchFromEigenDARevert() public { - // // finish filling out the illegalBlobHeader - // illegalBlobHeader.commitment = illegalCommitment; - // illegalBlobHeader.dataLength = 20; - // illegalBlobHeader.quorumBlobParams.push( - // IEigenDAServiceManager.QuorumBlobParam({ - // quorumNumber: uint8(1), - // adversaryThresholdPercentage: uint8(1), - // confirmationThresholdPercentage: uint8(1), - // chunkLength: uint32(1) - // }) - // ); - - // // change the eigenDAServiceManager to use the holesky testnet contract - // (SequencerInbox seqInbox, Bridge bridge) = deployRollup(false); - // address delayedInboxSender = address(140); - // uint8 delayedInboxKind = 3; - // bytes32 messageDataHash = RAND.Bytes32(); - // bytes memory data = biggerData; // 00 is BROTLI_MESSAGE_HEADER_FLAG - - // vm.prank(dummyInbox); - // bridge.enqueueDelayedMessage(delayedInboxKind, delayedInboxSender, messageDataHash); - - // uint256 subMessageCount = bridge.sequencerReportedSubMessageCount(); - // uint256 sequenceNumber = bridge.sequencerMessageCount(); - // uint256 delayedMessagesRead = bridge.delayedMessageCount(); - - // vm.prank(tx.origin); - - // vm.expectRevert(); - // seqInbox.addSequencerL2BatchFromEigenDA( - // sequenceNumber, - // illegalBlobVerificationProof, - // illegalBlobHeader, - // delayedMessagesRead, - // IGasRefunder(address(0)), - // subMessageCount, - // subMessageCount + 1 - // ); - // } + function testAddSequencerL2BatchFromEigenDA() public { + blobHeader.commitment = commitment; + blobHeader.dataLength = 1; + blobHeader.quorumBlobParams.push( + IEigenDAServiceManager.QuorumBlobParam({ + quorumNumber: 0, + adversaryThresholdPercentage: 33, + confirmationThresholdPercentage: 55, + chunkLength: 1 + }) + ); + blobHeader.quorumBlobParams.push( + IEigenDAServiceManager.QuorumBlobParam({ + quorumNumber: 1, + adversaryThresholdPercentage: 33, + confirmationThresholdPercentage: 55, + chunkLength: 1 + }) + ); + + (SequencerInbox seqInbox, Bridge bridge) = deployRollup(false); + // update the dummyEigenDAServiceManager to use the holesky serviceManager contract + vm.prank(rollupOwner); + seqInbox.setEigenDAServiceManager(0xD4A7E1Bd8015057293f0D0A557088c286942e84b); + address delayedInboxSender = address(140); + uint8 delayedInboxKind = 3; + bytes32 messageDataHash = RAND.Bytes32(); + + vm.prank(dummyInbox); + bridge.enqueueDelayedMessage(delayedInboxKind, delayedInboxSender, messageDataHash); + + // ed is EIGEN_DA_MESSAGE_HEADER_FLAG rest is abi.encodePacked(blobHeader.commitment.X, blobHeader.commitment.Y, blobHeader.dataLength) + bytes memory data = + hex"ed1a78ee576b0026de661b72106bf447f5bb70881f24a3fa8b1f312992c8e165970633b392b3d3f66407d912aafcc2f0231c31918f0485e8476975edc710fcb45200000001"; + + uint256 subMessageCount = bridge.sequencerReportedSubMessageCount(); + uint256 sequenceNumber = bridge.sequencerMessageCount(); + uint256 delayedMessagesRead = bridge.delayedMessageCount(); + + expectEvents(bridge, seqInbox, data, false, false, true); + + vm.prank(tx.origin); + + seqInbox.addSequencerL2BatchFromEigenDA( + sequenceNumber, + blobVerificationProof, + blobHeader, + delayedMessagesRead, + subMessageCount, + subMessageCount + 1 + ); + } + + // TODO: put these in jsons later + // create illegal commitment + BN254.G1Point illegalCommitment = BN254.G1Point({ + X: 11151623676041303181597631684634074376466382703418354161831688442589830350329, + Y: 4222041728992406478862708226745479381252734858741080790666424175645694456140 + }); + + IEigenDAServiceManager.BlobHeader illegalBlobHeader; + + IEigenDAServiceManager.BatchHeader illegalBatchHeader = IEigenDAServiceManager.BatchHeader({ + blobHeadersRoot: bytes32(0), + quorumNumbers: bytes(""), + signedStakeForQuorums: bytes(""), + referenceBlockNumber: 1 + }); + + IEigenDAServiceManager.BatchMetadata illegalBatchMetadata = IEigenDAServiceManager.BatchMetadata({ + batchHeader: illegalBatchHeader, + signatoryRecordHash: bytes32(0), + confirmationBlockNumber: 1 + }); + + EigenDARollupUtils.BlobVerificationProof illegalBlobVerificationProof = EigenDARollupUtils + .BlobVerificationProof({ + batchId: 1, + blobIndex: 1, + batchMetadata: illegalBatchMetadata, + inclusionProof: bytes(""), + quorumIndices: bytes("") + }); + + function testAddSequencerL2BatchFromEigenDARevert() public { + // finish filling out the illegalBlobHeader + illegalBlobHeader.commitment = illegalCommitment; + illegalBlobHeader.dataLength = 20; + illegalBlobHeader.quorumBlobParams.push( + IEigenDAServiceManager.QuorumBlobParam({ + quorumNumber: uint8(1), + adversaryThresholdPercentage: uint8(1), + confirmationThresholdPercentage: uint8(1), + chunkLength: uint32(1) + }) + ); + + // change the eigenDAServiceManager to use the holesky testnet contract + (SequencerInbox seqInbox, Bridge bridge) = deployRollup(false); + address delayedInboxSender = address(140); + uint8 delayedInboxKind = 3; + bytes32 messageDataHash = RAND.Bytes32(); + bytes memory data = biggerData; // 00 is BROTLI_MESSAGE_HEADER_FLAG + + vm.prank(dummyInbox); + bridge.enqueueDelayedMessage(delayedInboxKind, delayedInboxSender, messageDataHash); + + uint256 subMessageCount = bridge.sequencerReportedSubMessageCount(); + uint256 sequenceNumber = bridge.sequencerMessageCount(); + uint256 delayedMessagesRead = bridge.delayedMessageCount(); + + vm.prank(tx.origin); + + vm.expectRevert(); + seqInbox.addSequencerL2BatchFromEigenDA( + sequenceNumber, + illegalBlobVerificationProof, + illegalBlobHeader, + delayedMessagesRead, + subMessageCount, + subMessageCount + 1 + ); + } function testPostUpgradeInitAlreadyInit() public returns (SequencerInbox, SequencerInbox) { (SequencerInbox seqInbox,) = deployRollup(false); SequencerInbox seqInboxImpl = - new SequencerInbox(maxDataSize, dummyReader4844, dummyEigenDAServiceManager, rollupManager, false); + new SequencerInbox(maxDataSize, dummyReader4844, false); vm.expectRevert(abi.encodeWithSelector(AlreadyInit.selector)); vm.prank(proxyAdmin);