Skip to content

Commit

Permalink
Merge pull request #32 from Layr-Labs/epociask--fix-cert-timing-bug
Browse files Browse the repository at this point in the history
fix: Cert timing bug for L2s
  • Loading branch information
ethenotethan authored Nov 20, 2024
2 parents cb430d2 + 9c411a2 commit 53dcf37
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/bridge/EigenDABlobVerifierL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
pragma solidity ^0.8.9;

import "./IRollupManager.sol";
import {
ExpiredEigenDACert
} from "../libraries/Error.sol";

contract EigenDABlobVerifierL1 is IRollupManager {
IEigenDAServiceManager public immutable EIGEN_DA_SERVICE_MANAGER;
uint256 internal constant MAX_CERTIFICATE_DRIFT = 100;

constructor(address _eigenDAServiceManager) {
EIGEN_DA_SERVICE_MANAGER = IEigenDAServiceManager(_eigenDAServiceManager);
Expand All @@ -14,6 +18,23 @@ contract EigenDABlobVerifierL1 is IRollupManager {
IEigenDAServiceManager.BlobHeader calldata blobHeader,
EigenDARollupUtils.BlobVerificationProof calldata blobVerificationProof
) external view {
/*
Verify that the certificate is less than 2 epochs old from the L1 reference block number
This is to prevent timing attacks where the sequencer could submit an expired or close to expired
certificate which could impact liveness of full nodes as well as the safety of the bridge
*/
if (
(blobVerificationProof.batchMetadata.confirmationBlockNumber +
MAX_CERTIFICATE_DRIFT) < block.number
) {
revert ExpiredEigenDACert(
block.number,
blobVerificationProof.batchMetadata.confirmationBlockNumber +
MAX_CERTIFICATE_DRIFT
);
}


EigenDARollupUtils.verifyBlob(blobHeader, EIGEN_DA_SERVICE_MANAGER, blobVerificationProof);
}
}
3 changes: 3 additions & 0 deletions src/libraries/Error.sol
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ error BadSequencerMessageNumber(uint256 stored, uint256 received);
/// @dev Tried to create an already valid Data Availability Service keyset
error AlreadyValidDASKeyset(bytes32);

/// @dev The EigenDA certificate provided to the inbox was stale
error ExpiredEigenDACert(uint256 currentBlock, uint256 l1ReferenceBlock);

/// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
error NoSuchKeyset(bytes32);

Expand Down
67 changes: 67 additions & 0 deletions test/foundry/EigenDABlobVerifierL1.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "forge-std/Test.sol";
import "../../src/bridge/EigenDABlobVerifierL1.sol";
import "../../src/libraries/Error.sol";
import {EigenDARollupUtils} from "@eigenda/eigenda-utils/libraries/EigenDARollupUtils.sol";
import {IEigenDAServiceManager} from "@eigenda/eigenda-utils/interfaces/IEigenDAServiceManager.sol";
import {BN254} from "@eigenda/eigenda-utils/libraries/BN254.sol";
import {SequencerInboxTest} from "./SequencerInbox.t.sol";
import {
ExpiredEigenDACert
} from "../../src/libraries/Error.sol";

contract EigenDABlobVerifierL1Test is Test {
EigenDABlobVerifierL1 public verifier;
IEigenDAServiceManager dummyEigenDAServiceManager = IEigenDAServiceManager(address(138));

SequencerInboxTest inboxTest = new SequencerInboxTest();

function setUp() public {
// Deploy the verifier contract with a mock EigenDA Service Manager
verifier = new EigenDABlobVerifierL1(address(dummyEigenDAServiceManager));
}

function testCertificateTooOld() public {
(
IEigenDAServiceManager.BlobHeader memory blobHeader,
EigenDARollupUtils.BlobVerificationProof memory blobVerificationProof
) = inboxTest.readAndParseBlobInfo();

// Set the confirmation block number to be MAX_CERTIFICATE_DRIFT + 1
blobVerificationProof.batchMetadata.confirmationBlockNumber = 0;

vm.roll(101);
vm.expectRevert(
abi.encodeWithSelector(
ExpiredEigenDACert.selector,
block.number,
100
)
);

verifier.verifyBlob(
blobHeader,
blobVerificationProof
);
}

function testCertificateWithinSafetyBound() public {
(
IEigenDAServiceManager.BlobHeader memory blobHeader,
EigenDARollupUtils.BlobVerificationProof memory blobVerificationProof
) = inboxTest.readAndParseBlobInfo();

// Set the confirmation block number to be MAX_CERTIFICATE_DRIFT + 1
blobVerificationProof.batchMetadata.confirmationBlockNumber = 100;

vm.roll(101);
vm.expectRevert(bytes(""));

verifier.verifyBlob(
blobHeader,
blobVerificationProof
);
}
}

0 comments on commit 53dcf37

Please sign in to comment.