Integer Overflow in Lodestar
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.
| Package | Affected versions | Patched versions |
|---|---|---|
@chainsafe/lodestarnpm | < 0.36.0 | 0.36.0 |
Affected products
3Patches
128e2c74cf0f1sleep(0) must yield event loop (#3987)
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- github.com/advisories/GHSA-cvj7-5f3c-9vg9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-29219ghsaADVISORY
- github.com/ChainSafe/lodestar/pull/3977ghsax_refsource_MISCWEB
- github.com/ChainSafe/lodestar/releases/tag/v0.36.0ghsax_refsource_MISCWEB
- github.com/ChainSafe/lodestar/security/advisories/GHSA-cvj7-5f3c-9vg9ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.