Discount DoS: Exploding Frontier Nodes with Even Numbers
Jan 5, 2026·5 min read
Executive Summary (TL;DR)
Frontier's implementation of the `modexp` precompile underpriced operations involving even numbers. Because the underlying math library is significantly slower at processing even moduli than odd ones, attackers could spam cheap transactions that consumed massive amounts of CPU, effectively halting block production for a fraction of the intended cost.
A critical algorithmic complexity vulnerability in the Frontier Ethereum compatibility layer allowed attackers to trigger denial-of-service conditions by exploiting the performance discrepancy between odd and even moduli in modular exponentiation calculations.
The Hook: When Gas Lighting Fails
In the Ethereum ecosystem, 'Gas' is the currency of computation. It's supposed to be the ruthless arbiter of fairness: you pay for every cycle you burn. If a function is computationally expensive, the gas cost should be astronomically high. This economic model prevents malicious actors from spamming heavy compute jobs and clogging the network. It's the only thing standing between a healthy blockchain and a smoking crater.
Frontier is the bridge that lets Substrate-based chains (like those on Polkadot) run Ethereum smart contracts. It comes with standard precompiles—special built-in functions that live at fixed addresses. One of these is modexp (Modular Exponentiation) at address 0x00...05. It's a cryptographic workhorse used for signature verification and zero-knowledge proofs.
But here's the catch: Frontier assumed all numbers were created equal. They aren't. In the world of modular arithmetic, being 'even' makes you a problem child. And Frontier forgot to charge extra for babysitting problem children.
The Flaw: The Montgomery Shortcut
To understand this bug, we have to look at the math under the hood. The Frontier modexp precompile relies on a Rust crate called num-bigint to handle the heavy lifting ($B^E \pmod M$).
When you perform modular exponentiation with an odd modulus, num-bigint uses an optimization called Montgomery Multiplication. This is a brilliant mathematical trick that replaces expensive division operations with cheap bitwise shifts. It's fast, efficient, and well-behaved.
However, Montgomery Multiplication requires the modulus to be coprime to the machine word base (usually $2^64$). This condition fails if the modulus is even. When num-bigint encounters an even modulus, it can't use the shortcut. It falls back to a standard, non-optimized power algorithm (essentially binary exponentiation with standard reduction).
This fallback path is drastically slower—orders of magnitude slower for large numbers. The vulnerability is a classic mismatch: Frontier calculated gas costs based on the length of the inputs (EIP-2565), assuming the optimized path. It failed to check if the input would force the slow path. The result? A transaction that costs pennies in gas but demands hundreds of dollars' worth of CPU time.
The Code: The Missing Price Tag
Let's look at the smoking gun in frame/evm/precompile/modexp/src/lib.rs. The gas calculation logic was purely length-based.
The Vulnerable Logic:
// Pre-patch logic pseudo-code
fn calculate_gas_cost(base_len, mod_len, exponent) {
// Complexity is guessed based on bit length only
let complexity = math::complexity(base_len, mod_len);
let iterations = math::iterations(exponent);
// The price is fixed, regardless of the modulus value
return max(200, complexity * iterations / 3);
}Notice what's missing? There is no check for modulus % 2 == 0. An attacker sends a 2048-bit odd modulus, they pay $X$ gas and burn $Y$ CPU. An attacker sends a 2048-bit even modulus, they pay the same $X$ gas, but burn $20Y$ CPU.
The Fix (Commit 5af12e94):
The developers introduced a 'surcharge' for even moduli. It's a crude but effective fix: if you want to be even, you pay 20x more.
// The patched logic
fn calculate_gas_cost(..., mod_is_even: bool) -> u64 {
let base_gas = max(MIN_GAS, complexity * iterations / 3);
// If it's even, multiply the bill by 20.
// This reflects the lack of Montgomery optimization.
base_gas.saturating_mul(if mod_is_even { 20 } else { 1 })
}The Exploit: Crashing the Party
Exploiting this is trivially easy for anyone who knows how to craft a raw Ethereum transaction. You don't need special permissions; you just need enough ETH to pay the (undervalued) fee.
Here is the recipe for disaster:
- Target: Precompile
0x0000000000000000000000000000000000000005. - Payload:
- Base: Arbitrary large number.
- Exponent: Massive number (to maximize iteration count).
- Modulus: A large number (e.g., 2048 bits) ensuring the least significant bit is
0(making it even).
By chaining several of these transactions in a single block, an attacker can force the node to spend seconds or even minutes verifying the block. In a consensus protocol like Polkadot/Substrate where block times are strict (e.g., 6 seconds), delaying execution by even a few seconds causes the validator to miss its slot. Sustained attacks can partition the network or halt the chain entirely.
The Impact: Why This Hurts
This vulnerability is an Asymmetric Resource Exhaustion. The asymmetry is the killer. If the attack cost the attacker $1000 to stall the network for 5 minutes, it would be annoying but sustainable. Here, the attack might cost $0.50 to stall the network.
For Substrate chains relying on Frontier, the impact is:
- Denial of Service: Validators get stuck crunching numbers instead of finalizing blocks.
- Network Partition: Nodes with faster CPUs might scrape by, while slower nodes fall out of sync, causing forks.
- Reputational Damage: A halted chain is a useless chain.
The fix doesn't make the math faster; it just makes the attack too expensive to be fun anymore. It restores the economic balance of the gas model.
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Frontier Parity Technologies | <= 0.1.0 | PR #1017 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-682 (Incorrect Calculation) |
| Attack Vector | Network (Remote) |
| CVSS Score | 7.5 (High) |
| EPSS Score | 0.00249 (Low Prob) |
| Impact | Denial of Service (DoS) |
| Exploit Status | PoC / Trivial |
MITRE ATT&CK Mapping
MITRE ATT&CK Mapping
The product performs a calculation that generates incorrect or inaccurate results that can be exploited to cause a denial of service.
Exploit Resources
Known Exploits & Detection
Vulnerability Timeline
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.