Skip to content

feat: checked-arithmetic helper emission (#1993 emission half)#2028

Merged
Th0rgal merged 10 commits into
mainfrom
task/1993a-checked-arith
Jun 19, 2026
Merged

feat: checked-arithmetic helper emission (#1993 emission half)#2028
Th0rgal merged 10 commits into
mainfrom
task/1993a-checked-arith

Conversation

@Th0rgal

@Th0rgal Th0rgal commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

Implements the emission half of issue #1993 — Solidity-0.8-style overflow-checked arithmetic. (The proof-obligation / LocalNoOverflowFor axiom-discharge half is tracked separately in #1993b → PR #2013.)

  • Emits checked uint256 helpers: checked_add_t_uint256, checked_sub_t_uint256, checked_mul_t_uint256, checked_div_t_uint256, plus panic_error_0x11 / panic_error_0x12.
  • Compiler detects checked-arithmetic panic guards, emits helper definitions on demand, reserves their names, and routes emitted Yul through the Compiler.emitYulWithOptions facade while keeping CodegenCommon.emitYul proof-stable.
  • Adds SupportedSpec*.noCheckedArithmetic surface exclusions so checked arithmetic stays outside the existing helper-free proof theorems (kept axiom-clean) pending the #1993b discharge.

Stacking

Based on task/2000-dynamic-events (#2020), the tip of the Tier-1 dynamic-ABI stack.

Test plan

  • lake build Verity Contracts Compiler PrintAxioms → "Build completed successfully."
  • scripts/refresh_verification_artifacts.sh → "[refresh] PASS"
  • make check → "All checks passed."
  • zero sorry, zero axioms

Note

Medium Risk
Changes compiler Yul for arithmetic and panic behavior on contracts that trigger the new path; proof theorems explicitly exclude that fragment until follow-up work, but mis-detection or a bad fold could affect generated runtime code.

Overview
Adds Solidity 0.8-style checked uint256 arithmetic to the compiler: when contracts use panic guards for overflow, underflow, or division by zero, the pipeline emits on-demand Yul helpers (checked_add/sub/mul/div_t_uint256 plus panic_error_0x11 / 0x12 with the standard Panic(uint256) selector) and reserves those symbol names so user code cannot collide.

After normal Yul emission (via emitYulWithOptions), a peephole pass folds matching if revert guards plus raw add/sub/mul/div into calls to those helpers, while plain CodegenCommon.emitYul stays unchanged for existing proofs.

Proof surface: SupportedSpec* gains noCheckedArithmetic, keeping checked-arithmetic contracts outside current helper-free IR-generation theorems until the separate discharge work lands.

The same diff also introduces Calls.selfDelegateMulticallBytes (self-delegatecall multicall(bytes[]) with offset checks and revert bubbling, documented as an ECM assumption) and expands event source-shape proof scaffolding for dynamic ABI events—likely from the stacked branch, not the core #1993 emission story.

Reviewed by Cursor Bugbot for commit 87afe71. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Jun 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
verity Ready Ready Preview, Comment Jun 19, 2026 3:22am

Request Review

#1999) (#2030)

Extract the Panic(uint256) revert payload (selector 0x4e487b71 + one ABI word
holding the panic code) into a reusable solidityPanicPayload builder so panic
emission is compiler-owned and reusable for checked-arithmetic paths; assert
the encoded code words (mstore(4, 17/18)) in the arithmetic-panic smoke test.
* feat: add self-delegate multicall helper

* fix(verity): multicall offset-wrap bound check + documented trusted ECM (#2029)
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
\n### CI Failure Hints\n\nFailed jobs: `compiler-regressions`\n\nCopy-paste local triage:\n```bash\nmake check\nlake build\nFOUNDRY_PROFILE=difftest forge test -vv\n```

@Th0rgal Th0rgal changed the base branch from task/2000-dynamic-events to main June 18, 2026 15:02
Th0rgal added 2 commits June 19, 2026 02:21
Resolve #1997 internal-functions refactor vs checked-arithmetic feature:
- compileExpr -> compileExprWithInternals threading (main)
- internalParamYulNamesForType single source of truth + directForwardedInternalArgName? (main)
- preserve checkedArithmeticHelpers reserved-names + Dispatch helpers (feature)
- regenerate PrintAxioms.lean (5266 thms, 0 sorry)
The #1997 refactor moved findInternalFunctionForCall?, compileInternalCallArg,
compileInternalCallArgsWithParams, and compileInternalCallArgs into
ExpressionCompile.lean. The merge of origin/main kept the stale copies in
Compile.lean too, producing "already been declared" errors. Remove the stale
copies; ExpressionCompile.lean is the single source.
The merge brought in main's scalar-events supported-spec smoke test, which
the SupportedSpecSurfaceWithScalarEvents struct now requires to discharge the
noCheckedArithmetic obligation added in this PR. Prove it by simp over the
spec definitions.
…tched origin/main merge

The eb9fadb merge of origin/main into task/1993a-checked-arith dropped ~3385
lines of origin/main test content and left the namespace structure broken
(InternalHelperDynamicArgs never closed), causing the compiler-regressions CI
job to fail with a parse error. Restore origin/main's full feature-test file and
re-graft task/1993a's unique checked-arithmetic helper assertions on top, so the
union of both sides' test cases is preserved.
@Th0rgal Th0rgal merged commit 26344a0 into main Jun 19, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant