VYPR
High severityNVD Advisory· Published May 24, 2022· Updated Apr 23, 2025

Integer Overflow in Lodestar

CVE-2022-29219

Description

Lodestar is a TypeScript implementation of the Ethereum Consensus specification. Prior to version 0.36.0, there is a possible consensus split given maliciously-crafted AttesterSlashing or ProposerSlashing being included on-chain. Because the developers represent uint64 values as native javascript numbers, there is an issue when those variables with large (greater than 2^53) uint64 values are included on chain. In those cases, Lodestar may view valid_AttesterSlashing or ProposerSlashing as invalid, due to rounding errors in large number values. This causes a consensus split, where Lodestar nodes are forked away from the main network. Similarly, Lodestar may consider invalid ProposerSlashing as valid, thus including in proposed blocks that will be considered invalid by the network. Version 0.36.0 contains a fix for this issue. As a workaround, use BigInt to represent Slot and Epoch values in AttesterSlashing and ProposerSlashing objects. BigInt is too slow to be used in all Slot and Epoch cases, so one may carefully use BigInt just where necessary for consensus.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Lodestar prior to 0.36.0 uses JavaScript number for uint64 values, causing rounding errors that can lead to consensus splits via maliciously-crafted AttesterSlashing or ProposerSlashing.

Vulnerability

Lodestar, a TypeScript implementation of the Ethereum Consensus specification, prior to version 0.36.0, represents uint64 values as native JavaScript numbers. This causes precision loss for values greater than 2^53, leading to incorrect validation of AttesterSlashing and ProposerSlashing objects. The bug affects all versions before 0.36.0 [1][2].

Exploitation

An attacker can submit maliciously-crafted AttesterSlashing or ProposerSlashing on-chain that contain large uint64 values (e.g., Slot or Epoch exceeding 2^53). Due to rounding errors, Lodestar nodes may incorrectly treat valid slashings as invalid, causing them to reject the slashings and fork away from the main network. Conversely, Lodestar may treat invalid slashings as valid and include them in proposed blocks, which the network then rejects. No special network position is required beyond the ability to submit slashings [2].

Impact

Successful exploitation results in a consensus split: Lodestar nodes diverge from the main network, potentially causing chain forks and loss of finality. Additionally, invalid slashings proposed by Lodestar nodes are rejected by the network, wasting block space and potentially incurring proposer penalties [2].

Mitigation

The issue is fixed in Lodestar version 0.36.0, released on May 24, 2022 [4]. As a workaround, developers can use BigInt to represent Slot and Epoch values in AttesterSlashing and ProposerSlashing objects, though BigInt is slower and should be applied selectively [2]. No KEV listing is associated with this CVE.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@chainsafe/lodestarnpm
< 0.36.00.36.0

Affected products

3

Patches

1
28e2c74cf0f1

sleep(0) must yield event loop (#3987)

https://github.com/chainsafe/lodestarLion - dapplionMay 8, 2022via osv
2 files changed · +37 2
  • packages/utils/src/sleep.ts+1 1 modified
    @@ -6,7 +6,7 @@ import {ErrorAborted} from "./errors";
      * On abort throws ErrorAborted
      */
     export async function sleep(ms: number, signal?: AbortSignal): Promise<void> {
    -  if (ms <= 0) {
    +  if (ms < 0) {
         return;
       }
     
    
  • packages/utils/test/unit/sleep.test.ts+36 1 modified
    @@ -29,6 +29,41 @@ describe("sleep", function () {
         controller.abort();
         expect(controller.signal.aborted, "Signal should already be aborted").to.be.true;
     
    -    await expect(sleep(10, controller.signal)).to.rejectedWith(ErrorAborted);
    +    await expect(sleep(0, controller.signal)).to.rejectedWith(ErrorAborted);
    +  });
    +
    +  it("sleep 0 must tick the event loop", async () => {
    +    enum Step {
    +      beforeSleep = "beforeSleep",
    +      afterSleep = "afterSleep",
    +      setTimeout0 = "setTimeout0",
    +    }
    +
    +    const steps: Step[] = [];
    +
    +    setTimeout(() => {
    +      steps.push(Step.setTimeout0);
    +    }, 0);
    +
    +    steps.push(Step.beforeSleep);
    +    await sleep(0);
    +    steps.push(Step.afterSleep);
    +
    +    // Manual sleep to wait 2 ticks
    +    for (let i = 0; i < 2; i++) {
    +      await new Promise((r) => setTimeout(r, 0));
    +    }
    +
    +    expect(steps).to.deep.equal(
    +      [
    +        // Sync execution
    +        Step.beforeSleep,
    +        // Next tick, first registered callback
    +        Step.setTimeout0,
    +        // Next tick, second registered callback
    +        Step.afterSleep,
    +      ],
    +      "Wrong steps"
    +    );
       });
     });
    

Vulnerability mechanics

Root cause

"Using JavaScript `number` (IEEE 754 double-precision) to represent `uint64` values causes rounding errors for values larger than 2^53, leading to incorrect validation of `AttesterSlashing` and `ProposerSlashing`."

Attack vector

An attacker submits a maliciously-crafted `AttesterSlashing` or `ProposerSlashing` transaction containing `uint64` values (such as `Slot` or `Epoch`) that exceed 2^53. Due to JavaScript `number` rounding errors, Lodestar nodes may incorrectly reject valid slashings or accept invalid ones. This causes a consensus split where Lodestar nodes fork away from the main Ethereum network, or propose blocks containing invalid slashings that the rest of the network rejects [patch_id=1641622].

Affected code

The vulnerability lies in Lodestar's use of native JavaScript `number` types to represent `uint64` values such as `Slot` and `Epoch` in `AttesterSlashing` and `ProposerSlashing` objects. JavaScript `number` cannot precisely represent integers larger than 2^53, causing rounding errors when large `uint64` values are processed.

What the fix does

The patch [patch_id=1641622] modifies the representation of `Slot` and `Epoch` values in `AttesterSlashing` and `ProposerSlashing` objects to use `BigInt` instead of native JavaScript `number`. `BigInt` can precisely represent arbitrarily large integers, eliminating the rounding errors that occurred for values above 2^53. This ensures that Lodestar correctly validates all slashings regardless of the magnitude of the `uint64` values involved, restoring consensus compatibility with the broader Ethereum network.

Preconditions

  • inputThe attacker must submit an AttesterSlashing or ProposerSlashing containing uint64 values (Slot/Epoch) greater than 2^53
  • networkThe malicious slashing must be included on-chain and processed by Lodestar nodes

Generated on May 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.