Repository navigation
Breaking Changes:
- Builtins: Widen all
addmodandmulmodparameters and return values touint(uint512). Narrower unsigned inputs widen implicitly; assigning the result to a narrower type requires an explicit conversion. Intermediate arithmetic remains exact even when it exceeds 512 bits. - Code Generator: Use
Panic(uint512)with selector0xdf75fb3bfor compiler-generated panics andcatch Panic. The payload remains a 4-byte selector followed by a 64-byte code. Contracts compiled by 0.2.0 retain the0x4e487b71selector. - Type System: Bare
intanduintnow meanint512anduint512, the full QRVM word. Explicitly sized integers keep their declared widths. This changes ABI signatures, selectors and storage layouts containing bare integers. - Type System: Use full-word
uintfor call value and gas options,msg.valueand account balances. Narrower unsigned inputs widen implicitly; narrowing message values or balances requires an explicit conversion. - Type Checker: Reject a narrower fixed-size bytes value or a literal shorter than 64 bytes as the digest argument of
mldsa87verify, also as a branch of a conditional, since the implicit conversion tobytes64would pad it with zero bytes on the right without any hint in the source. Pass abytes64value, such as the result ofshake256, or convert explicitly withbytes64(...)(CIPH-HYPERION-12). - Type System: Array and fixed-bytes indices, calldata slice bounds, allocation lengths and generated array getter indices accept full-word integers.
catch Panic(uint code)binds auint512code.
Important Bugfixes:
- Code Generator: Mask packed internal function pointers before testing for zero in the legacy pipeline, so calling an unset pointer reverts with
Panic(0x51)even when a nonzero neighbour shares its storage slot (CIPH-HYPERION-7). - Code Generator: Fix clearing and copying of storage arrays that straddle the end of storage (slot
2**512 - 1), which could make assignment, initialization,delete,push()andpop()skip some or all of the intended storage writes and leave old data behind, in both code generators (upstream SOL-2025-1). - Code Generator: Fix
deleteapplied to an element of abytesarray in memory zeroing the whole 64-byte word starting at the element's location instead of only the element's byte, in the legacy code generator (upstream SOL-2026-5). - Yul Optimizer: Fix knowledge about storage/memory address relations going stale in the
DataFlowAnalyzerafter a variable is reassigned in Yul, which could causeLoadResolverto replace loads with outdated values andEqualStoreEliminatorto remove needed stores (upstream SOL-2026-7). - Yul Optimizer: Fix call graph cycle detection failing to classify some functions in intersecting recursive cycles as recursive, which let the IR code generator move their local variables to fixed memory offsets when working around stack-too-deep errors, so that recursive calls overwrote them (upstream SOL-2026-2).
- Yul Optimizer: Fix too few memory slots being reserved when moving local variables to memory to work around stack-too-deep errors in code containing mutually recursive functions, so that variables of two functions that can be live at the same time could get the same slot and overwrite each other (upstream SOL-2026-4).
Language Features:
- Add the
shake256(bytes memory) returns (bytes64)builtin, which computes a 64-byte SHAKE256 digest through the precompiled contract at address6, in both code generators and the SMTChecker.
Compiler Features:
- SMTChecker: Model
shake256, encoding its 64-byte result as two 256-bit halves so that Z3 can reconstruct CHC answers, and encodexmssverify,shake256andmldsa87verifyonly for contracts that reference them, which leaves the queries for every other contract unchanged. - Type Checker: Warn when an exponentiation or left shift with a literal base, which is computed in 256 bits, is converted to a wider integer type, as in
uint512 x = 2 ** n;ormsg.value + (1 << n), where forn >= 256the exponentiation reverts and the shift is zero (CIPH-HYPERION-35).
Bugfixes:
- Assembler: Print
data_references in--asmoutput zero-padded like the data labels they refer to (CIPH-HYPERION-35). - C API: Make
hyperion_reset()discard the state of a compilation that a JavaScript exception unwinding through the Emscripten build abandoned without running its destructors; until then every laterhyperion_compile()failed with an internal error about anotherCompilerStack. The memory of the abandoned compilation is not reclaimed, since its destructors cannot be run safely afterwards; an embedder that can load a fresh module instance should prefer that (CIPH-HYPERION-16). - Code Generator: Check at run time that an element of a dynamic storage array, and an element or member of a static array or struct of at least
2**128slots, lies below slot2**256, on element access,push(),pop(),delete, resizing and copying in both code generators, and revert withPanic(0x32)otherwise, since the chain keys storage by the low 256 bits of the slot and such an element would alias an unrelated slot (CIPH-HYPERION-10). - Code Generator: Clean narrowed and wrapped integer arguments when widening them for
addmodandmulmodin the legacy code generator. - Code Generator: Clean narrowed and wrapped integer arguments when widening them for call value and gas options in the legacy code generator.
- Code Generator: Convert
mldsa87verifyandxmssverifyarguments in evaluation order in the IR code generator, so a storagebytesargument is copied to memory before later arguments can modify it, as the legacy code generator and the SMTChecker already do. - Code Generator: Copy each
depositrootargument to memory right after evaluating it in both code generators, so a storagebytesargument that a later argument modifies is hashed with its original contents, as the SMTChecker models and asmldsa87verifyandxmssverifyalready do (CIPH-HYPERION-11). - Code Generator: Decode the
xmssverifyresult asmldsa87verifydoes, mapping only exactly 64 bytes of return data holding the value1totrueinstead of any non-zero word, and returnfalsefrommldsa87verifyfor arguments of the wrong length without calling the precompiled contract, which charged its full gas for the malformed frame (CIPH-HYPERION-15). - Code Generator: Fix constants read in both checked and
uncheckedcontexts within one contract getting the checked or unchecked semantics of whichever read the IR code generator generated first, which could remove a required overflow panic or introduce a spurious one (CIPH-HYPERION-6). - Code Generator: Fix public getters of mappings cleaning the key as a
uint256before hashing it in the legacy code generator, which truncated keys wider than 256 bits, including everyaddress, so that the getter read a different slot than the contract's own code and returned the default value. - Code Generator: Read the 32-byte result of the
sha256anddepositrootprecompiles and the 64-byte result ofshake256as go-qrl returns them, and revert when a precompile returns data of another size, in both code generators. - Commandline Interface: Do not allow imports from the working directory by default when it is the root of the filesystem, which made every readable file importable when no base path was given (CIPH-HYPERION-20).
- Commandline Interface: Report an assembly import error instead of crashing when a
tagis the last item of a.codearray in--import-asm-jsoninput, and reject more than one input file for that option with a proper error instead of an internal assertion (CIPH-HYPERION-19). - Commandline Interface: Report stack too deep errors from the IR pipeline and from
--strict-assemblyas ordinary errors that point to the source location where the stack limit was hit, instead of printing diagnostic information meant for internal compiler errors and exiting with code 2. - Gas Estimator: Report infinite gas instead of an underestimate for
LOGdata lengths and call gas arguments that do not fit in 256 bits (CIPH-HYPERION-35). - Parser: Count every array suffix of a type and every member access, index access, call and call option of an expression against the recursion limit, by the depth they give the syntax tree, since the passes after the parser visit it recursively; such chains, including the ones read ahead to tell a declaration from an expression, were accepted at any length before and could exhaust the stack, or take cubic time in the length of a nested array type (CIPH-HYPERION-17).
- Parser: Lower the recursion limit in the Emscripten build from 1200 to 256 guarded calls (about 50 nested parentheses or calls), because deeper nesting exhausts the JavaScript engine's stack long before the native limit is reached, and the resulting
RangeErrorleft the compiler unusable for the rest of the process (CIPH-HYPERION-16). - SMTChecker: Model message values and account balances as full-word integers.
- Standard JSON Interface: Report stack too deep errors in Yul mode as errors with a source location instead of as internal compiler errors.
- Yul Optimizer: Fix each bracketed part of a custom step sequence running at least twice even when the code size was already stable after its first round, so that nested brackets doubled the optimizer rounds per level (upstream 0.8.24, CIPH-HYPERION-18).
- Yul Optimizer: Fix incorrect removal of
returndatacopy()operations referencing a stale result ofreturndatasize()(CIPH-HYPERION-8). - Yul Optimizer: Limit the nesting depth of brackets in a custom step sequence to 3 levels, since every level can repeat its content up to 12 times (CIPH-HYPERION-18).
Build System:
- Emscripten: Set the wasm stack size to 5 MB explicitly (the default up to Emscripten 3.1.26, 64 KB from 3.1.27) and check the stack pointer on every assignment (
STACK_OVERFLOW_CHECK=2), so that recursion which exhausts the stack aborts instead of corrupting memory (CIPH-HYPERION-16, CIPH-HYPERION-17). ExportstackSaveandstackRestore, which hypc-js uses to put the stack pointer back after an exception has unwound through the compiler. - Tests: Re-enable 47 Zond semantic regressions, extend dual-pipeline coverage, require explanations for single-pipeline fixtures, and report excluded tests as skipped. Add differential integer cleanup tests for every supported width and 512-bit opcode boundaries (CIPH-HYPERION-13).
- Tests: Make the test host's
depositrootprecompile pad and truncate its input like go-qrl instead of rejecting other lengths, implement themodexpprecompile as go-qrl does, and check both against go-qrl's test vectors. A semantic test setting replaces the magicshake256input that made the host return a short output (CIPH-HYPERION-14). - Tests: Check the test host's
mldsa87verifyandxmssverifyprecompiles against go-qrl's test vectors and itsshake256precompile against vectors generated with go-qrl's implementation (CIPH-HYPERION-14). - Tests: Keep the full 64-byte topic of indexed
bytes33tobytes64event parameters in the semantic test framework, mark exactly the seven dispatched precompiles as existing in the test host, return a 32-byte deposit root from it and make itsshake256charge gas and refuse short calls as go-qrl does. - Build with current Apple toolchains (Apple Clang 21, libc++ 22), Boost 1.88+ (Boost.Process v1 headers) and Boost 1.89+ (no compiled Boost.System library).
- Raise the macOS deployment target from 10.14 to 11.0, the lowest that libc++ 22 supports. The released
hypc-macosbinary requires macOS 11 or later. - Release
hypc-macosas a universal binary that runs natively on Apple silicon and Intel Macs. Earlier releases were x86-64 only and needed Rosetta 2 on Apple silicon, which Apple supports for general use only through macOS 27. Build its Boost and jsoncpp libraries for the macOS 11.0 deployment target instead of the build machine's macOS version.
Installing and verifying
npm: npm install @theqrl/hypc@0.3.1 (published with provenance). Binaries: this page and https://binaries.theqrl.org.
Verifying the binaries
Every asset carries a build-provenance attestation signed by theQRL/hyperion/.github/workflows/ci.yml, and SHA256SUMS lists every asset. Verifying Release Binaries shows the gh attestation verify and sha256sum --check commands. hypc-macos is a universal binary and needs macOS 11 or later.
We especially thank all the contributors that made this release possible: cyyber, JP Lomas, moscowchill.