Skip to content

Back to the catalog

Misordered Named Parameters in require with Custom Errors Bug
soliditylang.orgadvisory

Misordered Named Parameters in require with Custom Errors Bug

The Solidity team discloses a bug (reported by Cantina Security via the Ethereum Foundation bug bounty) where the IR-based (--via-ir) code generator pushed named custom-error arguments in call-site order instead of declaration order before ABI-encoding, corrupting revert data for require(condition, ErrorName({...})) calls with reordered named parameters. Introduced in Solidity 0.8.26 and fixed in 0.8.37, the bug produces silently swapped or type-confused values in decoded revert data with no compiler warning, and can cause misaligned encoding in multi-slot-argument cases that either reverts with undecodable data or produces a plausible-but-wrong payload - a real concern for standards like ERC-3668 (CCIP Read) that treat revert data as part of the contract interface. Severity was rated "very low" since the affected transaction is already reverting and there is no attacker-controlled exploitation path, but audits of via-ir contracts using named custom-error arguments should check for it.

TL;DR Solidity via-ir compiler bug (0.8.26-0.8.36) silently mis-encodes revert data when custom-error named arguments are passed out of declaration order; fixed in 0.8.37.
Document

What it is

A code-generation bug in Solidity's IR pipeline (--via-ir / viaIR: true) that mis-encodes custom-error revert data when the error is passed to require using named-parameter syntax in a non-declaration order. Introduced in 0.8.26 (which first allowed custom errors as require's second argument), fixed in 0.8.37. Reported by Carl of Cantina Security via the Ethereum Foundation bug bounty on February 4, 2026; rated "very low" severity.

Precondition (all four must hold)

The summary describes the bug but not its exact trigger. A contract is affected only when:

  • Compiled with the IR pipeline — the legacy evmasm pipeline is unaffected.
  • Uses require(condition, ErrorName({...})) with a user-defined error.
  • At least two arguments appear in an order differing from the declaration.
  • At least one reordered argument is not a string literal (string literals occupy no stack slots, so reordering only them cannot shift anything).

Note the scope limit the summary omits: standalone revert ErrorName({...}) is NOT affected — it goes through a different path that reorders before encoding. The bug is specific to the require-with-custom-error path.

What to do

The page gives a concrete workaround the summary does not, usable before upgrading:

  • Upgrade to Solidity 0.8.37 or later before deploying IR-compiled contracts that use named parameters in custom errors.
  • Until then, avoid the bug by writing the named arguments in declaration order, or by using positional arguments.

Auditing guidance: the mistake is undetectable at compile time. Same-type swaps produce no type mismatch; different-type reorderings compile silently. Grep affected contracts for require(...) calls whose second argument is a custom error instantiated with {...} named syntax, then check argument order against each error's declaration.

Caveats

No third-party exploitation path exists — the misordered arguments must already be in the contract's own source, and an attacker wanting to present misleading revert data can already deploy a contract reverting with arbitrary bytes. The harm is limited to honest contracts unknowingly emitting wrong data to trusting consumers (indexers, decoders, and standards like ERC-3668 that treat revert data as interface).

Organisations named here

  • Cantina Security
  • ERC-3668
  • Ethereum Foundation
  • OffchainLookup

Technologies named here

  • Solidity compiler
  • Solidity
  • Ethereum

Techniques named here

  • Same-slot-count argument swap
  • Multi-slot argument misalignment
  • Observing revert data via try/catch or low-level CALL