Datachain - ELC for Bridge (OptimismELC)

QuantstampCode version: not recorded (see the report)

Quantstamp reviewed Datachain (Datachain - ELC for Bridge (OptimismELC)) on 25 Jul 2025: 8 findings, 0 critical; all marked fixed.

No open critical findings
Open the reportOpen Datachain’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings8

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium000
Low008
LowConsistency of `RollupConfig`Fixed

The `Derivation` object is stateless regarding `RollupConfig`. When `lightclient::Header::verify_l2` calls `self.derivation.verify()`, it uses the `rollup_config` from the `ClientState`. The preimages provided in the `Header` and the derivation claim fields must have been generated by an off-chain prover using a `RollupConfig` that is identical to the one held in the `ClientState`. Therefore, if a relayer provides a `Header` whose embedded preimages or derivation claims were generated using a different `RollupConfig` than the one the `ClientState` is configured with, the verification performed by `Derivation::verify()` might lead to incorrect results. The code itself passes the `ClientState`'s `rollup_config`, but the validity of the operation hinges on the external consistency of the supplied `Header` data with this configuration.

LowDuplicate Values Are Not Checked in `try_from()` for `MemoryOracleClient`Fixed

The `try_from()` function implemented for `MemoryOracleClient` loops on the `value` vector of preimages. The logic does not validate for duplicate preimages before operating on them, which may result in unwanted or broken behavior.

LowGlobal Generic and Local Keytypes Are AllowedFixed

The `try_from()` function implemented for `MemoryOracleClient` matches the `preimage_key.key_type()` value against the `PreimageKeyType::Keccak256` and `PreimageKeyType::Sha256` keytypes to validate them before including them in the oracle; however, the `_ => {}` arm would allow any other keytype to be included in the oracle without validation.

LowLack of Length Validation in `verify_blob_preimage()`Fixed

Validation in `verify_blob_preimage()` can be added with respect to a number of attributes: 1. At `oracle.rs#L176`, when `blob_key` is instantiated, it is expected to have length `POSITION_FIELD_ELEMENT + 8`, i.e. `80`, when calling `get_data_by_blob_key(blob_key, preimages)`. 2. At `oracle.rs#L195`, `sidecar_blob` is expected to have length `32` when copying it into `blob` slices. Validating the length of these data is useful to prevent runtime panics that may arise in the case of malformed data.

LowLack of Validation of the `frozen` and `revision_height` Values in `try_from()` for `ClientState`Fixed

The `try_from()` function implemented for `ClientState` accepts the value of `raw_latest_height.revision_height` from the latest height passed via the `value` provided without validation, which could be zero. Similarly, the value of `value.frozen` is not checked before being set in the generated `ClientState` instance, allowing for the creation of an initially frozen client.

LowMisbehaviour Handling Not ImplementedFixed

The `update_client()` function has a `todo!()` for `ClientMessage::Misbehaviour`. Hence, the light client cannot currently process or react to misbehaviour reports.

LowMissing Lower Bound Check in Timestamp ValidationFixed

The name of the `validate_state_timestamp_within_trusting_period()` function suggests it is supposed to ensure that `current_timestamp` is within a valid range defined by `trusting_period`. While the function checks that the `current_timestamp` is not too far in the future (i.e., it enforces an upper bound), it fails to ensure that the timestamp is also recent enough to be trusted (i.e., within the lower bound of the `trusting_period`). This could allow outdated or expired state timestamps to pass validation erroneously.

LowNondeterministic `verify_blob_preimage()`Fixed

Currently, when calling `verify_blob_preimage()`, the value of the last 32 bytes of `blob_key` when instantiated at `oracle.rs#L176` can in principle be arbitrary so long as the commitment within the first 48 bytes is correct. Although the function remains safe due to KZG verification, it may cause the client to accept preimages that other clients would reject, resulting in a subtle impact regarding client interoperability.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Part of Datachain’s security record

Datachain
Audits7 audits by 1 firmLast audit Jul 2025, by Quantstamp.
Critical findingsNo open critical findingsAcross 7 reports.
Open Datachain’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us