diff --git a/.github/workflows/evmyullean-fork-conformance.yml b/.github/workflows/evmyullean-fork-conformance.yml index d4651ede0..adc80fd49 100644 --- a/.github/workflows/evmyullean-fork-conformance.yml +++ b/.github/workflows/evmyullean-fork-conformance.yml @@ -30,19 +30,14 @@ on: - 'artifacts/evmyullean_adapter_report.json' - 'lake-manifest.json' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSignedArithSpec.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanStateBridge.lean' - 'Compiler/Proofs/YulGeneration/ReferenceOracle/Builtins.lean' - - 'Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean' pull_request: paths: - '.github/workflows/evmyullean-fork-conformance.yml' @@ -55,19 +50,14 @@ on: - 'artifacts/evmyullean_adapter_report.json' - 'lake-manifest.json' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean' - - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSignedArithSpec.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean' - 'Compiler/Proofs/YulGeneration/Backends/EvmYulLeanStateBridge.lean' - 'Compiler/Proofs/YulGeneration/ReferenceOracle/Builtins.lean' - - 'Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean' permissions: contents: read diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 50883ab75..90f24f423 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -143,7 +143,6 @@ jobs: code: ${{ steps.effective.outputs.code }} build: ${{ steps.effective.outputs.build }} compiler: ${{ steps.effective.outputs.compiler }} - macro_fuzz: ${{ steps.effective.outputs.macro_fuzz }} steps: - uses: actions/checkout@v6 @@ -205,18 +204,6 @@ jobs: - 'lake-manifest.json' - 'lean-toolchain' - 'foundry.toml' - macro_fuzz: - - '.github/actions/setup-lean/action.yml' - - 'Verity/Macro/**' - - 'Compiler/**' - - '!Compiler/Proofs/**' - - 'Compiler.lean' - - 'Contracts/**' - - '!Contracts/**/Proofs/**' - - 'Contracts.lean' - - 'lakefile.lean' - - 'lake-manifest.json' - - 'lean-toolchain' - name: Resolve effective change flags id: effective env: @@ -224,25 +211,21 @@ jobs: CODE_CHANGED: ${{ steps.filter.outputs.code }} BUILD_CHANGED: ${{ steps.filter.outputs.build }} COMPILER_CHANGED: ${{ steps.filter.outputs.compiler }} - MACRO_FUZZ_CHANGED: ${{ steps.filter.outputs.macro_fuzz }} run: | if [ "$FORCE_FULL_RUN" = "true" ]; then code=true build=true compiler=true - macro_fuzz=true else code="$CODE_CHANGED" build="$BUILD_CHANGED" compiler="$COMPILER_CHANGED" - macro_fuzz="$MACRO_FUZZ_CHANGED" fi { echo "code=$code" echo "build=$build" echo "compiler=$compiler" - echo "macro_fuzz=$macro_fuzz" } >> "$GITHUB_OUTPUT" checks: @@ -382,69 +365,6 @@ jobs: path: .lake key: lake-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }} - prepare-macro-fuzz: - runs-on: [self-hosted, linux, x64, verity, build] - timeout-minutes: 360 - needs: [changes, checks, build] - if: needs.checks.result == 'success' && needs.build.result == 'success' && needs.changes.outputs.macro_fuzz == 'true' - env: - LEAN_NUM_THREADS: 4 - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - - name: Setup Lean - uses: ./.github/actions/setup-lean - with: - cache-key-prefix: lake - use-sticky-disks: ${{ env.VERIFY_USE_STICKY_DISKS }} - sticky-disk-key-prefix: verify - lake-packages-sticky-key: lake-packages-verify-${{ env.VERIFY_CACHE_BUCKET }}-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }} - lake-packages-main-fallback-sticky-key: ${{ github.event_name == 'pull_request' && format('lake-packages-verify-{0}-{1}-{2}-{3}-{4}', env.VERIFY_MAIN_CACHE_BUCKET, runner.os, hashFiles('lean-toolchain'), hashFiles('lakefile.lean'), hashFiles('lake-manifest.json')) || '' }} - use-build-sticky-disk: ${{ env.VERIFY_USE_STICKY_DISKS }} - build-sticky-disk-key: verify-build-macro-fuzz-${{ env.VERIFY_CACHE_BUCKET }}-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }} - build-main-fallback-sticky-key: ${{ github.event_name == 'pull_request' && format('verify-build-macro-fuzz-{0}-{1}-{2}-{3}-{4}', env.VERIFY_MAIN_CACHE_BUCKET, runner.os, hashFiles('lean-toolchain'), hashFiles('lakefile.lean'), hashFiles('lake-manifest.json')) || '' }} - disable-lake-cache-restore: ${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }} - cache-primary-key: lake-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}-${{ github.run_id }} - - - name: Download prepared Lean workspace build - uses: actions/download-artifact@v7 - with: - name: lean-workspace-build - - - name: Restore prepared Lean workspace build - run: tar -xf lean-workspace-build.tar - - - name: Build macro round-trip fuzz executable - run: | - for attempt in 1 2 3; do - if stdbuf -oL -eL lake build macro-roundtrip-fuzz; then - exit 0 - fi - echo "::warning::lake build attempt $attempt failed; retrying in 10s" - sleep 10 - done - echo "::error::lake build failed after 3 attempts" - exit 1 - - - name: Package macro-fuzz Lean workspace build - run: tar -hcf lean-workspace-macro-fuzz-build.tar .lake/build .lake/lakefile.olean .lake/lakefile.olean.trace - - - name: Publish macro-fuzz build locally - run: | - scripts/ci_local_persistence.sh publish \ - --run-id "${{ github.run_id }}" \ - --name lean-workspace-macro-fuzz-build \ - --path lean-workspace-macro-fuzz-build.tar - - - name: Upload macro-fuzz Lean workspace build - continue-on-error: true - uses: actions/upload-artifact@v7 - with: - name: lean-workspace-macro-fuzz-build - path: lean-workspace-macro-fuzz-build.tar - build-audits: runs-on: [self-hosted, linux, x64, verity, build] timeout-minutes: 20 @@ -479,9 +399,6 @@ jobs: - name: Build split Lake packages independently run: python3 scripts/check_split_package_builds.py - - name: Check macro round-trip fuzz coverage - run: python3 scripts/check_macro_roundtrip_fuzz_coverage.py - - name: Check for axioms in proof files run: | echo "Checking for axioms in Compiler/ and Verity/..." @@ -539,61 +456,6 @@ jobs: axiom-report.md axiom-report-raw.log - macro-fuzz: - runs-on: [self-hosted, linux, x64, verity, build] - timeout-minutes: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '150' || '90') }} - needs: [changes, checks, prepare-macro-fuzz] - if: needs.checks.result == 'success' && needs.prepare-macro-fuzz.result == 'success' && needs.changes.outputs.macro_fuzz == 'true' - strategy: - fail-fast: false - max-parallel: 2 - matrix: - shard_index: [0, 1, 2, 3] - env: - LEAN_NUM_THREADS: 4 - MACRO_FUZZ_SHARD_INDEX: ${{ matrix.shard_index }} - MACRO_FUZZ_SHARD_COUNT: 4 - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - - name: Setup Lean - id: setup-lean - uses: ./.github/actions/setup-lean - with: - cache-key-prefix: lake - use-sticky-disks: ${{ env.VERIFY_USE_STICKY_DISKS }} - sticky-disk-key-prefix: verify - lake-packages-sticky-key: lake-packages-verify-${{ env.VERIFY_CACHE_BUCKET }}-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }} - lake-packages-main-fallback-sticky-key: ${{ github.event_name == 'pull_request' && format('lake-packages-verify-{0}-{1}-{2}-{3}-{4}', env.VERIFY_MAIN_CACHE_BUCKET, runner.os, hashFiles('lean-toolchain'), hashFiles('lakefile.lean'), hashFiles('lake-manifest.json')) || '' }} - disable-lake-cache-restore: ${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }} - cache-primary-key: lake-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}-${{ github.run_id }} - - - name: Restore macro-fuzz build (local) - id: local-restore-macro-fuzz - continue-on-error: true - run: | - scripts/ci_local_persistence.sh fetch \ - --run-id "${{ github.run_id }}" \ - --name lean-workspace-macro-fuzz-build \ - --timeout 30 - - - name: Download prepared Lean workspace build (fallback) - if: steps.local-restore-macro-fuzz.outcome != 'success' - uses: actions/download-artifact@v7 - with: - name: lean-workspace-macro-fuzz-build - - - name: Restore prepared Lean workspace build (fallback) - if: steps.local-restore-macro-fuzz.outcome != 'success' - run: tar -xf lean-workspace-macro-fuzz-build.tar - - - name: Run macro round-trip fuzz harness - run: | - chmod +x ./.lake/build/bin/macro-roundtrip-fuzz - ./.lake/build/bin/macro-roundtrip-fuzz - build-compiler-binaries: runs-on: [self-hosted, linux, x64, verity, build] timeout-minutes: 360 @@ -1628,7 +1490,7 @@ jobs: failure-hints: runs-on: [self-hosted, linux, ARM64, dgx-spark, verity, fastlane] - needs: [checks, build, prepare-macro-fuzz, build-audits, macro-fuzz, build-compiler-binaries, compiler-audits, compiler-regressions, foundry-gas-calibration, foundry, foundry-patched, foundry-multi-seed] + needs: [checks, build, build-audits, build-compiler-binaries, compiler-audits, compiler-regressions, foundry-gas-calibration, foundry, foundry-patched, foundry-multi-seed] if: always() && github.event_name == 'pull_request' && contains(join(needs.*.result, ','), 'failure') permissions: contents: read diff --git a/AUDIT.md b/AUDIT.md index 480e704fa..ef0949475 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -51,8 +51,8 @@ theorem is proved. builtin bridge matrix synchronization, Lean hygiene, proof length, and documentation counters. - `make test-evmyullean-fork` validates the pinned fork audit, checks the - adapter report, rebuilds adapter correctness and the public EndToEnd - EVMYulLean target, and runs the concrete bridge-equivalence tests. + adapter report, rebuilds the public EndToEnd EVMYulLean target, and runs + the concrete bridge-equivalence tests. - `.github/workflows/evmyullean-fork-conformance.yml` runs the EVMYulLean fork conformance probe weekly. Scheduled or manual failures fail the workflow and open or update a GitHub issue for drift triage. diff --git a/AXIOMS.md b/AXIOMS.md index b12ec947d..5136b55c9 100644 --- a/AXIOMS.md +++ b/AXIOMS.md @@ -117,9 +117,9 @@ the EVM. **Soundness controls**: - `make check` validates the fork-audit artifact against `lake-manifest.json`. - `make test-evmyullean-fork` rechecks the fork audit, checks the adapter - report, rebuilds adapter correctness, the native transition harness, the - public EndToEnd EVMYulLean target, and the concrete `native_decide` - bridge-equivalence tests. + report, rebuilds the native transition harness, the public EndToEnd + EVMYulLean target, and the concrete `native_decide` bridge-equivalence + tests. - `.github/workflows/evmyullean-fork-conformance.yml` runs the conformance probe weekly; scheduled or manual failures fail the workflow and open or update a GitHub issue for drift triage. diff --git a/Compiler/Proofs/EndToEnd.lean b/Compiler/Proofs/EndToEnd.lean index 06c5af247..015da2d2f 100644 --- a/Compiler/Proofs/EndToEnd.lean +++ b/Compiler/Proofs/EndToEnd.lean @@ -16097,6 +16097,82 @@ private def NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived (execIRFunction fn tx.args (applyIRTransactionContext tx state)) (.ok nativeYul) +/-- Parallel `_revived`-leave-aware variant of +`NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived` that uses +`NativeBlockPreservesWord_revived` in the matched-flag preservation conjunct. + +This is the variant designed for Leave-ending bodies whose final exec state is +a Checkpoint Leave: the OLD-form preservation conjunct is structurally false +for such bodies, while the `_revived` form reads through `reviveJump` and is +provable via the foundation PR #1826 shipped. + +Used by the E2/E4/E6 success-bridge chains that target Leave-ending bodies. +Downstream consumers that need to convert this back to OLD-form preservation +should use the conversion lemma +`NativeBlockPreservesWord_of_revived_when_final_ok` (TODO: not yet shipped). +For Ok-final bodies the two forms are equivalent; for Leave-final bodies only +the `_revived` form is usable. -/ +private def NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) : Prop := + ∀ (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) + (reservedNames : List String) (n0 : Nat) + (cases' : List (Nat × List EvmYul.Yul.Ast.Stmt)) + (body' bodyNative : List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd userBodyStart : Nat), + Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative + (Compiler.emitYul irContract).runtimeCode = .ok nativeContract → + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + cases'.find? (fun entry => entry.1 == tx.functionSelector) = + some (tx.functionSelector, body') → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd) → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames userBodyStart fn.body = + .ok (bodyNative, bodyEnd) → + DispatchGuardsSafe fn tx → + fn.params.length ≤ tx.args.length → + ∃ (final : EvmYul.Yul.State) (nativeYul : YulResult) + (shared : EvmYul.SharedState EvmYul.OperationType.Yul) + (store : EvmYul.Yul.VarStore), + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + EvmYul.Yul.exec + (nativeGeneratedSelectorHitUserBodyFuel irContract fn cases' + + suffix.length + 10) (.Block bodyNative) + (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract + (YulTransaction.ofIR tx) + state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0) + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore) = + .ok final) ∧ + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) bodyNative + (some nativeContract)) ∧ + final.reviveJump = EvmYul.Yul.State.Ok shared store ∧ + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok (final.reviveJump, [])) = + nativeYul ∧ + nativeResultsMatchOn observableSlots + (execIRFunction fn tx.args (applyIRTransactionContext tx state)) + (.ok nativeYul) + /-- Revived native function-body execution bridge without matched-flag preservation. @@ -16765,6 +16841,39 @@ private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_em Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore hBody +/-- S6: Selected user bodies of shape `preStmts` (no terminator) with all +statements in the `BridgedStraightStmts` fragment execute as a native +falling-through and project to the same observable result. + +The plan specifies a `fn.returnVars = []` hypothesis, but the current +`Compiler.IRFunction` has a single `ret : IRType` field (no `returnVars`); the +return-variable shape constraint is therefore expressed implicitly by the +absence of `.leave` in `preStmts` (i.e., the body falls through to function +return without an early-exit value). + +CURRENTLY LIMITED: this version only handles `preStmts = []` (degenerate empty +case). The general case requires the per-`BridgedStraightStmt` +observation-equivalence framework (P1 in the stage-2 DAG). Once that framework +lands, this constructor generalizes by replacing the `hOnlyEmpty` hypothesis +with a list induction over `BridgedStraightStmts preStmts`. -/ +private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (preStmts : List Compiler.Yul.YulStmt) + (_hBridged : Compiler.Proofs.YulGeneration.Backends.BridgedStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts) : + NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived irContract tx + state observableSlots := by + apply NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_empty_body + intro fn hFind + rw [hBody fn hFind, hOnlyEmpty] + /-- Selected user bodies containing only `leave` execute as a native checkpoint and project to the same observable result as `execIRFunction`. @@ -16817,6 +16926,56 @@ private theorem nativeResultsMatchOn_execIRFunction_leave_body_markedPrefix (Compiler.runtimeCode irContract) observableSlots) switchId store) +/-- IR-side match helper for body `[.block [], .leave]` (F2's body shape). +The IR `execIRFunction` on `[.block [], .leave]` produces the same observable +result as on `[.leave]` (the inner `.block []` is a no-op); after `reviveJump` +on the native `setLeave` state, both project to the same storage / return / +events. -/ +private theorem nativeResultsMatchOn_execIRFunction_label_prefix_leave_body_markedPrefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (nativeContract : EvmYul.Yul.Ast.YulContract) + (fn : IRFunction) + (switchId : Nat) + (store : EvmYul.Yul.VarStore) + (hBody : fn.body = [.block [], .leave]) : + nativeResultsMatchOn observableSlots + (execIRFunction fn tx.args (applyIRTransactionContext tx state)) + (.ok + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId store).setLeave).reviveJump, [])))) := by + simp only [nativeResultsMatchOn, + Compiler.Proofs.YulGeneration.Backends.Native.nativeResultsMatchOn] + unfold execIRFunction + simp [hBody, applyIRTransactionContext, execIRStmts, execIRStmt, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStorePrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreInitialState, + EvmYul.Yul.State.insert, EvmYul.Yul.State.setLeave, + EvmYul.Yul.State.reviveJump] + constructor + · intro slot hSlot + exact + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult_ok_nativeSwitchStoreMarkedPrefixStateForId_observableStorageSlot + nativeContract (YulTransaction.ofIR tx) state.storage state.events + (Compiler.runtimeCode irContract) observableSlots switchId store slot + hSlot).symm + · simpa [Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState] + using + (Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState_nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId store) + /-- Build the direct selected-user-body execution bridge for contracts whose selected generated function body is exactly `leave`. -/ private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body @@ -16872,6 +17031,97 @@ private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_le Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore hBody +/-- F2 ExecOnly: Build the direct selected-user-body execution bridge for +contracts whose selected generated function body is exactly `[.block [], .leave]` +(F2's body shape, label-prefix variant of E2). Composes the `_revived` +machinery: peel the `.Block []` head via `exec_block_label_prefix_leave_ok_add_ten` +then dispatch the `.Leave` like the existing `of_leave_body`. -/ +private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body_with_label_prefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hLabelLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .leave]) : + NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived irContract tx + state observableSlots := by + intro nativeContract fn reservedNames n0 cases' bodyNative bodyEnd + userBodyStart _hLowerRuntime hFind hUserBodyLower _hguards _hArgs + have hBody : fn.body = [.block [], .leave] := hLabelLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + let switchId := + Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId reservedNames n0 + let initial := + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore + let final := initial.setLeave + let nativeYul := + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok (final.reviveJump, [])) + have hReviveOk : + ∃ shared store, final.reviveJump = EvmYul.Yul.State.Ok shared store := by + simp [final, initial, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStorePrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreInitialState, + EvmYul.Yul.State.insert, EvmYul.Yul.State.setLeave, + EvmYul.Yul.State.reviveJump, EvmYul.Yul.State.revive] + rcases hReviveOk with ⟨shared, store, hRevive⟩ + refine ⟨final, nativeYul, shared, store, ?_, hRevive, rfl, ?_⟩ + · intro _pre suffix + simpa [final, initial] using + (Compiler.Proofs.YulGeneration.Backends.Native.exec_block_label_prefix_leave_ok_add_ten + (nativeGeneratedSelectorHitUserBodyFuel irContract fn cases') + suffix.length (some nativeContract) initial) + · exact + nativeResultsMatchOn_execIRFunction_label_prefix_leave_body_markedPrefix + irContract tx state observableSlots nativeContract fn switchId + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore + hBody + +/-- S5: Selected user bodies of shape `preStmts ++ [.leave]` with all statements +in the `NativePreservableStraightStmts` fragment execute as a native checkpoint +and project to the same observable result as `execIRFunction`. + +CURRENTLY LIMITED: this version only handles `preStmts = []` (body = +`[] ++ [.leave] = [.leave]`, reducing to `of_leave_body`). The general case +requires the per-stmt `NativeStmtPreservesWord_revived` framework (P1 in the +stage-2 DAG). Once that framework lands, this constructor generalizes by +removing `hOnlyEmpty` and inducting over `NativePreservableStraightStmts preStmts`. -/ +private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_nativePreservableStraightStmts_leave + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (preStmts : List Compiler.Yul.YulStmt) + (_hPreservable : + Compiler.Proofs.YulGeneration.Backends.Native.NativePreservableStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts ++ [.leave]) : + NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived irContract tx + state observableSlots := by + apply NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body + intro fn hFind + rw [hBody fn hFind, hOnlyEmpty, List.nil_append] + /-- Selected user bodies consisting of a single `.block [.leave]` produce the same observable result as the bare `.leave` body. @@ -16926,6 +17176,55 @@ private theorem nativeResultsMatchOn_execIRFunction_block_leave_body_markedPrefi (Compiler.runtimeCode irContract) observableSlots) switchId store) +/-- IR-side match helper for body `[.block [], .block [.leave]]` (F4's body +shape, label-prefix variant of E4). Same observation as `block_leave`: both +no-op blocks then `.leave` make the body observationally a checkpoint Leave; +after `reviveJump`, projects to the same storage / events. -/ +private theorem nativeResultsMatchOn_execIRFunction_label_prefix_block_leave_body_markedPrefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (nativeContract : EvmYul.Yul.Ast.YulContract) + (fn : IRFunction) + (switchId : Nat) + (store : EvmYul.Yul.VarStore) + (hBody : fn.body = [.block [], .block [.leave]]) : + nativeResultsMatchOn observableSlots + (execIRFunction fn tx.args (applyIRTransactionContext tx state)) + (.ok + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId store).setLeave).reviveJump, [])))) := by + simp only [nativeResultsMatchOn, + Compiler.Proofs.YulGeneration.Backends.Native.nativeResultsMatchOn] + unfold execIRFunction + simp [hBody, applyIRTransactionContext, execIRStmts, execIRStmt, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStorePrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreInitialState, + EvmYul.Yul.State.insert, EvmYul.Yul.State.setLeave, + EvmYul.Yul.State.reviveJump] + constructor + · intro slot hSlot + exact + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult_ok_nativeSwitchStoreMarkedPrefixStateForId_observableStorageSlot + nativeContract (YulTransaction.ofIR tx) state.storage state.events + (Compiler.runtimeCode irContract) observableSlots switchId store slot + hSlot).symm + · simpa [Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState] + using + (Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState_nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId store) + /-- Build the direct selected-user-body execution bridge for contracts whose selected generated function body is exactly `[.block [.leave]]`. @@ -16990,51 +17289,115 @@ private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_bl Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore hBody -/-- Selected user bodies consisting of a single `.block []` produce the same -observable result as an empty body. +/-- F4 ExecOnly: Build the direct selected-user-body execution bridge for +contracts whose selected generated function body is exactly +`[.block [], .block [.leave]]` (F4's body shape, label-prefix variant of E4). -The source `execIRFunction` enters the inner block (`execIRStmt` on `.block` -reduces to `execIRStmts` on the inner list) which returns `.continue` on the -empty list, and the outer `execIRStmts` falls through similarly. The native -lowering produces `[.Block []]` whose execution yields the entry state -unchanged (no `setLeave`), so `reviveJump` is the identity on it. -/ -private theorem nativeResultsMatchOn_execIRFunction_block_empty_body_markedPrefix +Lowers to `[.Block [], .Block [.Leave]]`; dispatcher exec via +`exec_block_label_prefix_block_leave_ok_add_ten`. -/ +private theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_leave_with_label_prefix (irContract : IRContract) (tx : IRTransaction) (state : IRState) (observableSlots : List Nat) - (nativeContract : EvmYul.Yul.Ast.YulContract) - (fn : IRFunction) - (switchId : Nat) - (store : EvmYul.Yul.VarStore) - (hBody : fn.body = [.block []]) : - nativeResultsMatchOn observableSlots - (execIRFunction fn tx.args (applyIRTransactionContext tx state)) - (.ok - (Compiler.Proofs.YulGeneration.Backends.Native.projectResult - (YulTransaction.ofIR tx) state.storage state.events - (.ok - ((Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId - nativeContract (YulTransaction.ofIR tx) state.storage - (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots - (Compiler.runtimeCode irContract) observableSlots) - switchId store).reviveJump, [])))) := by - simp only [nativeResultsMatchOn, - Compiler.Proofs.YulGeneration.Backends.Native.nativeResultsMatchOn] - unfold execIRFunction - simp [hBody, applyIRTransactionContext, execIRStmts, execIRStmt, - Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId_reviveJump_eq] - constructor - · intro slot hSlot - exact - (Compiler.Proofs.YulGeneration.Backends.Native.projectResult_ok_nativeSwitchStoreMarkedPrefixStateForId_observableStorageSlot - nativeContract (YulTransaction.ofIR tx) state.storage state.events - (Compiler.runtimeCode irContract) observableSlots switchId store slot - hSlot).symm - · simpa [Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState] - using - (Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState_nativeSwitchStoreMarkedPrefixStateForId - nativeContract (YulTransaction.ofIR tx) state.storage + (hLabelBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .block [.leave]]) : + NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived irContract tx + state observableSlots := by + intro nativeContract fn reservedNames n0 cases' bodyNative bodyEnd + userBodyStart _hLowerRuntime hFind hUserBodyLower _hguards _hArgs + have hBody : fn.body = [.block [], .block [.leave]] := hLabelBlockLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + let switchId := + Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId reservedNames n0 + let initial := + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore + let final := initial.setLeave + let nativeYul := + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok (final.reviveJump, [])) + have hReviveOk : + ∃ shared store, final.reviveJump = EvmYul.Yul.State.Ok shared store := by + simp [final, initial, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStorePrefixStateForId, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreInitialState, + EvmYul.Yul.State.insert, EvmYul.Yul.State.setLeave, + EvmYul.Yul.State.reviveJump, EvmYul.Yul.State.revive] + rcases hReviveOk with ⟨shared, store, hRevive⟩ + refine ⟨final, nativeYul, shared, store, ?_, hRevive, rfl, ?_⟩ + · intro _pre suffix + simpa [final, initial] using + (Compiler.Proofs.YulGeneration.Backends.Native.exec_block_label_prefix_block_leave_ok_add_ten + (nativeGeneratedSelectorHitUserBodyFuel irContract fn cases') + suffix.length (some nativeContract) initial) + · exact + nativeResultsMatchOn_execIRFunction_label_prefix_block_leave_body_markedPrefix + irContract tx state observableSlots nativeContract fn switchId + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore + hBody + +/-- Selected user bodies consisting of a single `.block []` produce the same +observable result as an empty body. + +The source `execIRFunction` enters the inner block (`execIRStmt` on `.block` +reduces to `execIRStmts` on the inner list) which returns `.continue` on the +empty list, and the outer `execIRStmts` falls through similarly. The native +lowering produces `[.Block []]` whose execution yields the entry state +unchanged (no `setLeave`), so `reviveJump` is the identity on it. -/ +private theorem nativeResultsMatchOn_execIRFunction_block_empty_body_markedPrefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (nativeContract : EvmYul.Yul.Ast.YulContract) + (fn : IRFunction) + (switchId : Nat) + (store : EvmYul.Yul.VarStore) + (hBody : fn.body = [.block []]) : + nativeResultsMatchOn observableSlots + (execIRFunction fn tx.args (applyIRTransactionContext tx state)) + (.ok + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + ((Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + switchId store).reviveJump, [])))) := by + simp only [nativeResultsMatchOn, + Compiler.Proofs.YulGeneration.Backends.Native.nativeResultsMatchOn] + unfold execIRFunction + simp [hBody, applyIRTransactionContext, execIRStmts, execIRStmt, + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId_reviveJump_eq] + constructor + · intro slot hSlot + exact + (Compiler.Proofs.YulGeneration.Backends.Native.projectResult_ok_nativeSwitchStoreMarkedPrefixStateForId_observableStorageSlot + nativeContract (YulTransaction.ofIR tx) state.storage state.events + (Compiler.runtimeCode irContract) observableSlots switchId store slot + hSlot).symm + · simpa [Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState] + using + (Compiler.Proofs.YulGeneration.Backends.Native.projectLogsFromState_nativeSwitchStoreMarkedPrefixStateForId + nativeContract (YulTransaction.ofIR tx) state.storage (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots (Compiler.runtimeCode irContract) observableSlots) switchId store) @@ -17350,6 +17713,46 @@ private def NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel reservedNames n0)) (EvmYul.UInt256.ofNat 1) bodyNative (some nativeContract) +/-- Parallel `_revived` form of the matched-flag preservation bridge. + +This uses `NativeBlockPreservesWord_revived` (which reads through `reviveJump`) +instead of `NativeBlockPreservesWord`. The `_revived` form is the one that +handles Leave-ending bodies correctly — `final = Checkpoint (.Leave shared +store)` has `final.reviveJump = Ok shared store`, so the lookup reads the +inner store rather than falling through to ⟨0⟩ via the empty `default` Finmap. + +Used by the `_revived` chain for E2/E4/E6/E7 (Leave-ending success bridges) +and by S7 components that need to preserve matched-flag through bodies whose +exec path enters a Leave checkpoint. -/ +private def NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived + (irContract : IRContract) + (tx : IRTransaction) : Prop := + ∀ (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) + (reservedNames : List String) (n0 : Nat) + (cases' : List (Nat × List EvmYul.Yul.Ast.Stmt)) + (body' bodyNative : List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd userBodyStart : Nat), + Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative + (Compiler.emitYul irContract).runtimeCode = .ok nativeContract → + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + cases'.find? (fun entry => entry.1 == tx.functionSelector) = + some (tx.functionSelector, body') → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd) → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames userBodyStart fn.body = + .ok (bodyNative, bodyEnd) → + ∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) bodyNative (some nativeContract) + /-- Unified selected-user-body result boundary. Native lowered function bodies can finish either by returning normally to the @@ -18495,6 +18898,160 @@ private theorem NativeBlockPreservesWord_switchCaseBody_nonpayable_of_user_body (NativeBlockPreservesWord_nativeRevertZeroZero _ _ _) · exact hUserPreserves +/-- `_revived` mirror of `NativeBlockPreservesWord_switchCaseBody_payable_of_user_body`. +The cond-reviveJump premise is discharged internally via the universal +`eval_lt_calldatasize_lit_preserves_reviveJump` lemma (any fuel, any state). -/ +private theorem NativeBlockPreservesWord_revived_switchCaseBody_payable_of_user_body + (fn : IRFunction) + (nativeContract : EvmYul.Yul.Ast.YulContract) + (reservedNames : List String) + (switchStart : Nat) + (body' guardBody bodyNative : List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd : Nat) + (hPayable : fn.payable = true) + (hBodyLower : + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd)) + (hBodyShape : + body' = + EvmYul.Yul.Ast.Stmt.Block [] :: + EvmYul.Yul.Ast.Stmt.If + (Compiler.Proofs.YulGeneration.Backends.lowerExprNative + (Compiler.Yul.YulExpr.call "lt" + [Compiler.Yul.YulExpr.call "calldatasize" [], + Compiler.Yul.YulExpr.lit (4 + fn.params.length * 32)])) + guardBody :: + bodyNative) + (hUserPreserves : + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames switchStart)) + (EvmYul.UInt256.ofNat 1) bodyNative (some nativeContract)) : + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames switchStart)) + (EvmYul.UInt256.ofNat 1) body' (some nativeContract) := by + rcases + Compiler.Proofs.YulGeneration.Backends.Native.lowerStmtsNativeWithSwitchIds_switchCaseBody_payable_revert_eq + reservedNames bodyStart fn body' bodyEnd hPayable hBodyLower with + ⟨bodyNative', userBodyStart', hShape, hUserBodyLower'⟩ + have hShapeEq : guardBody = [Compiler.Proofs.YulGeneration.Backends.Native.nativeRevertZeroZeroStmt] ∧ + bodyNative = bodyNative' := by + rw [hShape] at hBodyShape + simp at hBodyShape + exact ⟨hBodyShape.1.symm, hBodyShape.2.symm⟩ + rcases hShapeEq with ⟨hGuardBody, hBodyNativeEq⟩ + subst guardBody + subst bodyNative' + rw [hShape] + refine + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_cons + _ _ (.Block []) _ _ ?_ ?_ + · exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_block + _ _ [] _ (Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nil _ _ _) + · refine + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_cons + _ _ _ _ _ ?_ ?_ + · exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump + _ _ _ _ _ + (Compiler.Proofs.YulGeneration.Backends.Native.eval_lt_calldatasize_lit_preserves_reviveJump + (4 + fn.params.length * 32) (some nativeContract)) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nativeRevertZeroZero _ _ _) + · exact hUserPreserves + +/-- `_revived` mirror of `NativeBlockPreservesWord_switchCaseBody_nonpayable_of_user_body`. +Both cond-reviveJump premises (callvalue and lt-calldatasize) are discharged +internally via the universal-input discharge lemmas. -/ +private theorem NativeBlockPreservesWord_revived_switchCaseBody_nonpayable_of_user_body + (fn : IRFunction) + (nativeContract : EvmYul.Yul.Ast.YulContract) + (reservedNames : List String) + (switchStart : Nat) + (body' callvalueGuardBody calldataGuardBody bodyNative : + List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd : Nat) + (hNonPayable : fn.payable = false) + (hBodyLower : + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd)) + (hBodyShape : + body' = + EvmYul.Yul.Ast.Stmt.Block [] :: + EvmYul.Yul.Ast.Stmt.If + (Compiler.Proofs.YulGeneration.Backends.lowerExprNative + (Compiler.Yul.YulExpr.call "callvalue" [])) + callvalueGuardBody :: + EvmYul.Yul.Ast.Stmt.If + (Compiler.Proofs.YulGeneration.Backends.lowerExprNative + (Compiler.Yul.YulExpr.call "lt" + [Compiler.Yul.YulExpr.call "calldatasize" [], + Compiler.Yul.YulExpr.lit (4 + fn.params.length * 32)])) + calldataGuardBody :: + bodyNative) + (hUserPreserves : + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames switchStart)) + (EvmYul.UInt256.ofNat 1) bodyNative (some nativeContract)) : + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames switchStart)) + (EvmYul.UInt256.ofNat 1) body' (some nativeContract) := by + rcases + Compiler.Proofs.YulGeneration.Backends.Native.lowerStmtsNativeWithSwitchIds_switchCaseBody_nonpayable_revert_eq + reservedNames bodyStart fn body' bodyEnd hNonPayable hBodyLower with + ⟨bodyNative', _userBodyStart', hShape, _hUserBodyLower'⟩ + have hShapeEq : + callvalueGuardBody = + [Compiler.Proofs.YulGeneration.Backends.Native.nativeRevertZeroZeroStmt] ∧ + calldataGuardBody = + [Compiler.Proofs.YulGeneration.Backends.Native.nativeRevertZeroZeroStmt] ∧ + bodyNative = bodyNative' := by + rw [hShape] at hBodyShape + simp at hBodyShape + exact ⟨hBodyShape.1.symm, hBodyShape.2.1.symm, hBodyShape.2.2.symm⟩ + rcases hShapeEq with ⟨hCallvalueGuardBody, hCalldataGuardBody, + hBodyNativeEq⟩ + subst callvalueGuardBody + subst calldataGuardBody + subst bodyNative' + rw [hShape] + refine + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_cons + _ _ (.Block []) _ _ ?_ ?_ + · exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_block + _ _ [] _ (Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nil _ _ _) + · refine + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_cons + _ _ _ _ _ ?_ ?_ + · exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump + _ _ _ _ _ + (Compiler.Proofs.YulGeneration.Backends.Native.eval_callvalue_preserves_reviveJump + (some nativeContract)) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nativeRevertZeroZero _ _ _) + · refine + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_cons + _ _ _ _ _ ?_ ?_ + · exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump + _ _ _ _ _ + (Compiler.Proofs.YulGeneration.Backends.Native.eval_lt_calldatasize_lit_preserves_reviveJump + (4 + fn.params.length * 32) (some nativeContract)) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nativeRevertZeroZero _ _ _) + · exact hUserPreserves + /-- User-body matched-flag preservation implies preservation for the whole generated selected case body. -/ private theorem nativeGeneratedSelectorHitBodyPreservesMatched_of_user_body_preserves @@ -18928,24 +19485,520 @@ private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exe private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_empty_body (irContract : IRContract) (tx : IRTransaction) - (hEmpty : + (hEmpty : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = []) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [] := hEmpty fn hFind + simp [hBody] at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_nil + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract) + +/-- Empty selected user bodies preserve the generated matched flag (revived +form). Mirrors `of_empty_body` but uses `NativeBlockPreservesWord_revived_nil` +so it can be composed with Leave-ending revived chains. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_empty_body + (irContract : IRContract) + (tx : IRTransaction) + (hEmpty : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = []) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [] := hEmpty fn hFind + simp [hBody] at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nil + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract) + +/-- Leave-only selected user bodies preserve the generated matched flag in the +revived form. Body `[.leave]` lowers to `[.Leave]`, and +`NativeStmtPreservesWord_revived_leave` discharges the preservation through +the `reviveJump` projection. + +This is the breakthrough constructor: in the OLD form it was structurally +impossible (because `Yul.State.store` returns `default = ⟨0⟩` for the +Checkpoint produced by `.Leave`); in the `_revived` form `state.reviveJump` +projects the Checkpoint back to its inner `Ok` state so the matched-flag +lookup reads the actual store value. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body + (irContract : IRContract) + (tx : IRTransaction) + (hLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.leave]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [.leave] := hLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_singleton + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) .Leave (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_leave + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract)) + +/-- `[.block []]` selected user bodies preserve the generated matched flag in +the revived form. Body lowers to `[.Block []]`; discharged via the revived +empty-block stmt preservation lemma. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_empty + (irContract : IRContract) + (tx : IRTransaction) + (hBlockEmpty : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block []]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [.block []] := hBlockEmpty fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_singleton + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (.Block []) (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_empty_block + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract)) + +/-- `[.block [.leave]]` selected user bodies preserve the generated matched +flag in the revived form. Body lowers to `[.Block [.Leave]]`; discharged via +`NativeStmtPreservesWord_revived_block_leave`. + +This is a real (non-degenerate) Leave-ending preservation lemma — analogous +to `of_leave_body` but for the `.block [.leave]` shape that the E4 chain +targets. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave + (irContract : IRContract) + (tx : IRTransaction) + (hBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [.leave]]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [.block [.leave]] := hBlockLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_singleton + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (.Block [.Leave]) (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_block_leave + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract)) + +/-- `[.block [], .leave]` selected user bodies preserve the generated matched +flag in the revived form. Body lowers to `[.Block [], .Leave]`; discharged via +the composed `NativeBlockPreservesWord_revived_block_empty_then_leave`. + +This is the Preserves bridge for F2's body shape (label-prefix variant of E2). +A real non-degenerate Leave-ending preservation. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body_with_label_prefix + (irContract : IRContract) + (tx : IRTransaction) + (hLabelLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .leave]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [.block [], .leave] := hLabelLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_block_empty_then_leave + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract) + +/-- `[.block [], .block [.leave]]` selected user bodies preserve the generated +matched flag in the revived form. Body lowers to `[.Block [], .Block [.Leave]]`; +discharged via the composed +`NativeBlockPreservesWord_revived_block_empty_then_block_leave`. + +This is the Preserves bridge for F4's body shape (label-prefix variant of E4). -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave_with_label_prefix + (irContract : IRContract) + (tx : IRTransaction) + (hLabelBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .block [.leave]]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + have hBody : fn.body = [.block [], .block [.leave]] := hLabelBlockLeave fn hFind + rw [hBody] at hUserBodyLower + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_cons, + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_block, + Compiler.Proofs.YulGeneration.Backends.lowerStmtGroupNativeWithSwitchIds_leave, + Bind.bind, Except.bind, Pure.pure, Except.pure, List.append_nil] + at hUserBodyLower + rcases hUserBodyLower with ⟨rfl, _rfl⟩ + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_block_empty_then_block_leave + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract) + +/-- `[.comment text]` selected user bodies preserve the generated matched flag +in the revived form. Lowering is identical to `of_block_empty`. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_singleton_comment + (irContract : IRContract) + (tx : IRTransaction) + (hComment : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + ∃ text, fn.body = [.comment text]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower + hUserBodyLower _pre _suffix _hCases + obtain ⟨text, hBody⟩ := hComment fn hFind + rw [hBody] at hUserBodyLower + rcases Compiler.Proofs.YulGeneration.Backends.Native.lowerStmtsNativeWithSwitchIds_comment_head_eq + reservedNames userBodyStart text [] bodyNative bodyEnd hUserBodyLower + with ⟨rest', hShape, hRest⟩ + simp [Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds_nil] + at hRest + rcases hRest with ⟨hRest', _⟩ + subst hRest' + subst hShape + exact + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_singleton + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (.Block []) (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_empty_block + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) (some nativeContract)) + +/-- `_revived` mirror of `of_bridgedStraightStmts_falling_through` Preserves +bridge (degenerate `preStmts = []` case). Reduces to the revived empty-body +constructor. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through + (irContract : IRContract) + (tx : IRTransaction) + (preStmts : List Compiler.Yul.YulStmt) + (_hBridged : Compiler.Proofs.YulGeneration.Backends.BridgedStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + apply NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_empty_body + intro fn hFind + rw [hBody fn hFind, hOnlyEmpty] + +/-- E6 Preserves slot for the `_revived` chain: bodies of shape +`preStmts ++ [.leave]` with `NativePreservableStraightStmts preStmts`. + +CURRENTLY LIMITED: only handles `preStmts = []` (body = `[.leave]`, reduces to +the REAL `of_leave_body`). The general case requires per-stmt preservation +lemmas discharged via the per-`NativePreservableStraightStmt` lowering +sequence (which builds on PR #1826's `_revived` foundation). -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_nativePreservableStraightStmts_leave + (irContract : IRContract) + (tx : IRTransaction) + (preStmts : List Compiler.Yul.YulStmt) + (_hPreservable : + Compiler.Proofs.YulGeneration.Backends.Native.NativePreservableStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts ++ [.leave]) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx := by + apply NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body + intro fn hFind + rw [hBody fn hFind, hOnlyEmpty, List.nil_append] + +/-- Adapter: compose an exec-only Revived bridge with a `_revived` Preserves +bridge to produce the leave-aware revived exec bridge. Parallel to +`NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves` +but uses `_revived` Preserves so it works for Leave-ending bodies. -/ +private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hExec : + NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived + irContract tx state observableSlots) + (hRevivedPreserves : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived irContract tx) : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx + state observableSlots := by + intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart + bodyEnd userBodyStart hLowerRuntime hFind hCase hBodyLower hUserBodyLower + hguards hArgs + rcases hExec nativeContract fn reservedNames n0 cases' body' bodyNative + bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase hBodyLower + hUserBodyLower hguards hArgs with + ⟨final, nativeYul, shared, store, hBody, hRevive, hProject, hMatch⟩ + refine ⟨final, nativeYul, shared, store, hBody, ?_, hRevive, hProject, + hMatch⟩ + intro pre suffix hCases + exact + hRevivedPreserves nativeContract fn reservedNames n0 cases' body' bodyNative + bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase hBodyLower + hUserBodyLower pre suffix hCases + +/-- One-shot constructor for the leave-aware revived exec bridge for the +`[.leave]` body shape. Composes the existing exec-only `of_leave_body` leaf +(`NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body`) +with the `_revived` Preserves bridge `of_leave_body` (shipped in `6cf2a453`). -/ +private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.leave]) : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx + state observableSlots := + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves + irContract tx state observableSlots + (NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only + irContract tx state observableSlots + (NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body + irContract tx state observableSlots hLeave)) + (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body + irContract tx hLeave) + +/-- Pre-packaged type of the dispatcher continuation that +`nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation` +expects at its `hCont` parameter — the leave-aware version that takes +`NativeBlockPreservesWord_revived` at the matched-flag position. + +E2/E4/E6 SuccessBridge chains take this as a hypothesis (TODO: build a +parallel `_revived`-aware dispatcher continuation provider mirroring +`nativeGeneratedCallDispatcherResult_selector_hit_ok_matchesIR_forall_of_compile_ok_supported` +so callers can discharge it automatically). -/ +private def LeaveAwareCallDispatcherContinuation + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) : Prop := + ∀ (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) + (reservedNames : List String) (n0 : Nat) + (cases' : List (Nat × List EvmYul.Yul.Ast.Stmt)) + (body' bodyNative : List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd userBodyStart : Nat), + Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative + (Compiler.emitYul irContract).runtimeCode = .ok nativeContract → + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + cases'.find? (fun entry => entry.1 == tx.functionSelector) = + some (tx.functionSelector, body') → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd) → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames userBodyStart fn.body = + .ok (bodyNative, bodyEnd) → + ∀ (final : EvmYul.Yul.State) (nativeYul : YulResult), + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + EvmYul.Yul.exec + (nativeGeneratedSelectorHitUserBodyFuel irContract fn cases' + + suffix.length + 10) + (.Block bodyNative) + (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract + (YulTransaction.ofIR tx) + state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0) + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore) = + .ok final) → + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) bodyNative + (some nativeContract)) → + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((final.reviveJump.overwrite? + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))).setStore + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))), [])) = + nativeYul → + nativeResultsMatchOn observableSlots + (interpretIR irContract tx state) (.ok nativeYul) → + nativeResultsMatchOn observableSlots + (interpretIR irContract tx state) + (nativeGeneratedCallDispatcherResultOf irContract tx state + observableSlots nativeContract) + +/-- One-shot constructor for the leave-aware revived exec bridge for the +`[.block [.leave]]` body shape. Composes the existing exec-only +`of_block_leave` leaf with the `_revived` Preserves bridge `of_block_leave`. -/ +private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hBlockLeave : ∀ fn, irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = some fn → - fn.body = []) : - NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel irContract tx := by - intro nativeContract fn reservedNames n0 cases' body' bodyNative bodyStart - bodyEnd userBodyStart _hLowerRuntime hFind _hCase _hBodyLower - hUserBodyLower _pre _suffix _hCases - have hBody : fn.body = [] := hEmpty fn hFind - simp [hBody] at hUserBodyLower - rcases hUserBodyLower with ⟨rfl, _rfl⟩ - exact - Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_nil - (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName - (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId - reservedNames n0)) - (EvmYul.UInt256.ofNat 1) (some nativeContract) + fn.body = [.block [.leave]]) : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx + state observableSlots := + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves + irContract tx state observableSlots + (NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only + irContract tx state observableSlots + (NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_leave + irContract tx state observableSlots hBlockLeave)) + (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave + irContract tx hBlockLeave) + +/-- F2 one-shot LeaveAware ExecBridge for body `[.block [], .leave]` (label-prefix +variant of `of_leave_body`). Composes the F2 ExecOnly leaf +(`of_leave_body_with_label_prefix`, shipped in `bf9cffdf`) with the F2 +`_revived` Preserves bridge (`of_leave_body_with_label_prefix`, shipped in +`43c3a773`). -/ +private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body_with_label_prefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hLabelLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .leave]) : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx + state observableSlots := + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves + irContract tx state observableSlots + (NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only + irContract tx state observableSlots + (NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body_with_label_prefix + irContract tx state observableSlots hLabelLeave)) + (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body_with_label_prefix + irContract tx hLabelLeave) + +/-- F4 one-shot LeaveAware ExecBridge for body `[.block [], .block [.leave]]` +(label-prefix variant of `of_block_leave`). Composes the F4 ExecOnly leaf +with the F4 `_revived` Preserves bridge. -/ +private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave_with_label_prefix + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hLabelBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .block [.leave]]) : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx + state observableSlots := + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves + irContract tx state observableSlots + (NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only + irContract tx state observableSlots + (NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_leave_with_label_prefix + irContract tx state observableSlots hLabelBlockLeave)) + (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave_with_label_prefix + irContract tx hLabelBlockLeave) /-- Selected user bodies of shape `[.block []]` lower to `[.Block []]`, which preserves the generated matched flag via `NativeStmtPreservesWord_empty_block`. -/ @@ -19018,6 +20071,28 @@ private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_singl reservedNames n0)) (EvmYul.UInt256.ofNat 1) (some nativeContract)) +/-- E7 Preserves prereq: Selected user bodies of shape `preStmts` (no terminator) +with all statements in the `BridgedStraightStmts` fragment preserve the +generated matched flag. + +CURRENTLY LIMITED: this version only handles `preStmts = []` (reduces to +`of_empty_body`). The general case requires per-stmt preservation lemmas +discharged via the per-`BridgedStraightStmt` observation framework. -/ +private theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_bridgedStraightStmts_falling_through + (irContract : IRContract) + (tx : IRTransaction) + (preStmts : List Compiler.Yul.YulStmt) + (_hBridged : Compiler.Proofs.YulGeneration.Backends.BridgedStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts) : + NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel irContract tx := by + apply NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_empty_body + intro fn hFind + rw [hBody fn hFind, hOnlyEmpty] + /-- Empty selected user bodies discharge the full revived selector-hit user-body bridge. -/ private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_empty_body @@ -20198,15 +21273,235 @@ private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_w spec selectors hSupported irContract tx state observableSlots hcompile hSelectorRange hSelectorsRange hNoWrap hHaltBridge) -/-- Success-only selector-hit adapter from the exact-fuel user-body execution -bridge plus the generated-prefix continuation. +/-- Success-only selector-hit adapter from the exact-fuel user-body execution +bridge plus the generated-prefix continuation. + +This is the selected-function version of the older bridge composition: callers +provide guard safety and argument availability for the specific selector hit, +while guard failures are handled by +`NativeGeneratedSelectorHitBridge.of_success_bridge_and_generated_guard_reverts`. +-/ +private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revived_and_continuation + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hUserBodyBridge : + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived irContract tx + state observableSlots) + (hCont : + ∀ (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) + (reservedNames : List String) (n0 : Nat) + (cases' : List (Nat × List EvmYul.Yul.Ast.Stmt)) + (body' bodyNative : List EvmYul.Yul.Ast.Stmt) + (bodyStart bodyEnd userBodyStart : Nat), + Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative + (Compiler.emitYul irContract).runtimeCode = .ok nativeContract → + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + cases'.find? (fun entry => entry.1 == tx.functionSelector) = + some (tx.functionSelector, body') → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames bodyStart + (Compiler.Proofs.YulGeneration.Backends.Native.switchCaseBody fn) = + .ok (body', bodyEnd) → + Compiler.Proofs.YulGeneration.Backends.lowerStmtsNativeWithSwitchIds + reservedNames userBodyStart fn.body = + .ok (bodyNative, bodyEnd) → + ∀ (final : EvmYul.Yul.State) (nativeYul : YulResult), + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + EvmYul.Yul.exec + (nativeGeneratedSelectorHitUserBodyFuel irContract fn cases' + + suffix.length + 10) + (.Block bodyNative) + (some nativeContract) + (Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchStoreMarkedPrefixStateForId + nativeContract + (YulTransaction.ofIR tx) + state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0) + Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchHasSelectorStore) = + .ok final) → + (∀ pre suffix, + cases' = pre ++ (tx.functionSelector, body') :: suffix → + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord + (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName + (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId + reservedNames n0)) + (EvmYul.UInt256.ofNat 1) bodyNative + (some nativeContract)) → + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((final.reviveJump.overwrite? + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))).setStore + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))), [])) = + nativeYul → + nativeResultsMatchOn observableSlots + (interpretIR irContract tx state) (.ok nativeYul) → + nativeResultsMatchOn observableSlots + (interpretIR irContract tx state) + (nativeGeneratedCallDispatcherResultOf irContract tx state + observableSlots nativeContract)) + (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) + (hLowerRuntime : + Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative + (Compiler.emitYul irContract).runtimeCode = .ok nativeContract) + (hFind : + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn) + (hguards : DispatchGuardsSafe fn tx) + (hArgs : fn.params.length ≤ tx.args.length) : + nativeResultsMatchOn observableSlots + (interpretIR irContract tx state) + (nativeGeneratedCallDispatcherResultOf irContract tx state + observableSlots nativeContract) := by + let dummyNativeState : EvmYul.Yul.State := + (inferInstance : Inhabited EvmYul.Yul.State).default + let dummyYul : YulResult := + { success := false + returnValue := none + finalStorage := state.storage + finalMappings := Compiler.Proofs.storageAsMappings state.storage + events := state.events } + rcases + nativeGeneratedCallDispatcherResult_selector_hit_ok_matchesIR_of_compile_ok_supported + spec selectors hSupported irContract tx state observableSlots nativeContract + fn dummyNativeState dummyYul hcompile hLowerRuntime hFind hSelectorRange + hSelectorsRange hNoWrap with + ⟨reservedNames, n0, cases', hCaseMidN, body', bodyStart, bodyEnd, + hLowerCases, hCase, hBodyLower, _hCaseCont⟩ + have hProjectRestored + (final : EvmYul.Yul.State) (nativeYul : YulResult) + (shared : EvmYul.SharedState EvmYul.OperationType.Yul) + (store : EvmYul.Yul.VarStore) + (hRevive : final.reviveJump = EvmYul.Yul.State.Ok shared store) + (hProject : + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok (final.reviveJump, [])) = + nativeYul) : + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((final.reviveJump.overwrite? + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))).setStore + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))), [])) = + nativeYul := by + have hInitialOk : + ∃ initialShared initialStore, + Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots) = + EvmYul.Yul.State.Ok initialShared initialStore := by + simp [Compiler.Proofs.YulGeneration.Backends.Native.initialState] + calc + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok + (((final.reviveJump.overwrite? + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))).setStore + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots))), [])) + = + Compiler.Proofs.YulGeneration.Backends.Native.projectResult + (YulTransaction.ofIR tx) state.storage state.events + (.ok (final.reviveJump, [])) := by + exact + Compiler.Proofs.YulGeneration.Backends.Native.projectResult_ok_restoreCallFrame_of_reviveJump_ok + (YulTransaction.ofIR tx) state.storage state.events final + (Compiler.Proofs.YulGeneration.Backends.Native.initialState + nativeContract + (YulTransaction.ofIR tx) state.storage + (Compiler.Proofs.YulGeneration.Backends.Native.materializedStorageSlots + (Compiler.runtimeCode irContract) observableSlots)) + [] shared store hRevive hInitialOk + _ = nativeYul := hProject + by_cases hPayable : fn.payable + · rcases + Compiler.Proofs.YulGeneration.Backends.Native.lowerStmtsNativeWithSwitchIds_switchCaseBody_payable_eq + reservedNames bodyStart fn body' bodyEnd + (by simpa using hPayable) hBodyLower with + ⟨_guardBody, bodyNative, userBodyStart, _hBodyShape, hUserBodyLower⟩ + rcases hUserBodyBridge nativeContract fn reservedNames n0 cases' body' + bodyNative bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase + hBodyLower hUserBodyLower hguards hArgs with + ⟨final, nativeYul, shared, store, hBody, hPreserves, hRevive, + hProject, hMatchExec⟩ + exact + hCont nativeContract fn reservedNames n0 cases' body' bodyNative + bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase hBodyLower + hUserBodyLower final nativeYul hBody hPreserves + (hProjectRestored final nativeYul shared store hRevive hProject) + (nativeResultsMatchOn_interpretIR_of_execIRFunction_dispatchGuards + irContract tx state observableSlots fn (.ok nativeYul) hFind + hguards hArgs hMatchExec) + · have hNonPayable : fn.payable = false := Bool.eq_false_iff.2 hPayable + rcases + Compiler.Proofs.YulGeneration.Backends.Native.lowerStmtsNativeWithSwitchIds_switchCaseBody_nonpayable_eq + reservedNames bodyStart fn body' bodyEnd hNonPayable hBodyLower with + ⟨_callvalueGuardBody, _calldataGuardBody, bodyNative, userBodyStart, + _hBodyShape, hUserBodyLower⟩ + rcases hUserBodyBridge nativeContract fn reservedNames n0 cases' body' + bodyNative bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase + hBodyLower hUserBodyLower hguards hArgs with + ⟨final, nativeYul, shared, store, hBody, hPreserves, hRevive, + hProject, hMatchExec⟩ + exact + hCont nativeContract fn reservedNames n0 cases' body' bodyNative + bodyStart bodyEnd userBodyStart hLowerRuntime hFind hCase hBodyLower + hUserBodyLower final nativeYul hBody hPreserves + (hProjectRestored final nativeYul shared store hRevive hProject) + (nativeResultsMatchOn_interpretIR_of_execIRFunction_dispatchGuards + irContract tx state observableSlots fn (.ok nativeYul) hFind + hguards hArgs hMatchExec) + +/-- Leave-aware parallel variant of +`nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revived_and_continuation` +that accepts the `_revived`-leave-aware exec bridge (with `_revived` Preserves +in the matched-flag conjunct) and a continuation that consumes `_revived` +Preserves at the matching position. -This is the selected-function version of the older bridge composition: callers -provide guard safety and argument availability for the specific selector hit, -while guard failures are handled by -`NativeGeneratedSelectorHitBridge.of_success_bridge_and_generated_guard_reverts`. --/ -private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revived_and_continuation +Mechanical mirror: the proof body is identical to the OLD-form consumer; only +the types of `hUserBodyBridge` and the `hCont`'s Preserves parameter change. -/ +private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation (spec : CompilationModel.CompilationModel) (selectors : List Nat) (hSupported : SupportedSpec spec selectors) (irContract : IRContract) @@ -20220,7 +21515,7 @@ private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFu selector < Compiler.Constants.selectorModulus) (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) (hUserBodyBridge : - NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived irContract tx + NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware irContract tx state observableSlots) (hCont : ∀ (nativeContract : EvmYul.Yul.Ast.YulContract) (fn : IRFunction) @@ -20261,7 +21556,7 @@ private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFu .ok final) → (∀ pre suffix, cases' = pre ++ (tx.functionSelector, body') :: suffix → - Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived (Compiler.Proofs.YulGeneration.Backends.nativeSwitchMatchedTempName (Compiler.Proofs.YulGeneration.Backends.freshNativeSwitchId reservedNames n0)) @@ -20314,7 +21609,7 @@ private theorem nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFu spec selectors hSupported irContract tx state observableSlots nativeContract fn dummyNativeState dummyYul hcompile hLowerRuntime hFind hSelectorRange hSelectorsRange hNoWrap with - ⟨reservedNames, n0, cases', hCaseMidN, body', bodyStart, bodyEnd, + ⟨reservedNames, n0, cases', _hCaseMidN, body', bodyStart, bodyEnd, hLowerCases, hCase, hBodyLower, _hCaseCont⟩ have hProjectRestored (final : EvmYul.Yul.State) (nativeYul : YulResult) @@ -21561,6 +22856,315 @@ private theorem NativeGeneratedSelectorHitSuccessBridge.of_singleton_comment (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_singleton_comment irContract tx hComment) +/-- E7 (S7 component): Selected user bodies of shape `preStmts` (no terminator) +with all statements in the `BridgedStraightStmts` fragment supply the named +selector-hit success bridge by composing the exec-only Revived leaf S6 with +the matching Preserves bridge. + +CURRENTLY LIMITED: this version only handles `preStmts = []` (reduces to a +chain of `of_empty_body` constructors). The general case requires the +per-`BridgedStraightStmt` observation framework + list induction. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_bridgedStraightStmts_falling_through + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (preStmts : List Compiler.Yul.YulStmt) + (hBridged : Compiler.Proofs.YulGeneration.Backends.BridgedStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := + NativeGeneratedSelectorHitSuccessBridge.of_selected_user_body_exec_only_and_preserves + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through + irContract tx state observableSlots preStmts hBridged hOnlyEmpty hBody) + (NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_bridgedStraightStmts_falling_through + irContract tx preStmts hBridged hOnlyEmpty hBody) + +/-- F7 (label-prefix variant of E7): Selected user bodies of shape +`.block [] :: preStmts` with all statements in the `BridgedStraightStmts` +fragment supply the named selector-hit success bridge. + +CURRENTLY LIMITED: degenerate `preStmts = []` only — body reduces to +`[.block []]` and delegates to E3 (`of_block_empty`). The general case +requires the per-`BridgedStraightStmt` observation framework + a +label-prefix lift via `exec_block_noop_block_head_eq`. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_bridgedStraightStmts_falling_through_with_label_prefix + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (preStmts : List Compiler.Yul.YulStmt) + (_hBridged : Compiler.Proofs.YulGeneration.Backends.BridgedStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = .block [] :: preStmts) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := + NativeGeneratedSelectorHitSuccessBridge.of_block_empty + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (fun fn hFind => by rw [hBody fn hFind, hOnlyEmpty]) + +/-- F2 (label-prefix variant of E2): Selected user bodies of shape +`[.block [], .leave]` supply the named selector-hit success bridge. + +CONDITIONAL: takes a body-shape-specific `ExecBridgeAtFuelRevivedLeaveAware` +and the `LeaveAwareCallDispatcherContinuation` as hypotheses. The body-shape +ExecBridge for `[.block [], .leave]` is TODO — needs a lift via +`exec_block_noop_block_head_eq` (peel the `.Block []` head and reduce to the +existing `ExecBridgeAtFuelRevivedLeaveAware.of_leave_body`). ~80-100 LoC of +proof engineering. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_leave_body_with_label_prefix + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hLabelLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .leave]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := by + intro nativeContract fn hLowerRuntime hFind hguards hArgs + exact + nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body_with_label_prefix + irContract tx state observableSlots hLabelLeave) + hCont + nativeContract fn hLowerRuntime hFind hguards hArgs + +/-- F4 (label-prefix variant of E4): Selected user bodies of shape +`[.block [], .block [.leave]]` supply the named selector-hit success bridge. + +DIRECT (no `hExecBridge` hypothesis): composes the F4 LeaveAware ExecBridge +(`of_block_leave_with_label_prefix`) with the +`revivedLeaveAware_and_continuation` consumer. Only requires the standard +`LeaveAwareCallDispatcherContinuation` hypothesis. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_block_leave_with_label_prefix + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hLabelBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [], .block [.leave]]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := by + intro nativeContract fn hLowerRuntime hFind hguards hArgs + exact + nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave_with_label_prefix + irContract tx state observableSlots hLabelBlockLeave) + hCont + nativeContract fn hLowerRuntime hFind hguards hArgs + +/-- F6 (label-prefix variant of E6, degenerate): Selected user bodies of shape +`.block [] :: preStmts ++ [.leave]` with `NativePreservableStraightStmts preStmts` +and `preStmts = []` (degenerate empty case) supply the named selector-hit +success bridge by delegating to F2 (`of_leave_body_with_label_prefix`) via +`List.nil_append` rewriting. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_nativePreservableStraightStmts_leave_with_label_prefix + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (preStmts : List Compiler.Yul.YulStmt) + (_hPreservable : + Compiler.Proofs.YulGeneration.Backends.Native.NativePreservableStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = .block [] :: preStmts ++ [.leave]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := + NativeGeneratedSelectorHitSuccessBridge.of_leave_body_with_label_prefix + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (fun fn hFind => by rw [hBody fn hFind, hOnlyEmpty]; rfl) + hCont + +/-- E2 (S7 component): Selected user bodies of shape `[.leave]` supply the +named selector-hit success bridge through the `_revived` Leave-aware chain. + +Composes `ExecBridgeAtFuelRevivedLeaveAware.of_leave_body` (which packages +the exec-only Revived `of_leave_body` with the real `_revived.of_leave_body` +Preserves bridge) with the `revivedLeaveAware_and_continuation` consumer. + +Takes `LeaveAwareCallDispatcherContinuation` as a hypothesis — until a +parallel `_revived`-aware dispatcher continuation provider lands (mirror of +`nativeGeneratedCallDispatcherResult_selector_hit_ok_matchesIR_forall_of_compile_ok_supported`), +the caller must supply this directly. The hypothesis encodes the +"after-body" dispatcher logic with `_revived` Preserves at the matched-flag +position. -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_leave_body + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.leave]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := by + intro nativeContract fn hLowerRuntime hFind hguards hArgs + exact + nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body + irContract tx state observableSlots hLeave) + hCont + nativeContract fn hLowerRuntime hFind hguards hArgs + +/-- E4 (S7 component): Selected user bodies of shape `[.block [.leave]]` +supply the named selector-hit success bridge through the `_revived` +Leave-aware chain. Parallels E2 but with the block-wrapped Leave shape. + +Composes `ExecBridgeAtFuelRevivedLeaveAware.of_block_leave` with the +`revivedLeaveAware_and_continuation` consumer, taking +`LeaveAwareCallDispatcherContinuation` as a hypothesis (same as E2). -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_block_leave + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hBlockLeave : + ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = [.block [.leave]]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := by + intro nativeContract fn hLowerRuntime hFind hguards hArgs + exact + nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave + irContract tx state observableSlots hBlockLeave) + hCont + nativeContract fn hLowerRuntime hFind hguards hArgs + +/-- E6 (S7 component, degenerate): Selected user bodies of shape +`preStmts ++ [.leave]` with `NativePreservableStraightStmts preStmts` and +`preStmts = []` (degenerate empty case) supply the named selector-hit +success bridge. + +CURRENTLY LIMITED: only handles `preStmts = []`, where body reduces to +`[.leave]` and dispatches to E2 (`of_leave_body`). The general case requires +per-stmt preservation lemmas via the per-`NativePreservableStraightStmt` +observation framework. + +Takes `LeaveAwareCallDispatcherContinuation` as a hypothesis (same as E2/E4). -/ +private theorem NativeGeneratedSelectorHitSuccessBridge.of_nativePreservableStraightStmts_leave + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (state : IRState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (preStmts : List Compiler.Yul.YulStmt) + (_hPreservable : + Compiler.Proofs.YulGeneration.Backends.Native.NativePreservableStraightStmts preStmts) + (hOnlyEmpty : preStmts = []) + (hBody : ∀ fn, + irContract.functions.find? (fun fn => fn.selector == tx.functionSelector) = + some fn → + fn.body = preStmts ++ [.leave]) + (hCont : LeaveAwareCallDispatcherContinuation irContract tx state observableSlots) : + NativeGeneratedSelectorHitSuccessBridge irContract tx state + observableSlots := + NativeGeneratedSelectorHitSuccessBridge.of_leave_body + spec selectors hSupported irContract tx state observableSlots hcompile + hSelectorRange hSelectorsRange hNoWrap + (fun fn hFind => by rw [hBody fn hFind, hOnlyEmpty, List.nil_append]) + hCont + /-- Generated `callDispatcher` result theorem from `SupportedSpec + compile`, modulo the exact-fuel lowered-user-body proof stated against `execIRFunction`, with generated guard failures already discharged. @@ -22352,14 +23956,79 @@ theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported ⟨nativeContract, _hLower, hMatch⟩ exact ⟨nativeContract, hMatch⟩ -/-- Source-level native compiler correctness for the generated native runtime. +/-- Strictly more general variant of +`compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher` +that accepts the unified `NativeGeneratedSelectedUserBodyResultBridgeAtFuel` +(disjunction of HaltExec and ExecOnly+Preserves) instead of just +`HaltExecBridge`. This is the S8-direction generalization: callers with +halt-ending bodies supply `of_halt hUserBodyHalt`; callers with Leave-ending +or falling-through bodies supply the ExecOnly+Preserves disjunct (S5/S6/E2/E4/E6). + +Path to true S8 (drop `hUserBodyHalt` premise entirely): derive the Result +bridge from `SupportedSpec` + body-shape dispatch by case-analyzing on +the supported body shapes and applying the appropriate S5/S6/S7 chain. That +requires the per-stmt observation framework to discharge the non-degenerate +cases of S5/S6/E6/E7. -/ +private theorem compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher_via_result + (spec : CompilationModel.CompilationModel) (selectors : List Nat) + (hSupported : SupportedSpec spec selectors) + (irContract : IRContract) + (tx : IRTransaction) + (initialWorld : Verity.ContractState) + (observableSlots : List Nat) + (hcompile : CompilationModel.compile spec selectors = Except.ok irContract) + (htxNormalized : Function.TxContextNormalized tx) + (hcalldataSizeFits : Function.TxCalldataSizeFitsEvm tx) + (hSelectorRange : tx.functionSelector < Compiler.Constants.selectorModulus) + (hSelectorsRange : + ∀ selector, selector ∈ selectors → + selector < Compiler.Constants.selectorModulus) + (hNoWrap : 4 + tx.args.length * 32 < EvmYul.UInt256.size) + (hUserBodyResult : + NativeGeneratedSelectedUserBodyResultBridgeAtFuel irContract tx + (FunctionBody.initialIRStateForTx spec tx initialWorld) + observableSlots) + (hEnv : + Compiler.Proofs.YulGeneration.Backends.Native.validateNativeRuntimeEnvironment + (Compiler.emitYul irContract).runtimeCode (YulTransaction.ofIR tx) = + .ok ()) : + sourceResultMatchesNativeOn observableSlots + (supportedSourceContractSemantics spec selectors hSupported tx + initialWorld) + (Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative + (Nat.succ (sizeOf (Compiler.emitYul irContract).runtimeCode)) + irContract tx (FunctionBody.initialIRStateForTx spec tx initialWorld) + observableSlots) := by + rcases + nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_result_threshold + spec selectors hSupported irContract tx + (FunctionBody.initialIRStateForTx spec tx initialWorld) + observableSlots hcompile hSelectorRange hSelectorsRange hNoWrap + hUserBodyResult + (fun fn hFind => + generatedFunctionCalldataThreshold_of_compile_ok_supported + spec selectors hSupported irContract tx hcompile fn hFind) with + ⟨nativeContract, hLower, hMatch⟩ + have hEq : + nativeGeneratedCallDispatcherResultOf irContract tx + (FunctionBody.initialIRStateForTx spec tx initialWorld) + observableSlots nativeContract = + Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative + (Nat.succ (sizeOf (Compiler.emitYul irContract).runtimeCode)) + irContract tx + (FunctionBody.initialIRStateForTx spec tx initialWorld) + observableSlots := + nativeGeneratedCallDispatcherResultOf_eq_interpretIRRuntimeNative_of_lowerRuntimeContractNative_supported + tx (FunctionBody.initialIRStateForTx spec tx initialWorld) observableSlots + nativeContract hcompile hSupported hLower hEnv + rw [hEq] at hMatch + exact + sourceResultMatchesNativeOn_of_sourceResultMatchesIRResult_of_nativeResultsMatchOn + (Compiler.Proofs.IRGeneration.Contract.compile_preserves_semantics + spec selectors hSupported irContract tx initialWorld htxNormalized + hcalldataSizeFits hcompile) + hMatch -This is the public composition surface over the generated native dispatcher -stack: `SupportedSpec + compile` discharges the lowered native runtime witness -internally, rewrites the projected `EvmYul.Yul.callDispatcher` result to the -canonical `interpretIRRuntimeNative` target, discharges selector miss and -generated selector-hit guard failures internally, and composes the remaining -selected-body halt execution bridge with the source-to-IR compiler theorem. -/ theorem compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher (spec : CompilationModel.CompilationModel) (selectors : List Nat) (hSupported : SupportedSpec spec selectors) @@ -35460,22 +37129,13 @@ families remain file-local transition evidence. EndToEnd no longer defines compatibility wrappers over the older backend-parameterized proof-interpreter surface. -The retargeting module (`EvmYulLeanRetarget.lean`) still internally records the -bridge-history facts: `backends_agree_on_bridged_builtins`, `BridgedExpr` -expression lifting, statement-fragment helpers for straight-line, block, if, -switch, and for cases, and recursive `BridgedTarget` execution equivalence. -Those file-local facts remain useful as transition evidence for the bridged -fragment, but they are no longer composed into this file's compiler-correctness theorems. The -retargeting module also proves -`emitYul_runtimeCode_bridged`, the emitted-runtime closure witness conditional -on bridged IR function, entrypoint, and internal helper bodies, and - `emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies`, the corresponding - emitted-runtime equality between the transition proof-interpreter backend and - the EVMYulLean backend executor under those body witnesses. These theorems compose the - fully proven builtin bridge equivalences. This file intentionally does not - define EndToEnd wrappers over that proof-interpreter backend target; the - public EndToEnd theorem family targets native dispatcher execution through - the direct projected `nativeGeneratedCallDispatcherResultOf` result. +The retargeting module (`EvmYulLeanRetarget.lean`) that previously recorded +bridge-history facts has been removed (DoD 5 of the EVMYulLean transition). +The file-local `runtimeCode_bridged_local` lemma in this module retains the +emitted-runtime closure witness, and the SupportedSpec-discharged variants +`emitYul_runtimeCode_bridged_of_compile_ok_supported` and +`emitYul_runtimeCode_bridged_of_compile_ok_supported_except_mapping_writes_stmt_safety` +expose the public surface this file needs. The body-closure increments prove that generated external function bodies can discharge raw `BridgedStmts` witnesses from `SupportedSpec`, static-parameter witnesses, and `BridgedSafeStmts` source-body witnesses. @@ -35533,8 +37193,10 @@ on bridged IR function, entrypoint, and internal helper bodies, and and needs separate simulation work before it can be admitted into the safe-body EndToEnd wrapper. -See `Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean` for -the Phase 4 retargeting theorems. +The Phase 4 retargeting module has been removed; the equivalent +proof-interpreter-backed retargeting theorems are no longer needed because the +public EndToEnd surface targets EVMYulLean's native dispatcher execution +directly via `nativeGeneratedCallDispatcherResultOf`. -/ end Compiler.Proofs.EndToEnd diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean deleted file mode 100644 index ae15eca21..000000000 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean +++ /dev/null @@ -1,123 +0,0 @@ -/- - EvmYulLeanAdapterCorrectness: Semantic equivalence proofs for the two - non-trivial lowering transformations in the EVMYulLean adapter. - - The adapter (`EvmYulLeanAdapter.lean`) performs two structural - transformations when lowering Verity Yul to EVMYulLean AST: - - 1. **Assign → Let**: EVMYulLean has no `Assign` statement; the adapter - re-encodes `assign name value` as `Let [name] (some (lowerExpr value))`. - This is semantically valid because both operations call `state.setVar`, - which prepends a new binding and removes the old one. - - 2. **For init-hoisting**: EVMYulLean's `For` has no init block; the adapter - emits `init' ++ [.For cond post' body']`. This is semantically valid - because `legacyExecYulFuel` executes the init block once before entering the - loop, then recurses with `for_ [] cond post body`. - - Both proofs establish that executing the Verity AST directly and executing - the adapter's lowered form produce identical `YulExecResult` values. - - These proofs address two of the "Known Challenges" in issue #1722: - - "`Assign` statement: EVMYulLean lacks `Assign`; adapter uses `Let`" - - "`For` initializer: EVMYulLean `For` has no init block" --/ - -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics - -namespace Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness - -open Compiler.Yul -open Compiler.Proofs.YulGeneration - -/-! ## Assign ↔ Let Semantic Equivalence - -Both `YulStmt.assign name value` and `YulStmt.let_ name value` execute -identically in `legacyExecYulFuel`: they evaluate `value` and call `state.setVar`. - -This justifies the adapter's lowering of `assign` to `Let`. -/ - -/-- Assign and let_ produce identical execution results for all states and - fuel values. This is the core semantic justification for the adapter's - Assign → Let lowering. -/ -private theorem assign_equiv_let (fuel : Nat) (state : YulState) - (name : String) (value : YulExpr) : - execYulStmtFuel fuel state (.assign name value) = - execYulStmtFuel fuel state (.let_ name value) := by - cases fuel with - | zero => rfl - | succ n => rfl - -/-- Variant of the assign/let equivalence for the noncomputable wrapper. -/ -private theorem assign_equiv_let' (state : YulState) - (name : String) (value : YulExpr) : - execYulStmt state (.assign name value) = - execYulStmt state (.let_ name value) := by - simp only [execYulStmt] - exact assign_equiv_let _ _ _ _ - -/-! ## For Init-Hoisting Semantic Equivalence - -The adapter transforms `for_ init cond post body` into -`init_stmts ++ [for_ [] cond post body]`. We prove this produces -identical results: executing the for loop with init is the same as -executing init as a prefix, then the loop with empty init. - -The key insight is that `legacyExecYulFuel` handles `for_` by: -1. Executing `init` to get state `s'` -2. If init succeeds, checking `cond` on `s'` -3. Recursing with `for_ [] cond post body` - -When init is empty, step 1 is a no-op: `legacyExecYulFuel fuel state (.stmts []) = .continue state`. -So `for_ [] cond post body` starts directly at step 2. -/ - -/-- Executing an empty statement list is a no-op for any fuel value. -/ -@[simp] private theorem legacyExecYulFuel_stmts_nil (fuel : Nat) (state : YulState) : - legacyExecYulFuel fuel state (.stmts []) = .continue state := by - cases fuel <;> rfl - -/-- Init-hoisting for the continue case: when init succeeds with state `s'`, - the for-loop behaves the same as running the loop with empty init on `s'`. - - This is the core semantic justification for the adapter's transformation of - `for (init; cond; post) body` into `init; for (; cond; post) body`. -/ -private theorem for_init_hoist (fuel : Nat) (state : YulState) - (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) - (s' : YulState) (hinit : legacyExecYulFuel fuel state (.stmts init) = .continue s') : - execYulStmtFuel (fuel + 1) state (.for_ init cond post body) = - execYulStmtFuel (fuel + 1) s' (.for_ [] cond post body) := by - simp [execYulStmtFuel, legacyExecYulFuel, hinit, legacyExecYulFuel_stmts_nil] - -/-- Init-hoisting for the revert case. -/ -private theorem for_init_hoist_revert (fuel : Nat) (state : YulState) - (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) - (s : YulState) (hinit : legacyExecYulFuel fuel state (.stmts init) = .revert s) : - execYulStmtFuel (fuel + 1) state (.for_ init cond post body) = .revert s := by - simp [execYulStmtFuel, legacyExecYulFuel, hinit] - -/-- Init-hoisting for the return case. -/ -private theorem for_init_hoist_return (fuel : Nat) (state : YulState) - (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) - (v : Nat) (s : YulState) (hinit : legacyExecYulFuel fuel state (.stmts init) = .return v s) : - execYulStmtFuel (fuel + 1) state (.for_ init cond post body) = .return v s := by - simp [execYulStmtFuel, legacyExecYulFuel, hinit] - -/-- Init-hoisting for the stop case. -/ -private theorem for_init_hoist_stop (fuel : Nat) (state : YulState) - (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) - (s : YulState) (hinit : legacyExecYulFuel fuel state (.stmts init) = .stop s) : - execYulStmtFuel (fuel + 1) state (.for_ init cond post body) = .stop s := by - simp [execYulStmtFuel, legacyExecYulFuel, hinit] - -/-! ## Combined: the adapter's lowering preserves semantics - -These theorems together establish that the two non-trivial transformations -in the EVMYulLean adapter are semantically correct: - -1. `assign name value` → `Let [name] (some value)`: proved by `assign_equiv_let` -2. `for_ init cond post body` → `init ++ [for_ [] cond post body]`: proved by - `for_init_hoist` (continue case) and the halt-case variants - -All other lowering cases are structural (1:1 mapping) and trivially correct. -/ - -end Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean index 7155aaf45..5ab3cc7b3 100644 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean +++ b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean @@ -2,9 +2,9 @@ Body closure under `BridgedStmt` for compiler-emitted IR function prologues. This module begins the proof that compiler-emitted IR function and entrypoint - bodies satisfy `BridgedStmt`, enabling `emitYul_runtimeCode_bridged` - (`Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget`) to be used - unconditionally for real programs. + bodies satisfy `BridgedStmt`, enabling the SupportedSpec-discharged + `emitYul_runtimeCode_bridged_of_compile_ok_supported` (in `EndToEnd.lean`) + to be used unconditionally for real programs. The first increment covers `Compiler.CompilationModel.genParamLoads` for parameter lists whose types are all primitive scalar ABI types @@ -156,9 +156,8 @@ private theorem bridgedStraightStmt_revert_zero : (YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])) := BridgedStraightStmt.expr_revert (YulExpr.lit 0) (YulExpr.lit 0) -/-- `lt(calldatasize(), lit n)` as a `BridgedExpr`. Uses the same shape as -`bridgedExpr_calldatasize_lt` from `EvmYulLeanRetarget` but is re-exposed -here at the public level for downstream body-closure work. -/ +/-- `lt(calldatasize(), lit n)` as a `BridgedExpr`. Exposed here at the public +level for downstream body-closure work. -/ private theorem bridgedExpr_lt_calldatasize (n : Nat) : BridgedExpr (YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit n]) := by diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean deleted file mode 100644 index db3b10440..000000000 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean +++ /dev/null @@ -1,644 +0,0 @@ -import Compiler.CompilationModel -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics - -namespace Compiler.Proofs.YulGeneration.Backends.NativeDispatchOracleTest - -open Compiler -open Compiler.Proofs.IRGeneration -open Compiler.Proofs.YulGeneration -open Compiler.Proofs.YulGeneration.Backends - -private def mappingReadSlot : Nat := - Compiler.Proofs.abstractMappingSlot 21 5 - -private def mappingWriteSlot : Nat := - Compiler.Proofs.abstractMappingSlot 21 5 - -private def nestedMappingWriteSlot : Nat := - Compiler.Proofs.abstractMappingSlot (Compiler.Proofs.abstractMappingSlot 22 3) 4 - -private def packedMappingSlot : Nat := - Compiler.Proofs.abstractMappingSlot 23 6 - -private def multiWordMappingBaseSlot : Nat := - Compiler.Proofs.abstractMappingSlot 24 7 - -private def multiWordMappingMemberSlot : Nat := - multiWordMappingBaseSlot + 1 - -private def nestedMultiWordMappingBaseSlot : Nat := - Compiler.Proofs.abstractMappingSlot (Compiler.Proofs.abstractMappingSlot 25 3) 4 - -private def nestedMultiWordMappingMemberSlot : Nat := - nestedMultiWordMappingBaseSlot + 1 - -private def seededStorage : IRStorageSlot -> IRStorageWord := fun slot => - if slot = IRStorageSlot.ofNat 7 then IRStorageWord.ofNat 77 else - if slot = IRStorageSlot.ofNat mappingReadSlot then IRStorageWord.ofNat 515 else - if slot = IRStorageSlot.ofNat packedMappingSlot then IRStorageWord.ofNat 0x123456 else - if slot = IRStorageSlot.ofNat multiWordMappingBaseSlot then IRStorageWord.ofNat 0xAAAA else - if slot = IRStorageSlot.ofNat multiWordMappingMemberSlot then IRStorageWord.ofNat 0xBBBB else - if slot = IRStorageSlot.ofNat nestedMultiWordMappingBaseSlot then IRStorageWord.ofNat 0xCCCC else - if slot = IRStorageSlot.ofNat nestedMultiWordMappingMemberSlot then IRStorageWord.ofNat 0xDDDD else IRStorageWord.ofNat 0 - -private def sampleIRTx (selector : Nat) (args : List Nat := []) : IRTransaction := - { sender := 0xCAFE - msgValue := 0 - thisAddress := 0x1234 - blockTimestamp := 12345 - blockNumber := 678 - chainId := 31337 - blobBaseFee := 19 - functionSelector := selector - args := args } - -private def sampleIRState : IRState := - { vars := [] - storage := seededStorage - transientStorage := fun _ => 0 - memory := fun _ => 0 - calldata := [] - returnValue := none - sender := 0 - msgValue := 0 - thisAddress := 0 - blockTimestamp := 0 - blockNumber := 0 - chainId := 0 - blobBaseFee := 0 - selector := 0 - events := [[9, 9]] } - -private def dispatchSmokeContract : IRContract := - { name := "NativeDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "left" - selector := 0x11111111 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 11, .lit 101]) - ] }, - { name := "right" - selector := 0x22222222 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 11, .lit 202]) - ] } - ] - usesMapping := false } - -private def storageReadIRContract : IRContract := - { name := "NativeStorageReadOracleSmoke" - deploy := [] - functions := [ - { name := "copySlot" - selector := 0x44444444 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 8, .call "sload" [.lit 7]]) - ] } - ] - usesMapping := false } - -private def mappingHelperDispatchSmokeContract : IRContract := - { name := "NativeMappingHelperDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "storeMapped" - selector := 0x88888888 - params := [{ name := "key", ty := .uint256 }] - ret := .unit - body := [ - .expr (.call "sstore" [ - .call "mappingSlot" [.lit 21, .call "calldataload" [.lit 4]], - .lit 909]) - ] } - ] - usesMapping := true } - -private def mappingHelperReadDispatchSmokeContract : IRContract := - { name := "NativeMappingHelperReadDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "loadMapped" - selector := 0x99999999 - params := [{ name := "key", ty := .uint256 }] - ret := .unit - body := [ - .expr (.call "sstore" [ - .lit 15, - .call "sload" [ - .call "mappingSlot" [.lit 21, .call "calldataload" [.lit 4]] - ]]) - ] } - ] - usesMapping := true } - -private def nestedMappingHelperDispatchSmokeContract : IRContract := - { name := "NativeNestedMappingHelperDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "storeNestedMapped" - selector := 0xAAAAAAAA - params := [ - { name := "outerKey", ty := .uint256 }, - { name := "innerKey", ty := .uint256 } - ] - ret := .unit - body := [ - .expr (.call "sstore" [ - .call "mappingSlot" [ - .call "mappingSlot" [.lit 22, .call "calldataload" [.lit 4]], - .call "calldataload" [.lit 36] - ], - .lit 808]) - ] } - ] - usesMapping := true } - -private def packedMember : Compiler.CompilationModel.StructMember := - { name := "flags" - wordOffset := 0 - packed := some { offset := 8, width := 8 } } - -private def packedMappingModel : Compiler.CompilationModel.CompilationModel := - { name := "NativePackedMappingOracleSmoke" - fields := [ - { name := "positions" - ty := .mappingStruct .uint256 [packedMember] - slot := some 23 }, - { name := "scratch" - ty := .uint256 - slot := some 16 } - ] - constructor := none - functions := [ - { name := "readFlags" - params := [{ name := "key", ty := .uint256 }] - returnType := none - body := [ - .setStorage "scratch" (.structMember "positions" (.param "key") "flags") - ] }, - { name := "writeFlags" - params := [ - { name := "key", ty := .uint256 }, - { name := "value", ty := .uint256 } - ] - returnType := none - body := [ - .setStructMember "positions" (.param "key") "flags" (.param "value") - ] } - ] } - -private def packedMappingDispatchSmokeContract : Except String IRContract := - Compiler.CompilationModel.compile packedMappingModel [0xBBBBBBBB, 0xCCCCCCCC] - -private def multiWordMember : Compiler.CompilationModel.StructMember := - { name := "balance" - wordOffset := 1 - packed := none } - -private def multiWordMappingModel : Compiler.CompilationModel.CompilationModel := - { name := "NativeMultiWordMappingOracleSmoke" - fields := [ - { name := "accounts" - ty := .mappingStruct .uint256 [multiWordMember] - slot := some 24 }, - { name := "nestedAccounts" - ty := .mappingStruct2 .uint256 .uint256 [multiWordMember] - slot := some 25 }, - { name := "scratch" - ty := .uint256 - slot := some 17 } - ] - constructor := none - functions := [ - { name := "readBalance" - params := [{ name := "key", ty := .uint256 }] - returnType := none - body := [ - .setStorage "scratch" (.structMember "accounts" (.param "key") "balance") - ] }, - { name := "writeBalance" - params := [ - { name := "key", ty := .uint256 }, - { name := "value", ty := .uint256 } - ] - returnType := none - body := [ - .setStructMember "accounts" (.param "key") "balance" (.param "value") - ] }, - { name := "readNestedBalance" - params := [ - { name := "outerKey", ty := .uint256 }, - { name := "innerKey", ty := .uint256 } - ] - returnType := none - body := [ - .setStorage "scratch" - (.structMember2 "nestedAccounts" (.param "outerKey") (.param "innerKey") "balance") - ] }, - { name := "writeNestedBalance" - params := [ - { name := "outerKey", ty := .uint256 }, - { name := "innerKey", ty := .uint256 }, - { name := "value", ty := .uint256 } - ] - returnType := none - body := [ - .setStructMember2 "nestedAccounts" (.param "outerKey") (.param "innerKey") - "balance" (.param "value") - ] } - ] } - -private def multiWordMappingDispatchSmokeContract : Except String IRContract := - Compiler.CompilationModel.compile multiWordMappingModel - [0xDDDDDDDD, 0xEEEEEEEE, 0xDADADADA, 0xEFEFEFEF] - -private def calldataArgDispatchSmokeContract : IRContract := - { name := "NativeCalldataArgDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "storeArg" - selector := 0x77777777 - params := [{ name := "x", ty := .uint256 }] - ret := .unit - body := [ - .let_ "x" (.call "calldataload" [.lit 4]), - .expr (.call "sstore" [.lit 12, .ident "x"]) - ] } - ] - usesMapping := false } - -private def returnDispatchSmokeContract : IRContract := - { name := "NativeReturnDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "answer" - selector := 0x33333333 - params := [] - ret := .uint256 - body := [ - .expr (.call "mstore" [.lit 0, .lit 42]), - .expr (.call "return" [.lit 0, .lit 32]) - ] } - ] - usesMapping := false } - -private def multiWordReturnDispatchSmokeContract : IRContract := - { name := "NativeMultiWordReturnDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "pair" - selector := 0x55555555 - params := [] - ret := .unit - body := [ - .expr (.call "mstore" [.lit 0, .lit 41]), - .expr (.call "mstore" [.lit 32, .lit 42]), - .expr (.call "return" [.lit 0, .lit 64]) - ] } - ] - usesMapping := false } - -private def memoryRevertDispatchSmokeContract : IRContract := - { name := "NativeMemoryRevertDispatchOracleSmoke" - deploy := [] - functions := [ - { name := "fail" - selector := 0x66666666 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 7, .lit 99]), - .expr (.call "mstore" [.lit 0, .lit 0xDEAD]), - .expr (.call "revert" [.lit 0, .lit 32]) - ] } - ] - usesMapping := false } - -/- Regression-only comparison oracle for this executable smoke test. The -production retarget executor in `EvmYulLeanRetarget.lean` stays private so it -cannot become public proof authority. -/ -mutual - -private def referenceEvalYulExprsWithBackend - (backend : BuiltinBackend) (state : YulState) : - List Compiler.Yul.YulExpr → Option (List Nat) - | [] => some [] - | e :: es => do - let v ← referenceEvalYulExprWithBackend backend state e - let vs ← referenceEvalYulExprsWithBackend backend state es - pure (v :: vs) -termination_by es => exprsSize es -decreasing_by - all_goals - simp [exprsSize] - omega - -private def referenceEvalYulCallWithBackend - (backend : BuiltinBackend) (state : YulState) - (func : String) : List Compiler.Yul.YulExpr → Option Nat - | args => do - let argVals ← referenceEvalYulExprsWithBackend backend state args - if func = "tload" then - match argVals with - | [slot] => some (state.transientStorage (slot % Compiler.Constants.evmModulus)) - | _ => none - else if func = "mload" then - match argVals with - | [offset] => some (state.memory offset) - | _ => none - else if func = "keccak256" then - match argVals with - | [offset, size] => some (abstractKeccakMemorySlice state.memory offset size) - | _ => none - else - evalBuiltinCallWithBackendContext backend - state.storage state.sender state.msgValue state.thisAddress state.blockTimestamp - state.blockNumber state.chainId state.blobBaseFee state.selector state.calldata func argVals -termination_by args => exprsSize args + 1 -decreasing_by - omega - -private def referenceEvalYulExprWithBackend - (backend : BuiltinBackend) (state : YulState) : - Compiler.Yul.YulExpr → Option Nat - | .lit n => some n - | .hex n => some n - | .str _ => none - | .ident name => state.getVar name - | .call func args => referenceEvalYulCallWithBackend backend state func args -termination_by e => exprSize e -decreasing_by - simp [exprSize] - -end - -private def referenceExecYulFuelWithBackend (backend : BuiltinBackend) : - Nat → YulState → YulExecTarget → YulExecResult - | _, state, .stmts [] => .continue state - | _, state, .stmt (Compiler.Yul.YulStmt.funcDef _ _ _ _) => .continue state - | 0, state, _ => .revert state - | Nat.succ fuel, state, target => - match target with - | .stmt stmt => - match stmt with - | .comment _ => .continue state - | .let_ name value => - match referenceEvalYulExprWithBackend backend state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .letMany _ _ => .revert state - | .assign name value => - match referenceEvalYulExprWithBackend backend state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .leave => .continue state - | .expr e => - match e with - | .call "sstore" [slotExpr, valExpr] => - match slotExpr with - | .call "mappingSlot" [baseExpr, keyExpr] => - match referenceEvalYulExprWithBackend backend state baseExpr, - referenceEvalYulExprWithBackend backend state keyExpr, - referenceEvalYulExprWithBackend backend state valExpr with - | some baseSlot, some key, some val => - let updated := Compiler.Proofs.abstractStoreMappingEntry - state.storage baseSlot key val - .continue { state with storage := updated } - | _, _, _ => .revert state - | _ => - match referenceEvalYulExprWithBackend backend state slotExpr, - referenceEvalYulExprWithBackend backend state valExpr with - | some slot, some val => - let updated := Compiler.Proofs.abstractStoreStorageOrMapping - state.storage slot val - .continue { state with storage := updated } - | _, _ => .revert state - | .call "mstore" [offsetExpr, valExpr] => - match referenceEvalYulExprWithBackend backend state offsetExpr, - referenceEvalYulExprWithBackend backend state valExpr with - | some offset, some val => - .continue { state with - memory := fun o => if o = offset then val else state.memory o } - | _, _ => .revert state - | .call "tstore" [offsetExpr, valExpr] => - match referenceEvalYulExprWithBackend backend state offsetExpr, - referenceEvalYulExprWithBackend backend state valExpr with - | some offset, some val => - .continue { state with - transientStorage := fun o => - if o = offset then val else state.transientStorage o } - | _, _ => .revert state - | .call "stop" [] => .stop state - | .call "return" [offsetExpr, sizeExpr] => - match referenceEvalYulExprWithBackend backend state offsetExpr, - referenceEvalYulExprWithBackend backend state sizeExpr with - | some offset, some size => - if size = 32 then - .return (state.memory offset) state - else - .return 0 state - | _, _ => .revert state - | .call "revert" [_, _] => .revert state - | .call func args => - if isYulLogName func then - match referenceEvalYulExprsWithBackend backend state args with - | some argVals => - match applyYulLogCall? state func argVals with - | some next => .continue next - | none => .revert state - | none => .revert state - else - match referenceEvalYulExprWithBackend backend state e with - | some _ => .continue state - | none => .revert state - | _ => - match referenceEvalYulExprWithBackend backend state e with - | some _ => .continue state - | none => .revert state - | .if_ cond body => - match referenceEvalYulExprWithBackend backend state cond with - | some v => - if v = 0 then - .continue state - else - referenceExecYulFuelWithBackend backend fuel state (.stmts body) - | none => .revert state - | .switch expr cases defaultCase => - match referenceEvalYulExprWithBackend backend state expr with - | some v => - match cases.find? (fun x => decide (x.fst = v)) with - | some (_, body) => - referenceExecYulFuelWithBackend backend fuel state (.stmts body) - | none => - match defaultCase with - | some body => - referenceExecYulFuelWithBackend backend fuel state (.stmts body) - | none => .continue state - | none => .revert state - | .for_ init cond post body => - match referenceExecYulFuelWithBackend backend fuel state (.stmts init) with - | .continue s' => - match referenceEvalYulExprWithBackend backend s' cond with - | some v => - if v = 0 then .continue s' - else - match referenceExecYulFuelWithBackend backend fuel s' (.stmts body) with - | .continue s'' => - match referenceExecYulFuelWithBackend backend fuel s'' (.stmts post) with - | .continue s''' => - referenceExecYulFuelWithBackend backend fuel s''' - (.stmt (.for_ [] cond post body)) - | other => other - | other => other - | none => .revert s' - | other => other - | .block stmts => - referenceExecYulFuelWithBackend backend fuel state (.stmts stmts) - | .funcDef _ _ _ _ => .continue state - | .stmts [] => .continue state - | .stmts (stmt :: rest) => - match referenceExecYulFuelWithBackend backend fuel state (.stmt stmt) with - | .continue s' => referenceExecYulFuelWithBackend backend fuel s' (.stmts rest) - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s - -private def referenceRuntimeWithBackendFuel - (fuel : Nat) (runtimeCode : List Compiler.Yul.YulStmt) - (tx : YulTransaction) (storage : IRStorageSlot -> IRStorageWord) (events : List (List Nat)) : - YulResult := - let initialState := YulState.initial tx storage events - yulResultOfExecWithRollback initialState - (referenceExecYulFuelWithBackend .evmYulLean fuel initialState (.stmts runtimeCode)) - -private def resultsMatchOnSlots - (slots : List Nat) (nativeResult referenceResult : YulResult) : Bool := - nativeResult.success == referenceResult.success && - nativeResult.returnValue == referenceResult.returnValue && - nativeResult.events == referenceResult.events && - slots.all (fun slot => - nativeResult.finalStorage (IRStorageSlot.ofNat slot) == - referenceResult.finalStorage (IRStorageSlot.ofNat slot)) - -private def emittedDispatchMatchesReferenceWithExpected - (contract : IRContract) (tx : IRTransaction) - (observableSlots compareSlots : List Nat) - (expectedSuccess : Bool) (expectedReturn : Option Nat) - (expectedSlots : List (Nat × Nat)) : Except String Bool := do - let yulTx := YulTransaction.ofIR tx - let reference := - referenceRuntimeWithBackendFuel 256 (Compiler.emitYul contract).runtimeCode - yulTx sampleIRState.storage sampleIRState.events - let nativeResult ← - match Native.interpretIRRuntimeNative 256 contract tx sampleIRState observableSlots with - | .ok result => .ok result - | .error _ => .error "native runtime lowering failed" - pure ( - resultsMatchOnSlots compareSlots nativeResult reference && - nativeResult.success == expectedSuccess && - reference.success == expectedSuccess && - nativeResult.returnValue == expectedReturn && - reference.returnValue == expectedReturn && - expectedSlots.all (fun (slot, value) => - nativeResult.finalStorage (IRStorageSlot.ofNat slot) == IRStorageWord.ofNat value && - reference.finalStorage (IRStorageSlot.ofNat slot) == IRStorageWord.ofNat value)) - -private def emittedCompiledDispatchMatchesReferenceWithExpected - (contract : Except String IRContract) (tx : IRTransaction) - (observableSlots compareSlots : List Nat) - (expectedSuccess : Bool) (expectedReturn : Option Nat) - (expectedSlots : List (Nat × Nat)) : Except String Bool := do - let irContract ← contract - emittedDispatchMatchesReferenceWithExpected irContract tx observableSlots compareSlots - expectedSuccess expectedReturn expectedSlots - -private def check (label : String) (actual : Except String Bool) : IO Unit := do - match actual with - | .ok true => IO.println s!"ok: {label}" - | .ok false => throw (IO.userError s!"native/reference mismatch: {label}") - | .error err => throw (IO.userError s!"{label}: {err}") - -def main : IO Unit := do - check "emitted dispatcher selects first storage-writing case" - (emittedDispatchMatchesReferenceWithExpected dispatchSmokeContract - (sampleIRTx 0x11111111) [11] [11] true none [(11, 101)]) - check "emitted dispatcher selects second storage-writing case" - (emittedDispatchMatchesReferenceWithExpected dispatchSmokeContract - (sampleIRTx 0x22222222) [11] [11] true none [(11, 202)]) - check "emitted dispatcher forwards observable storage reads" - (emittedDispatchMatchesReferenceWithExpected storageReadIRContract - (sampleIRTx 0x44444444) [7, 8] [7, 8] true none [(7, 77), (8, 77)]) - check "emitted dispatcher decodes ABI argument words" - (emittedDispatchMatchesReferenceWithExpected calldataArgDispatchSmokeContract - (sampleIRTx 0x77777777 [0xABCD]) [12] [12] true none [(12, 0xABCD)]) - check "emitted dispatcher executes mappingSlot helper writes" - (emittedDispatchMatchesReferenceWithExpected mappingHelperDispatchSmokeContract - (sampleIRTx 0x88888888 [5]) [mappingWriteSlot] [mappingWriteSlot] true none - [(mappingWriteSlot, 909)]) - check "emitted dispatcher executes mappingSlot helper reads" - (emittedDispatchMatchesReferenceWithExpected mappingHelperReadDispatchSmokeContract - (sampleIRTx 0x99999999 [5]) [mappingReadSlot, 15] [mappingReadSlot, 15] true none - [(mappingReadSlot, 515), (15, 515)]) - check "emitted dispatcher executes nested mappingSlot helper writes" - (emittedDispatchMatchesReferenceWithExpected nestedMappingHelperDispatchSmokeContract - (sampleIRTx 0xAAAAAAAA [3, 4]) [nestedMappingWriteSlot] [nestedMappingWriteSlot] - true none [(nestedMappingWriteSlot, 808)]) - check "compiled dispatcher reads packed mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected packedMappingDispatchSmokeContract - (sampleIRTx 0xBBBBBBBB [6]) [packedMappingSlot, 16] [packedMappingSlot, 16] - true none [(packedMappingSlot, 0x123456), (16, 0x34)]) - check "compiled dispatcher writes packed mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected packedMappingDispatchSmokeContract - (sampleIRTx 0xCCCCCCCC [6, 0xABCD]) [packedMappingSlot] [packedMappingSlot] - true none [(packedMappingSlot, 0x12CD56)]) - check "compiled dispatcher reads multi-word mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected multiWordMappingDispatchSmokeContract - (sampleIRTx 0xDDDDDDDD [7]) - [multiWordMappingBaseSlot, multiWordMappingMemberSlot, 17] - [multiWordMappingBaseSlot, multiWordMappingMemberSlot, 17] - true none - [(multiWordMappingBaseSlot, 0xAAAA), (multiWordMappingMemberSlot, 0xBBBB), (17, 0xBBBB)]) - check "compiled dispatcher writes multi-word mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected multiWordMappingDispatchSmokeContract - (sampleIRTx 0xEEEEEEEE [7, 0x1234]) - [multiWordMappingBaseSlot, multiWordMappingMemberSlot] - [multiWordMappingBaseSlot, multiWordMappingMemberSlot] - true none - [(multiWordMappingBaseSlot, 0xAAAA), (multiWordMappingMemberSlot, 0x1234)]) - check "compiled dispatcher reads nested multi-word mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected multiWordMappingDispatchSmokeContract - (sampleIRTx 0xDADADADA [3, 4]) - [nestedMultiWordMappingBaseSlot, nestedMultiWordMappingMemberSlot, 17] - [nestedMultiWordMappingBaseSlot, nestedMultiWordMappingMemberSlot, 17] - true none - [(nestedMultiWordMappingBaseSlot, 0xCCCC), (nestedMultiWordMappingMemberSlot, 0xDDDD), - (17, 0xDDDD)]) - check "compiled dispatcher writes nested multi-word mapping struct members" - (emittedCompiledDispatchMatchesReferenceWithExpected multiWordMappingDispatchSmokeContract - (sampleIRTx 0xEFEFEFEF [3, 4, 0x5678]) - [nestedMultiWordMappingBaseSlot, nestedMultiWordMappingMemberSlot] - [nestedMultiWordMappingBaseSlot, nestedMultiWordMappingMemberSlot] - true none - [(nestedMultiWordMappingBaseSlot, 0xCCCC), (nestedMultiWordMappingMemberSlot, 0x5678)]) - check "emitted dispatcher projects 32-byte return halts" - (emittedDispatchMatchesReferenceWithExpected returnDispatchSmokeContract - (sampleIRTx 0x33333333) [] [] true (some 42) []) - check "emitted dispatcher projects multi-word return fallback" - (emittedDispatchMatchesReferenceWithExpected multiWordReturnDispatchSmokeContract - (sampleIRTx 0x55555555) [] [] true (some 0) []) - check "emitted dispatcher rolls back memory-backed revert" - (emittedDispatchMatchesReferenceWithExpected memoryRevertDispatchSmokeContract - (sampleIRTx 0x66666666) [7] [7] false none [(7, 77)]) - -end Compiler.Proofs.YulGeneration.Backends.NativeDispatchOracleTest - -def main : IO Unit := - Compiler.Proofs.YulGeneration.Backends.NativeDispatchOracleTest.main diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean index 638945173..3a796b10c 100644 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean +++ b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean @@ -6619,6 +6619,249 @@ theorem eval_lowerExprNative_lt_calldatasize_ok_fuel EvmYul.Yul.evalPrimCall, EvmYul.Yul.reverse', EvmYul.Yul.cons', EvmYul.Yul.head', EvmYul.Yul.State.executionEnv] +/-- State-generic native evaluation of the lowered `lt(calldatasize(), k)` +expression. At any fuel ≥ 8, eval returns the SAME state unchanged with value +`lt(s.executionEnv.calldata.size, k)`. Works for any state form (Ok, +OutOfFuel, Checkpoint) because the underlying `executionEnvOp` and +`dispatchBinary` are state-preserving (no shape-match on state). -/ +theorem eval_lowerExprNative_lt_calldatasize_fuel + (fuel : Nat) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (k : Nat) : + EvmYul.Yul.eval (fuel + 8) + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride s = + .ok (s, + EvmYul.UInt256.lt + (EvmYul.UInt256.ofNat s.executionEnv.calldata.size) + (EvmYul.UInt256.ofNat k)) := by + simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, + EvmYul.Yul.evalPrimCall, EvmYul.Yul.reverse', EvmYul.Yul.cons', + EvmYul.Yul.head'] + +/-- Tight (minimum-fuel) state-generic version: eval succeeds at fuel ≥ 6. -/ +theorem eval_lowerExprNative_lt_calldatasize_fuel_ge_6 + (fuel : Nat) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (k : Nat) : + EvmYul.Yul.eval (fuel + 6) + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride s = + .ok (s, + EvmYul.UInt256.lt + (EvmYul.UInt256.ofNat s.executionEnv.calldata.size) + (EvmYul.UInt256.ofNat k)) := by + simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, + EvmYul.Yul.evalPrimCall, EvmYul.Yul.reverse', EvmYul.Yul.cons', + EvmYul.Yul.head'] + +/-- State-generic native evaluation of the lowered `callvalue()` expression. +At any fuel ≥ 5, eval returns the SAME state unchanged with value +`s.executionEnv.weiValue`. Works for any state form. -/ +theorem eval_lowerExprNative_callvalue_fuel + (fuel : Nat) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + EvmYul.Yul.eval (fuel + 5) + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride s = + .ok (s, s.executionEnv.weiValue) := by + simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.head'] + +/-- Tight (minimum-fuel) state-generic version: eval succeeds at fuel ≥ 2. -/ +theorem eval_lowerExprNative_callvalue_fuel_ge_2 + (fuel : Nat) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + EvmYul.Yul.eval (fuel + 2) + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride s = + .ok (s, s.executionEnv.weiValue) := by + simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.head'] + +/-- At fuel `n + 8` with Ok input state, the dispatcher's `lt(calldatasize, k)` +guard eval returns the same Ok state, so `final.reviveJump = state.reviveJump`. +Direct corollary of `eval_lowerExprNative_lt_calldatasize_ok_fuel`. -/ +theorem eval_lt_calldatasize_lit_preserves_reviveJump_of_ok_at_fuel + (k : Nat) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (shared : EvmYul.SharedState .Yul) + (store : EvmYul.Yul.VarStore) + (n : Nat) : + ∀ final v, + EvmYul.Yul.eval (n + 8) + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride (.Ok shared store) = .ok (final, v) → + final.reviveJump = (EvmYul.Yul.State.Ok shared store).reviveJump := by + intro final v hEval + rw [eval_lowerExprNative_lt_calldatasize_ok_fuel] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + +/-- At fuel `n + 5` with Ok input state, the dispatcher's `callvalue()` guard +eval returns the same Ok state, so `final.reviveJump = state.reviveJump`. +Direct corollary of `eval_lowerExprNative_callvalue_ok_fuel`. Used to discharge +the `hCallvalueReviveJump` premise of +`NativeBlockPreservesWord_revived_switchCaseBody_nonpayable_of_user_body` when +the caller can establish Ok input form (the dispatcher's actual case at the +selected-body entry). -/ +theorem eval_callvalue_preserves_reviveJump_of_ok_at_fuel + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (shared : EvmYul.SharedState .Yul) + (store : EvmYul.Yul.VarStore) + (n : Nat) : + ∀ final v, + EvmYul.Yul.eval (n + 5) + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride (.Ok shared store) = .ok (final, v) → + final.reviveJump = (EvmYul.Yul.State.Ok shared store).reviveJump := by + intro final v hEval + rw [eval_lowerExprNative_callvalue_ok_fuel] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + +/-- State-generic reviveJump preservation for `lt(calldatasize, k)` at +fuel ≥ 8. -/ +theorem eval_lt_calldatasize_lit_preserves_reviveJump_at_fuel_ge_8 + (k : Nat) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (s : EvmYul.Yul.State) + (n : Nat) : + ∀ final v, + EvmYul.Yul.eval (n + 8) + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride s = .ok (final, v) → + final.reviveJump = s.reviveJump := by + intro final v hEval + rw [eval_lowerExprNative_lt_calldatasize_fuel] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + +/-- State-generic reviveJump preservation for `callvalue()` at fuel ≥ 5. -/ +theorem eval_callvalue_preserves_reviveJump_at_fuel_ge_5 + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (s : EvmYul.Yul.State) + (n : Nat) : + ∀ final v, + EvmYul.Yul.eval (n + 5) + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride s = .ok (final, v) → + final.reviveJump = s.reviveJump := by + intro final v hEval + rw [eval_lowerExprNative_callvalue_fuel] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + +/-- For fuel < 2, eval of the lowered `callvalue()` expression errors out: +the outer `.Call` decrement plus inner `evalArgs 0` returns `.error +.OutOfFuel`. -/ +private theorem eval_lowerExprNative_callvalue_lt2_not_ok + (fuel : Nat) (hLT : fuel < 2) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (result : EvmYul.Yul.State × EvmYul.Literal) : + EvmYul.Yul.eval fuel + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride s ≠ .ok result := by + intro hEval + rcases fuel with _ | _ | _ + all_goals first + | omega + | (simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.head'] at hEval) + +/-- UNIVERSAL-INPUT reviveJump discharge for the dispatcher's `callvalue()` +guard: for ANY fuel and ANY state, a successful eval preserves `reviveJump`. +This is the closed lemma that callers of +`NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump` apply +blind for the callvalue guard. -/ +theorem eval_callvalue_preserves_reviveJump + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + ∀ fuel state final v, + EvmYul.Yul.eval fuel + (Backends.lowerExprNative (Yul.YulExpr.call "callvalue" [])) + codeOverride state = .ok (final, v) → + final.reviveJump = state.reviveJump := by + intro fuel state final v hEval + by_cases hFuel : fuel ≥ 2 + · obtain ⟨n, rfl⟩ : ∃ n, fuel = n + 2 := ⟨fuel - 2, by omega⟩ + rw [eval_lowerExprNative_callvalue_fuel_ge_2] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + · exact absurd hEval + (eval_lowerExprNative_callvalue_lt2_not_ok fuel (by omega) + state codeOverride (final, v)) + +set_option maxHeartbeats 4000000 in +/-- For fuel < 6, eval of the lowered `lt(calldatasize, k)` expression errors +out: the deeply nested Call/PrimCall structure consumes 6 fuel units before +the inner CALLDATASIZE primop's `executionEnvOp` runs. -/ +private theorem eval_lowerExprNative_lt_calldatasize_lt6_not_ok + (fuel : Nat) (hLT : fuel < 6) + (s : EvmYul.Yul.State) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (k : Nat) (result : EvmYul.Yul.State × EvmYul.Literal) : + EvmYul.Yul.eval fuel + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride s ≠ .ok result := by + intro hEval + rcases fuel with _ | _ | _ | _ | _ | _ | _ + all_goals first + | omega + | (simp [Backends.lowerExprNative, Backends.lookupRuntimePrimOp, + EvmYul.Yul.eval, EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, + EvmYul.Yul.evalPrimCall, EvmYul.Yul.reverse', EvmYul.Yul.cons', + EvmYul.Yul.head'] at hEval) + +/-- UNIVERSAL-INPUT reviveJump discharge for the dispatcher's +`lt(calldatasize, k)` guard: for ANY fuel and ANY state, a successful eval +preserves `reviveJump`. Closes the `hCondReviveJump` premise for this +guard. -/ +theorem eval_lt_calldatasize_lit_preserves_reviveJump + (k : Nat) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + ∀ fuel state final v, + EvmYul.Yul.eval fuel + (Backends.lowerExprNative + (Yul.YulExpr.call "lt" + [Yul.YulExpr.call "calldatasize" [], + Yul.YulExpr.lit k])) + codeOverride state = .ok (final, v) → + final.reviveJump = state.reviveJump := by + intro fuel state final v hEval + by_cases hFuel : fuel ≥ 6 + · obtain ⟨n, rfl⟩ : ∃ n, fuel = n + 6 := ⟨fuel - 6, by omega⟩ + rw [eval_lowerExprNative_lt_calldatasize_fuel_ge_6] at hEval + obtain ⟨hStateEq, _⟩ := Prod.mk.inj (Except.ok.inj hEval) + rw [hStateEq] + · exact absurd hEval + (eval_lowerExprNative_lt_calldatasize_lt6_not_ok fuel (by omega) + state codeOverride k (final, v)) + /-- Native evaluation of the lowered `sload(lit slot)` Yul expression. At any fuel `≥ fuel + 6`, the eval reduces to the closed-form pair returned by EVMYulLean's `SLOAD` primitive: the new `SharedState` carries the @@ -7371,6 +7614,51 @@ theorem exec_block_block_leave_ok_add_ten rw [hFuel] simp [EvmYul.Yul.exec] +/-- Executing the native lowering of a source `[.block [], .leave]` user body +(F2's body shape). + +`[.block [], .leave]` lowers to `[.Block [], .Leave]`; wrapped in the outer +dispatcher block this becomes `.Block [.Block [], .Leave]`. The inner +`.Block []` is a no-op head, the outer block continues with `.Leave`, and the +final state is `state.setLeave`. Mirrors `exec_block_block_leave_ok_add_ten` +but with a leading `.Block []` no-op instead of a wrapping `.Block`. -/ +theorem exec_block_label_prefix_leave_ok_add_ten + (fuel suffixLen : Nat) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (state : EvmYul.Yul.State) : + EvmYul.Yul.exec (fuel + suffixLen + 10) (.Block [.Block [], .Leave]) + codeOverride state = + .ok (state.setLeave) := by + have hFuel : + fuel + suffixLen + 10 = + Nat.succ (Nat.succ (Nat.succ (Nat.succ (fuel + suffixLen + 6)))) := by + omega + rw [hFuel] + simp [EvmYul.Yul.exec] + +/-- Executing the native lowering of a source `[.block [], .block [.leave]]` +user body (F4's body shape). + +`[.block [], .block [.leave]]` lowers to `[.Block [], .Block [.Leave]]`; +wrapped in the outer dispatcher block this becomes +`.Block [.Block [], .Block [.Leave]]`. The leading `.Block []` is a no-op, the +inner `.Block [.Leave]` sets the leave flag, and the final state is +`state.setLeave`. -/ +theorem exec_block_label_prefix_block_leave_ok_add_ten + (fuel suffixLen : Nat) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (state : EvmYul.Yul.State) : + EvmYul.Yul.exec (fuel + suffixLen + 10) + (.Block [.Block [], .Block [.Leave]]) codeOverride state = + .ok (state.setLeave) := by + have hFuel : + fuel + suffixLen + 10 = + Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ + (fuel + suffixLen + 4)))))) := by + omega + rw [hFuel] + simp [EvmYul.Yul.exec] + /-- Executing the native lowering of a source `.block []` user body. `[.block []]` lowers to `[.Block []]`; wrapped in the outer dispatcher block @@ -13353,6 +13641,51 @@ theorem NativeStmtPreservesWord_if_of_cond_preserves_and_nativeStmtsWriteNames_n (NativeBlockPreservesWord_of_nativeStmtsWriteNames_not_mem name value body codeOverride hFresh hPreserves) +/-- `_revived` mirror of `NativeStmtPreservesWord_if_of_cond_preserves` using a +condition-state-preservation premise stated via `reviveJump` (instead of OLD-form +`NativeExprPreservesWord` which is unsound on Checkpoint inputs — see memory +`yul-state-lookup-bracket-vs-lookup`). + +The premise `hCondReviveJump` is per-condition; for the dispatcher's +`lt(calldatasize, k)` and `callvalue` guards on Ok input, it follows from +`eval_lowerExprNative_*_ok_fuel` (eval returns the same state). -/ +theorem NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (cond : EvmYul.Yul.Ast.Expr) + (body : List EvmYul.Yul.Ast.Stmt) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (hCondReviveJump : + ∀ fuel state final v, + EvmYul.Yul.eval fuel cond codeOverride state = .ok (final, v) → + final.reviveJump = state.reviveJump) + (hBody : NativeBlockPreservesWord_revived name value body codeOverride) : + NativeStmtPreservesWord_revived name value (.If cond body) codeOverride := by + intro fuel state final hLookup hExec + cases fuel with + | zero => + simp [EvmYul.Yul.exec] at hExec + | succ fuel' => + simp [EvmYul.Yul.exec] at hExec + cases hEval : EvmYul.Yul.eval fuel' cond codeOverride state with + | error err => + simp [hEval] at hExec + | ok condResult => + rcases condResult with ⟨condState, condValue⟩ + have hReviveEq : condState.reviveJump = state.reviveJump := + hCondReviveJump fuel' state condState condValue hEval + have hCondLookup : condState.reviveJump[name]! = value := by + rw [hReviveEq]; exact hLookup + simp [hEval] at hExec + by_cases hCondNonzero : condValue ≠ ⟨0⟩ + · simp [hCondNonzero] at hExec + exact hBody fuel' condState final hCondLookup hExec + · have hCondZero : condValue = ⟨0⟩ := + Decidable.not_not.mp hCondNonzero + simp [hCondZero] at hExec + cases hExec + exact hCondLookup + theorem nativeSwitchBranchFold_ok_preserves_word (name : EvmYul.Identifier) (value cond : EvmYul.Literal) @@ -14488,7 +14821,7 @@ theorem NativeStmtPreservesWord_revived_leave cases state with | Ok shared store => subst final - simp [EvmYul.Yul.State.setLeave, reviveJump_Leave_eq, reviveJump_Ok_eq] + simp [EvmYul.Yul.State.setLeave, reviveJump_Leave_eq] simpa [reviveJump_Ok_eq] using hLookup | OutOfFuel => subst final @@ -14524,6 +14857,135 @@ theorem NativeStmtPreservesWord_revived_block_leave (NativeBlockPreservesWord_revived_singleton name value .Leave codeOverride (NativeStmtPreservesWord_revived_leave name value codeOverride)) +/-- `_revived` block preservation for the body shape `[.Block [], .Leave]` — +the lowered form of an IR `[.block [], .leave]` body (F2's body shape). Used +by the future label-prefix lift `ExecBridgeAtFuelRevivedLeaveAware.of_leave_body_with_label_prefix`. -/ +theorem NativeBlockPreservesWord_revived_block_empty_then_leave + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + NativeBlockPreservesWord_revived name value [.Block [], .Leave] + codeOverride := + NativeBlockPreservesWord_revived_cons name value (.Block []) [.Leave] + codeOverride + (NativeStmtPreservesWord_revived_empty_block name value codeOverride) + (NativeBlockPreservesWord_revived_singleton name value .Leave codeOverride + (NativeStmtPreservesWord_revived_leave name value codeOverride)) + +/-- Generic vacuity helper: if a `.Block` body's exec never produces an +`.ok` result, then `_revived` preservation holds trivially (the implication's +premise is unsatisfiable). + +Useful for halt-style bodies whose exec always returns `.error YulHalt` +(stop / return / revert), where `_revived` preservation is vacuous. The +counterpart for the OLD-form `NativeBlockPreservesWord` follows by the same +argument; see `NativeBlockPreservesWord_of_never_ok` below. -/ +theorem NativeBlockPreservesWord_revived_of_never_ok + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (body : List EvmYul.Yul.Ast.Stmt) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (hNeverOk : + ∀ fuel state final, + EvmYul.Yul.exec fuel (.Block body) codeOverride state ≠ .ok final) : + NativeBlockPreservesWord_revived name value body codeOverride := by + intro fuel state final _hRevive hExec + exact absurd hExec (hNeverOk fuel state final) + +/-- OLD-form counterpart of `NativeBlockPreservesWord_revived_of_never_ok`. -/ +theorem NativeBlockPreservesWord_of_never_ok + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (body : List EvmYul.Yul.Ast.Stmt) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (hNeverOk : + ∀ fuel state final, + EvmYul.Yul.exec fuel (.Block body) codeOverride state ≠ .ok final) : + NativeBlockPreservesWord name value body codeOverride := by + intro fuel state final _hLookup hExec + exact absurd hExec (hNeverOk fuel state final) + +/-- Helper for `NativeBlockPreservesWord_revived_nativeRevertZeroZero`: for +fuel < 7, `exec fuel (.Block [revert]) state` is structurally not `.ok` — the +fuel runs out before completing the primitive-call unfolding. -/ +private theorem exec_block_nativeRevertZeroZero_low_fuel_ne_ok + (codeOverride : Option EvmYul.Yul.Ast.YulContract) + (state final : EvmYul.Yul.State) (fuel : Nat) (hLt : fuel < 7) : + EvmYul.Yul.exec fuel (.Block [nativeRevertZeroZeroStmt]) codeOverride state + ≠ .ok final := by + intro hExec + match fuel, hLt, hExec with + | 0, _, hExec => simp [EvmYul.Yul.exec] at hExec + | 1, _, hExec => simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt] at hExec + | 2, _, hExec => + simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt, EvmYul.Yul.eval, + EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, EvmYul.Yul.execPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.cons'] at hExec + | 3, _, hExec => + simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt, EvmYul.Yul.eval, + EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, EvmYul.Yul.execPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.cons'] at hExec + | 4, _, hExec => + simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt, EvmYul.Yul.eval, + EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, EvmYul.Yul.execPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.cons'] at hExec + | 5, _, hExec => + simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt, EvmYul.Yul.eval, + EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, EvmYul.Yul.execPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.cons'] at hExec + | 6, _, hExec => + simp [EvmYul.Yul.exec, nativeRevertZeroZeroStmt, EvmYul.Yul.eval, + EvmYul.Yul.evalArgs, EvmYul.Yul.evalTail, EvmYul.Yul.execPrimCall, + EvmYul.Yul.reverse', EvmYul.Yul.cons'] at hExec + +/-- `_revived` block preservation for the singleton revert body +`[nativeRevertZeroZeroStmt]`. Proved via the vacuity helper: revert always +errors, so `exec ... = .ok final` is structurally unsatisfiable. + +This is the first leaf of the parallel `_revived` upstream chain needed by +the dispatcher continuation provider — mirror of the OLD-form +`NativeBlockPreservesWord_nativeRevertZeroZero` (in EndToEnd.lean) without +going through the (currently missing) `_revived` primitive call chain. -/ +theorem NativeBlockPreservesWord_revived_nativeRevertZeroZero + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + NativeBlockPreservesWord_revived name value + [nativeRevertZeroZeroStmt] codeOverride := by + apply NativeBlockPreservesWord_revived_of_never_ok + intro fuel state final hExec + by_cases hLt : fuel < 7 + · exact exec_block_nativeRevertZeroZero_low_fuel_ne_ok codeOverride state + final fuel hLt hExec + · obtain ⟨n, rfl⟩ : ∃ n, fuel = n + 7 := ⟨fuel - 7, by omega⟩ + have hStmt : + EvmYul.Yul.exec (n + 6) nativeRevertZeroZeroStmt codeOverride state = + .error EvmYul.Yul.Exception.Revert := + exec_revert_zero_zero_error n state codeOverride + have hBlock : + EvmYul.Yul.exec (Nat.succ (n + 6)) (.Block [nativeRevertZeroZeroStmt]) + codeOverride state = .error EvmYul.Yul.Exception.Revert := + exec_block_cons_error (n + 6) nativeRevertZeroZeroStmt [] codeOverride + state EvmYul.Yul.Exception.Revert hStmt + rw [show n + 7 = Nat.succ (n + 6) from rfl, hBlock] at hExec + cases hExec + +/-- `_revived` block preservation for the body shape `[.Block [], .Block [.Leave]]` +— the lowered form of an IR `[.block [], .block [.leave]]` body (F4's body +shape). Used by the future label-prefix lift for the block-leave case. -/ +theorem NativeBlockPreservesWord_revived_block_empty_then_block_leave + (name : EvmYul.Identifier) + (value : EvmYul.Literal) + (codeOverride : Option EvmYul.Yul.Ast.YulContract) : + NativeBlockPreservesWord_revived name value + [.Block [], .Block [.Leave]] codeOverride := + NativeBlockPreservesWord_revived_cons name value (.Block []) + [.Block [.Leave]] codeOverride + (NativeStmtPreservesWord_revived_empty_block name value codeOverride) + (NativeBlockPreservesWord_revived_singleton name value (.Block [.Leave]) + codeOverride + (NativeStmtPreservesWord_revived_block_leave name value codeOverride)) + theorem NativeStmtPreservesWord_lowerStmtGroupNativeWithSwitchIds_comment (name : EvmYul.Identifier) (expected : EvmYul.Literal) diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean deleted file mode 100644 index 8a84eb7a7..000000000 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean +++ /dev/null @@ -1,1257 +0,0 @@ -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import EvmYul.Yul.Interpreter - -namespace Compiler.Proofs.YulGeneration.Backends - -open Compiler.Yul -open Compiler.Proofs.IRGeneration (IRStorageWord IRStorageSlot) - -private def runNativeProgram (stmts : List YulStmt) : Option EvmYul.Yul.State := - match lowerStmtsNative stmts with - | .error _ => none - | .ok lowered => - let initial : EvmYul.Yul.State := Inhabited.default - match EvmYul.Yul.exec 64 (.Block lowered) none initial with - | .error _ => none - | .ok state => some state - -private def varIs (name : String) (value : Nat) (state : EvmYul.Yul.State) : Bool := - match state with - | .Ok _ store => - match store.lookup name with - | some got => got == EvmYul.UInt256.ofNat value - | none => false - | _ => false - -private def sampleTx : Compiler.Proofs.YulGeneration.YulTransaction := - { sender := 0xCAFE - msgValue := 7 - thisAddress := 0x1234 - blockTimestamp := 12345 - blockNumber := 678 - chainId := 31337 - blobBaseFee := 19 - functionSelector := 0x01020304 - args := [41] } - -private def zeroStorage : IRStorageSlot → IRStorageWord := fun _ => IRStorageWord.ofNat 0 - -private def seededStorage : IRStorageSlot → IRStorageWord := fun slot => - if slot = 7 then IRStorageWord.ofNat 77 else IRStorageWord.ofNat 0 - -private def wordByteArray (value : Nat) : ByteArray := - ByteArray.ofFn fun i : Fin 32 => - if i.1 = 31 then UInt8.ofNat value else UInt8.ofNat 0 - -private def sampleLogEntry (topics : List Nat) (dataWord : Nat) : EvmYul.LogEntry := - { address := StateBridge.natToAddress sampleTx.thisAddress - topics := topics.toArray.map EvmYul.UInt256.ofNat - data := wordByteArray dataWord } - -private def stateWithLogEntries (entries : List EvmYul.LogEntry) : EvmYul.Yul.State := - let shared := StateBridge.toSharedState - (Compiler.Proofs.YulGeneration.YulState.initial sampleTx zeroStorage) [] - .Ok { shared with substate := { shared.substate with logSeries := entries.toArray } } ∅ - -private def stateWithStorageLogReturn - (storage : IRStorageSlot → IRStorageWord) (observableSlots : List Nat) - (entries : List EvmYul.LogEntry) (returnWord : Nat) : EvmYul.Yul.State := - let shared := StateBridge.toSharedState - (Compiler.Proofs.YulGeneration.YulState.initial sampleTx storage) observableSlots - .Ok - { shared with - substate := { shared.substate with logSeries := entries.toArray } - H_return := wordByteArray returnWord } - ∅ - -private def nativeStoresBuiltinWithTx - (builtin : String) - (slot expected : Nat) - (tx : Compiler.Proofs.YulGeneration.YulTransaction) : - Bool := - match Native.interpretRuntimeNative 128 [ - .let_ "v" (.call builtin []), - .expr (.call "sstore" [.lit slot, .ident "v"]) - ] tx zeroStorage [slot] with - | .ok result => - result.success && result.finalStorage (IRStorageSlot.ofNat slot) == IRStorageWord.ofNat expected - | .error _ => false - -private def nativeStoresBuiltin (builtin : String) (slot expected : Nat) : Bool := - nativeStoresBuiltinWithTx builtin slot expected sampleTx - -private def nativeRejectsUnsupportedBlobBaseFee : Bool := - match Native.interpretRuntimeNative 128 [ - .let_ "v" (.call "blobbasefee" []), - .expr (.call "sstore" [.lit 16, .ident "v"]) - ] sampleTx zeroStorage [16] with - | .error _ => true - | .ok _ => false - -private def nativeRejectsUnsupportedChainId : Bool := - match Native.interpretRuntimeNative 128 [ - .let_ "v" (.call "chainid" []), - .expr (.call "sstore" [.lit 15, .ident "v"]) - ] sampleTx zeroStorage [15] with - | .error _ => true - | .ok _ => false - -private def nativeRejectsUnsupportedHeaderBuiltin (builtin : String) : Bool := - match Native.interpretRuntimeNative 128 [ - .let_ "v" (.call builtin []), - .expr (.call "sstore" [.lit 17, .ident "v"]) - ] sampleTx zeroStorage [17] with - | .error _ => true - | .ok _ => false - -private def runtimeWithUnselectedUnsupportedEnvironmentBuiltin : List YulStmt := - let selectorExpr := - YulExpr.call "shr" [ - YulExpr.lit Compiler.Constants.selectorShift, - YulExpr.call "calldataload" [YulExpr.lit 0] - ] - let runtimeCode := [ - YulStmt.funcDef "unusedEnvHelper" [] [] [ - .let_ "v" (.call "chainid" []), - .expr (.call "sstore" [.lit 15, .ident "v"]) - ], - YulStmt.block [ - .let_ "__has_selector" - (.call "iszero" [.call "lt" [.call "calldatasize" [], .lit 4]]), - .if_ (.call "iszero" [.ident "__has_selector"]) [], - .if_ (.ident "__has_selector") [ - .switch selectorExpr [ - (sampleTx.functionSelector, [ - .expr (.call "sstore" [.lit 1, .lit 7]) - ]) - ] (some []) - ] - ] - ] - runtimeCode - -private def nativeAllowsUnselectedUnsupportedEnvironmentBuiltin : Bool := - match Native.validateNativeRuntimeEnvironment - runtimeWithUnselectedUnsupportedEnvironmentBuiltin sampleTx with - | .ok () => true - | .error _ => false - -private def runtimeWithUserFunctionNamedChainid : List YulStmt := [ - .funcDef "chainid" [] ["ret"] [ - .assign "ret" (.lit 7) - ], - .let_ "v" (.call "chainid" []), - .expr (.call "sstore" [.lit 15, .ident "v"]) -] - -private def nativeAllowsUserFunctionNamedChainid : Bool := - match Native.validateNativeRuntimeEnvironment - runtimeWithUserFunctionNamedChainid sampleTx with - | .ok () => true - | .error _ => false - -private def referenceRuntimeWithFuel - (fuel : Nat) (stmts : List YulStmt) (tx : Compiler.Proofs.YulGeneration.YulTransaction) - (storage : IRStorageSlot → IRStorageWord) (events : List (List Nat)) : - Compiler.Proofs.YulGeneration.YulResult := - let initialState := Compiler.Proofs.YulGeneration.YulState.initial tx storage events - match Compiler.Proofs.YulGeneration.legacyExecYulFuel fuel initialState (.stmts stmts) with - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := storage - finalMappings := Compiler.Proofs.storageAsMappings storage - events := events } - -private def resultsMatchOnSlots - (slots : List Nat) - (nativeResult referenceResult : Compiler.Proofs.YulGeneration.YulResult) : Bool := - nativeResult.success == referenceResult.success && - nativeResult.returnValue == referenceResult.returnValue && - nativeResult.events == referenceResult.events && - slots.all (fun slot => - nativeResult.finalStorage (IRStorageSlot.ofNat slot) == - referenceResult.finalStorage (IRStorageSlot.ofNat slot)) - -private def nativeMatchesReferenceRuntime - (stmts : List YulStmt) (observableSlots compareSlots : List Nat) : Bool := - match Native.interpretRuntimeNative 128 stmts sampleTx zeroStorage observableSlots with - | .ok nativeResult => - resultsMatchOnSlots compareSlots nativeResult - (referenceRuntimeWithFuel 128 stmts sampleTx zeroStorage []) - | .error _ => false - -private def nativeEnvironmentMatchesReferenceRuntime : Bool := - nativeMatchesReferenceRuntime [ - .expr (.call "sstore" [.lit 8, .call "callvalue" []]), - .expr (.call "sstore" [.lit 9, .call "timestamp" []]), - .expr (.call "sstore" [.lit 10, .call "number" []]), - .expr (.call "sstore" [.lit 12, .call "caller" []]), - .expr (.call "sstore" [.lit 13, .call "address" []]), - .expr (.call "sstore" [.lit 14, .call "calldatasize" []]) - ] [8, 9, 10, 12, 13, 14] [8, 9, 10, 12, 13, 14] - -private def nativeCopiesSloadToSlot - (observableSlots : List Nat) (expected : Nat) : Bool := - match Native.interpretRuntimeNative 128 [ - .expr (.call "sstore" [.lit 8, .call "sload" [.lit 7]]) - ] sampleTx seededStorage observableSlots with - | .ok result => result.success && result.finalStorage (IRStorageSlot.ofNat 8) == IRStorageWord.ofNat expected - | .error _ => false - -private def nativeCopiesTransientLoadToStorage : Bool := - match Native.interpretRuntimeNative 128 [ - .expr (.call "tstore" [.lit 3, .lit 88]), - .expr (.call "sstore" [.lit 9, .call "tload" [.lit 3]]) - ] sampleTx zeroStorage [9] with - | .ok result => result.success && result.finalStorage (IRStorageSlot.ofNat 9) == IRStorageWord.ofNat 88 - | .error _ => false - -private def nativeInitialStateInstallsContractAndStorage : Bool := - let contract : EvmYul.Yul.Ast.YulContract := - { dispatcher := .Block [] - functions := ∅ } - let addr := StateBridge.natToAddress sampleTx.thisAddress - match Native.initialState contract sampleTx seededStorage [7] with - | .Ok shared _ => - shared.executionEnv.code == contract && - shared.executionEnv.codeOwner == addr && - shared.executionEnv.perm && - (match shared.accountMap.find? addr with - | some account => - account.code == contract && - StateBridge.storageLookup account.storage - (StateBridge.natToUInt256 7) == EvmYul.UInt256.ofNat 77 - | none => false) - | _ => false - -private def nativeInitialStateOmittedSlotDefaultsToZero : Bool := - let contract : EvmYul.Yul.Ast.YulContract := - { dispatcher := .Block [] - functions := ∅ } - let addr := StateBridge.natToAddress sampleTx.thisAddress - match Native.initialState contract sampleTx seededStorage [8] with - | .Ok shared _ => - match shared.accountMap.find? addr with - | some account => - StateBridge.storageLookup account.storage - (StateBridge.natToUInt256 7) == EvmYul.UInt256.ofNat 0 - | none => false - | _ => false - -private def nativeInitialStatePinsTransactionEnvironment : Bool := - let contract : EvmYul.Yul.Ast.YulContract := - { dispatcher := .Block [] - functions := ∅ } - match Native.initialState contract sampleTx zeroStorage [] with - | .Ok shared _ => - shared.executionEnv.source == StateBridge.natToAddress sampleTx.sender && - shared.executionEnv.sender == StateBridge.natToAddress sampleTx.sender && - shared.executionEnv.codeOwner == StateBridge.natToAddress sampleTx.thisAddress && - shared.executionEnv.weiValue == EvmYul.UInt256.ofNat sampleTx.msgValue && - shared.executionEnv.header.timestamp == sampleTx.blockTimestamp && - shared.executionEnv.header.number == sampleTx.blockNumber && - shared.executionEnv.calldata.size == 36 && - shared.executionEnv.calldata.get? 0 == some (UInt8.ofNat 0x01) && - shared.executionEnv.calldata.get? 1 == some (UInt8.ofNat 0x02) && - shared.executionEnv.calldata.get? 2 == some (UInt8.ofNat 0x03) && - shared.executionEnv.calldata.get? 3 == some (UInt8.ofNat 0x04) && - Native.byteArrayWord shared.executionEnv.calldata 4 == 41 - | _ => false - -private def nativeStopCommitsStorageAndPreservesEvents : Bool := - match Native.interpretRuntimeNative 128 [ - .expr (.call "sstore" [.lit 7, .lit 99]), - .expr (.call "stop" []) - ] sampleTx seededStorage [7] [[1, 2, 3]] with - | .ok result => - result.success && - result.returnValue.isNone && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 99 && - result.events == [[1, 2, 3]] - | .error _ => false - -private def nativeReturnHaltProjectsStorageReturnAndEvents : Bool := - let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.error (.YulHalt - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 44) - (EvmYul.UInt256.ofNat 1))) - result.success && - result.returnValue == some 44 && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 99 && - result.events == [[1, 2, 3], [5, 88]] - -private def nativeValueResultProjectsStorageReturnAndEvents : Bool := - let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.ok - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 0, - [EvmYul.UInt256.ofNat 44])) - result.success && - result.returnValue == some 44 && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 99 && - result.events == [[1, 2, 3], [5, 88]] - -private def nativeHardErrorRollsBackStorageAndEvents : Bool := - let result := - Native.projectResult sampleTx - (fun slot => if slot = 7 then 5 else 0) - [[1, 2, 3]] - (.error EvmYul.Yul.Exception.OutOfFuel) - !result.success && - result.returnValue.isNone && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 5 && - result.events == [[1, 2, 3]] - -private def nativeRevertErrorRollsBackStorageAndEvents : Bool := - let result := - Native.projectResult sampleTx - (fun slot => if slot = 7 then 5 else 0) - [[1, 2, 3]] - (.error EvmYul.Yul.Exception.Revert) - !result.success && - result.returnValue.isNone && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 5 && - result.events == [[1, 2, 3]] - -private def dispatchSmokeContract : Compiler.IRContract := - { name := "NativeDispatchSmoke" - deploy := [] - functions := [ - { name := "left" - selector := 0x11111111 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 11, .lit 101]) - ] }, - { name := "right" - selector := 0x22222222 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 11, .lit 202]) - ] } - ] - usesMapping := false } - -private def returnDispatchSmokeContract : Compiler.IRContract := - { name := "NativeReturnDispatchSmoke" - deploy := [] - functions := [ - { name := "answer" - selector := 0x33333333 - params := [] - ret := .uint256 - body := [ - .expr (.call "mstore" [.lit 0, .lit 42]), - .expr (.call "return" [.lit 0, .lit 32]) - ] } - ] - usesMapping := false } - -private def sampleIRTx : Compiler.Proofs.IRGeneration.IRTransaction := - { sender := sampleTx.sender - msgValue := sampleTx.msgValue - thisAddress := sampleTx.thisAddress - blockTimestamp := sampleTx.blockTimestamp - blockNumber := sampleTx.blockNumber - chainId := sampleTx.chainId - blobBaseFee := sampleTx.blobBaseFee - functionSelector := 0x11111111 - args := [] } - -private def sampleIRState : Compiler.Proofs.IRGeneration.IRState := - { vars := [] - storage := seededStorage - transientStorage := fun _ => 0 - memory := fun _ => 0 - calldata := [] - returnValue := none - sender := 0 - msgValue := 0 - thisAddress := 0 - blockTimestamp := 0 - blockNumber := 0 - chainId := 0 - blobBaseFee := 0 - selector := 0 - events := [[9, 9]] } - -private def duplicateHelperIRContract : Compiler.IRContract := - { name := "DuplicateHelperIR" - deploy := [] - functions := [] - internalFunctions := [ - .funcDef "dup" [] [] [], - .funcDef "dup" [] [] [] - ] - usesMapping := false } - -private def storageReadIRContract : Compiler.IRContract := - { name := "NativeStorageReadSmoke" - deploy := [] - functions := [ - { name := "copySlot" - selector := 0x44444444 - params := [] - ret := .unit - body := [ - .expr (.call "sstore" [.lit 8, .call "sload" [.lit 7]]) - ] } - ] - usesMapping := false } - -private def storageReadIRTx : Compiler.Proofs.IRGeneration.IRTransaction := - { sampleIRTx with functionSelector := 0x44444444 } - -private def calldataBridgePinsSelectorAndFirstArg : Bool := - let bytes := StateBridge.calldataToByteArray 0x11223344 [42] - bytes.get? 0 == some (UInt8.ofNat 0x11) && - bytes.get? 1 == some (UInt8.ofNat 0x22) && - bytes.get? 2 == some (UInt8.ofNat 0x33) && - bytes.get? 3 == some (UInt8.ofNat 0x44) && - Native.byteArrayWord bytes 4 == 42 - -private def nativeAssignRebindsExistingLocal : Bool := - match runNativeProgram [ - .let_ "x" (.lit 1), - .assign "x" (.lit 2), - .let_ "y" (.ident "x") - ] with - | some state => varIs "x" 2 state && varIs "y" 2 state - | none => false - -private partial def nativeStmtContainsSwitch : EvmYul.Yul.Ast.Stmt → Bool - | .Switch _ _ _ => true - | .Block stmts => stmts.any nativeStmtContainsSwitch - | .If _ body => body.any nativeStmtContainsSwitch - | .For _ post body => - post.any nativeStmtContainsSwitch || body.any nativeStmtContainsSwitch - | _ => false - -private def nativeExprIsSelectorLoad : EvmYul.Yul.Ast.Expr → Bool - | .Call (.inl op) - [.Lit shift, .Call (.inl loadOp) [.Lit offset]] => - op == (EvmYul.Operation.SHR : EvmYul.Operation .Yul) && - StateBridge.uint256ToNat shift == Compiler.Constants.selectorShift && - loadOp == (EvmYul.Operation.CALLDATALOAD : EvmYul.Operation .Yul) && - StateBridge.uint256ToNat offset == 0 - | _ => false - -private def nativeSwitchDiscrName : String := - "__verity_native_switch_discr_0" - -private def nativeExprSwitchCaseLabel? : EvmYul.Yul.Ast.Expr → Option Nat - | .Call (.inl op) [.Var name, .Lit label] => - if op == (EvmYul.Operation.EQ : EvmYul.Operation .Yul) && - name == nativeSwitchDiscrName then - some (StateBridge.uint256ToNat label) - else - none - | .Call (.inl op) [.Lit label, .Var name] => - if op == (EvmYul.Operation.EQ : EvmYul.Operation .Yul) && - name == nativeSwitchDiscrName then - some (StateBridge.uint256ToNat label) - else - none - | .Call (.inl op) [left, right] => - if op == (EvmYul.Operation.AND : EvmYul.Operation .Yul) || - op == (EvmYul.Operation.OR : EvmYul.Operation .Yul) then - match nativeExprSwitchCaseLabel? left with - | some label => some label - | none => nativeExprSwitchCaseLabel? right - else - none - | _ => none - -private partial def nativeStmtContainsSelectorSwitch : EvmYul.Yul.Ast.Stmt → Bool - | .Switch selector _ _ => nativeExprIsSelectorLoad selector - | .Let [name] (some selector) => - name == nativeSwitchDiscrName && nativeExprIsSelectorLoad selector - | .Block stmts => stmts.any nativeStmtContainsSelectorSwitch - | .If _ body => body.any nativeStmtContainsSelectorSwitch - | .For _ post body => - post.any nativeStmtContainsSelectorSwitch || body.any nativeStmtContainsSelectorSwitch - | _ => false - -private partial def nativeStmtContainsScopedSelectorSwitch : EvmYul.Yul.Ast.Stmt → Bool - | .Block stmts => - stmts.any (fun stmt => - match stmt with - | .Block inner => inner.any nativeStmtContainsSelectorSwitch - | _ => nativeStmtContainsScopedSelectorSwitch stmt) - | .If _ body => body.any nativeStmtContainsScopedSelectorSwitch - | .For _ post body => - post.any nativeStmtContainsScopedSelectorSwitch || - body.any nativeStmtContainsScopedSelectorSwitch - | _ => false - -private partial def nativeStmtSwitchCaseLabels : EvmYul.Yul.Ast.Stmt → List Nat - | .Switch _ cases defaultBody => - cases.map (fun (label, _) => StateBridge.uint256ToNat label) ++ - defaultBody.foldl (fun acc stmt => acc ++ nativeStmtSwitchCaseLabels stmt) [] - | .Block stmts => - stmts.foldl (fun acc stmt => acc ++ nativeStmtSwitchCaseLabels stmt) [] - | .If cond body => - let nested := body.foldl (fun acc stmt => acc ++ nativeStmtSwitchCaseLabels stmt) [] - match nativeExprSwitchCaseLabel? cond with - | some label => label :: nested - | none => nested - | .For _ post body => - post.foldl (fun acc stmt => acc ++ nativeStmtSwitchCaseLabels stmt) [] ++ - body.foldl (fun acc stmt => acc ++ nativeStmtSwitchCaseLabels stmt) [] - | _ => [] - -private partial def nativeStmtContainsSstore (slot value : Nat) : EvmYul.Yul.Ast.Stmt → Bool - | .ExprStmtCall (.Call (.inl op) [.Lit gotSlot, .Lit gotValue]) => - op == (EvmYul.Operation.SSTORE : EvmYul.Operation .Yul) && - StateBridge.uint256ToNat gotSlot == slot && - StateBridge.uint256ToNat gotValue == value - | .Block stmts => - stmts.any (nativeStmtContainsSstore slot value) - | .If _ body => - body.any (nativeStmtContainsSstore slot value) - | .Switch _ cases defaultBody => - cases.any (fun (_, body) => body.any (nativeStmtContainsSstore slot value)) || - defaultBody.any (nativeStmtContainsSstore slot value) - | .For _ post body => - post.any (nativeStmtContainsSstore slot value) || - body.any (nativeStmtContainsSstore slot value) - | _ => false - -private def nativeExprMatchesLit (expected : Nat) : EvmYul.Yul.Ast.Expr → Bool - | .Lit got => StateBridge.uint256ToNat got == expected - | _ => false - -private def nativeExprsMatchLits - (args : List EvmYul.Yul.Ast.Expr) (expected : List Nat) : Bool := - args.length == expected.length && - (args.zip expected).all (fun (arg, value) => nativeExprMatchesLit value arg) - -private partial def nativeExprContainsPrimCall - (op : EvmYul.Operation .Yul) (args : List Nat) : - EvmYul.Yul.Ast.Expr → Bool - | .Call (.inl got) gotArgs => - (got == op && nativeExprsMatchLits gotArgs args) || - gotArgs.any (nativeExprContainsPrimCall op args) - | .Call (.inr _) gotArgs => - gotArgs.any (nativeExprContainsPrimCall op args) - | _ => false - -private partial def nativeStmtContainsPrimCall - (op : EvmYul.Operation .Yul) (args : List Nat) : - EvmYul.Yul.Ast.Stmt → Bool - | .Let _ (some expr) => - nativeExprContainsPrimCall op args expr - | .ExprStmtCall expr => - nativeExprContainsPrimCall op args expr - | .Block stmts => - stmts.any (nativeStmtContainsPrimCall op args) - | .If _ body => - body.any (nativeStmtContainsPrimCall op args) - | .Switch _ cases defaultBody => - cases.any (fun (_, body) => body.any (nativeStmtContainsPrimCall op args)) || - defaultBody.any (nativeStmtContainsPrimCall op args) - | .For _ post body => - post.any (nativeStmtContainsPrimCall op args) || - body.any (nativeStmtContainsPrimCall op args) - | _ => false - -private partial def nativeStmtSwitchCaseStores - (label slot value : Nat) : EvmYul.Yul.Ast.Stmt → Bool - | .Switch _ cases defaultBody => - cases.any (fun (gotLabel, body) => - StateBridge.uint256ToNat gotLabel == label && - body.any (nativeStmtContainsSstore slot value)) || - defaultBody.any (nativeStmtSwitchCaseStores label slot value) - | .Block stmts => - stmts.any (nativeStmtSwitchCaseStores label slot value) - | .If cond body => - (nativeExprSwitchCaseLabel? cond == some label && - body.any (nativeStmtContainsSstore slot value)) || - body.any (nativeStmtSwitchCaseStores label slot value) - | .For _ post body => - post.any (nativeStmtSwitchCaseStores label slot value) || - body.any (nativeStmtSwitchCaseStores label slot value) - | _ => false - -private partial def nativeStmtSwitchCaseContainsPrimCall - (label : Nat) (op : EvmYul.Operation .Yul) (args : List Nat) : - EvmYul.Yul.Ast.Stmt → Bool - | .Switch _ cases defaultBody => - cases.any (fun (gotLabel, body) => - StateBridge.uint256ToNat gotLabel == label && - body.any (nativeStmtContainsPrimCall op args)) || - defaultBody.any (nativeStmtSwitchCaseContainsPrimCall label op args) - | .Block stmts => - stmts.any (nativeStmtSwitchCaseContainsPrimCall label op args) - | .If cond body => - (nativeExprSwitchCaseLabel? cond == some label && - body.any (nativeStmtContainsPrimCall op args)) || - body.any (nativeStmtSwitchCaseContainsPrimCall label op args) - | .For _ post body => - post.any (nativeStmtSwitchCaseContainsPrimCall label op args) || - body.any (nativeStmtSwitchCaseContainsPrimCall label op args) - | _ => false - -private def emittedDispatchLowersToLazyNativeDispatcher : Bool := - match lowerRuntimeContractNative (Compiler.emitYul dispatchSmokeContract).runtimeCode with - | .ok contract => - !nativeStmtContainsSwitch contract.dispatcher && - nativeStmtContainsSelectorSwitch contract.dispatcher && - (contract.functions.lookup "left").isNone && - (contract.functions.lookup "right").isNone - | .error _ => false - -private def emittedDispatchScopesLazyNativeDispatcher : Bool := - match lowerRuntimeContractNative (Compiler.emitYul dispatchSmokeContract).runtimeCode with - | .ok contract => nativeStmtContainsScopedSelectorSwitch contract.dispatcher - | .error _ => false - -private def topLevelNativeSwitchIdsAreThreaded : Bool := - match lowerRuntimeContractNative [ - .switch (.lit 1) [(1, [.expr (.call "sstore" [.lit 1, .lit 11])])] none, - .switch (.lit 2) [(2, [.expr (.call "sstore" [.lit 2, .lit 22])])] none - ] with - | .ok { dispatcher := .Block [ - .Block (.Let [first] (some _) :: _), - .Block (.Let [second] (some _) :: _) - ], .. } => - first == "__verity_native_switch_discr_0" && - second == "__verity_native_switch_discr_1" - | _ => false - -private def nativeSwitchTempNamesAvoidUserNames : Bool := - nativeMatchesReferenceRuntime [ - .let_ "__verity_native_switch_discr_0" (.lit 99), - .let_ "__verity_native_switch_matched_0" (.lit 77), - .switch (.lit 1) - [(1, [.expr (.call "sstore" [.lit 7, .ident "__verity_native_switch_discr_0"])])] - none, - .expr (.call "sstore" [.lit 8, .ident "__verity_native_switch_matched_0"]) - ] [7, 8] [7, 8] - -private def nativeFunctionSwitchTempNamesAvoidLocalUserNames : Bool := - match lowerFunctionDefinitionNativeWithReserved [] [] [] [ - .let_ "__verity_native_switch_discr_0" (.lit 99), - .let_ "__verity_native_switch_matched_0" (.lit 77), - .switch (.lit 1) - [(1, [.let_ "after" (.ident "__verity_native_switch_discr_0")])] - none - ] with - | .ok (.Def _ _ [ - .Let ["__verity_native_switch_discr_0"] (some _), - .Let ["__verity_native_switch_matched_0"] (some _), - .Block (.Let [freshDiscr] (some _) :: .Let [freshMatched] (some _) :: _) - ]) => - freshDiscr != "__verity_native_switch_discr_0" && - freshMatched != "__verity_native_switch_matched_0" - | _ => false - -private def nativeSwitchExecutesOnlyFirstMatchingNonHaltingCase : Bool := - nativeMatchesReferenceRuntime [ - .switch (.lit 1) - [ (1, [.expr (.call "sstore" [.lit 7, .lit 11])]) - , (1, [.expr (.call "sstore" [.lit 7, .lit 22])]) ] - (some [.expr (.call "sstore" [.lit 7, .lit 33])]), - .expr (.call "sstore" [.lit 8, .lit 44]) - ] [7, 8] [7, 8] - -private def duplicateNativeHelperFailsClosed : Bool := - match lowerRuntimeContractNative [ - .funcDef "dup" [] [] [], - .funcDef "dup" [] [] [] - ] with - | .ok _ => false - | .error _ => true - -private def nestedNativeFunctionDefinitionsFailClosed : Bool := - (match lowerRuntimeContractNative [ - .block [ - .funcDef "nested_dispatcher" [] [] [] - ] - ] with - | .ok _ => false - | .error _ => true) && - (match lowerRuntimeContractNative [ - .funcDef "outer" [] [] [ - .funcDef "nested_helper" [] [] [] - ] - ] with - | .ok _ => false - | .error _ => true) - -private def emittedRuntimeSatisfiesGeneratedNativeFragment : Bool := - Native.generatedRuntimeNativeFragment - (Compiler.emitYul dispatchSmokeContract).runtimeCode - -private def duplicateHelpersRejectedByGeneratedNativeFragment : Bool := - !Native.generatedRuntimeNativeFragment [ - .funcDef "dup" [] [] [], - .funcDef "dup" [] [] [] - ] - -private def nestedDispatcherFuncDefRejectedByGeneratedNativeFragment : Bool := - !Native.generatedRuntimeNativeFragment [ - .block [ - .funcDef "nested_dispatcher" [] [] [] - ] - ] - -private def nestedHelperFuncDefRejectedByGeneratedNativeFragment : Bool := - !Native.generatedRuntimeNativeFragment [ - .funcDef "outer" [] [] [ - .funcDef "nested_helper" [] [] [] - ] - ] - -private def nativeRuntimeFragmentGateRejectsDuplicateHelper : Bool := - match Native.interpretRuntimeNative 128 [ - .funcDef "dup" [] [] [], - .funcDef "dup" [] [] [] - ] sampleTx zeroStorage [] with - | .error err => err == Native.unsupportedGeneratedRuntimeNativeFragmentError - | .ok _ => false - -private def nativeIRRuntimeFragmentGateRejectsDuplicateHelper : Bool := - match Native.interpretIRRuntimeNative 128 duplicateHelperIRContract sampleIRTx - sampleIRState [] with - | .error err => err == Native.unsupportedGeneratedRuntimeNativeFragmentError - | .ok _ => false - -private def emittedDispatchLowersNativeSelectorCases : Bool := - match lowerRuntimeContractNative (Compiler.emitYul dispatchSmokeContract).runtimeCode with - | .ok contract => - let labels := nativeStmtSwitchCaseLabels contract.dispatcher - labels.contains 0x11111111 && labels.contains 0x22222222 - | .error _ => false - -private def emittedDispatchLowersNativeSelectorExpr : Bool := - match lowerRuntimeContractNative (Compiler.emitYul dispatchSmokeContract).runtimeCode with - | .ok contract => nativeStmtContainsSelectorSwitch contract.dispatcher - | .error _ => false - -private def emittedDispatchNativeSelectorCaseBodies : Bool := - match lowerRuntimeContractNative (Compiler.emitYul dispatchSmokeContract).runtimeCode with - | .ok contract => - nativeStmtSwitchCaseStores 0x11111111 11 101 contract.dispatcher && - nativeStmtSwitchCaseStores 0x22222222 11 202 contract.dispatcher - | .error _ => false - -private def emittedReturnDispatchLowersNativeMemoryReturn : Bool := - match lowerRuntimeContractNative (Compiler.emitYul returnDispatchSmokeContract).runtimeCode with - | .ok contract => - nativeStmtSwitchCaseContainsPrimCall 0x33333333 .MSTORE [0, 42] - contract.dispatcher && - nativeStmtSwitchCaseContainsPrimCall 0x33333333 .RETURN [0, 32] - contract.dispatcher - | .error _ => false - -private def emittedStorageReadDispatchLowersNativeSloadBody : Bool := - match lowerRuntimeContractNative (Compiler.emitYul storageReadIRContract).runtimeCode with - | .ok contract => - nativeStmtSwitchCaseContainsPrimCall 0x44444444 .SLOAD [7] - contract.dispatcher - | .error _ => false - -private partial def nativeExprContainsUserCall (name : String) : EvmYul.Yul.Ast.Expr → Bool - | .Call (.inr got) args => - got == name || args.any (nativeExprContainsUserCall name) - | .Call (.inl _) args => - args.any (nativeExprContainsUserCall name) - | _ => false - -private partial def nativeStmtContainsUserCall (name : String) : EvmYul.Yul.Ast.Stmt → Bool - | .Let _ (some expr) => nativeExprContainsUserCall name expr - | .ExprStmtCall expr => nativeExprContainsUserCall name expr - | .Switch discr cases defaultBody => - nativeExprContainsUserCall name discr || - cases.any (fun (_, body) => body.any (nativeStmtContainsUserCall name)) || - defaultBody.any (nativeStmtContainsUserCall name) - | .For cond post body => - nativeExprContainsUserCall name cond || - post.any (nativeStmtContainsUserCall name) || - body.any (nativeStmtContainsUserCall name) - | .Block stmts => stmts.any (nativeStmtContainsUserCall name) - | .If cond body => - nativeExprContainsUserCall name cond || - body.any (nativeStmtContainsUserCall name) - | _ => false - -private def helperFuncDefMovesToMapAndCallStaysUserCall : Bool := - match lowerRuntimeContractNative [ - .funcDef "inc" ["x"] ["r"] [ - .let_ "r" (.call "add" [.ident "x", .lit 1]) - ], - .letMany ["y"] (.call "inc" [.lit 41]) - ] with - | .ok contract => - (contract.functions.lookup "inc").isSome && - nativeStmtContainsUserCall "inc" contract.dispatcher - | .error _ => false - -private def lowersAddAsPrim : Bool := - match lowerExprNative (.call "add" [.lit 1, .lit 2]) with - | .Call (.inl op) args => - op == (EvmYul.Operation.ADD : EvmYul.Operation .Yul) && args.length == 2 - | _ => false - -private def lowersHelperAsUserFunction : Bool := - match lowerExprNative (.call "helper" [.lit 1]) with - | .Call (.inr name) args => name == "helper" && args.length == 1 - | _ => false - -private def lowerCallIsPrim - (name : String) (args : List YulExpr) (op : EvmYul.Operation .Yul) : Bool := - match lowerExprNative (.call name args) with - | .Call (.inl got) lowered => got == op && lowered.length == args.length - | _ => false - -private def lowersNativeHaltAndLogBuiltinsAsPrims : Bool := - lowerCallIsPrim "stop" [] .STOP && - lowerCallIsPrim "return" [.lit 0, .lit 32] .RETURN && - lowerCallIsPrim "revert" [.lit 0, .lit 0] .REVERT && - lowerCallIsPrim "log0" [.lit 0, .lit 32] .LOG0 && - lowerCallIsPrim "log1" [.lit 0, .lit 32, .lit 1] .LOG1 && - lowerCallIsPrim "log2" [.lit 0, .lit 32, .lit 1, .lit 2] .LOG2 && - lowerCallIsPrim "log3" [.lit 0, .lit 32, .lit 1, .lit 2, .lit 3] .LOG3 && - lowerCallIsPrim "log4" [.lit 0, .lit 32, .lit 1, .lit 2, .lit 3, .lit 4] .LOG4 - -example : lowersAddAsPrim = true := by - native_decide - -example : lowersHelperAsUserFunction = true := by - native_decide - -example : lowersNativeHaltAndLogBuiltinsAsPrims = true := by - native_decide - -example : - (match runNativeProgram [ - .let_ "x" (.call "add" [.lit 40, .lit 2]) - ] with - | some state => varIs "x" 42 state - | none => false) = true := by - native_decide - -example : - (match lowerRuntimeContractNative [ - .funcDef "inc" ["x"] ["r"] [ - .let_ "r" (.call "add" [.ident "x", .lit 1]) - ], - .letMany ["y"] (.call "inc" [.lit 41]) - ] with - | .ok contract => - contract.functions.lookup "inc" |>.isSome - | .error _ => false) = true := by - native_decide - -example : - (match Native.interpretRuntimeNative 128 [ - .funcDef "inc" ["x"] ["r"] [ - .let_ "r" (.call "add" [.ident "x", .lit 1]) - ], - .expr (.call "sstore" [.lit 7, .call "inc" [.lit 41]]) - ] sampleTx zeroStorage [7] with - | .ok result => result.success && result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 42 - | .error _ => false) = true := by - native_decide - -example : - (match Native.interpretRuntimeNative 128 - [.expr (.call "sstore" [.lit 7, .lit 99])] - sampleTx zeroStorage [7] with - | .ok result => result.success && result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 99 - | .error _ => false) = true := by - native_decide - -example : - nativeCopiesSloadToSlot [7, 8] 77 = true := by - native_decide - -example : - nativeCopiesSloadToSlot [8] 77 = true := by - native_decide - -example : - nativeCopiesTransientLoadToStorage = true := by - native_decide - -example : - nativeInitialStateInstallsContractAndStorage = true := by - native_decide - -example : - nativeInitialStateOmittedSlotDefaultsToZero = true := by - native_decide - -example : - nativeInitialStatePinsTransactionEnvironment = true := by - native_decide - -example : - nativeEnvironmentMatchesReferenceRuntime = true := by - native_decide - -example : - nativeStopCommitsStorageAndPreservesEvents = true := by - native_decide - -example : - nativeReturnHaltProjectsStorageReturnAndEvents = true := by - native_decide - -example : - nativeValueResultProjectsStorageReturnAndEvents = true := by - native_decide - -example : - nativeHardErrorRollsBackStorageAndEvents = true := by - native_decide - -example : - nativeRevertErrorRollsBackStorageAndEvents = true := by - native_decide - -example : - (let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.ok - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 0, - [EvmYul.UInt256.ofNat 44])) - result.finalMappings) = - (let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.ok - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 0, - [EvmYul.UInt256.ofNat 44])) - Compiler.Proofs.storageAsMappings result.finalStorage) := by - rfl - -example : - (let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.error (.YulHalt - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 44) - (EvmYul.UInt256.ofNat 1))) - result.finalMappings) = - (let finalStorage : IRStorageSlot → IRStorageWord := fun slot => if slot = 7 then IRStorageWord.ofNat 99 else IRStorageWord.ofNat 0 - let result := - Native.projectResult sampleTx seededStorage [[1, 2, 3]] - (.error (.YulHalt - (stateWithStorageLogReturn finalStorage [7] [sampleLogEntry [5] 88] 44) - (EvmYul.UInt256.ofNat 1))) - Compiler.Proofs.storageAsMappings result.finalStorage) := by - rfl - -example : - Native.byteArrayWord - (ByteArray.ofFn fun i : Fin 32 => - if i.1 = 31 then UInt8.ofNat 210 else UInt8.ofNat 0) - 0 = 210 := by - native_decide - -example : - Native.projectLogEntry - { address := StateBridge.natToAddress sampleTx.thisAddress - topics := #[EvmYul.UInt256.ofNat 7] - data := wordByteArray 55 } = - [7, 55] := by - native_decide - -example : - Native.projectLogsFromState - (stateWithLogEntries [ - sampleLogEntry [] 50, - sampleLogEntry [1] 51, - sampleLogEntry [1, 2] 52, - sampleLogEntry [1, 2, 3] 53, - sampleLogEntry [1, 2, 3, 4] 54 - ]) = - [[50], [1, 51], [1, 2, 52], [1, 2, 3, 53], [1, 2, 3, 4, 54]] := by - native_decide - -example : - (let result := - Native.projectResult sampleTx zeroStorage [[9]] - (.error (.YulHalt - (stateWithLogEntries [ - sampleLogEntry [] 50, - sampleLogEntry [1] 51, - sampleLogEntry [1, 2] 52, - sampleLogEntry [1, 2, 3] 53, - sampleLogEntry [1, 2, 3, 4] 54 - ]) - (EvmYul.UInt256.ofNat 0))) - result.success && - result.events == - [[9], [50], [1, 51], [1, 2, 52], [1, 2, 3, 53], [1, 2, 3, 4, 54]]) = true := by - native_decide - -example : - (let result := - Native.projectResult sampleTx zeroStorage [[9]] - (.ok - (stateWithLogEntries [sampleLogEntry [7] 70], - [EvmYul.UInt256.ofNat 44])) - result.success && - result.returnValue == some 44 && - result.events == [[9], [7, 70]]) = true := by - native_decide - -example : - (let state : EvmYul.Yul.State := - .Ok - { (StateBridge.toSharedState - (Compiler.Proofs.YulGeneration.YulState.initial sampleTx zeroStorage) []) with - H_return := - ByteArray.ofFn fun i : Fin 32 => - if i.1 = 31 then UInt8.ofNat 99 else UInt8.ofNat 0 } - ∅ - Native.projectHaltReturn state (EvmYul.UInt256.ofNat 1)) = some 99 := by - native_decide - -example : - nativeStoresBuiltin "callvalue" 8 sampleTx.msgValue = true := by - native_decide - -example : - nativeStoresBuiltin "timestamp" 9 sampleTx.blockTimestamp = true := by - native_decide - -example : - nativeStoresBuiltin "number" 10 sampleTx.blockNumber = true := by - native_decide - -example : - nativeStoresBuiltinWithTx "chainid" 15 EvmYul.chainId - { sampleTx with chainId := EvmYul.chainId } = true := by - native_decide - -example : - nativeRejectsUnsupportedChainId = true := by - native_decide - -example : - nativeAllowsUnselectedUnsupportedEnvironmentBuiltin = true := by - native_decide - -example : - nativeAllowsUserFunctionNamedChainid = true := by - native_decide - -example : - nativeStoresBuiltinWithTx "blobbasefee" 16 EvmYul.MIN_BASE_FEE_PER_BLOB_GAS - { sampleTx with blobBaseFee := EvmYul.MIN_BASE_FEE_PER_BLOB_GAS } = true := by - native_decide - -example : - nativeRejectsUnsupportedBlobBaseFee = true := by - native_decide - -example : - nativeRejectsUnsupportedHeaderBuiltin "coinbase" = true := by - native_decide - -example : - nativeRejectsUnsupportedHeaderBuiltin "gaslimit" = true := by - native_decide - -example : - nativeRejectsUnsupportedHeaderBuiltin "selfbalance" = true := by - native_decide - -example : - nativeStoresBuiltin "caller" 12 sampleTx.sender = true := by - native_decide - -example : - nativeStoresBuiltin "address" 13 sampleTx.thisAddress = true := by - native_decide - -example : - nativeStoresBuiltin "calldatasize" 14 36 = true := by - native_decide - -example : - emittedDispatchLowersToLazyNativeDispatcher = true := by - native_decide - -example : - emittedDispatchLowersNativeSelectorCases = true := by - native_decide - -example : - emittedDispatchLowersNativeSelectorExpr = true := by - native_decide - -example : - emittedDispatchNativeSelectorCaseBodies = true := by - native_decide - -example : - emittedReturnDispatchLowersNativeMemoryReturn = true := by - native_decide - -example : - emittedStorageReadDispatchLowersNativeSloadBody = true := by - native_decide - -example : - calldataBridgePinsSelectorAndFirstArg = true := by - native_decide - -example : - nativeAssignRebindsExistingLocal = true := by - native_decide - -example : - emittedDispatchScopesLazyNativeDispatcher = true := by - native_decide - -example : - topLevelNativeSwitchIdsAreThreaded = true := by - native_decide - -example : - nativeSwitchTempNamesAvoidUserNames = true := by - native_decide - -example : - nativeFunctionSwitchTempNamesAvoidLocalUserNames = true := by - native_decide - -example : - nativeSwitchExecutesOnlyFirstMatchingNonHaltingCase = true := by - native_decide - -example : - duplicateNativeHelperFailsClosed = true := by - native_decide - -example : - nestedNativeFunctionDefinitionsFailClosed = true := by - native_decide - -example : - emittedRuntimeSatisfiesGeneratedNativeFragment = true := by - native_decide - -example : - duplicateHelpersRejectedByGeneratedNativeFragment = true := by - native_decide - -example : - nestedDispatcherFuncDefRejectedByGeneratedNativeFragment = true := by - native_decide - -example : - nestedHelperFuncDefRejectedByGeneratedNativeFragment = true := by - native_decide - -example : - nativeRuntimeFragmentGateRejectsDuplicateHelper = true := by - native_decide - -example : - nativeIRRuntimeFragmentGateRejectsDuplicateHelper = true := by - native_decide - -example : - helperFuncDefMovesToMapAndCallStaysUserCall = true := by - native_decide - -example : - Native.interpretIRRuntimeNative 128 dispatchSmokeContract sampleIRTx - sampleIRState [11] = - Native.interpretRuntimeNative 128 - (Compiler.emitYul dispatchSmokeContract).runtimeCode - (Compiler.Proofs.YulGeneration.YulTransaction.ofIR sampleIRTx) - sampleIRState.storage [11] sampleIRState.events := by - rfl - -example : - Native.interpretIRRuntimeNative 128 storageReadIRContract storageReadIRTx - sampleIRState [7, 8] = - Native.interpretRuntimeNative 128 - (Compiler.emitYul storageReadIRContract).runtimeCode - (Compiler.Proofs.YulGeneration.YulTransaction.ofIR storageReadIRTx) - sampleIRState.storage [7, 8] sampleIRState.events := by - rfl - -example : - Native.interpretIRRuntimeNative 128 storageReadIRContract storageReadIRTx - sampleIRState [8] = - Native.interpretRuntimeNative 128 - (Compiler.emitYul storageReadIRContract).runtimeCode - (Compiler.Proofs.YulGeneration.YulTransaction.ofIR storageReadIRTx) - sampleIRState.storage [8] sampleIRState.events := by - rfl - -example : - (match Native.interpretIRRuntimeNative 128 duplicateHelperIRContract - sampleIRTx sampleIRState [] with - | .ok _ => false - | .error _ => true) = true := by - native_decide - -example : - (match Native.interpretRuntimeNative 128 [] - sampleTx zeroStorage [] [[1, 2, 3]] with - | .ok result => result.success && result.events == [[1, 2, 3]] - | .error _ => false) = true := by - native_decide - -example : - (let result := - Native.projectResult sampleTx - (fun slot => if slot = 7 then 5 else 0) - [[1, 2, 3]] - (.error EvmYul.Yul.Exception.Revert) - !result.success && - result.finalStorage (IRStorageSlot.ofNat 7) == IRStorageWord.ofNat 5 && - result.events == [[1, 2, 3]]) = true := by - native_decide - -example : - (let result := - Native.projectResult sampleTx - (fun slot => if slot = 7 then 5 else 0) - [[1, 2, 3]] - (.error EvmYul.Yul.Exception.Revert) - result.finalMappings) = - (let result := - Native.projectResult sampleTx - (fun slot => if slot = 7 then 5 else 0) - [[1, 2, 3]] - (.error EvmYul.Yul.Exception.Revert) - Compiler.Proofs.storageAsMappings result.finalStorage) := by - rfl - -end Compiler.Proofs.YulGeneration.Backends diff --git a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean b/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean deleted file mode 100644 index 1be82e566..000000000 --- a/Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean +++ /dev/null @@ -1,1631 +0,0 @@ -/- - Phase 4: Retarget the theorem stack to EVMYulLean. - - This module proves that the legacy Verity builtin backend and the - `.evmYulLean` builtin backend are equivalent for programs that use only - bridged builtins. - - **Key transition theorem**: the file-local - `backends_agree_on_bridged_builtins` shows that - `evalBuiltinCallWithBackendContext .verity ... func args = - evalBuiltinCallWithBackendContext .evmYulLean ... func args` - for every `func ∈ bridgedBuiltins`. - - This module also proves file-local expression and recursive target lifts for - `BridgedExpr` and `BridgedTarget` executions. The Layer-3 runtime-code lift - remains parameterized by embedded-body `BridgedStmts` witnesses; - `EvmYulLeanBodyClosure.lean` and `EndToEnd.lean` discharge those witnesses for - the supported safe source-body fragment. - - **Trust boundary shift (pointwise)**: For any builtin call using a bridged - name, the trust boundary moves from "Verity's custom Yul builtin semantics - are correct" to "EVMYulLean's builtin semantics match the EVM" (backed by - upstream conformance tests). Whole-program guarantees are exposed through the - safe-body EndToEnd wrapper, with the external-call/function-table family left - as the explicit carve-out. - - Run: lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget --/ - -import Compiler.Codegen -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgePredicates -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanPureBuiltinLemmas - -namespace Compiler.Proofs.YulGeneration.Backends - -open Compiler.Proofs.YulGeneration -open Compiler.Proofs.IRGeneration - -/-! ## Per-builtin backend equivalence helpers - -Each helper proves that `evalBuiltinCallWithBackendContext .verity` and -`.evmYulLean` agree for a single concrete builtin name with arbitrary `argVals`. -The proof strategy: -1. Unfold the backend dispatch via `simp only [evalBuiltinCallWithBackendContext]` -2. Case-split `argVals` by arity -3. Right arity: apply the context-lifted bridge lemma from `EvmYulLeanBridgeLemmas` -4. Wrong arity: both sides are definitionally equal (`rfl`) - -This avoids unfolding the expensive `legacyEvalBuiltinCallWithContext` if-chain. -/ - --- Binary builtins: argVals matches [a, b] -private theorem backends_agree_add s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "add" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "add" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_add_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_sub s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "sub" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "sub" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_sub_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_mul s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "mul" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "mul" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_mul_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_div s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "div" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "div" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_div_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_mod s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "mod" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "mod" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_mod_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_lt s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "lt" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "lt" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_lt_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_gt s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "gt" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "gt" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_gt_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_eq s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "eq" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "eq" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_eq_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - --- Unary builtin: iszero -private theorem backends_agree_iszero s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "iszero" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "iszero" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a] => exact (evalBuiltinCallWithBackendContext_evmYulLean_iszero_bridge s se mv ta bt bn ci bb sl cd a).symm - | [] => rfl | _ :: _ :: _ => rfl - -private theorem backends_agree_and s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "and" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "and" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_and_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_or s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "or" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "or" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_or_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_xor s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "xor" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "xor" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_xor_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - --- Unary builtin: not -private theorem backends_agree_not s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "not" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "not" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a] => exact (evalBuiltinCallWithBackendContext_evmYulLean_not_bridge s se mv ta bt bn ci bb sl cd a).symm - | [] => rfl | _ :: _ :: _ => rfl - -private theorem backends_agree_shl s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "shl" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "shl" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_shl_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_shr s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "shr" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "shr" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_shr_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - --- Ternary builtins: addmod, mulmod -private theorem backends_agree_addmod s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "addmod" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "addmod" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b, n] => exact (evalBuiltinCallWithBackendContext_evmYulLean_addmod_bridge s se mv ta bt bn ci bb sl cd a b n).symm - | [] => rfl | [_] => rfl | [_, _] => rfl | _ :: _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_mulmod s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "mulmod" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "mulmod" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b, n] => exact (evalBuiltinCallWithBackendContext_evmYulLean_mulmod_bridge s se mv ta bt bn ci bb sl cd a b n).symm - | [] => rfl | [_] => rfl | [_, _] => rfl | _ :: _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_byte s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "byte" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "byte" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_byte_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_slt s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "slt" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "slt" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_slt_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_sgt s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "sgt" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "sgt" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_sgt_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_exp s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "exp" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "exp" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_exp_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_sdiv s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "sdiv" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "sdiv" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_sdiv_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_smod s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "smod" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "smod" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_smod_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_sar s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "sar" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "sar" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_sar_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - -private theorem backends_agree_signextend s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "signextend" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "signextend" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [a, b] => exact (evalBuiltinCallWithBackendContext_evmYulLean_signextend_bridge s se mv ta bt bn ci bb sl cd a b).symm - | [] => rfl | [_] => rfl | _ :: _ :: _ :: _ => rfl - --- Nullary builtins: caller, address, callvalue, timestamp, number, chainid, blobbasefee, calldatasize -private theorem backends_agree_caller s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "caller" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "caller" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_caller_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_address s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "address" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "address" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_address_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_callvalue s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "callvalue" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "callvalue" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_callvalue_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_timestamp s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "timestamp" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "timestamp" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_timestamp_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_number s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "number" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "number" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_number_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_chainid s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "chainid" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "chainid" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_chainid_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - -private theorem backends_agree_blobbasefee s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "blobbasefee" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "blobbasefee" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_blobbasefee_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - --- Unary builtin: calldataload -private theorem backends_agree_calldataload s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "calldataload" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "calldataload" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [offset] => exact (evalBuiltinCallWithBackendContext_evmYulLean_calldataload_bridge s se mv ta bt bn ci bb sl cd offset).symm - | [] => rfl | _ :: _ :: _ => rfl - --- Nullary builtin: calldatasize -private theorem backends_agree_calldatasize s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "calldatasize" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "calldatasize" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [] => exact (evalBuiltinCallWithBackendContext_evmYulLean_calldatasize_bridge s se mv ta bt bn ci bb sl cd).symm - | _ :: _ => rfl - --- Unary builtin: sload (state-dependent, routed through the same --- `storage : IRStorageSlot → IRStorageWord` lookup used by Verity's `legacyEvalBuiltinCallWithContext`) -private theorem backends_agree_sload s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "sload" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "sload" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [slot] => exact (evalBuiltinCallWithBackendContext_evmYulLean_sload_bridge s se mv ta bt bn ci bb sl cd slot).symm - | [] => rfl - | _ :: _ :: _ => rfl - --- Binary builtin: mappingSlot (Verity-specific helper, routed through the --- shared keccak-faithful `abstractMappingSlot` derivation) -private theorem backends_agree_mappingSlot s se mv ta bt bn ci bb sl cd av : - evalBuiltinCallWithBackendContext .verity s se mv ta bt bn ci bb sl cd "mappingSlot" av = - evalBuiltinCallWithBackendContext .evmYulLean s se mv ta bt bn ci bb sl cd "mappingSlot" av := by - simp only [evalBuiltinCallWithBackendContext] - match av with - | [base, key] => exact (evalBuiltinCallWithBackendContext_evmYulLean_mappingSlot_bridge s se mv ta bt bn ci bb sl cd base key).symm - | [] => rfl - | [_] => rfl - | _ :: _ :: _ :: _ => rfl - -/-! ## Backend Equivalence for Bridged Builtins - -The `.evmYulLean` and `.verity` backends agree on all 36 bridged builtins. -This is the pointwise equivalence theorem that Phase 4 retargeting relies on. -All bridged builtin dependencies are fully proven in `EvmYulLeanBridgeLemmas.lean`. --/ - -/-- For any builtin in `bridgedBuiltins`, the `.verity` and `.evmYulLean` backends - produce identical results under `evalBuiltinCallWithBackendContext`. - - This is the master backend equivalence theorem for Phase 4 retargeting. - It composes the 36 per-builtin bridge theorems into a single dispatch proof. - Every builtin handled by `legacyEvalBuiltinCallWithContext` is now bridged, so - `unbridgedBuiltins` is empty. - - This theorem is sorry-free, composing the fully proven per-builtin bridge - lemmas in `EvmYulLeanBridgeLemmas.lean`. -/ -private theorem backends_agree_on_bridged_builtins - (storage : IRStorageSlot → IRStorageWord) (sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector : Nat) - (calldata : List Nat) - (func : String) (argVals : List Nat) - (hBridged : func ∈ bridgedBuiltins) : - evalBuiltinCallWithBackendContext .verity storage sender msgValue thisAddress - blockTimestamp blockNumber chainId blobBaseFee selector calldata func argVals = - evalBuiltinCallWithBackendContext .evmYulLean storage sender msgValue thisAddress - blockTimestamp blockNumber chainId blobBaseFee selector calldata func argVals := by - simp only [bridgedBuiltins, List.mem_cons, List.mem_nil_iff, or_false] at hBridged - rcases hBridged with rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | - rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | - rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl | - rfl | rfl | rfl | rfl | rfl | rfl - -- 36 goals, one per bridged builtin. Dispatch to per-builtin helpers. - · exact backends_agree_add storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_sub storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_mul storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_div storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_mod storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_lt storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_gt storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_eq storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_iszero storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_and storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_or storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_xor storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_not storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_shl storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_shr storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_addmod storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_mulmod storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_byte storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_slt storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_sgt storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_exp storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_sdiv storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_smod storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_sar storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_signextend storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_caller storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_address storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_callvalue storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_timestamp storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_number storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_chainid storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_blobbasefee storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_calldataload storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_calldatasize storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_sload storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - · exact backends_agree_mappingSlot storage sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector calldata argVals - -/-! ## Expression-level backend equivalence - -The pointwise builtin theorem lifts through Yul expressions whose call nodes use -only bridged builtin names, plus the backend-independent `tload`/`mload` -special cases handled directly by the Verity Yul expression evaluator. --/ - -set_option maxHeartbeats 1000000 in -/-- `keccak256` is not handled by Verity's `legacyEvalBuiltinCallWithContext` (it - falls through the 35-case if-else chain to the final `else none`) and is - not handled by the EVMYulLean adapter (`evalBuiltinCallViaEvmYulLean` and - `evalPureBuiltinViaEvmYulLean` both default to `none` for unknown funcs). - Both backends therefore agree trivially by returning `none`. This makes - `keccak256` a safe "bridged by absence" expression name: the Yul - interpreter cannot compute a hash under either backend, and any Yul - program that evaluates `keccak256(...)` through this interpreter halts - identically on both sides. -/ -private theorem backends_agree_on_keccak256 - (storage : IRStorageSlot → IRStorageWord) - (sender msgValue thisAddress blockTimestamp blockNumber chainId blobBaseFee selector : Nat) - (calldata : List Nat) (argVals : List Nat) : - evalBuiltinCallWithBackendContext .verity storage sender msgValue thisAddress - blockTimestamp blockNumber chainId blobBaseFee selector calldata "keccak256" argVals = - evalBuiltinCallWithBackendContext .evmYulLean storage sender msgValue thisAddress - blockTimestamp blockNumber chainId blobBaseFee selector calldata "keccak256" argVals := by - -- Both sides reduce definitionally to `none` via their respective long - -- if-else chains on `func`. Using `rfl` with bumped heartbeats is the - -- simplest path; targeted simp at every level would be longer and no faster. - rfl - -mutual - -private def evalYulExprsWithBackend (backend : BuiltinBackend) (state : YulState) : - List Compiler.Yul.YulExpr → Option (List Nat) - | [] => some [] - | e :: es => do - let v ← evalYulExprWithBackend backend state e - let vs ← evalYulExprsWithBackend backend state es - pure (v :: vs) -termination_by es => exprsSize es -decreasing_by - all_goals - simp [exprsSize] - omega - -private def evalYulCallWithBackend (backend : BuiltinBackend) (state : YulState) - (func : String) : List Compiler.Yul.YulExpr → Option Nat - | args => do - let argVals ← evalYulExprsWithBackend backend state args - if func = "tload" then - match argVals with - | [slot] => some (state.transientStorage (slot % Compiler.Constants.evmModulus)) - | _ => none - else if func = "mload" then - match argVals with - | [offset] => some (state.memory offset) - | _ => none - else if func = "keccak256" then - match argVals with - | [offset, size] => some (abstractKeccakMemorySlice state.memory offset size) - | _ => none - else - evalBuiltinCallWithBackendContext backend - state.storage state.sender state.msgValue state.thisAddress state.blockTimestamp - state.blockNumber state.chainId state.blobBaseFee state.selector state.calldata func argVals -termination_by args => exprsSize args + 1 -decreasing_by - omega - -private def evalYulExprWithBackend (backend : BuiltinBackend) (state : YulState) : - Compiler.Yul.YulExpr → Option Nat - | .lit n => some n - | .hex n => some n - | .str _ => none - | .ident name => state.getVar name - | .call func args => evalYulCallWithBackend backend state func args -termination_by e => exprSize e -decreasing_by - simp [exprSize] - -end - -mutual - -private theorem evalYulExprWithBackend_evmYulLean_eq - (state : YulState) (expr : Compiler.Yul.YulExpr) : - evalYulExprWithBackend .evmYulLean state expr = evalYulExpr state expr := by - cases expr with - | lit _ => simp [evalYulExprWithBackend, evalYulExpr] - | hex _ => simp [evalYulExprWithBackend, evalYulExpr] - | str _ => simp [evalYulExprWithBackend, evalYulExpr] - | ident _ => simp [evalYulExprWithBackend, evalYulExpr] - | call func args => - simp only [evalYulExprWithBackend, evalYulExpr, evalYulCallWithBackend, evalYulCall] - rw [evalYulExprsWithBackend_evmYulLean_eq state args] - rfl - -private theorem evalYulExprsWithBackend_evmYulLean_eq - (state : YulState) (args : List Compiler.Yul.YulExpr) : - evalYulExprsWithBackend .evmYulLean state args = evalYulExprs state args := by - cases args with - | nil => simp [evalYulExprsWithBackend, evalYulExprs] - | cons arg rest => - simp only [evalYulExprsWithBackend, evalYulExprs] - rw [evalYulExprWithBackend_evmYulLean_eq state arg, - evalYulExprsWithBackend_evmYulLean_eq state rest] - -end - -mutual - -private theorem evalYulExprWithBackend_eq_on_bridged - (state : YulState) (expr : Compiler.Yul.YulExpr) (hExpr : BridgedExpr expr) : - evalYulExprWithBackend .verity state expr = - evalYulExprWithBackend .evmYulLean state expr := by - cases hExpr with - | lit _ => simp [evalYulExprWithBackend] - | hex _ => simp [evalYulExprWithBackend] - | str _ => simp [evalYulExprWithBackend] - | ident _ => simp [evalYulExprWithBackend] - | call func args hName hArgs => - simp only [evalYulExprWithBackend, evalYulCallWithBackend] - rw [evalYulExprsWithBackend_eq_on_bridged state args hArgs] - cases hEval : evalYulExprsWithBackend .evmYulLean state args with - | none => rfl - | some argVals => - rcases hName with hBridged | rfl | rfl | rfl - · have hEq := backends_agree_on_bridged_builtins - state.storage state.sender state.msgValue state.thisAddress - state.blockTimestamp state.blockNumber state.chainId state.blobBaseFee - state.selector state.calldata func argVals hBridged - simp [hEq] - · simp - · simp - · -- func = "keccak256": both backends now have a direct keccak256 - -- branch that computes `abstractKeccakMemorySlice` identically. - rfl - -private theorem evalYulExprsWithBackend_eq_on_bridged - (state : YulState) (args : List Compiler.Yul.YulExpr) - (hArgs : ∀ arg ∈ args, BridgedExpr arg) : - evalYulExprsWithBackend .verity state args = - evalYulExprsWithBackend .evmYulLean state args := by - cases args with - | nil => - simp [evalYulExprsWithBackend] - | cons arg rest => - have hArg : BridgedExpr arg := hArgs arg (by simp) - have hRest : ∀ e ∈ rest, BridgedExpr e := by - intro e he - exact hArgs e (by simp [he]) - simp only [evalYulExprsWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state arg hArg, - evalYulExprsWithBackend_eq_on_bridged state rest hRest] - -end - -private theorem evalYulExpr_evmYulLean_eq_on_bridged - (state : YulState) (expr : Compiler.Yul.YulExpr) (_hExpr : BridgedExpr expr) : - evalYulExpr state expr = - evalYulExprWithBackend .evmYulLean state expr := by - exact (evalYulExprWithBackend_evmYulLean_eq state expr).symm - -/-! ## Statement-level backend-parameterized executor - -`execYulFuelWithBackend` mirrors `legacyExecYulFuel` from `Semantics.lean` but routes -each expression evaluation through `evalYulExprWithBackend backend`. The -statement and runtime-code theorems below bridge `.verity` and `.evmYulLean` -on targets satisfying the `Bridged*` predicates. Source-body closure and the -public safe-body EndToEnd wrapper live in `EvmYulLeanBodyClosure.lean` and -`Compiler.Proofs.EndToEnd`. --/ - -private def execYulFuelWithBackend (backend : BuiltinBackend) : - Nat → YulState → YulExecTarget → YulExecResult - | _, state, .stmts [] => .continue state - | _, state, .stmt (Compiler.Yul.YulStmt.funcDef _ _ _ _) => .continue state - | 0, state, _ => .revert state - | Nat.succ fuel, state, target => - match target with - | .stmt stmt => - match stmt with - | .comment _ => .continue state - | .let_ name value => - match evalYulExprWithBackend backend state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .letMany _ _ => .revert state - | .assign name value => - match evalYulExprWithBackend backend state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .leave => .continue state - | .expr e => - match e with - | .call "sstore" [slotExpr, valExpr] => - match slotExpr with - | .call "mappingSlot" [baseExpr, keyExpr] => - match evalYulExprWithBackend backend state baseExpr, - evalYulExprWithBackend backend state keyExpr, - evalYulExprWithBackend backend state valExpr with - | some baseSlot, some key, some val => - let updated := Compiler.Proofs.abstractStoreMappingEntry - state.storage baseSlot key val - .continue { state with storage := updated } - | _, _, _ => .revert state - | _ => - match evalYulExprWithBackend backend state slotExpr, - evalYulExprWithBackend backend state valExpr with - | some slot, some val => - let updated := Compiler.Proofs.abstractStoreStorageOrMapping - state.storage slot val - .continue { state with storage := updated } - | _, _ => .revert state - | .call "mstore" [offsetExpr, valExpr] => - match evalYulExprWithBackend backend state offsetExpr, - evalYulExprWithBackend backend state valExpr with - | some offset, some val => - .continue { state with - memory := fun o => if o = offset then val else state.memory o } - | _, _ => .revert state - | .call "tstore" [offsetExpr, valExpr] => - match evalYulExprWithBackend backend state offsetExpr, - evalYulExprWithBackend backend state valExpr with - | some offset, some val => - .continue { state with - transientStorage := fun o => - if o = offset then val else state.transientStorage o } - | _, _ => .revert state - | .call "stop" [] => .stop state - | .call "return" [offsetExpr, sizeExpr] => - match evalYulExprWithBackend backend state offsetExpr, - evalYulExprWithBackend backend state sizeExpr with - | some offset, some size => - if size = 32 then - .return (state.memory offset) state - else - .return 0 state - | _, _ => .revert state - | .call "revert" [_, _] => .revert state - | .call func args => - if isYulLogName func then - match evalYulExprsWithBackend backend state args with - | some argVals => - match applyYulLogCall? state func argVals with - | some next => .continue next - | none => .revert state - | none => .revert state - else - match evalYulExprWithBackend backend state e with - | some _ => .continue state - | none => .revert state - | _ => - match evalYulExprWithBackend backend state e with - | some _ => .continue state - | none => .revert state - | .if_ cond body => - match evalYulExprWithBackend backend state cond with - | some v => - if v = 0 then - .continue state - else - execYulFuelWithBackend backend fuel state (.stmts body) - | none => .revert state - | .switch expr cases defaultCase => - match evalYulExprWithBackend backend state expr with - | some v => - match cases.find? (fun x => decide (x.fst = v)) with - | some (_, body) => - execYulFuelWithBackend backend fuel state (.stmts body) - | none => - match defaultCase with - | some body => - execYulFuelWithBackend backend fuel state (.stmts body) - | none => .continue state - | none => .revert state - | .for_ init cond post body => - match execYulFuelWithBackend backend fuel state (.stmts init) with - | .continue s' => - match evalYulExprWithBackend backend s' cond with - | some v => - if v = 0 then .continue s' - else - match execYulFuelWithBackend backend fuel s' (.stmts body) with - | .continue s'' => - match execYulFuelWithBackend backend fuel s'' (.stmts post) with - | .continue s''' => - execYulFuelWithBackend backend fuel s''' - (.stmt (.for_ [] cond post body)) - | other => other - | other => other - | none => .revert s' - | other => other - | .block stmts => - execYulFuelWithBackend backend fuel state (.stmts stmts) - | .funcDef _ _ _ _ => .continue state - | .stmts [] => .continue state - | .stmts (stmt :: rest) => - match execYulFuelWithBackend backend fuel state (.stmt stmt) with - | .continue s' => execYulFuelWithBackend backend fuel s' (.stmts rest) - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s - -/-- The backend-parameterized executor recovers `legacyExecYulFuel` at the `.verity` - backend. Statement-level analogue of `evalYulExprWithBackend_verity_eq` — - this is the correctness obligation that justifies replacing every - `legacyExecYulFuel` call in upstream theorems with - `execYulFuelWithBackend .verity`. -/ -private theorem execYulFuelWithBackend_evmYulLean_eq - (fuel : Nat) (state : YulState) (target : YulExecTarget) : - execYulFuelWithBackend .evmYulLean fuel state target = - legacyExecYulFuel fuel state target := by - induction fuel generalizing state target with - | zero => - cases target with - | stmt s => cases s <;> rfl - | stmts ss => cases ss <;> rfl - | succ fuel ih => - cases target with - | stmt s => - cases s <;> ( - try rfl - all_goals ( - simp only [execYulFuelWithBackend, legacyExecYulFuel, - evalYulExprWithBackend_evmYulLean_eq, - evalYulExprsWithBackend_evmYulLean_eq, ih] - try rfl)) - | stmts ss => - cases ss <;> ( - try rfl - all_goals ( - simp only [execYulFuelWithBackend, legacyExecYulFuel, ih] - try rfl)) - -/-! ## Statement-level backend equivalence: value-binding helpers - -The following pair of theorems establish the first statement-level bridges -between `.verity` and `.evmYulLean` backends. They cover the `.let_` and -`.assign` Yul statement forms when their right-hand-side expression is a -`BridgedExpr`. Both proofs reduce by unfolding the executor one step then -rewriting through `evalYulExprWithBackend_eq_on_bridged`. - -These are intentionally narrow helpers. A future statement-level predicate -(covering `.block`, sstore/mstore/tstore, and control flow) can dispatch to -them rather than re-deriving the expression rewrite each time. --/ - -private theorem execYulFuelWithBackend_let_eq_on_bridged - (fuel : Nat) (state : YulState) (name : String) - (value : Compiler.Yul.YulExpr) (hValue : BridgedExpr value) : - execYulFuelWithBackend .verity fuel state (.stmt (.let_ name value)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.let_ name value)) := by - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state value hValue] - -private theorem execYulFuelWithBackend_assign_eq_on_bridged - (fuel : Nat) (state : YulState) (name : String) - (value : Compiler.Yul.YulExpr) (hValue : BridgedExpr value) : - execYulFuelWithBackend .verity fuel state (.stmt (.assign name value)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.assign name value)) := by - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state value hValue] - -/-! ## Straight-line statement backend equivalence - -This predicate captures the non-branching statement fragment whose backend -dependence is solely through expression evaluation. It is the first -statement-level lift of `evalYulExprWithBackend_eq_on_bridged`; structured -control flow (`switch`, `for`, recursive `block`) still needs a separate -fuel/AST induction. --/ - -private theorem execYulFuelWithBackend_eq_on_bridged_straight_stmt - (fuel : Nat) (state : YulState) (stmt : Compiler.Yul.YulStmt) - (hStmt : BridgedStraightStmt stmt) : - execYulFuelWithBackend .verity fuel state (.stmt stmt) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt stmt) := by - cases hStmt with - | comment _ => cases fuel <;> rfl - | let_ name value hValue => - exact execYulFuelWithBackend_let_eq_on_bridged fuel state name value hValue - | letMany _ _ => cases fuel <;> rfl - | assign name value hValue => - exact execYulFuelWithBackend_assign_eq_on_bridged fuel state name value hValue - | «leave» => cases fuel <;> rfl - | expr_sstore_mapping baseExpr keyExpr valExpr hBase hKey hVal => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state baseExpr hBase, - evalYulExprWithBackend_eq_on_bridged state keyExpr hKey, - evalYulExprWithBackend_eq_on_bridged state valExpr hVal] - | expr_sstore_lit slot valExpr hVal => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state (.lit slot) (BridgedExpr.lit slot), - evalYulExprWithBackend_eq_on_bridged state valExpr hVal] - | expr_sstore_ident slotName valExpr hVal => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state (.ident slotName) - (BridgedExpr.ident slotName), - evalYulExprWithBackend_eq_on_bridged state valExpr hVal] - | expr_sstore_add leftExpr rightExpr valExpr hLeft hRight hVal => - cases fuel with - | zero => rfl - | succ fuel => - have hAdd : BridgedExpr - (Compiler.Yul.YulExpr.call "add" [leftExpr, rightExpr]) := by - refine BridgedExpr.call "add" [leftExpr, rightExpr] - (Or.inl ?_) ?_ - · simp [bridgedBuiltins] - · intro arg hMem - rcases List.mem_cons.mp hMem with rfl | hMem - · exact hLeft - · rcases List.mem_cons.mp hMem with rfl | hMem - · exact hRight - · cases hMem - have hAddEval := evalYulExprWithBackend_eq_on_bridged state - (Compiler.Yul.YulExpr.call "add" [leftExpr, rightExpr]) hAdd - have hValEval := evalYulExprWithBackend_eq_on_bridged state valExpr hVal - -- The slot `.call "add" [...]` is not a `.call "mappingSlot" [...]` - -- so the inner slot match takes the generic `_` branch. `simp` - -- reduces the string-literal pattern mismatch via iota; the two - -- backend evals are unified via `hAddEval` / `hValEval`. - simp [execYulFuelWithBackend, hAddEval, hValEval] - | expr_mstore offsetExpr valExpr hOffset hVal => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state offsetExpr hOffset, - evalYulExprWithBackend_eq_on_bridged state valExpr hVal] - | expr_tstore offsetExpr valExpr hOffset hVal => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state offsetExpr hOffset, - evalYulExprWithBackend_eq_on_bridged state valExpr hVal] - | expr_stop => cases fuel <;> rfl - | expr_return offsetExpr sizeExpr hOffset hSize => - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state offsetExpr hOffset, - evalYulExprWithBackend_eq_on_bridged state sizeExpr hSize] - | expr_revert _ _ => cases fuel <;> rfl - | expr_log func args hLog hArgs => - cases fuel with - | zero => rfl - | succ fuel => - -- Enumerate the five log names so the specific-string cases - -- (`sstore`, `mstore`, `tstore`, `stop`, `return`, `revert`) drop - -- out and the match reduces into the generic `.call func args` - -- branch where both backends share `applyYulLogCall?`. Each backend - -- differs only in `evalYulExprWithBackend` / `evalYulExprsWithBackend` - -- on the bridged argument list, so rewriting the verity side to the - -- evmYulLean side makes both sides syntactically identical. - have hFunc : func = "log0" ∨ func = "log1" ∨ func = "log2" ∨ - func = "log3" ∨ func = "log4" := by - simp [isYulLogName] at hLog - tauto - have hEval := evalYulExprsWithBackend_eq_on_bridged state args hArgs - rcases hFunc with rfl | rfl | rfl | rfl | rfl <;> - simp [execYulFuelWithBackend, isYulLogName, hEval] - | funcDef _ _ _ _ => cases fuel <;> rfl - -private theorem execYulFuelWithBackend_eq_on_bridged_straight_stmts - (fuel : Nat) (state : YulState) (stmts : List Compiler.Yul.YulStmt) - (hStmts : BridgedStraightStmts stmts) : - execYulFuelWithBackend .verity fuel state (.stmts stmts) = - execYulFuelWithBackend .evmYulLean fuel state (.stmts stmts) := by - induction fuel generalizing state stmts with - | zero => - cases stmts <;> rfl - | succ fuel ih => - cases stmts with - | nil => rfl - | cons stmt rest => - have hStmt : BridgedStraightStmt stmt := hStmts stmt (by simp) - have hRest : BridgedStraightStmts rest := by - intro s hs - exact hStmts s (by simp [hs]) - simp only [execYulFuelWithBackend] - rw [execYulFuelWithBackend_eq_on_bridged_straight_stmt fuel state stmt hStmt] - cases hExec : execYulFuelWithBackend .evmYulLean fuel state (.stmt stmt) with - | «continue» s' => - simp only - exact ih s' rest hRest - | «return» v s => rfl - | «stop» s => rfl - | «revert» s => rfl - -/-- A `.block` wrapper around a straight-line statement list preserves the - backend equivalence established for `BridgedStraightStmts`. This discharges - the block constructor when the block body is already in the straight-line - fragment; recursive blocks and branching control flow still require the - broader statement predicate/induction. -/ -private theorem execYulFuelWithBackend_block_eq_on_bridged_straight_stmts - (fuel : Nat) (state : YulState) (stmts : List Compiler.Yul.YulStmt) - (hStmts : BridgedStraightStmts stmts) : - execYulFuelWithBackend .verity fuel state (.stmt (.block stmts)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.block stmts)) := by - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - exact execYulFuelWithBackend_eq_on_bridged_straight_stmts fuel state stmts hStmts - -/-- An `.if_` with a bridged condition and a straight-line body preserves - backend equivalence. The condition is evaluated via `BridgedExpr`; when the - condition evaluates to a nonzero value the body is executed at one less - fuel, which we discharge via `execYulFuelWithBackend_eq_on_bridged_straight_stmts`. - First narrow-helper lift into branching control flow; `.switch` and `.for_` - still require their own helpers, and recursive control-flow bodies still - require a broader predicate/induction. -/ -private theorem execYulFuelWithBackend_if_eq_on_bridged_body - (fuel : Nat) (state : YulState) (cond : Compiler.Yul.YulExpr) - (body : List Compiler.Yul.YulStmt) - (hCond : BridgedExpr cond) (hBody : BridgedStraightStmts body) : - execYulFuelWithBackend .verity fuel state (.stmt (.if_ cond body)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.if_ cond body)) := by - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state cond hCond] - cases evalYulExprWithBackend .evmYulLean state cond with - | none => rfl - | some v => - by_cases hv : v = 0 - · simp [hv] - · simp [hv] - exact execYulFuelWithBackend_eq_on_bridged_straight_stmts fuel state body hBody - -/-- A `.switch` with a bridged scrutinee and straight-line selected bodies - preserves backend equivalence. The predicate only needs to cover bodies that - can actually be selected by `find?`; the default branch is handled - separately. Recursive switch bodies and loops still need the broader - statement predicate/induction. -/ -private theorem execYulFuelWithBackend_switch_eq_on_bridged_cases - (fuel : Nat) (state : YulState) (expr : Compiler.Yul.YulExpr) - (cases : List (Nat × List Compiler.Yul.YulStmt)) - (defaultCase : Option (List Compiler.Yul.YulStmt)) - (hExpr : BridgedExpr expr) (hCases : BridgedSwitchCases cases) - (hDefault : ∀ body, defaultCase = some body → BridgedStraightStmts body) : - execYulFuelWithBackend .verity fuel state (.stmt (.switch expr cases defaultCase)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.switch expr cases defaultCase)) := by - cases fuel with - | zero => rfl - | succ fuel => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state expr hExpr] - cases evalYulExprWithBackend .evmYulLean state expr with - | none => rfl - | some v => - cases hFind : cases.find? (fun x => decide (x.fst = v)) with - | some hit => - cases hit with - | mk value body => - simp [hFind] - exact execYulFuelWithBackend_eq_on_bridged_straight_stmts - fuel state body (hCases v value body hFind) - | none => - cases hDefaultCase : defaultCase with - | none => - simp [hFind] - | some body => - simp [hFind] - exact execYulFuelWithBackend_eq_on_bridged_straight_stmts - fuel state body (hDefault body hDefaultCase) - -/-- A `.for_` with bridged straight-line init/body/post lists and a bridged - condition preserves backend equivalence. The recursive loop call is made at - the predecessor fuel with an empty initializer, so the proof follows the - executor's fuel structure directly. Recursive control-flow inside the loop - lists still needs the broader statement predicate/induction. -/ -private theorem execYulFuelWithBackend_for_eq_on_bridged_parts - (fuel : Nat) (state : YulState) - (init : List Compiler.Yul.YulStmt) (cond : Compiler.Yul.YulExpr) - (post body : List Compiler.Yul.YulStmt) - (hInit : BridgedStraightStmts init) (hCond : BridgedExpr cond) - (hPost : BridgedStraightStmts post) (hBody : BridgedStraightStmts body) : - execYulFuelWithBackend .verity fuel state (.stmt (.for_ init cond post body)) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt (.for_ init cond post body)) := by - induction fuel generalizing state init with - | zero => rfl - | succ fuel ih => - simp only [execYulFuelWithBackend] - rw [execYulFuelWithBackend_eq_on_bridged_straight_stmts fuel state init hInit] - cases execYulFuelWithBackend .evmYulLean fuel state (.stmts init) with - | «continue» s' => - simp only - rw [evalYulExprWithBackend_eq_on_bridged s' cond hCond] - cases evalYulExprWithBackend .evmYulLean s' cond with - | none => rfl - | some v => - by_cases hv : v = 0 - · simp [hv] - · simp [hv] - rw [execYulFuelWithBackend_eq_on_bridged_straight_stmts fuel s' body hBody] - cases execYulFuelWithBackend .evmYulLean fuel s' (.stmts body) with - | «continue» s'' => - simp only - rw [execYulFuelWithBackend_eq_on_bridged_straight_stmts fuel s'' post hPost] - cases execYulFuelWithBackend .evmYulLean fuel s'' (.stmts post) with - | «continue» s''' => - simp only - exact ih s''' [] (by intro stmt hMem; cases hMem) - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - -/-! ## Recursive statement backend equivalence - -`BridgedStmt` lifts the earlier straight-line/control-flow helpers to recursive -Yul statement structure. It is still an explicit fragment predicate: every -expression dependency must satisfy `BridgedExpr`, and every nested statement -list must recursively satisfy `BridgedStmt`. --/ - -private inductive BridgedTarget : YulExecTarget → Prop - | stmt (stmt : Compiler.Yul.YulStmt) (hStmt : BridgedStmt stmt) : - BridgedTarget (.stmt stmt) - | stmts (stmts : List Compiler.Yul.YulStmt) (hStmts : BridgedStmts stmts) : - BridgedTarget (.stmts stmts) - -/-! ## Generated-code closure under the recursive statement predicate - -The recursive executor theorem above is useful for Layer 3 only once generated -runtime wrappers are known to satisfy `BridgedStmt`. These lemmas prove that -the compiler-emitted dispatch shell (`callvalue`/`calldatasize` guards, -selector switch, fallback/receive wrapper, optional mapping helper) is bridged -whenever the IR function and entrypoint bodies it contains are bridged. --/ - -private theorem bridgedExpr_callvalue : - BridgedExpr (Compiler.Yul.YulExpr.call "callvalue" []) := by - exact BridgedExpr.call "callvalue" [] (Or.inl (by simp [bridgedBuiltins])) - (by intro arg hMem; cases hMem) - -private theorem bridgedExpr_calldatasize : - BridgedExpr (Compiler.Yul.YulExpr.call "calldatasize" []) := by - exact BridgedExpr.call "calldatasize" [] (Or.inl (by simp [bridgedBuiltins])) - (by intro arg hMem; cases hMem) - -private theorem bridgedExpr_selector : - BridgedExpr - (Compiler.Yul.YulExpr.call "shr" - [Compiler.Yul.YulExpr.lit Compiler.Constants.selectorShift, - Compiler.Yul.YulExpr.call "calldataload" [Compiler.Yul.YulExpr.lit 0]]) := by - refine BridgedExpr.call "shr" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro arg hMem - simp only [List.mem_cons, List.mem_nil_iff, or_false] at hMem - rcases hMem with rfl | rfl - · exact BridgedExpr.lit Compiler.Constants.selectorShift - · refine BridgedExpr.call "calldataload" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro nested hNested - simp only [List.mem_singleton] at hNested - subst hNested - exact BridgedExpr.lit 0 - -/-- The generated dispatcher selector expression is in the bridged expression -fragment, so the EVMYulLean fuel wrapper evaluates it exactly like -the historical Verity interpreter. -/ -private theorem bridgedExpr_selectorExpr : - BridgedExpr Compiler.Proofs.YulGeneration.selectorExpr := by - simpa [Compiler.Proofs.YulGeneration.selectorExpr] using bridgedExpr_selector - -set_option maxHeartbeats 1000000 in -@[simp] private theorem evalYulExpr_selectorExpr_semantics : - ∀ state : YulState, - evalYulExpr state Compiler.Proofs.YulGeneration.selectorExpr = - some (state.selector % selectorModulus) := by - intro state - have hShiftModEq : selectorShift % evmModulus = selectorShift := by - have hShiftLtModulus : selectorShift < evmModulus := by - norm_num [selectorShift, evmModulus] - exact Nat.mod_eq_of_lt hShiftLtModulus - have hSelectorShiftLt256 : selectorShift < 256 := by - norm_num [selectorShift] - have hSelectorShiftNotGe256 : ¬ 256 ≤ selectorShift := Nat.not_le_of_lt hSelectorShiftLt256 - have hSelectorWordLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < evmModulus := by - have hModLt : state.selector % selectorModulus < selectorModulus := by - exact Nat.mod_lt _ (by decide) - have hPowPos : 0 < 2 ^ selectorShift := by - exact Nat.pow_pos (a := 2) (n := selectorShift) (by decide) - have hMulLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < - selectorModulus * 2 ^ selectorShift := by - exact Nat.mul_lt_mul_of_pos_right hModLt hPowPos - have hModulusSplit : selectorModulus * 2 ^ selectorShift = evmModulus := by - norm_num [selectorModulus, selectorShift, evmModulus, Nat.pow_add, Nat.mul_comm, - Nat.mul_left_comm, Nat.mul_assoc] - simpa [hModulusSplit] using hMulLt - have hSelectorWordMod : - ((state.selector % selectorModulus) * 2 ^ selectorShift) % evmModulus = - (state.selector % selectorModulus) * 2 ^ selectorShift := by - exact Nat.mod_eq_of_lt hSelectorWordLt - simp [Compiler.Proofs.YulGeneration.selectorExpr, evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext, - Backends.evalBuiltinCallViaEvmYulLean, - calldataloadWord, selectorWord, - hShiftModEq, hSelectorWordMod, hSelectorShiftNotGe256] - -/-- The EVMYulLean fuel wrapper selects the same 4-byte dispatcher -selector as the generated Verity selector expression. - -This is the first generated-dispatcher semantic slice needed by the native -migration: every native/EVMYulLean dispatcher simulation branches on this -expression before it reaches storage, memory, or halt behavior. -/ -@[simp] private theorem evalYulExprWithBackend_evmYulLean_selectorExpr_semantics - (state : YulState) : - evalYulExprWithBackend .evmYulLean state - Compiler.Proofs.YulGeneration.selectorExpr = - some (state.selector % selectorModulus) := by - rw [← evalYulExpr_evmYulLean_eq_on_bridged state - Compiler.Proofs.YulGeneration.selectorExpr bridgedExpr_selectorExpr] - exact evalYulExpr_selectorExpr_semantics state - -private theorem bridgedExpr_calldatasize_lt (n : Nat) : - BridgedExpr - (Compiler.Yul.YulExpr.call "lt" - [Compiler.Yul.YulExpr.call "calldatasize" [], Compiler.Yul.YulExpr.lit n]) := by - refine BridgedExpr.call "lt" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro arg hMem - simp only [List.mem_cons, List.mem_nil_iff, or_false] at hMem - rcases hMem with rfl | rfl - · exact bridgedExpr_calldatasize - · exact BridgedExpr.lit n - -private theorem bridgedExpr_has_selector : - BridgedExpr - (Compiler.Yul.YulExpr.call "iszero" - [Compiler.Yul.YulExpr.call "lt" - [Compiler.Yul.YulExpr.call "calldatasize" [], Compiler.Yul.YulExpr.lit 4]]) := by - refine BridgedExpr.call "iszero" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro arg hMem - simp only [List.mem_singleton] at hMem - subst hMem - exact bridgedExpr_calldatasize_lt 4 - -private theorem bridgedExpr_empty_calldata : - BridgedExpr - (Compiler.Yul.YulExpr.call "eq" - [Compiler.Yul.YulExpr.call "calldatasize" [], Compiler.Yul.YulExpr.lit 0]) := by - refine BridgedExpr.call "eq" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro arg hMem - simp only [List.mem_cons, List.mem_nil_iff, or_false] at hMem - rcases hMem with rfl | rfl - · exact bridgedExpr_calldatasize - · exact BridgedExpr.lit 0 - -private theorem bridgedExpr_iszero_ident (name : String) : - BridgedExpr - (Compiler.Yul.YulExpr.call "iszero" [Compiler.Yul.YulExpr.ident name]) := by - refine BridgedExpr.call "iszero" _ (Or.inl (by simp [bridgedBuiltins])) ?_ - intro arg hMem - simp only [List.mem_singleton] at hMem - subst hMem - exact BridgedExpr.ident name - - -private theorem callvalueGuard_bridged : BridgedStmt Compiler.CodegenCommon.callvalueGuard := by - unfold Compiler.CodegenCommon.callvalueGuard - exact bridgedStmt_if_of_bridgedStmts bridgedExpr_callvalue - BridgedStmts_singleton_revert_zero - -private theorem calldatasizeGuard_bridged (numParams : Nat) : - BridgedStmt (Compiler.CodegenCommon.calldatasizeGuard numParams) := by - unfold Compiler.CodegenCommon.calldatasizeGuard - exact bridgedStmt_if_of_bridgedStmts (bridgedExpr_calldatasize_lt (4 + numParams * 32)) - BridgedStmts_singleton_revert_zero - -/-- Dispatch guards preserve bridgedness around an already-bridged entrypoint -body. -/ -theorem dispatchBody_bridged (payable : Bool) (label : String) - (body : List Compiler.Yul.YulStmt) (hBody : BridgedStmts body) : - BridgedStmts (Compiler.CodegenCommon.dispatchBody payable label body) := by - unfold Compiler.CodegenCommon.dispatchBody - cases payable <;> - simp only [Bool.false_eq_true, ite_false, ite_true, - List.singleton_append] - · exact BridgedStmts_cons_comment label - (BridgedStmts_cons callvalueGuard_bridged hBody) - · exact BridgedStmts_cons_comment label hBody - -/-- The generated default dispatch case is bridged whenever its optional -fallback and receive bodies are bridged. -/ -theorem defaultDispatchCase_bridged - (fallback receive : Option Compiler.IREntrypoint) - (hFallback : ∀ fb, fallback = some fb → BridgedStmts fb.body) - (hReceive : ∀ rc, receive = some rc → BridgedStmts rc.body) : - BridgedStmts (Compiler.CodegenCommon.defaultDispatchCase fallback receive) := by - cases receive with - | none => - cases fallback with - | none => - unfold Compiler.CodegenCommon.defaultDispatchCase - exact BridgedStmts_singleton_revert_zero - | some fb => - unfold Compiler.CodegenCommon.defaultDispatchCase - exact dispatchBody_bridged fb.payable "fallback()" fb.body - (hFallback fb rfl) - | some rc => - cases fallback with - | none => - unfold Compiler.CodegenCommon.defaultDispatchCase - refine BridgedStmts_singleton_block ?_ - exact BridgedStmts_cons_let "__is_empty_calldata" _ bridgedExpr_empty_calldata - (BridgedStmts_cons_if - (BridgedExpr.ident "__is_empty_calldata") - (dispatchBody_bridged rc.payable "receive()" rc.body - (hReceive rc rfl)) - (BridgedStmts_cons_if (bridgedExpr_iszero_ident "__is_empty_calldata") - BridgedStmts_singleton_revert_zero - BridgedStmts_nil)) - | some fb => - unfold Compiler.CodegenCommon.defaultDispatchCase - refine BridgedStmts_singleton_block ?_ - exact BridgedStmts_cons_let "__is_empty_calldata" _ bridgedExpr_empty_calldata - (BridgedStmts_cons_if - (BridgedExpr.ident "__is_empty_calldata") - (dispatchBody_bridged rc.payable "receive()" rc.body - (hReceive rc rfl)) - (BridgedStmts_cons_if (bridgedExpr_iszero_ident "__is_empty_calldata") - (dispatchBody_bridged fb.payable "fallback()" fb.body - (hFallback fb rfl)) - BridgedStmts_nil)) - -/-- Every lowered generated selector-switch case is bridged when every source -function body in the case list is bridged. -/ -theorem switchCases_bridged - (funcs : List Compiler.IRFunction) - (hFunctions : ∀ fn, fn ∈ funcs → BridgedStmts fn.body) : - ∀ scrutinee value body, - (funcs.map (fun fn => - (fn.selector, - Compiler.CodegenCommon.dispatchBody fn.payable s!"{fn.name}()" - ([Compiler.CodegenCommon.calldatasizeGuard fn.params.length] ++ fn.body)))).find? - (fun x => decide (x.fst = scrutinee)) = some (value, body) → - BridgedStmts body := by - intro scrutinee value body hFind - have hMem : - (value, body) ∈ funcs.map (fun fn => - (fn.selector, - Compiler.CodegenCommon.dispatchBody fn.payable s!"{fn.name}()" - ([Compiler.CodegenCommon.calldatasizeGuard fn.params.length] ++ fn.body))) := - List.mem_of_find?_eq_some hFind - rcases List.mem_map.mp hMem with ⟨fn, hFn, hEq⟩ - cases hEq - exact dispatchBody_bridged fn.payable s!"{fn.name}()" - ([Compiler.CodegenCommon.calldatasizeGuard fn.params.length] ++ fn.body) - (BridgedStmts_cons (calldatasizeGuard_bridged fn.params.length) - (hFunctions fn hFn)) - -/-- The generated runtime selector switch is bridged from bridged external -function, fallback, and receive bodies. -/ -theorem buildSwitch_bridged - (funcs : List Compiler.IRFunction) - (fallback receive : Option Compiler.IREntrypoint) - (hFunctions : ∀ fn, fn ∈ funcs → BridgedStmts fn.body) - (hFallback : ∀ fb, fallback = some fb → BridgedStmts fb.body) - (hReceive : ∀ rc, receive = some rc → BridgedStmts rc.body) : - BridgedStmt (Compiler.CodegenCommon.buildSwitch funcs fallback receive false) := by - unfold Compiler.CodegenCommon.buildSwitch - exact bridgedStmt_block_of_bridgedStmts - (BridgedStmts_cons_let "__has_selector" _ bridgedExpr_has_selector - (BridgedStmts_cons_if (bridgedExpr_iszero_ident "__has_selector") - (defaultDispatchCase_bridged fallback receive hFallback hReceive) - (BridgedStmts_cons_if - (BridgedExpr.ident "__has_selector") - (BridgedStmts_singleton_switch - bridgedExpr_selector - (switchCases_bridged funcs hFunctions) - (by - intro body hBody - cases hBody - exact defaultDispatchCase_bridged fallback receive hFallback hReceive)) - BridgedStmts_nil))) - -/-- The generated `mappingSlot` helper body is in the bridged fragment. -/ -theorem mappingSlotFuncAt_bridged (scratchBase : Nat) : - BridgedStmt (Compiler.CodegenCommon.mappingSlotFuncAt scratchBase) := by - unfold Compiler.CodegenCommon.mappingSlotFuncAt - exact bridgedStmt_funcDef "mappingSlot" ["baseSlot", "key"] ["slot"] _ - -/-- Generic bridge proof for all generated runtime code emitted from an -`IRContract`: mapping helper, internal helpers, dispatcher switch, and optional -fallback/receive bodies. -/ -theorem runtimeCode_bridged - (contract : Compiler.IRContract) - (hFunctions : ∀ fn, fn ∈ contract.functions → BridgedStmts fn.body) - (hFallback : ∀ fb, contract.fallbackEntrypoint = some fb → BridgedStmts fb.body) - (hReceive : ∀ rc, contract.receiveEntrypoint = some rc → BridgedStmts rc.body) - (hInternals : BridgedStmts contract.internalFunctions) : - BridgedStmts (Compiler.CodegenCommon.runtimeCode contract) := by - unfold Compiler.CodegenCommon.runtimeCode - cases contract.usesMapping - · exact BridgedStmts_snoc hInternals - (buildSwitch_bridged contract.functions contract.fallbackEntrypoint - contract.receiveEntrypoint hFunctions hFallback hReceive) - · simp only [ite_true] - exact BridgedStmts_cons (mappingSlotFuncAt_bridged 0) - (BridgedStmts_snoc hInternals - (buildSwitch_bridged contract.functions contract.fallbackEntrypoint - contract.receiveEntrypoint hFunctions hFallback hReceive)) - -/-- The runtime code emitted by `emitYul` is a bridged execution target whenever -all constituent function, helper, fallback, and receive bodies are bridged. -/ -theorem emitYul_runtimeCode_bridged - (contract : Compiler.IRContract) - (hFunctions : ∀ fn, fn ∈ contract.functions → BridgedStmts fn.body) - (hFallback : ∀ fb, contract.fallbackEntrypoint = some fb → BridgedStmts fb.body) - (hReceive : ∀ rc, contract.receiveEntrypoint = some rc → BridgedStmts rc.body) - (hInternals : BridgedStmts contract.internalFunctions) : - BridgedTarget (.stmts (Compiler.emitYul contract).runtimeCode) := by - exact BridgedTarget.stmts _ (by - simpa [Compiler.emitYul] using - runtimeCode_bridged contract hFunctions hFallback hReceive hInternals) - -private theorem execYulFuelWithBackend_eq_on_bridged_target - (fuel : Nat) (state : YulState) (target : YulExecTarget) - (hTarget : BridgedTarget target) : - execYulFuelWithBackend .verity fuel state target = - execYulFuelWithBackend .evmYulLean fuel state target := by - induction fuel generalizing state target with - | zero => - cases hTarget with - | stmt stmt hStmt => - cases hStmt with - | straight stmt hStraight => - exact execYulFuelWithBackend_eq_on_bridged_straight_stmt - 0 state stmt hStraight - | block _ _ => rfl - | if_ _ _ _ _ => rfl - | «switch» _ _ _ _ _ _ => rfl - | for_ _ _ _ _ _ _ _ _ => rfl - | stmts stmts hStmts => - cases stmts <;> rfl - | succ fuel ih => - cases hTarget with - | stmt stmt hStmt => - cases hStmt with - | straight stmt hStraight => - exact execYulFuelWithBackend_eq_on_bridged_straight_stmt - (Nat.succ fuel) state stmt hStraight - | block stmts hStmts => - simp only [execYulFuelWithBackend] - exact ih state (.stmts stmts) (.stmts stmts hStmts) - | if_ cond body hCond hBody => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state cond hCond] - cases evalYulExprWithBackend .evmYulLean state cond with - | none => rfl - | some v => - by_cases hv : v = 0 - · simp [hv] - · simp [hv] - exact ih state (.stmts body) (.stmts body hBody) - | «switch» expr cases defaultCase hExpr hCases hDefault => - simp only [execYulFuelWithBackend] - rw [evalYulExprWithBackend_eq_on_bridged state expr hExpr] - cases evalYulExprWithBackend .evmYulLean state expr with - | none => rfl - | some v => - cases hFind : cases.find? (fun x => decide (x.fst = v)) with - | some hit => - cases hit with - | mk value body => - simp [hFind] - exact ih state (.stmts body) - (.stmts body (hCases v value body hFind)) - | none => - cases hDefaultCase : defaultCase with - | none => - simp [hFind] - | some body => - simp [hFind] - exact ih state (.stmts body) - (.stmts body (hDefault body hDefaultCase)) - | for_ init cond post body hInit hCond hPost hBody => - simp only [execYulFuelWithBackend] - rw [ih state (.stmts init) (.stmts init hInit)] - cases execYulFuelWithBackend .evmYulLean fuel state (.stmts init) with - | «continue» s' => - simp only - rw [evalYulExprWithBackend_eq_on_bridged s' cond hCond] - cases evalYulExprWithBackend .evmYulLean s' cond with - | none => rfl - | some v => - by_cases hv : v = 0 - · simp [hv] - · simp [hv] - rw [ih s' (.stmts body) (.stmts body hBody)] - cases execYulFuelWithBackend .evmYulLean fuel s' (.stmts body) with - | «continue» s'' => - simp only - rw [ih s'' (.stmts post) (.stmts post hPost)] - cases execYulFuelWithBackend .evmYulLean fuel s'' (.stmts post) with - | «continue» s''' => - simp only - exact ih s''' (.stmt (.for_ [] cond post body)) - (.stmt (.for_ [] cond post body) - (.for_ [] cond post body - (by intro stmt hMem; cases hMem) - hCond hPost hBody)) - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - | stmts stmts hStmts => - cases stmts with - | nil => rfl - | cons stmt rest => - have hStmt : BridgedStmt stmt := hStmts stmt (by simp) - have hRest : BridgedStmts rest := by - intro s hs - exact hStmts s (by simp [hs]) - simp only [execYulFuelWithBackend] - rw [ih state (.stmt stmt) (.stmt stmt hStmt)] - cases execYulFuelWithBackend .evmYulLean fuel state (.stmt stmt) with - | «continue» s' => - simp only - exact ih s' (.stmts rest) (.stmts rest hRest) - | «return» _ _ => rfl - | «stop» _ => rfl - | «revert» _ => rfl - -private theorem execYulFuelWithBackend_eq_on_bridged_stmt - (fuel : Nat) (state : YulState) (stmt : Compiler.Yul.YulStmt) - (hStmt : BridgedStmt stmt) : - execYulFuelWithBackend .verity fuel state (.stmt stmt) = - execYulFuelWithBackend .evmYulLean fuel state (.stmt stmt) := - execYulFuelWithBackend_eq_on_bridged_target fuel state (.stmt stmt) - (.stmt stmt hStmt) - -private theorem execYulFuelWithBackend_eq_on_bridged_stmts - (fuel : Nat) (state : YulState) (stmts : List Compiler.Yul.YulStmt) - (hStmts : BridgedStmts stmts) : - execYulFuelWithBackend .verity fuel state (.stmts stmts) = - execYulFuelWithBackend .evmYulLean fuel state (.stmts stmts) := - execYulFuelWithBackend_eq_on_bridged_target fuel state (.stmts stmts) - (.stmts stmts hStmts) - -private theorem emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies - (fuel : Nat) (state : YulState) (contract : Compiler.IRContract) - (_hFunctions : ∀ fn, fn ∈ contract.functions → BridgedStmts fn.body) - (_hFallback : ∀ fb, contract.fallbackEntrypoint = some fb → BridgedStmts fb.body) - (_hReceive : ∀ rc, contract.receiveEntrypoint = some rc → BridgedStmts rc.body) - (_hInternals : BridgedStmts contract.internalFunctions) : - legacyExecYulFuel fuel state (.stmts (Compiler.emitYul contract).runtimeCode) = - execYulFuelWithBackend .evmYulLean fuel state - (.stmts (Compiler.emitYul contract).runtimeCode) := by - exact (execYulFuelWithBackend_evmYulLean_eq fuel state - (.stmts (Compiler.emitYul contract).runtimeCode)).symm - -private noncomputable def execYulStmtsWithBackend - (backend : BuiltinBackend) (state : YulState) (stmts : List Compiler.Yul.YulStmt) : - YulExecResult := - execYulFuelWithBackend backend (sizeOf stmts + 1) state (.stmts stmts) - -private noncomputable def interpretYulRuntimeWithBackend - (backend : BuiltinBackend) (runtimeCode : List Compiler.Yul.YulStmt) - (tx : YulTransaction) (storage : IRStorageSlot → IRStorageWord) - (events : List (List Nat) := []) : - YulResult := - let initialState := YulState.initial tx storage events - yulResultOfExecWithRollback initialState - (execYulFuelWithBackend backend (sizeOf runtimeCode + 1) initialState - (.stmts runtimeCode)) - -private noncomputable def interpretYulFromIR - (contract : Compiler.IRContract) - (tx : Compiler.Proofs.IRGeneration.IRTransaction) - (state : Compiler.Proofs.IRGeneration.IRState) : YulResult := - interpretYulRuntime (Compiler.emitYul contract).runtimeCode - (YulTransaction.ofIR tx) state.storage state.events - -private theorem interpretYulRuntimeWithBackend_evmYulLean_eq - (runtimeCode : List Compiler.Yul.YulStmt) (tx : YulTransaction) - (storage : IRStorageSlot → IRStorageWord) (events : List (List Nat) := []) : - interpretYulRuntimeWithBackend .evmYulLean runtimeCode tx storage events = - interpretYulRuntime runtimeCode tx storage events := by - unfold interpretYulRuntimeWithBackend interpretYulRuntime - unfold execYulStmts execYulStmtsFuel - change - yulResultOfExecWithRollback (YulState.initial tx storage events) - (execYulFuelWithBackend .evmYulLean (sizeOf runtimeCode + 1) - (YulState.initial tx storage events) (.stmts runtimeCode)) = - match legacyExecYulFuel (sizeOf runtimeCode + 1) - (YulState.initial tx storage events) (.stmts runtimeCode) with - | .continue s => - { success := true, returnValue := s.returnValue, finalStorage := s.storage, - finalMappings := Compiler.Proofs.storageAsMappings s.storage, events := s.events } - | .return v s => - { success := true, returnValue := some v, finalStorage := s.storage, - finalMappings := Compiler.Proofs.storageAsMappings s.storage, events := s.events } - | .stop s => - { success := true, returnValue := none, finalStorage := s.storage, - finalMappings := Compiler.Proofs.storageAsMappings s.storage, events := s.events } - | .revert _ => - { success := false, returnValue := none, finalStorage := storage, - finalMappings := Compiler.Proofs.storageAsMappings storage, events := events } - rw [execYulFuelWithBackend_evmYulLean_eq] - cases legacyExecYulFuel (sizeOf runtimeCode + 1) (YulState.initial tx storage events) - (.stmts runtimeCode) <;> rfl - -private theorem interpretYulFromIR_evmYulLean_eq_on_bridged_bodies - (contract : Compiler.IRContract) (tx : Compiler.Proofs.IRGeneration.IRTransaction) - (state : Compiler.Proofs.IRGeneration.IRState) - (_hFunctions : ∀ fn, fn ∈ contract.functions → BridgedStmts fn.body) - (_hFallback : ∀ fb, contract.fallbackEntrypoint = some fb → BridgedStmts fb.body) - (_hReceive : ∀ rc, contract.receiveEntrypoint = some rc → BridgedStmts rc.body) - (_hInternals : BridgedStmts contract.internalFunctions) : - interpretYulFromIR contract tx state = - interpretYulRuntimeWithBackend .evmYulLean - (Compiler.emitYul contract).runtimeCode (YulTransaction.ofIR tx) - state.storage state.events := by - unfold interpretYulFromIR - exact (interpretYulRuntimeWithBackend_evmYulLean_eq - (Compiler.emitYul contract).runtimeCode (YulTransaction.ofIR tx) - state.storage (events := state.events)).symm - -/-! ## Phase 4 Completion Summary - -### What this module establishes: -1. **`backends_agree_on_bridged_builtins`**: Pointwise backend equivalence for - the full bridged-builtin set at the `evalBuiltinCallWithBackendContext` - level. For every `func ∈ bridgedBuiltins`, `.verity` and `.evmYulLean` - return the same result. The dispatch proof and all per-builtin bridge dependencies are sorry-free. -2. **`evalYulExpr_evmYulLean_eq_on_bridged`**: Expression-level backend - equivalence for `BridgedExpr`, covering literals, identifiers, nested calls - to bridged builtins, and backend-independent `tload`/`mload`. -3. **Backend-parameterized statement executor**: `execYulFuelWithBackend` is a - backend-parameterized mirror of `legacyExecYulFuel`, providing the executor surface - used by the statement-level equivalence proofs below. -4. **`execYulFuelWithBackend_{let,assign}_eq_on_bridged`**: First - statement-level backend-equivalence theorems — `.let_ n v` and `.assign n v` - produce identical results under `.verity` and `.evmYulLean` when `v` is a - `BridgedExpr`. These are narrow helpers used by the broader statement-list - and recursive-target predicates below. -5. **`execYulFuelWithBackend_eq_on_bridged_straight_stmts`**: Statement-level - backend equivalence for straight-line statement lists whose expression - dependencies satisfy `BridgedExpr`; the unsupported `.letMany` form is also - covered because both backends revert identically. -6. **`execYulFuelWithBackend_block_eq_on_bridged_straight_stmts`**: The `.block` - statement constructor preserves that straight-line list equivalence when its - body is a `BridgedStraightStmts` list. -7. **`execYulFuelWithBackend_if_eq_on_bridged_body`**: The `.if_` statement - constructor preserves backend equivalence when its condition is a - `BridgedExpr` and its body is a `BridgedStraightStmts` list. -8. **`execYulFuelWithBackend_switch_eq_on_bridged_cases`**: The `.switch` - statement constructor preserves backend equivalence when its scrutinee is a - `BridgedExpr`, every selectable case body satisfies `BridgedStraightStmts`, - and the optional default body is straight-line when present. -9. **`execYulFuelWithBackend_for_eq_on_bridged_parts`**: The `.for_` - statement constructor preserves backend equivalence when its init/body/post - lists are `BridgedStraightStmts` and its condition is a `BridgedExpr`. -10. **`execYulFuelWithBackend_eq_on_bridged_target`**: Recursive - statement/statement-list backend equivalence for targets constrained by - `BridgedTarget`, whose nested statements satisfy `BridgedStmt`. -11. **`emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies`**: Composes - emitted runtime-wrapper closure with recursive target equivalence to state - that Verity `legacyExecYulFuel` equals the EVMYulLean backend executor for - `emitYul` runtime code when its embedded bodies are bridged. -12. The former contract-level EVMYulLean fuel-wrapper retarget theorem has - been removed from this module. The remaining facts are transition/regression - evidence for the bridged proof-interpreter fragment, while public - compiler-correctness theorems are expected to target native dispatcher - execution through `EvmYul.Yul.callDispatcher`. - -### Trust boundary: -Expressions constrained by `BridgedExpr`, straight-line statement lists -constrained by `BridgedStraightStmts`, and recursive statement targets -constrained by `BridgedTarget` inherit EVMYulLean semantics. Contract-level -proof-interpreter preservation is not exported from this module as public -compiler-correctness authority. The remaining scope limit is the -external-call/function-table family carved out by `BridgedSafeStmts`. --/ - -end Compiler.Proofs.YulGeneration.Backends diff --git a/Compiler/Proofs/YulGeneration/Codegen.lean b/Compiler/Proofs/YulGeneration/Codegen.lean deleted file mode 100644 index 69b69b7e0..000000000 --- a/Compiler/Proofs/YulGeneration/Codegen.lean +++ /dev/null @@ -1,258 +0,0 @@ -import Compiler.Codegen -import Compiler.Proofs.IRGeneration.IRInterpreter -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanPureBuiltinLemmas - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Yul -open Compiler.Proofs.IRGeneration - -/-! ## Codegen Proof Obligations (Layer 3) - -These lemmas capture the core obligations for Yul codegen correctness: -1. Selector extraction matches the function selector. -2. Runtime switch dispatch executes the selected function body. --/ - -@[simp] -private theorem emitYul_runtimeCode_eq (contract : IRContract) : - (Compiler.emitYul contract).runtimeCode = Compiler.runtimeCode contract := by - rfl - -/-- Selector extraction via `selectorExpr` yields the 4-byte selector. -/ -@[simp] -private theorem evalYulExpr_selectorExpr (state : YulState) : - evalYulExpr state selectorExpr = some (state.selector % selectorModulus) := -by - have hShiftModEq : selectorShift % evmModulus = selectorShift := by - have hShiftLtModulus : selectorShift < evmModulus := by - norm_num [selectorShift, evmModulus] - exact Nat.mod_eq_of_lt hShiftLtModulus - have hSelectorShiftLt256 : selectorShift < 256 := by - norm_num [selectorShift] - have hSelectorShiftNotGe256 : ¬ 256 ≤ selectorShift := Nat.not_le_of_lt hSelectorShiftLt256 - have hSelectorWordLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < evmModulus := by - have hModLt : state.selector % selectorModulus < selectorModulus := by - exact Nat.mod_lt _ (by decide) - have hPowPos : 0 < 2 ^ selectorShift := by - exact Nat.pow_pos (a := 2) (n := selectorShift) (by decide) - have hMulLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < - selectorModulus * 2 ^ selectorShift := by - exact Nat.mul_lt_mul_of_pos_right hModLt hPowPos - have hModulusSplit : selectorModulus * 2 ^ selectorShift = evmModulus := by - norm_num [selectorModulus, selectorShift, evmModulus, Nat.pow_add, Nat.mul_comm, - Nat.mul_left_comm, Nat.mul_assoc] - simpa [hModulusSplit] using hMulLt - have hSelectorWordMod : - ((state.selector % selectorModulus) * 2 ^ selectorShift) % evmModulus = - (state.selector % selectorModulus) * 2 ^ selectorShift := by - exact Nat.mod_eq_of_lt hSelectorWordLt - simp [selectorExpr, evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext, - Backends.evalBuiltinCallViaEvmYulLean, - calldataloadWord, selectorWord, - hShiftModEq, hSelectorWordMod, hSelectorShiftNotGe256] - -/-- Selector extraction yields the raw selector when it fits in 4 bytes. -/ -@[simp] -private theorem evalYulExpr_selectorExpr_eq (state : YulState) - (hselector : state.selector < selectorModulus) : - evalYulExpr state selectorExpr = some state.selector := -by - simp [Nat.mod_eq_of_lt hselector] - -/-- Dispatch body emitted for one external function case. -/ -private def switchCaseBody (fn : IRFunction) : List YulStmt := - let valueGuard := if fn.payable then [] else [Compiler.callvalueGuard] - [YulStmt.comment s!"{fn.name}()"] ++ valueGuard ++ [Compiler.calldatasizeGuard fn.params.length] ++ fn.body - -/-- Switch cases generated from IR functions. -/ -private def switchCases (fns : List IRFunction) : List (Prod Nat (List YulStmt)) := - fns.map (fun f => (f.selector, switchCaseBody f)) - -/-- Default dispatch body used by `buildSwitch`. -/ -private def switchDefaultCase - (fallback : Option IREntrypoint) - (receive : Option IREntrypoint) : List YulStmt := - match receive, fallback with - | none, none => - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - | none, some fb => - let valueGuard := if fb.payable then [] else [Compiler.callvalueGuard] - [YulStmt.comment "fallback()"] ++ valueGuard ++ fb.body - | some rc, none => - let receiveGuard := if rc.payable then [] else [Compiler.callvalueGuard] - [YulStmt.block [ - YulStmt.let_ "__is_empty_calldata" (YulExpr.call "eq" [YulExpr.call "calldatasize" [], YulExpr.lit 0]), - YulStmt.if_ (YulExpr.ident "__is_empty_calldata") - ([YulStmt.comment "receive()"] ++ receiveGuard ++ rc.body), - YulStmt.if_ (YulExpr.call "iszero" [YulExpr.ident "__is_empty_calldata"]) - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - ]] - | some rc, some fb => - let receiveGuard := if rc.payable then [] else [Compiler.callvalueGuard] - let fallbackGuard := if fb.payable then [] else [Compiler.callvalueGuard] - [YulStmt.block [ - YulStmt.let_ "__is_empty_calldata" (YulExpr.call "eq" [YulExpr.call "calldatasize" [], YulExpr.lit 0]), - YulStmt.if_ (YulExpr.ident "__is_empty_calldata") - ([YulStmt.comment "receive()"] ++ receiveGuard ++ rc.body), - YulStmt.if_ (YulExpr.call "iszero" [YulExpr.ident "__is_empty_calldata"]) - ([YulStmt.comment "fallback()"] ++ fallbackGuard ++ fb.body) - ]] - -/-- If the selector matches a case, the switch executes that case body (fueled). -/ -private theorem execYulStmtFuel_switch_match - (state : YulState) (expr : YulExpr) (cases' : List (Prod Nat (List YulStmt))) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) (body : List YulStmt) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun (c, _) => c = v) cases' = some (v, body)) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - execYulStmtsFuel fuel state body := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - -/-- If no selector case matches, the switch executes the default (or continues). -/ -private def execYulStmtFuel_switch_miss_result (state : YulState) (fuel : Nat) - (defaultCase : Option (List YulStmt)) : YulExecResult := - match defaultCase with - | some body => execYulStmtsFuel fuel state body - | none => YulExecResult.continue state - -private theorem execYulStmtFuel_switch_miss - (state : YulState) (expr : YulExpr) (cases' : List (Prod Nat (List YulStmt))) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun (c, _) => c = v) cases' = none) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - execYulStmtFuel_switch_miss_result state fuel defaultCase := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind, - execYulStmtFuel_switch_miss_result] - rfl - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind, - execYulStmtFuel_switch_miss_result] - rfl - -/- Bridge lemmas for switch-case lookup. -/ -private theorem find_switch_case_of_find_function - (fns : List IRFunction) (sel : Nat) (fn : IRFunction) - (hFind : fns.find? (fun f => f.selector == sel) = some fn) : - (switchCases fns).find? (fun (c, _) => c = sel) = - some (fn.selector, switchCaseBody fn) := by - induction fns with - | nil => - simp at hFind - | cons f rest ih => - by_cases hsel : f.selector = sel - · have hselb : (f.selector == sel) = true := by - simp [hsel] - have hFind' : some f = some fn := by - simpa [List.find?, hselb] using hFind - cases hFind' - simp [switchCases, hsel] - · have hselb : (f.selector == sel) = false := by - simp [hsel] - have hFind' : rest.find? (fun f => f.selector == sel) = some fn := by - simpa [List.find?, hselb] using hFind - have ih' := ih hFind' - simpa [switchCases, List.find?, hsel] using ih' - -/-- Selector-specialized variant: if `find?` hits `fn` at `sel`, the switch case -lookup returns the same selector `sel` paired with `switchCaseBody fn`. -/ -private theorem find_switch_case_of_find_function_eq_selector - (fns : List IRFunction) (sel : Nat) (fn : IRFunction) - (hFind : fns.find? (fun f => f.selector == sel) = some fn) : - (switchCases fns).find? (fun (c, _) => c = sel) = - some (sel, switchCaseBody fn) := by - have hCase := find_switch_case_of_find_function fns sel fn hFind - have hSel : fn.selector = sel := by - have h := List.find?_some hFind - simp at h - exact h - simpa [hSel] using hCase - -private theorem find_switch_case_of_find_function_none - (fns : List IRFunction) (sel : Nat) - (hFind : fns.find? (fun f => f.selector == sel) = none) : - (switchCases fns).find? (fun (c, _) => c = sel) = none := by - induction fns with - | nil => - simp at hFind - simp [switchCases] - | cons f rest ih => - by_cases hsel : f.selector = sel - · have hselb : (f.selector == sel) = true := by - simp [hsel] - have hFind' : (some f : Option IRFunction) = none := by - simp [List.find?, hselb] at hFind - cases hFind' - · have hselb : (f.selector == sel) = false := by - simp [hsel] - have hFind' : rest.find? (fun f => f.selector == sel) = none := by - simpa [List.find?, hselb] using hFind - have ih' := ih hFind' - simpa [switchCases, List.find?, hsel] using ih' - - -/-! ## Runtime code reduction lemmas -/ - -/-- Function definitions are no-ops in execution. -/ -@[simp] private theorem execYulStmtFuel_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body : List YulStmt) : - execYulStmtFuel fuel state (YulStmt.funcDef name params ret body) = - YulExecResult.continue state := by - cases fuel <;> simp [execYulStmtFuel, legacyExecYulFuel] - -/-- `legacyExecYulFuel` on a funcDef target gives `.continue state` for any fuel. -/ -@[simp] private theorem legacyExecYulFuel_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body : List YulStmt) : - legacyExecYulFuel fuel state (.stmt (YulStmt.funcDef name params ret body)) = - YulExecResult.continue state := by - cases fuel <;> simp [legacyExecYulFuel] - -/-- Stepping through a funcDef in a statement list consumes one fuel unit. -/ -@[simp] private theorem execYulStmtsFuel_cons_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body rest : List YulStmt) : - execYulStmtsFuel (Nat.succ fuel) state (YulStmt.funcDef name params ret body :: rest) = - execYulStmtsFuel fuel state rest := by - simp only [execYulStmtsFuel, legacyExecYulFuel] - rw [legacyExecYulFuel_funcDef] - -/-- Executing funcDef statements followed by a suffix: the funcDefs are no-ops -and each one burns one fuel unit. -/ -private theorem execYulStmtsFuel_funcDefs_then_suffix (fuel : Nat) (state : YulState) - (prefix_ : List YulStmt) (suffix_ : List YulStmt) - (hFuncDefs : ∀ s ∈ prefix_, ∃ nm p r b, s = YulStmt.funcDef nm p r b) : - execYulStmtsFuel (prefix_.length + fuel) state (prefix_ ++ suffix_) = - execYulStmtsFuel fuel state suffix_ := by - induction prefix_ generalizing state with - | nil => simp - | cons h t ih => - have hmem : h ∈ h :: t := .head t - obtain ⟨nm, p, r, b, rfl⟩ := hFuncDefs h hmem - simp only [List.cons_append, List.length_cons] - conv_lhs => rw [show t.length + 1 + fuel = Nat.succ (t.length + fuel) from by omega] - rw [execYulStmtsFuel_cons_funcDef] - exact ih state (fun s hs => hFuncDefs s (List.mem_cons_of_mem _ hs)) - -/-- Variant with `fuel ≥ prefix_.length` instead of exact `prefix_.length + fuel`. -/ -private theorem execYulStmtsFuel_funcDefs_then_suffix_ge (fuel : Nat) (state : YulState) - (prefix_ : List YulStmt) (suffix_ : List YulStmt) - (hFuncDefs : ∀ s ∈ prefix_, ∃ nm p r b, s = YulStmt.funcDef nm p r b) - (hFuel : fuel ≥ prefix_.length) : - execYulStmtsFuel fuel state (prefix_ ++ suffix_) = - execYulStmtsFuel (fuel - prefix_.length) state suffix_ := by - have : fuel = prefix_.length + (fuel - prefix_.length) := by omega - conv_lhs => rw [this] - exact execYulStmtsFuel_funcDefs_then_suffix _ state prefix_ suffix_ hFuncDefs - -end Compiler.Proofs.YulGeneration diff --git a/Compiler/Proofs/YulGeneration/Equivalence.lean b/Compiler/Proofs/YulGeneration/Equivalence.lean deleted file mode 100644 index 61b9ef978..000000000 --- a/Compiler/Proofs/YulGeneration/Equivalence.lean +++ /dev/null @@ -1,427 +0,0 @@ -import Compiler.Codegen -import Compiler.Proofs.IRGeneration.IRInterpreter -import Compiler.Proofs.YulGeneration.IRFuel -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Proofs.IRGeneration -open Compiler.Yul - -/-! ## IR ↔ Yul State Alignment -/ - -private def yulStateOfIR (_selector : Nat) (state : IRState) : YulState := - { vars := state.vars - storage := state.storage - transientStorage := state.transientStorage - memory := state.memory - calldata := state.calldata - selector := state.selector - returnValue := state.returnValue - sender := state.sender - msgValue := state.msgValue - thisAddress := state.thisAddress - blockTimestamp := state.blockTimestamp - blockNumber := state.blockNumber - chainId := state.chainId - blobBaseFee := state.blobBaseFee - events := state.events } - -private def statesAligned (selector : Nat) (ir : IRState) (yul : YulState) : Prop := - yul = yulStateOfIR selector ir - -/- ## Layer 3 Equivalence Scaffolding - -These statements capture the generic proof shape for IR → Yul equivalence. -They are intentionally parameterized so contract-level results become -mechanical instantiations once the instruction-level lemmas are proven. --/ - -private def execResultsAligned (selector : Nat) : IRExecResult → YulExecResult → Prop - | .continue ir, .continue yul => statesAligned selector ir yul - | .return v ir, .return v' yul => v = v' ∧ statesAligned selector ir yul - | .stop ir, .stop yul => statesAligned selector ir yul - | .revert ir, .revert yul => statesAligned selector ir yul - | _, _ => False - -/-- Results match when success, return value, and storage/mapping functions agree. -/ -private def resultsMatch (ir : IRResult) (yul : YulResult) : Prop := - ir.success = yul.success ∧ - ir.returnValue = yul.returnValue ∧ - (∀ slot, ir.finalStorage slot = yul.finalStorage slot) ∧ - (∀ base key, ir.finalMappings base key = yul.finalMappings base key) ∧ - ir.events = yul.events - -private def irResultOfExecWithRollback (rollback : IRState) : IRExecResult → IRResult - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := rollback.storage - finalMappings := Compiler.Proofs.storageAsMappings rollback.storage - events := rollback.events } - -/-- Interpret a function body starting from an aligned IR-derived state. -/ -private noncomputable def interpretYulBodyFromState - (fn : IRFunction) (selector : Nat) (state rollback : IRState) : YulResult := - let yulState := yulStateOfIR selector state - let yulRollback := yulStateOfIR selector rollback - yulResultOfExecWithRollback yulRollback (execYulStmts yulState fn.body) - -private theorem resultsMatch_of_execResultsAligned - (selector : Nat) (rollbackIR : IRState) (rollbackYul : YulState) - (hAligned : statesAligned selector rollbackIR rollbackYul) : - ∀ irExec yulExec, - execResultsAligned selector irExec yulExec → - resultsMatch (irResultOfExecWithRollback rollbackIR irExec) - (yulResultOfExecWithRollback rollbackYul yulExec) := by - intro irExec yulExec hExec - cases irExec <;> cases yulExec - · -- continue / continue - cases hExec - simp [irResultOfExecWithRollback, yulResultOfExecWithRollback, resultsMatch, - yulStateOfIR] - · -- continue / return - cases hExec - · -- continue / stop - cases hExec - · -- continue / revert - cases hExec - · -- return / continue - cases hExec - · -- return / return - rcases hExec with ⟨hVal, hAligned'⟩ - cases hAligned' - simp [irResultOfExecWithRollback, yulResultOfExecWithRollback, resultsMatch, - yulStateOfIR, hVal] - · -- return / stop - cases hExec - · -- return / revert - cases hExec - · -- stop / continue - cases hExec - · -- stop / return - cases hExec - · -- stop / stop - cases hExec - simp [irResultOfExecWithRollback, yulResultOfExecWithRollback, resultsMatch, - yulStateOfIR] - · -- stop / revert - cases hExec - · -- revert / continue - cases hExec - · -- revert / return - cases hExec - · -- revert / stop - cases hExec - · -- revert / revert - cases hExec - cases hAligned - simp [irResultOfExecWithRollback, yulResultOfExecWithRollback, resultsMatch, - yulStateOfIR] - -/-! ## Generic Layer 3 Lemmas (Fuel-Agnostic) - -These lemmas lift instruction-level equivalence to sequences and function -bodies. They do not assume any specific instruction equivalence proof; -instead, they require it as a parameter and then compose it. --/ - -private theorem statesAligned_refl (selector : Nat) (state : IRState) : - statesAligned selector state (yulStateOfIR selector state) := by - rfl - -/-! ## Fuel-Parametric Sequencing Lemmas - -These unfolding lemmas expose how `execYulStmtsFuel` consumes one unit of -fuel before executing the first statement. They are intended as building -blocks for the generic sequence equivalence proof. --/ - -private theorem execYulStmtsFuel_nil (fuel : Nat) (state : YulState) : - execYulStmtsFuel fuel state [] = .continue state := by - cases fuel <;> rfl - -private theorem execYulStmtsFuel_cons - (fuel : Nat) (state : YulState) (stmt : YulStmt) (rest : List YulStmt) : - execYulStmtsFuel (Nat.succ fuel) state (stmt :: rest) = - match execYulStmtFuel fuel state stmt with - | .continue s' => execYulStmtsFuel fuel s' rest - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s := by - rfl - -private theorem execYulStmtFuel_for - (fuel : Nat) (state : YulState) (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.for_ init cond post body) = - match execYulStmtsFuel fuel state init with - | .continue s' => - match evalYulExpr s' cond with - | some v => - if v = 0 then .continue s' - else - match execYulStmtsFuel fuel s' body with - | .continue s'' => - match execYulStmtsFuel fuel s'' post with - | .continue s''' => execYulStmtFuel fuel s''' (.for_ [] cond post body) - | other => other - | other => other - | none => .revert s' - | other => other := by - rfl - -/-- Instruction-level equivalence goal: single IR statement matches Yul statement (fuel-parametric). -/ -private def execIRStmt_equiv_execYulStmt_goal - (selector : Nat) (fuel : Nat) (stmt : YulStmt) (irState : IRState) (yulState : YulState) : Prop := - statesAligned selector irState yulState → - execResultsAligned selector (execIRStmtFuel fuel irState stmt) (execYulStmtFuel fuel yulState stmt) - -/-- Sequence/program equivalence goal: statement lists compose under alignment (fuel-parametric). -/ -private def execIRStmts_equiv_execYulStmts_goal - (selector : Nat) (fuel : Nat) (stmts : List YulStmt) (irState : IRState) (yulState : YulState) : Prop := - statesAligned selector irState yulState → - execResultsAligned selector (execIRStmtsFuel fuel irState stmts) (execYulStmtsFuel fuel yulState stmts) - -private theorem stmt_align_contra - {selector fuel : Nat} {stmt : YulStmt} {irState : IRState} {yulState : YulState} - {irExec : IRExecResult} {yulExec : YulExecResult} - (hStmt : execResultsAligned selector - (execIRStmtFuel fuel irState stmt) - (execYulStmtFuel fuel yulState stmt)) - (hIR : execIRStmtFuel fuel irState stmt = irExec) - (hYul : execYulStmtFuel fuel yulState stmt = yulExec) - (hImpossible : ¬ execResultsAligned selector irExec yulExec) : False := by - apply hImpossible - simpa [hIR, hYul] using hStmt - -private def ir_yul_function_equiv_fuel_goal - (fn : IRFunction) (selector : Nat) (args : List Nat) (initialState : IRState) : Prop := - resultsMatch - (execIRFunctionFuel (sizeOf fn.body + 1) fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) - - -/-! ## Generic Sequence Equivalence - -This lemma lifts statement-level equivalence to statement lists, parameterized -by the fuel used for Yul execution. It is intentionally fuel-parametric so -later proofs can specialize to the compiler-chosen fuel without re-proving the -composition logic. --/ - -private theorem execIRStmtsFuel_equiv_execYulStmtsFuel_of_stmt_equiv - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) : - ∀ selector fuel stmts irState yulState, - execIRStmts_equiv_execYulStmts_goal selector fuel stmts irState yulState := by - intro selector fuel stmts irState yulState hAligned - revert fuel irState yulState hAligned - induction stmts with - | nil => - intro fuel irState yulState hAligned - simp [execIRStmtsFuel, execIRStmts, - execYulStmtsFuel_nil, execResultsAligned, hAligned] - | cons stmt rest ih => - intro fuel irState yulState hAligned - cases fuel with - | zero => - simp [execIRStmtsFuel, execIRStmts, - execYulStmtsFuel, legacyExecYulFuel, execResultsAligned, hAligned] - | succ fuel => - have hStmt := stmt_equiv selector fuel stmt irState yulState hAligned - cases hIR : execIRStmtFuel fuel irState stmt with - | «continue» ir' => - cases hYul : execYulStmtFuel fuel yulState stmt with - | «continue» y' => - have hAligned' : statesAligned selector ir' y' := by - simpa [execResultsAligned, hIR, hYul] using hStmt - have hRest := ih (irState := ir') (yulState := y') (fuel := fuel) hAligned' - simpa [execIRStmtsFuel, execIRStmts, execYulStmtsFuel_cons, hIR, hYul] using hRest - | «return» v y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «stop» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «revert» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «return» v ir' => - cases hYul : execYulStmtFuel fuel yulState stmt with - | «return» v' y' => - simpa [execIRStmtsFuel, execIRStmts, execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «stop» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «revert» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «stop» ir' => - cases hYul : execYulStmtFuel fuel yulState stmt with - | «stop» y' => - simpa [execIRStmtsFuel, execIRStmts, execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «return» v y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «revert» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «revert» ir' => - cases hYul : execYulStmtFuel fuel yulState stmt with - | «revert» y' => - simpa [execIRStmtsFuel, execIRStmts, execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «return» v y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - | «stop» y' => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp [execResultsAligned])) - -private theorem execIRStmtsFuel_equiv_execYulStmts_of_stmt_equiv - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) : - ∀ selector stmts irState yulState, - statesAligned selector irState yulState → - execResultsAligned selector - (execIRStmtsFuel (sizeOf stmts + 1) irState stmts) - (execYulStmts yulState stmts) := by - intro selector stmts irState yulState hAligned - have hFuel := - execIRStmtsFuel_equiv_execYulStmtsFuel_of_stmt_equiv stmt_equiv - selector (sizeOf stmts + 1) stmts irState yulState hAligned - simpa [execYulStmts] using hFuel - -private theorem execIRFunctionFuel_equiv_interpretYulBodyFromState_of_stmt_equiv - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) : - ∀ selector fn args initialState, - resultsMatch - (execIRFunctionFuel (sizeOf fn.body + 1) fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) := by - intro selector fn args initialState - let stateWithParams := - fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState - have hAligned : statesAligned selector stateWithParams (yulStateOfIR selector stateWithParams) := by - rfl - have hExec := - execIRStmtsFuel_equiv_execYulStmts_of_stmt_equiv stmt_equiv - selector fn.body stateWithParams (yulStateOfIR selector stateWithParams) hAligned - have hRollback : statesAligned selector initialState (yulStateOfIR selector initialState) := by - rfl - simpa [execIRFunctionFuel, interpretYulBodyFromState, stateWithParams] using - (resultsMatch_of_execResultsAligned selector initialState - (yulStateOfIR selector initialState) hRollback _ _ hExec) - -private theorem ir_yul_function_equiv_fuel_goal_of_stmt_equiv - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) : - ∀ selector fn args initialState, - ir_yul_function_equiv_fuel_goal fn selector args initialState := by - intro selector fn args initialState - simpa [ir_yul_function_equiv_fuel_goal] using - (execIRFunctionFuel_equiv_interpretYulBodyFromState_of_stmt_equiv stmt_equiv - selector fn args initialState) - -private theorem ir_yul_function_equiv_from_state_of_fuel_goal - (fn : IRFunction) (selector : Nat) (args : List Nat) (initialState : IRState) - (hFuel : - execIRFunctionFuel (sizeOf fn.body + 1) fn args initialState = - execIRFunction fn args initialState) - (hFuelGoal : ir_yul_function_equiv_fuel_goal fn selector args initialState) : - resultsMatch - (execIRFunction fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) := by - simpa [ir_yul_function_equiv_fuel_goal, hFuel] using hFuelGoal - -private theorem ir_yul_function_equiv_from_state_of_fuel_goal_and_adequacy - (fn : IRFunction) (selector : Nat) (args : List Nat) (initialState : IRState) - (hAdequacy : execIRFunctionFuel_adequate_goal fn args initialState) - (hFuelGoal : ir_yul_function_equiv_fuel_goal fn selector args initialState) : - resultsMatch - (execIRFunction fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) := by - apply ir_yul_function_equiv_from_state_of_fuel_goal - · simpa [execIRFunctionFuel_adequate_goal] using hAdequacy - · exact hFuelGoal - -private theorem ir_yul_function_equiv_from_state_of_stmt_equiv_and_adequacy - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) - (fn : IRFunction) (selector : Nat) (args : List Nat) (initialState : IRState) - (hAdequacy : execIRFunctionFuel_adequate_goal fn args initialState) : - resultsMatch - (execIRFunction fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) := by - have hFuelGoal := - ir_yul_function_equiv_fuel_goal_of_stmt_equiv stmt_equiv - selector fn args initialState - exact - ir_yul_function_equiv_from_state_of_fuel_goal_and_adequacy - fn selector args initialState hAdequacy hFuelGoal - -/-- Direct function-level equivalence without an explicit adequacy hypothesis. - -Since `execIRFunctionFuel` and `execIRFunction` are definitionally equal -(fuel adequacy is `rfl`), the adequacy hypothesis is always trivially -dischargeable. This theorem composes `stmt_equiv` with the internal -adequacy proof, eliminating the need for callers to supply it. -/ -private theorem ir_yul_function_equiv_from_state_of_stmt_equiv - (stmt_equiv : - ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) - (fn : IRFunction) (selector : Nat) (args : List Nat) (initialState : IRState) : - resultsMatch - (execIRFunction fn args initialState) - (interpretYulBodyFromState fn selector - (fn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState) - initialState) := - ir_yul_function_equiv_from_state_of_stmt_equiv_and_adequacy - stmt_equiv fn selector args initialState - (execIRFunctionFuel_adequate fn args initialState) - -end Compiler.Proofs.YulGeneration diff --git a/Compiler/Proofs/YulGeneration/Lemmas.lean b/Compiler/Proofs/YulGeneration/Lemmas.lean deleted file mode 100644 index 034687017..000000000 --- a/Compiler/Proofs/YulGeneration/Lemmas.lean +++ /dev/null @@ -1,82 +0,0 @@ -import Compiler.Codegen -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanPureBuiltinLemmas - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Yul - -/-! ## Yul Runtime Lemmas - -These lemmas connect the runtime codegen structure with the Yul semantics. --/ - -set_option maxHeartbeats 1000000 in -@[simp] private theorem evalYulExpr_selectorExpr_semantics : - ∀ state : YulState, evalYulExpr state selectorExpr = some (state.selector % selectorModulus) := by - intro state - have hShiftModEq : selectorShift % evmModulus = selectorShift := by - have hShiftLtModulus : selectorShift < evmModulus := by - norm_num [selectorShift, evmModulus] - exact Nat.mod_eq_of_lt hShiftLtModulus - have hSelectorShiftLt256 : selectorShift < 256 := by - norm_num [selectorShift] - have hSelectorShiftNotGe256 : ¬ 256 ≤ selectorShift := Nat.not_le_of_lt hSelectorShiftLt256 - have hSelectorWordLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < evmModulus := by - have hModLt : state.selector % selectorModulus < selectorModulus := by - exact Nat.mod_lt _ (by decide) - have hPowPos : 0 < 2 ^ selectorShift := by - exact Nat.pow_pos (a := 2) (n := selectorShift) (by decide) - have hMulLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < - selectorModulus * 2 ^ selectorShift := by - exact Nat.mul_lt_mul_of_pos_right hModLt hPowPos - have hModulusSplit : selectorModulus * 2 ^ selectorShift = evmModulus := by - norm_num [selectorModulus, selectorShift, evmModulus, Nat.pow_add, Nat.mul_comm, Nat.mul_left_comm, - Nat.mul_assoc] - simpa [hModulusSplit] using hMulLt - have hSelectorWordMod : - ((state.selector % selectorModulus) * 2 ^ selectorShift) % evmModulus = - (state.selector % selectorModulus) * 2 ^ selectorShift := by - exact Nat.mod_eq_of_lt hSelectorWordLt - simp [selectorExpr, evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext, - Backends.evalBuiltinCallViaEvmYulLean, - calldataloadWord, selectorWord, - hShiftModEq, hSelectorWordMod, hSelectorShiftNotGe256] - -@[simp] -private theorem execYulStmtFuel_switch_match_semantics - (state : YulState) (expr : YulExpr) (cases' : List (Nat × List YulStmt)) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) (body : List YulStmt) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun x : Nat × List YulStmt => decide (x.1 = v)) cases' = some (v, body)) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - execYulStmtsFuel fuel state body := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - -@[simp] -private theorem execYulStmtFuel_switch_miss_semantics - (state : YulState) (expr : YulExpr) (cases' : List (Nat × List YulStmt)) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun x : Nat × List YulStmt => decide (x.1 = v)) cases' = none) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - (match defaultCase with - | some body => execYulStmtsFuel fuel state body - | none => YulExecResult.continue state) := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - rfl - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - rfl - -end Compiler.Proofs.YulGeneration diff --git a/Compiler/Proofs/YulGeneration/Preservation.lean b/Compiler/Proofs/YulGeneration/Preservation.lean deleted file mode 100644 index e2b18db5a..000000000 --- a/Compiler/Proofs/YulGeneration/Preservation.lean +++ /dev/null @@ -1,1586 +0,0 @@ -import Compiler.Codegen -import Compiler.Proofs.YulGeneration.RuntimeTypes -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanPureBuiltinLemmas -import Compiler.Proofs.IRGeneration.IRInterpreter - -set_option linter.unusedSimpArgs false - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Yul -open Compiler.Proofs.IRGeneration - -/-! ## Codegen Preservation Theorem (Layer 3 — CompilationModel Path) - -We prove that Yul code generation preserves IR semantics, assuming that -executing an IR function body matches executing the same Yul statements. - -**Scope**: This proof applies to the compilation path -`CompilationModel -> IR -> Yul`. -See `TRUST_ASSUMPTIONS.md` for the full trust-boundary description. --/ - -private noncomputable def interpretYulFromIR - (contract : IRContract) (tx : IRTransaction) (state : IRState) : YulResult := - interpretYulRuntime (Compiler.emitYul contract).runtimeCode - (YulTransaction.ofIR tx) state.storage state.events - -private noncomputable def interpretYulBody - (fn : IRFunction) (tx : IRTransaction) (state : IRState) : YulResult := - interpretYulRuntime fn.body (YulTransaction.ofIR tx) state.storage state.events - -@[simp] private theorem interpretYulBody_eq_runtime (fn : IRFunction) (tx : IRTransaction) (state : IRState) : - interpretYulBody fn tx state = - interpretYulRuntime fn.body (YulTransaction.ofIR tx) state.storage state.events := by - rfl - -@[simp] private theorem interpretYulRuntime_eq_yulResultOfExecWithRollback_initial - (runtimeCode : List YulStmt) (tx : YulTransaction) (storage : IRStorageSlot → IRStorageWord) - (events : List (List Nat)) : - interpretYulRuntime runtimeCode tx storage events = - yulResultOfExecWithRollback (YulState.initial tx storage events) - (execYulStmts (YulState.initial tx storage events) runtimeCode) := by - rfl - -@[simp] private theorem interpretYulBody_eq_execWithRollback (fn : IRFunction) - (tx : IRTransaction) (state : IRState) : - interpretYulBody fn tx state = - yulResultOfExecWithRollback - (YulState.initial (YulTransaction.ofIR tx) state.storage state.events) - (execYulStmts - (YulState.initial (YulTransaction.ofIR tx) state.storage state.events) - fn.body) := by - simp [interpretYulBody] - -mutual -private def yulExprNoRef (name : String) : YulExpr → Prop - | .lit _ => True - | .hex _ => True - | .str _ => True - | .ident ident => ident ≠ name - | .call _ args => yulExprsNoRef name args - -private def yulExprsNoRef (name : String) : List YulExpr → Prop - | [] => True - | expr :: exprs => yulExprNoRef name expr ∧ yulExprsNoRef name exprs -end - -mutual -private def yulStmtNoRef (name : String) : YulStmt → Prop - | .comment _ => True - | .let_ _ value => yulExprNoRef name value - | .letMany _ value => yulExprNoRef name value - | .assign _ value => yulExprNoRef name value - | .expr expr => yulExprNoRef name expr - | .leave => True - | .if_ cond body => yulExprNoRef name cond ∧ yulStmtsNoRef name body - | .for_ init cond post body => - yulStmtsNoRef name init ∧ yulExprNoRef name cond ∧ - yulStmtsNoRef name post ∧ yulStmtsNoRef name body - | .switch expr cases defaultCase => - yulExprNoRef name expr ∧ yulSwitchCasesNoRef name cases ∧ - yulOptionStmtsNoRef name defaultCase - | .block stmts => yulStmtsNoRef name stmts - | .funcDef _ _ _ _ => True - -private def yulStmtsNoRef (name : String) : List YulStmt → Prop - | [] => True - | stmt :: stmts => yulStmtNoRef name stmt ∧ yulStmtsNoRef name stmts - -private def yulSwitchCasesNoRef (name : String) : List (Nat × List YulStmt) → Prop - | [] => True - | (_, body) :: rest => yulStmtsNoRef name body ∧ yulSwitchCasesNoRef name rest - -private def yulOptionStmtsNoRef (name : String) : Option (List YulStmt) → Prop - | none => True - | some body => yulStmtsNoRef name body -end - -/-- Explicit theorem hypothesis used in place of the old kernel axiom. -/ -private def HasSelectorDeadBridge (body : List YulStmt) : Prop := - ∀ state fuel, - yulStmtsNoRef "__has_selector" body → - yulResultOfExecWithRollback state - (execYulStmtsFuel fuel (state.setVar "__has_selector" 1) body) = - yulResultOfExecWithRollback state - (execYulStmtsFuel fuel state body) - -/-- Helper: initial Yul state aligned with the IR transaction/state. -/ -private def initialYulState (tx : YulTransaction) (state : IRState) : YulState := - YulState.initial tx state.storage state.events - -private def resultsMatch (ir : IRResult) (yul : YulResult) : Prop := - ir.success = yul.success ∧ - ir.returnValue = yul.returnValue ∧ - (∀ slot, ir.finalStorage slot = yul.finalStorage slot) ∧ - (∀ base key, ir.finalMappings base key = yul.finalMappings base key) ∧ - ir.events = yul.events - -private def switchCaseBody (fn : IRFunction) : List YulStmt := - let valueGuard := if fn.payable then [] else [Compiler.callvalueGuard] - [YulStmt.comment s!"{fn.name}()"] ++ valueGuard ++ - [Compiler.calldatasizeGuard fn.params.length] ++ fn.body - -private def switchCases (fns : List IRFunction) : List (Prod Nat (List YulStmt)) := - fns.map (fun f => (f.selector, switchCaseBody f)) - -private def switchDefaultCase - (fallback : Option IREntrypoint) - (receive : Option IREntrypoint) : List YulStmt := - match receive, fallback with - | none, none => - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - | none, some fb => - let valueGuard := if fb.payable then [] else [Compiler.callvalueGuard] - [YulStmt.comment "fallback()"] ++ valueGuard ++ fb.body - | some rc, none => - let receiveGuard := if rc.payable then [] else [Compiler.callvalueGuard] - [YulStmt.block [ - YulStmt.let_ "__is_empty_calldata" - (YulExpr.call "eq" [YulExpr.call "calldatasize" [], YulExpr.lit 0]), - YulStmt.if_ (YulExpr.ident "__is_empty_calldata") - ([YulStmt.comment "receive()"] ++ receiveGuard ++ rc.body), - YulStmt.if_ (YulExpr.call "iszero" [YulExpr.ident "__is_empty_calldata"]) - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - ]] - | some rc, some fb => - let receiveGuard := if rc.payable then [] else [Compiler.callvalueGuard] - let fallbackGuard := if fb.payable then [] else [Compiler.callvalueGuard] - [YulStmt.block [ - YulStmt.let_ "__is_empty_calldata" - (YulExpr.call "eq" [YulExpr.call "calldatasize" [], YulExpr.lit 0]), - YulStmt.if_ (YulExpr.ident "__is_empty_calldata") - ([YulStmt.comment "receive()"] ++ receiveGuard ++ rc.body), - YulStmt.if_ (YulExpr.call "iszero" [YulExpr.ident "__is_empty_calldata"]) - ([YulStmt.comment "fallback()"] ++ fallbackGuard ++ fb.body) - ]] - -@[simp] -private theorem preservation_execYulStmtFuel_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body : List YulStmt) : - execYulStmtFuel fuel state (YulStmt.funcDef name params ret body) = - YulExecResult.continue state := by - cases fuel <;> simp [execYulStmtFuel, legacyExecYulFuel] - -@[simp] -private theorem preservation_legacyExecYulFuel_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body : List YulStmt) : - legacyExecYulFuel fuel state (.stmt (YulStmt.funcDef name params ret body)) = - YulExecResult.continue state := by - cases fuel <;> simp [legacyExecYulFuel] - -private theorem preservation_execYulStmtsFuel_cons_funcDef (fuel : Nat) (state : YulState) - (name : String) (params ret : List String) (body rest : List YulStmt) : - execYulStmtsFuel (Nat.succ fuel) state (YulStmt.funcDef name params ret body :: rest) = - execYulStmtsFuel fuel state rest := by - simp only [execYulStmtsFuel, legacyExecYulFuel] - rw [preservation_legacyExecYulFuel_funcDef] - -private theorem preservation_emitYul_runtimeCode_eq (contract : IRContract) : - (Compiler.emitYul contract).runtimeCode = Compiler.runtimeCode contract := by - rfl - -private theorem preservation_evalYulExpr_selectorExpr (state : YulState) : - evalYulExpr state selectorExpr = some (state.selector % selectorModulus) := by - have hShiftModEq : selectorShift % evmModulus = selectorShift := by - have hShiftLtModulus : selectorShift < evmModulus := by - norm_num [selectorShift, evmModulus] - exact Nat.mod_eq_of_lt hShiftLtModulus - have hSelectorShiftLt256 : selectorShift < 256 := by - norm_num [selectorShift] - have hSelectorShiftNotGe256 : ¬ 256 ≤ selectorShift := Nat.not_le_of_lt hSelectorShiftLt256 - have hSelectorWordLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < evmModulus := by - have hModLt : state.selector % selectorModulus < selectorModulus := by - exact Nat.mod_lt _ (by decide) - have hPowPos : 0 < 2 ^ selectorShift := by - exact Nat.pow_pos (a := 2) (n := selectorShift) (by decide) - have hMulLt : - (state.selector % selectorModulus) * 2 ^ selectorShift < - selectorModulus * 2 ^ selectorShift := by - exact Nat.mul_lt_mul_of_pos_right hModLt hPowPos - have hModulusSplit : selectorModulus * 2 ^ selectorShift = evmModulus := by - norm_num [selectorModulus, selectorShift, evmModulus, Nat.pow_add, Nat.mul_comm, - Nat.mul_left_comm, Nat.mul_assoc] - simpa [hModulusSplit] using hMulLt - have hSelectorWordMod : - ((state.selector % selectorModulus) * 2 ^ selectorShift) % evmModulus = - (state.selector % selectorModulus) * 2 ^ selectorShift := by - exact Nat.mod_eq_of_lt hSelectorWordLt - simp [selectorExpr, evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext, - Backends.evalBuiltinCallViaEvmYulLean, - calldataloadWord, selectorWord, - hShiftModEq, hSelectorWordMod, hSelectorShiftNotGe256] - -private theorem preservation_evalYulExpr_selectorExpr_eq (state : YulState) - (hselector : state.selector < selectorModulus) : - evalYulExpr state selectorExpr = some state.selector := by - rw [preservation_evalYulExpr_selectorExpr] - simp [Nat.mod_eq_of_lt hselector] - -private theorem preservation_execYulStmtFuel_switch_match - (state : YulState) (expr : YulExpr) (cases' : List (Prod Nat (List YulStmt))) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) (body : List YulStmt) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun (c, _) => c = v) cases' = some (v, body)) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - execYulStmtsFuel fuel state body := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind] - -private def preservation_execYulStmtFuel_switch_miss_result (state : YulState) (fuel : Nat) - (defaultCase : Option (List YulStmt)) : YulExecResult := - match defaultCase with - | some body => execYulStmtsFuel fuel state body - | none => YulExecResult.continue state - -private theorem preservation_execYulStmtFuel_switch_miss - (state : YulState) (expr : YulExpr) (cases' : List (Prod Nat (List YulStmt))) - (defaultCase : Option (List YulStmt)) (fuel v : Nat) - (hEval : evalYulExpr state expr = some v) - (hFind : List.find? (fun (c, _) => c = v) cases' = none) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.switch expr cases' defaultCase) = - preservation_execYulStmtFuel_switch_miss_result state fuel defaultCase := by - cases fuel with - | zero => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind, - preservation_execYulStmtFuel_switch_miss_result] - rfl - | succ fuel => - simp [execYulStmtFuel, execYulStmtsFuel, legacyExecYulFuel, hEval, hFind, - preservation_execYulStmtFuel_switch_miss_result] - rfl - -private theorem preservation_find_switch_case_of_find_function - (fns : List IRFunction) (sel : Nat) (fn : IRFunction) - (hFind : fns.find? (fun f => f.selector == sel) = some fn) : - (switchCases fns).find? (fun (c, _) => c = sel) = - some (fn.selector, switchCaseBody fn) := by - induction fns with - | nil => - simp at hFind - | cons f rest ih => - by_cases hsel : f.selector = sel - · have hselb : (f.selector == sel) = true := by - simp [hsel] - have hFind' : some f = some fn := by - simpa [List.find?, hselb] using hFind - cases hFind' - simp [switchCases, hsel] - · have hselb : (f.selector == sel) = false := by - simp [hsel] - have hFind' : rest.find? (fun f => f.selector == sel) = some fn := by - simpa [List.find?, hselb] using hFind - have ih' := ih hFind' - simpa [switchCases, List.find?, hsel] using ih' - -private theorem preservation_find_switch_case_of_find_function_eq_selector - (fns : List IRFunction) (sel : Nat) (fn : IRFunction) - (hFind : fns.find? (fun f => f.selector == sel) = some fn) : - (switchCases fns).find? (fun (c, _) => c = sel) = - some (sel, switchCaseBody fn) := by - have hCase := preservation_find_switch_case_of_find_function fns sel fn hFind - have hSel : fn.selector = sel := by - have h := List.find?_some hFind - simp at h - exact h - simpa [hSel] using hCase - -private theorem preservation_find_switch_case_of_find_function_none - (fns : List IRFunction) (sel : Nat) - (hFind : fns.find? (fun f => f.selector == sel) = none) : - (switchCases fns).find? (fun (c, _) => c = sel) = none := by - induction fns with - | nil => - simp at hFind - simp [switchCases] - | cons f rest ih => - by_cases hsel : f.selector = sel - · have hselb : (f.selector == sel) = true := by - simp [hsel] - have hFind' : (some f : Option IRFunction) = none := by - simp [List.find?, hselb] at hFind - cases hFind' - · have hselb : (f.selector == sel) = false := by - simp [hsel] - have hFind' : rest.find? (fun f => f.selector == sel) = none := by - simpa [List.find?, hselb] using hFind - have ih' := ih hFind' - simpa [switchCases, List.find?, hsel] using ih' - -private theorem preservation_execYulStmtsFuel_funcDefs_then_suffix (fuel : Nat) (state : YulState) - (prefix_ : List YulStmt) (suffix_ : List YulStmt) - (hFuncDefs : ∀ s ∈ prefix_, ∃ nm p r b, s = YulStmt.funcDef nm p r b) : - execYulStmtsFuel (prefix_.length + fuel) state (prefix_ ++ suffix_) = - execYulStmtsFuel fuel state suffix_ := by - induction prefix_ generalizing state with - | nil => simp - | cons h t ih => - have hmem : h ∈ h :: t := .head t - obtain ⟨nm, p, r, b, rfl⟩ := hFuncDefs h hmem - simp only [List.cons_append, List.length_cons] - conv_lhs => rw [show t.length + 1 + fuel = Nat.succ (t.length + fuel) from by omega] - rw [preservation_execYulStmtsFuel_cons_funcDef] - exact ih state (fun s hs => hFuncDefs s (List.mem_cons_of_mem _ hs)) - -private theorem preservation_execYulStmtsFuel_funcDefs_then_suffix_ge - (fuel : Nat) (state : YulState) - (prefix_ : List YulStmt) (suffix_ : List YulStmt) - (hFuncDefs : ∀ s ∈ prefix_, ∃ nm p r b, s = YulStmt.funcDef nm p r b) - (hFuel : fuel ≥ prefix_.length) : - execYulStmtsFuel fuel state (prefix_ ++ suffix_) = - execYulStmtsFuel (fuel - prefix_.length) state suffix_ := by - have : fuel = prefix_.length + (fuel - prefix_.length) := by omega - conv_lhs => rw [this] - exact preservation_execYulStmtsFuel_funcDefs_then_suffix _ state prefix_ suffix_ hFuncDefs - -@[simp] -private theorem evalYulExpr_selectorExpr_initial - (tx : YulTransaction) (state : IRState) - (hselector : tx.functionSelector < selectorModulus) : - evalYulExpr (initialYulState tx state) selectorExpr = some tx.functionSelector := by - simpa using (preservation_evalYulExpr_selectorExpr_eq (initialYulState tx state) hselector) - -/-- Well-formedness: all internalFunctions are funcDef statements. -/ -private def ContractWF (contract : IRContract) : Prop := - ∀ s ∈ contract.internalFunctions, ∃ n p r b, s = YulStmt.funcDef n p r b - -private theorem runtimeCode_prefix_allFuncDefs (contract : IRContract) - (hWF : ContractWF contract) : - ∀ s ∈ (if contract.usesMapping then [Compiler.mappingSlotFuncAt 0] else []) ++ - contract.internalFunctions, - ∃ nm p r b, s = YulStmt.funcDef nm p r b := by - intro s hs - simp only [List.mem_append] at hs - cases hs with - | inl hMapping => - split at hMapping <;> simp at hMapping - subst hMapping - exact ⟨"mappingSlot", ["baseSlot", "key"], ["slot"], _, rfl⟩ - | inr hInternal => exact hWF s hInternal - -private theorem list_length_le_sizeOf : (l : List YulStmt) → l.length ≤ sizeOf l - | [] => by simp - | _ :: t => by - simp [List.length_cons] - have := list_length_le_sizeOf t - omega - -private theorem sizeOf_append_ge_length_add (l₁ l₂ : List YulStmt) : - sizeOf (l₁ ++ l₂) ≥ l₁.length + sizeOf l₂ := by - induction l₁ with - | nil => simp - | cons h t ih => - simp only [List.cons_append, List.length_cons] - have : sizeOf (h :: (t ++ l₂)) = 1 + sizeOf h + sizeOf (t ++ l₂) := rfl - omega - -/-- Membership in a list implies the element's sizeOf is strictly smaller than the list's. -/ -private theorem sizeOf_lt_of_mem {α : Type _} [SizeOf α] {x : α} {l : List α} - (hx : x ∈ l) : sizeOf x < sizeOf l := by - induction l with - | nil => cases hx - | cons h t ih => - cases hx with - | head => show sizeOf x < 1 + sizeOf x + sizeOf t; omega - | tail _ hmem => have := ih hmem; show sizeOf x < 1 + sizeOf h + sizeOf t; omega - -/-- The `buildSwitch` output for a list of functions has `sizeOf` at least -`sizeOf fn.body + 12` for any function in the list. This is a structural -bound following from the nesting depth of the generated Yul AST. -/ -private theorem sizeOf_switchCaseBody_ge (fn : IRFunction) : - sizeOf (switchCaseBody fn) ≥ sizeOf fn.body + 2 := by - -- switchCaseBody fn = prefix ++ fn.body where prefix has ≥ 2 elements - show sizeOf (([YulStmt.comment s!"{fn.name}()"] ++ - (if fn.payable then [] else [Compiler.callvalueGuard]) ++ - [Compiler.calldatasizeGuard fn.params.length]) ++ fn.body) ≥ _ - have h := sizeOf_append_ge_length_add - ([YulStmt.comment s!"{fn.name}()"] ++ - (if fn.payable then [] else [Compiler.callvalueGuard]) ++ - [Compiler.calldatasizeGuard fn.params.length]) - fn.body - have hlen : ([YulStmt.comment s!"{fn.name}()"] ++ - (if fn.payable then [] else [Compiler.callvalueGuard]) ++ - [Compiler.calldatasizeGuard fn.params.length]).length ≥ 2 := by - cases fn.payable <;> simp - omega - -/-- `sizeOf` of the `switchCases` list is strictly greater than `sizeOf (switchCaseBody fn)` -for any `fn ∈ fns`. -/ -private theorem sizeOf_switchCases_gt_body {fns : List IRFunction} {fn : IRFunction} - (hmem : fn ∈ fns) : - sizeOf (switchCases fns) > sizeOf (switchCaseBody fn) := by - have hmem' : (fn.selector, switchCaseBody fn) ∈ switchCases fns := by - simp only [switchCases] - exact List.mem_map_of_mem hmem - have hlt := sizeOf_lt_of_mem hmem' - have : sizeOf (fn.selector, switchCaseBody fn) = - 1 + sizeOf fn.selector + sizeOf (switchCaseBody fn) := rfl - omega - -/-- Helper: `sizeOf` of a singleton list `[x]` equals `1 + sizeOf x + 1`. -/ -private theorem sizeOf_singleton_list {α : Type _} [SizeOf α] (x : α) : - sizeOf [x] = 1 + sizeOf x + 1 := rfl - -/-- Helper: `sizeOf` of a 3-element list. -/ -private theorem sizeOf_list_three {α : Type _} [SizeOf α] (a b c : α) : - sizeOf [a, b, c] = 1 + sizeOf a + (1 + sizeOf b + (1 + sizeOf c + 1)) := rfl - -/-- `buildSwitch fns none none` wraps `switchCases fns` in an AST structure that adds -a fixed overhead. The nesting is: -`[block [let_, if_, if_ [switch selectorExpr (switchCases fns) (some default)]]]`. -/ -private theorem sizeOf_buildSwitch_ge_switchCases - (fns : List IRFunction) : - sizeOf [Compiler.CodegenCommon.buildSwitch fns none none] ≥ sizeOf (switchCases fns) + 9 := by - -- sizeOf [x] = sizeOf x + 2 - have h_list : sizeOf [Compiler.CodegenCommon.buildSwitch fns none none] ≥ - sizeOf (Compiler.CodegenCommon.buildSwitch fns none none) + 2 := by - show 1 + sizeOf (Compiler.CodegenCommon.buildSwitch fns none none) + 1 ≥ _; omega - suffices h : sizeOf (Compiler.CodegenCommon.buildSwitch fns none none) ≥ - sizeOf (switchCases fns) + 7 by - omega - -- Unfold buildSwitch, simplify the sortCasesBySelector=false branch, fold map to switchCases - change sizeOf (Compiler.CodegenCommon.buildSwitch fns none none false) ≥ _ - unfold Compiler.CodegenCommon.buildSwitch - simp only [ite_false, Bool.false_eq_true, Compiler.CodegenCommon.defaultDispatchCase] - have hcases : - (fns.map (fun fn => - (fn.selector, - Compiler.CodegenCommon.dispatchBody fn.payable s!"{fn.name}()" - ([Compiler.CodegenCommon.calldatasizeGuard fn.params.length] ++ fn.body)))) = - switchCases fns := by - induction fns with - | nil => - simp [switchCases] - | cons fn rest ih => - cases hpay : fn.payable <;> - simp [switchCases, switchCaseBody, Compiler.CodegenCommon.dispatchBody, - Compiler.callvalueGuard, Compiler.calldatasizeGuard, - Compiler.CodegenCommon.callvalueGuard, Compiler.CodegenCommon.calldatasizeGuard, - hpay, ih] - rw [hcases] - -- Name sub-expressions and decompose sizeOf level by level (simp normalizes - -- auto-generated SizeOf instances; omega closes the arithmetic) - set defaultStmts : List YulStmt := - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - set sw := YulStmt.switch - (YulExpr.call "shr" [YulExpr.lit selectorShift, YulExpr.call "calldataload" [YulExpr.lit 0]]) - (switchCases fns) (some defaultStmts) - set if2 := YulStmt.if_ (YulExpr.ident "__has_selector") [sw] - have h1 : sizeOf (YulStmt.block [ - YulStmt.let_ "__has_selector" (YulExpr.call "iszero" - [YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit 4]]), - YulStmt.if_ (YulExpr.call "iszero" [YulExpr.ident "__has_selector"]) defaultStmts, - if2]) ≥ 5 + sizeOf if2 := by simp; omega - have h2 : sizeOf if2 ≥ 2 + sizeOf [sw] := by simp [if2]; omega - have h3 : sizeOf [sw] = sizeOf sw + 2 := by simp; omega - have h4 : sizeOf sw ≥ 1 + sizeOf (switchCases fns) := by simp [sw]; omega - omega - -private theorem sizeOf_buildSwitch_ge_fn_body - {fns : List IRFunction} {fn : IRFunction} - (hmem : fn ∈ fns) : - sizeOf [Compiler.CodegenCommon.buildSwitch fns none none] ≥ sizeOf fn.body + 12 := by - have h1 := sizeOf_buildSwitch_ge_switchCases fns - have h2 := sizeOf_switchCases_gt_body hmem - have h3 := sizeOf_switchCaseBody_ge fn - omega - -/-- Calldatasize is always ≥ 4 in the proof semantics (4-byte selector prefix). -/ -@[simp] private theorem calldatasize_ge_4 (args : List Nat) : - ¬ (4 + args.length * 32 < 4) := by omega - -/-- Simplification: lt(calldatasize, 4) = 0. -/ -@[simp] private theorem calldatasize_lt_4_eq_zero (args : List Nat) : - (if 4 + args.length * 32 < 4 then 1 else 0) = (0 : Nat) := by - simp [show ¬ (4 + args.length * 32 < 4) from by omega] - -/-- Simplification: iszero(0) = 1. -/ -@[simp] private theorem iszero_zero : (if (0 : Nat) = 0 then 1 else 0) = (1 : Nat) := by simp - -/-- Simplification: iszero(1) = 0. -/ -@[simp] private theorem iszero_one : (if (1 : Nat) = 0 then 1 else 0) = (0 : Nat) := by simp - -/-- Simplification: 1 ≠ 0 for if_ branch. -/ -@[simp] private theorem one_ne_zero : (1 : Nat) ≠ 0 := by omega - -/-- Identity simplifier for result-shaped matches emitted by `legacyExecYulFuel` reductions. -/ -@[simp] private theorem yulExecResult_match_id (r : YulExecResult) : - (match r with - | .continue s => .continue s - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s) = r := by - cases r <;> rfl - -/-- Executing a singleton statement list consumes one list-step of fuel. -/ -@[simp] private theorem execYulStmtsFuel_singleton_succ_bridge - (fuel : Nat) (state : YulState) (stmt : YulStmt) : - execYulStmtsFuel (fuel + 2) state [stmt] = execYulStmtFuel (fuel + 1) state stmt := by - simp [execYulStmtsFuel, execYulStmtFuel, legacyExecYulFuel] - cases hExec : legacyExecYulFuel (fuel + 1) state (.stmt stmt) <;> simp - -/-- Fueled `if_` step: a zero condition skips the body and continues unchanged. -/ -@[simp] private theorem execYulStmtFuel_if_zero_continue_bridge - (fuel : Nat) (state : YulState) (cond : YulExpr) (body : List YulStmt) - (hEval : evalYulExpr state cond = some 0) : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = .continue state := by - simp [execYulStmtFuel, legacyExecYulFuel, hEval] - -/-- Fueled `if_` step: a nonzero condition executes the body with decremented fuel. -/ -@[simp] private theorem execYulStmtFuel_if_nonzero_exec_bridge - (fuel : Nat) (state : YulState) (cond : YulExpr) (body : List YulStmt) (v : Nat) - (hEval : evalYulExpr state cond = some v) (hNonzero : v ≠ 0) : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = execYulStmtsFuel fuel state body := by - simpa [execYulStmtsFuel] using - (by simp [execYulStmtFuel, legacyExecYulFuel, hEval, hNonzero] : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = - legacyExecYulFuel fuel state (.stmts body)) - -/-- Zero fuel on a non-empty statement list always reverts. -/ -@[simp] private theorem execYulStmtsFuel_zero_of_ne_nil_bridge - (state : YulState) (stmts : List YulStmt) (hNe : stmts ≠ []) : - execYulStmtsFuel 0 state stmts = .revert state := by - cases stmts with - | nil => cases hNe rfl - | cons stmt rest => - simp [execYulStmtsFuel, legacyExecYulFuel] - -/-- `callvalueGuard` is a no-op when the execution context observes zero - `callvalue()` modulo `2^256`, matching `DispatchGuardsSafe`. -/ -private theorem exec_callvalueGuard_noop (fuel : Nat) (state : YulState) - (hMsgValue : state.msgValue % evmModulus = 0) : - execYulStmtsFuel (fuel + 2) state [Compiler.callvalueGuard] = - YulExecResult.continue state := by - have hCallvalue : evalYulExpr state (YulExpr.call "callvalue" []) = some 0 := by - simp [hMsgValue, evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext] - have hstmt : - execYulStmtFuel (fuel + 1) state Compiler.callvalueGuard = .continue state := by - simpa [Compiler.callvalueGuard] using - (execYulStmtFuel_if_zero_continue_bridge fuel state - (YulExpr.call "callvalue" []) - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - hCallvalue) - simpa [execYulStmtsFuel_singleton_succ_bridge] using hstmt - -/-- If calldata is too short for the expected arity, the singleton - `calldatasizeGuard` list reverts. This is the smallest checked short-arity - guard fact needed for the remaining switch-case bridge work. -/ -private theorem exec_calldatasizeGuard_revert_of_short_noWrap - (fuel : Nat) (state : YulState) (numParams : Nat) - (hShort : ¬ numParams ≤ state.calldata.length) - (hDataNoWrap : 4 + state.calldata.length * 32 < evmModulus) - (hParamNoWrap : 4 + numParams * 32 < evmModulus) : - execYulStmtsFuel (fuel + 2) state [Compiler.calldatasizeGuard numParams] = - .revert state := by - have hLtTrue : 4 + state.calldata.length * 32 < 4 + numParams * 32 := by - omega - have hEval : - evalYulExpr state - (YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit (4 + numParams * 32)]) = - some 1 := by - simp [evalYulExpr, evalYulCall, evalYulExprs, evalBuiltinCallWithBackendContext, - Backends.evalBuiltinCallWithEvmYulLeanContext, Backends.evalBuiltinCallViaEvmYulLean, - hLtTrue, Nat.mod_eq_of_lt hDataNoWrap, Nat.mod_eq_of_lt hParamNoWrap] - have hguard : - execYulStmtFuel (fuel + 1) state (Compiler.calldatasizeGuard numParams) = - execYulStmtsFuel fuel state [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] := by - simpa [Compiler.calldatasizeGuard] using - (execYulStmtFuel_if_nonzero_exec_bridge fuel state - (YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit (4 + numParams * 32)]) - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - 1 hEval one_ne_zero) - have hRevertBody : - execYulStmtsFuel fuel state [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] = - .revert state := by - cases fuel with - | zero => - exact execYulStmtsFuel_zero_of_ne_nil_bridge state - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] (by simp) - | succ k => - cases k <;> simp [legacyExecYulFuel, execYulStmtsFuel, execYulStmtFuel] - rw [execYulStmtsFuel_singleton_succ_bridge, hguard, hRevertBody] - -/-- If calldata has enough words for `numParams`, `calldatasizeGuard` is a no-op. - -Under the current builtin model, `lt` compares modulo `2^256`, so the generic -statement additionally needs a no-wrap hypothesis on `calldatasize()`. -/ -private theorem exec_calldatasizeGuard_noop_of_noWrap - (fuel : Nat) (state : YulState) (numParams : Nat) - (hArity : numParams ≤ state.calldata.length) - (hNoWrap : 4 + state.calldata.length * 32 < evmModulus) : - execYulStmtsFuel (fuel + 2) state [Compiler.calldatasizeGuard numParams] = - YulExecResult.continue state := by - have hLtFalse : ¬ (4 + state.calldata.length * 32 < 4 + numParams * 32) := by - omega - have hParamNoWrap : 4 + numParams * 32 < evmModulus := by - omega - have hEval : - evalYulExpr state - (YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit (4 + numParams * 32)]) = - some 0 := by - simp [evalYulExpr, evalYulCall, evalYulExprs, evalBuiltinCallWithBackendContext, - Backends.evalBuiltinCallWithEvmYulLeanContext, Backends.evalBuiltinCallViaEvmYulLean, - hLtFalse, Nat.mod_eq_of_lt hNoWrap, Nat.mod_eq_of_lt hParamNoWrap] - have hstmt : - execYulStmtFuel (fuel + 1) state (Compiler.calldatasizeGuard numParams) = .continue state := by - simpa [Compiler.calldatasizeGuard] using - (execYulStmtFuel_if_zero_continue_bridge fuel state - (YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit (4 + numParams * 32)]) - [YulStmt.expr (YulExpr.call "revert" [YulExpr.lit 0, YulExpr.lit 0])] - hEval) - simpa [execYulStmtsFuel_singleton_succ_bridge] using hstmt - -/-! ### buildSwitch stepping lemmas - -The `buildSwitch` block structure generates: -``` -block [ - let_ "__has_selector" (iszero(lt(calldatasize(), 4))), - if_ (iszero "__has_selector") defaultCase, - if_ "__has_selector" [switch selectorExpr cases (some defaultCase)] -] -``` - -Executing this with enough fuel steps through: -1. `calldatasize() = 4 + calldata.length * 32 ≥ 4` always, so `lt(_, 4) = 0`, `iszero(0) = 1` -2. `__has_selector = 1`, so `iszero(1) = 0` → first `if_` skipped -3. `1 ≠ 0` → second `if_` enters body containing the switch - -This reduction is proved mechanically below via bridge lemmas that avoid -`legacyExecYulFuel`'s `[reducible]` over-reduction into `Option.map`/`List.find?_map` -fusion forms. --/ - -/-- After setting `__has_selector := 1`, reading `__has_selector` yields 1. -/ -private theorem eval_hasSelector_after_set (state : YulState) : - evalYulExpr (state.setVar "__has_selector" 1) (YulExpr.ident "__has_selector") = some 1 := by - simp [evalYulExpr, YulState.setVar, YulState.getVar] - -/-- Fueled `if_` step: a zero condition skips the body and continues unchanged. -/ -@[simp] private theorem execYulStmtFuel_if_zero_continue - (fuel : Nat) (state : YulState) (cond : YulExpr) (body : List YulStmt) - (hEval : evalYulExpr state cond = some 0) : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = .continue state := by - simp [execYulStmtFuel, legacyExecYulFuel, hEval] - -/-- Fueled `if_` step: a nonzero condition executes the body with decremented fuel. -/ -@[simp] private theorem execYulStmtFuel_if_nonzero_exec - (fuel : Nat) (state : YulState) (cond : YulExpr) (body : List YulStmt) (v : Nat) - (hEval : evalYulExpr state cond = some v) (hNonzero : v ≠ 0) : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = execYulStmtsFuel fuel state body := by - simpa [execYulStmtsFuel] using - (by simp [execYulStmtFuel, legacyExecYulFuel, hEval, hNonzero] : - execYulStmtFuel (fuel + 1) state (YulStmt.if_ cond body) = - legacyExecYulFuel fuel state (.stmts body)) - -/-- Zero fuel on a non-empty statement list always reverts. -/ -@[simp] private theorem execYulStmtsFuel_zero_of_ne_nil - (state : YulState) (stmts : List YulStmt) (hNe : stmts ≠ []) : - execYulStmtsFuel 0 state stmts = .revert state := by - cases stmts with - | nil => - contradiction - | cons _ _ => - simp [execYulStmtsFuel, legacyExecYulFuel] - -/-- Executing a singleton statement list consumes one list-step of fuel. -/ -@[simp] private theorem execYulStmtsFuel_singleton_succ_local - (fuel : Nat) (state : YulState) (stmt : YulStmt) : - execYulStmtsFuel (fuel + 2) state [stmt] = execYulStmtFuel (fuel + 1) state stmt := by - simp [execYulStmtsFuel, execYulStmtFuel, legacyExecYulFuel] - cases hExec : legacyExecYulFuel (fuel + 1) state (.stmt stmt) <;> simp - -/-- Executing `[buildSwitch fns none none]` with enough fuel reduces to the singleton - switch list when `calldatasize()` does not wrap modulo `2^256`. - - The old direct-`execYulStmtFuel` target was stronger than the literal small-step - trace provides; this singleton-list form is the strongest true shape needed by - the current Layer 3 proof. -/ -private theorem execBuildSwitch_none_none_aux_of_noWrap (fuel : Nat) (state : YulState) - (fns : List IRFunction) - (hNoWrap : 4 + state.calldata.length * 32 < evmModulus) : - execYulStmtsFuel (fuel + 6) state [Compiler.CodegenCommon.buildSwitch fns none none] = - execYulStmtsFuel fuel (state.setVar "__has_selector" 1) - [YulStmt.switch selectorExpr (switchCases fns) - (some (switchDefaultCase none none))] := by - let state' := state.setVar "__has_selector" 1 - have h4 : 4 < evmModulus := by - norm_num [evmModulus] - have hHasSelectorEval : - evalYulExpr state - (YulExpr.call "iszero" - [YulExpr.call "lt" [YulExpr.call "calldatasize" [], YulExpr.lit 4]]) = some 1 := by - simp [evalYulExpr, evalYulCall, evalYulExprs, evalBuiltinCallWithBackendContext, - Backends.evalBuiltinCallWithEvmYulLeanContext, Backends.evalBuiltinCallViaEvmYulLean, - Nat.mod_eq_of_lt hNoWrap, Nat.mod_eq_of_lt h4] - have hIdentEval : - evalYulExpr state' (YulExpr.ident "__has_selector") = some 1 := by - simpa [state', evalYulExpr] using eval_hasSelector_after_set state - have hIfZeroEval : - evalYulExpr state' - (YulExpr.call "iszero" [YulExpr.ident "__has_selector"]) = some 0 := by - simp [evalYulExpr, evalYulCall, evalYulExprs, - evalBuiltinCallWithBackendContext, Backends.evalBuiltinCallWithEvmYulLeanContext, - Backends.evalBuiltinCallViaEvmYulLean, hIdentEval] - rw [show fuel + 6 = (fuel + 4) + 2 by omega, execYulStmtsFuel_singleton_succ_local] - simp only [Compiler.CodegenCommon.buildSwitch, execYulStmtFuel, legacyExecYulFuel] - simp [state', execYulStmtsFuel, hHasSelectorEval, hIfZeroEval, hIdentEval, - switchCases, switchCaseBody, dispatchBody, selectorExpr, switchDefaultCase] - exact yulExecResult_match_id _ - -/-- Executing a singleton statement list consumes one list-step of fuel. -/ -@[simp] private theorem execYulStmtsFuel_singleton_succ - (fuel : Nat) (state : YulState) (stmt : YulStmt) : - execYulStmtsFuel (fuel + 2) state [stmt] = execYulStmtFuel (fuel + 1) state stmt := by - simp [execYulStmtsFuel, execYulStmtFuel, legacyExecYulFuel] - cases hExec : legacyExecYulFuel (fuel + 1) state (.stmt stmt) <;> simp - -/-- If a head statement continues, the surrounding list steps into the tail. -/ -@[simp] private theorem execYulStmtsFuel_cons_continue - (fuel : Nat) (state next : YulState) (stmt : YulStmt) (rest : List YulStmt) - (hstmt : execYulStmtFuel (fuel + 1) state stmt = .continue next) : - execYulStmtsFuel (fuel + 2) state (stmt :: rest) = - execYulStmtsFuel (fuel + 1) next rest := by - have hstmt' : legacyExecYulFuel (fuel + 1) state (.stmt stmt) = .continue next := by - simpa [execYulStmtFuel] using hstmt - simp [execYulStmtsFuel, legacyExecYulFuel, hstmt'] - -/-- If a head statement reverts, the surrounding list reverts immediately. -/ -@[simp] private theorem execYulStmtsFuel_cons_revert - (fuel : Nat) (state : YulState) (stmt : YulStmt) (rest : List YulStmt) - (hstmt : execYulStmtFuel (fuel + 1) state stmt = .revert state) : - execYulStmtsFuel (fuel + 2) state (stmt :: rest) = .revert state := by - have hstmt' : legacyExecYulFuel (fuel + 1) state (.stmt stmt) = .revert state := by - simpa [execYulStmtFuel] using hstmt - simp [execYulStmtsFuel, legacyExecYulFuel, hstmt'] - -/-- The case list emitted by `buildSwitch` is definitionally `switchCases`. - Keeping this fact explicit helps avoid large reducible unfold chains in the - buildSwitch stepping proofs. -/ -private theorem buildSwitch_cases_eq_switchCases (fns : List IRFunction) : - (fns.map (fun fn => - (fn.selector, - dispatchBody fn.payable s!"{fn.name}()" - ([calldatasizeGuard fn.params.length] ++ fn.body)))) = - switchCases fns := by - induction fns with - | nil => - simp [switchCases] - | cons fn rest ih => - cases hpay : fn.payable <;> - simp [switchCases, switchCaseBody, dispatchBody, - Compiler.CodegenCommon.dispatchBody, Compiler.callvalueGuard, - Compiler.calldatasizeGuard, Compiler.CodegenCommon.callvalueGuard, - Compiler.CodegenCommon.calldatasizeGuard, hpay, ih] - -/-- Normalize switch-case lookup to function-list lookup. - This removes `List.find?_map` noise from mechanical `buildSwitch` proofs. -/ -private theorem find_switchCases_eq_find_function - (fns : List IRFunction) (sel : Nat) : - (switchCases fns).find? (fun (c, _) => c = sel) = - Option.map (fun fn => (fn.selector, switchCaseBody fn)) - (fns.find? (fun fn => fn.selector == sel)) := by - induction fns with - | nil => - simp [switchCases] - | cons fn rest ih => - by_cases hsel : fn.selector = sel - · simp [switchCases, hsel] - · have hPred : - ((fun x : Prod Nat (List YulStmt) => decide (x.1 = sel)) ∘ - fun f : IRFunction => (f.selector, switchCaseBody f)) = - (fun f : IRFunction => f.selector == sel) := by - funext f - simp [beq_eq_decide] - simp [switchCases, hsel, hPred] - -/-- `selectorExpr` does not depend on `__has_selector`, so the selector evaluation - is the same in the augmented state. -/ -private theorem evalSelectorExpr_setVar_has_selector (state : YulState) (v : Nat) - (hselector : state.selector < selectorModulus) : - evalYulExpr (state.setVar "__has_selector" v) selectorExpr = - some state.selector := by - -- Keep this bridge local and avoid unfolding the full builtin evaluator. - simpa using (preservation_evalYulExpr_selectorExpr_eq (state.setVar "__has_selector" v) (by - simpa [YulState.setVar] using hselector)) - -/-- In the non-payable branch, `DispatchGuardsSafe` forces `msgValue = 0 mod 2^256`. -/ -private theorem dispatchGuardsSafe_msgValue_zero_mod_of_nonpayable - (fn : IRFunction) (tx : IRTransaction) - (hguards : DispatchGuardsSafe fn tx) - (hNonPayable : fn.payable = false) : - tx.msgValue % evmModulus = 0 := by - rcases hguards with ⟨hValueSafe, _⟩ - rcases hValueSafe with hPayable | hZero - · cases (by simp [hNonPayable] at hPayable : False) - · exact hZero - -private theorem exec_switchCaseBody_revert_of_short - (fn : IRFunction) (tx : IRTransaction) (irState : IRState) (fuel : Nat) - (hguards : DispatchGuardsSafe fn tx) - (hNoWrap : 4 + tx.args.length * 32 < evmModulus) - (hShort : ¬ fn.params.length ≤ tx.args.length) : - execYulStmtsFuel (fuel + 2) - ((YulState.initial (YulTransaction.ofIR tx) - irState.storage irState.events).setVar "__has_selector" 1) - (switchCaseBody fn) = - .revert - ((YulState.initial (YulTransaction.ofIR tx) - irState.storage irState.events).setVar "__has_selector" 1) := by - rcases hguards with ⟨hValueSafe, hParamNoWrap⟩ - let state := - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - have hDataNoWrap : 4 + state.calldata.length * 32 < evmModulus := by - simpa [state, YulState.initial, YulState.setVar] using hNoWrap - have hComment : - execYulStmtFuel (fuel + 1) state (YulStmt.comment s!"{fn.name}()") = .continue state := by - simp [execYulStmtFuel, legacyExecYulFuel] - cases hPayable : fn.payable with - | true => - rw [show switchCaseBody fn = - YulStmt.comment s!"{fn.name}()" :: Compiler.calldatasizeGuard fn.params.length :: fn.body by - simp [switchCaseBody, hPayable]] - rw [execYulStmtsFuel_cons_continue (fuel := fuel) (next := state) (hstmt := hComment)] - cases fuel with - | zero => - rfl - | succ fuel => - have hGuard : - execYulStmtFuel (fuel + 1) state (Compiler.calldatasizeGuard fn.params.length) = - .revert state := by - simpa [execYulStmtFuel] using - (exec_calldatasizeGuard_revert_of_short_noWrap fuel state fn.params.length - hShort hDataNoWrap hParamNoWrap) - exact execYulStmtsFuel_cons_revert (fuel := fuel) (state := state) - (stmt := Compiler.calldatasizeGuard fn.params.length) (rest := fn.body) hGuard - | false => - rw [show switchCaseBody fn = - YulStmt.comment s!"{fn.name}()" :: - Compiler.callvalueGuard :: - Compiler.calldatasizeGuard fn.params.length :: fn.body by - simp [switchCaseBody, hPayable]] - rw [execYulStmtsFuel_cons_continue (fuel := fuel) (next := state) (hstmt := hComment)] - cases fuel with - | zero => - rfl - | succ fuel => - have hMsgValue : - state.msgValue % evmModulus = 0 := by - have hZero : tx.msgValue % evmModulus = 0 := - dispatchGuardsSafe_msgValue_zero_mod_of_nonpayable fn tx - ⟨hValueSafe, hParamNoWrap⟩ hPayable - simpa [state, YulState.initial, YulState.setVar] using hZero - have hValueGuard : - execYulStmtFuel (fuel + 1) state Compiler.callvalueGuard = .continue state := by - simpa [execYulStmtFuel] using exec_callvalueGuard_noop fuel state hMsgValue - rw [execYulStmtsFuel_cons_continue (fuel := fuel) (next := state) (hstmt := hValueGuard)] - cases fuel with - | zero => - rfl - | succ fuel => - have hGuard : - execYulStmtFuel (fuel + 1) state (Compiler.calldatasizeGuard fn.params.length) = - .revert state := by - simpa [execYulStmtFuel] using - (exec_calldatasizeGuard_revert_of_short_noWrap fuel state fn.params.length - hShort hDataNoWrap hParamNoWrap) - exact execYulStmtsFuel_cons_revert (fuel := fuel) (state := state) - (stmt := Compiler.calldatasizeGuard fn.params.length) (rest := fn.body) hGuard - -private theorem SwitchCaseBodyBridge_short - (fn : IRFunction) (tx : IRTransaction) (irState : IRState) (fuel : Nat) : - DispatchGuardsSafe fn tx → - 4 + tx.args.length * 32 < evmModulus → - ¬ fn.params.length ≤ tx.args.length → - resultsMatch - { success := false - returnValue := none - finalStorage := irState.storage - finalMappings := storageAsMappings irState.storage - events := irState.events } - (yulResultOfExecWithRollback - (YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events) - (execYulStmtsFuel (fuel + 2) - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - (switchCaseBody fn))) := by - intro hguards hNoWrap hShort - have hExec := exec_switchCaseBody_revert_of_short fn tx irState fuel hguards hNoWrap hShort - rw [hExec] - simp [YulState.initial, yulResultOfExecWithRollback, resultsMatch] - -/-! ### switchCaseBody guard-stepping helpers - -These helpers decompose execution of `switchCaseBody fn` — which is -`[comment] ++ valueGuard ++ [calldatasizeGuard] ++ fn.body` — into -individually justified steps. --/ - -/-- When dispatch guards are safe and calldata is long enough, executing the - guard prefix of `switchCaseBody fn` is a no-op: the execution steps through - comment, optional callvalue guard, and calldatasize guard, reaching - `fn.body` in the same state with reduced fuel. This is the success-path - counterpart to `exec_switchCaseBody_revert_of_short`. -/ -private theorem exec_switchCaseBody_continue_of_long - (fn : IRFunction) (tx : IRTransaction) (irState : IRState) (fuel : Nat) - (hguards : DispatchGuardsSafe fn tx) - (hNoWrap : 4 + tx.args.length * 32 < evmModulus) - (hLong : fn.params.length ≤ tx.args.length) - (hfuel : fuel ≥ 2) : - ∃ fuel' : Nat, fuel' ≤ fuel ∧ fuel' ≥ fuel - 2 ∧ - execYulStmtsFuel (fuel + 2) - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - (switchCaseBody fn) = - execYulStmtsFuel fuel' - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - fn.body := by - rcases hguards with ⟨hValueSafe, hParamNoWrap⟩ - let state := - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - have hDataNoWrap : 4 + state.calldata.length * 32 < evmModulus := by - simpa [state, YulState.initial, YulState.setVar] using hNoWrap - have hArity : fn.params.length ≤ state.calldata.length := by - simpa [state, YulState.initial, YulState.setVar] using hLong - have hComment : - execYulStmtFuel (fuel + 1) state (YulStmt.comment s!"{fn.name}()") = .continue state := by - simp [execYulStmtFuel, legacyExecYulFuel] - cases hPayable : fn.payable with - | true => - rw [show switchCaseBody fn = - YulStmt.comment s!"{fn.name}()" :: Compiler.calldatasizeGuard fn.params.length :: fn.body by - simp [switchCaseBody, hPayable]] - rw [execYulStmtsFuel_cons_continue (fuel := fuel) (next := state) (hstmt := hComment)] - -- fuel ≥ 2, so fuel ≥ 1 and we can write fuel = k + 1 - obtain ⟨k, rfl⟩ : ∃ k, fuel = k + 1 := ⟨fuel - 1, by omega⟩ - have hGuard : - execYulStmtFuel (k + 1) state (Compiler.calldatasizeGuard fn.params.length) = - .continue state := by - simpa [execYulStmtFuel] using - (exec_calldatasizeGuard_noop_of_noWrap k state fn.params.length - hArity hDataNoWrap) - rw [execYulStmtsFuel_cons_continue (fuel := k) (next := state) (hstmt := hGuard)] - exact ⟨k + 1, by omega, by omega, rfl⟩ - | false => - rw [show switchCaseBody fn = - YulStmt.comment s!"{fn.name}()" :: - Compiler.callvalueGuard :: - Compiler.calldatasizeGuard fn.params.length :: fn.body by - simp [switchCaseBody, hPayable]] - -- fuel ≥ 2, so we can step through both guards without hitting zero fuel - obtain ⟨k, rfl⟩ : ∃ k, fuel = k + 2 := ⟨fuel - 2, by omega⟩ - rw [execYulStmtsFuel_cons_continue (fuel := k + 2) (next := state) (hstmt := hComment)] - have hMsgValue : - state.msgValue % evmModulus = 0 := by - have hZero : tx.msgValue % evmModulus = 0 := - dispatchGuardsSafe_msgValue_zero_mod_of_nonpayable fn tx - ⟨hValueSafe, hParamNoWrap⟩ hPayable - simpa [state, YulState.initial, YulState.setVar] using hZero - have hValueGuard : - execYulStmtFuel (k + 1 + 1) state Compiler.callvalueGuard = .continue state := by - simpa [execYulStmtFuel] using exec_callvalueGuard_noop (k + 1) state hMsgValue - rw [show k + 2 + 1 = (k + 1) + 2 from by omega] - rw [execYulStmtsFuel_cons_continue (fuel := k + 1) (next := state) (hstmt := hValueGuard)] - have hGuard : - execYulStmtFuel (k + 1) state (Compiler.calldatasizeGuard fn.params.length) = - .continue state := by - simpa [execYulStmtFuel] using - (exec_calldatasizeGuard_noop_of_noWrap k state fn.params.length - hArity hDataNoWrap) - rw [execYulStmtsFuel_cons_continue (fuel := k) (next := state) (hstmt := hGuard)] - exact ⟨k + 1, by omega, by omega, rfl⟩ - -/-! ### switchCaseBody body bridge axioms - -After the guard prefix has been proved to pass (by `exec_switchCaseBody_continue_of_long`), -the remaining gap is connecting fuel-bounded execution of `fn.body` in a state -where `__has_selector = 1` to the total `interpretYulRuntime fn.body ...`. - -This gap is decomposed into: -- an explicit dead-variable bridge hypothesis for bodies that syntactically do - not read `__has_selector` -- the remaining fuel-adequacy axiom --/ - -/-! #### Fuel adequacy proof - -We prove that for loop-free Yul bodies, once the fuel budget reaches -`sizeOf body + 1`, adding more fuel does not change the result. -/ - -/-- Loop-free predicate lifted to `YulExecTarget`. -/ -private def yulExecTargetLoopFree : YulExecTarget → Bool - | .stmt s => yulStmtLoopFree s - | .stmts ss => yulStmtsLoopFree ss - -/-- Inner sizeOf measure matching `execYulStmts`'s fuel convention. -/ -private noncomputable def sizeOfExecTarget : YulExecTarget → Nat - | .stmt s => sizeOf s - | .stmts ss => sizeOf ss - -/-- Loop-free switch cases: if the list is loop-free and a pair is a member, - its body is loop-free. -/ -private theorem yulSwitchCasesLoopFree_mem - {cases : List (Nat × List YulStmt)} {p : Nat × List YulStmt} - (hLF : yulSwitchCasesLoopFree cases = true) (hmem : p ∈ cases) : - yulStmtsLoopFree p.2 = true := by - induction cases with - | nil => exact absurd hmem List.not_mem_nil - | cons hd tl ih => - simp [yulSwitchCasesLoopFree] at hLF - cases List.mem_cons.mp hmem with - | inl heq => rw [heq]; exact hLF.1 - | inr htl => exact ih hLF.2 htl - -/-- Key lemma: adding one unit of fuel does not change the result when the -target is loop-free and fuel already exceeds the structural measure. -/ -private theorem legacyExecYulFuel_succ_eq - (target : YulExecTarget) (state : YulState) (fuel : Nat) - (hLF : yulExecTargetLoopFree target = true) - (hFuel : fuel ≥ sizeOfExecTarget target + 1) : - legacyExecYulFuel (fuel + 1) state target = legacyExecYulFuel fuel state target := by - -- Strong induction on sizeOf target. - -- The measure decreases at every recursive position in legacyExecYulFuel - -- (stmt in a list, body of if/switch/block). Loop-free excludes for_. - suffices ∀ (n : Nat) (target : YulExecTarget) (state : YulState) (fuel : Nat), - sizeOf target = n → - yulExecTargetLoopFree target = true → - fuel ≥ sizeOfExecTarget target + 1 → - legacyExecYulFuel (fuel + 1) state target = legacyExecYulFuel fuel state target from - this (sizeOf target) target state fuel rfl hLF hFuel - intro n - induction n using Nat.strongRecOn with - | _ n ih => - intro target state fuel hn hLF hFuel - cases target with - | stmts ss => - cases ss with - | nil => - cases fuel with - | zero => rfl - | succ f => rfl - | cons s rest => - have hf : fuel ≥ 2 := by - simp only [sizeOfExecTarget] at hFuel - have : sizeOf s < sizeOf (s :: rest) := by simp_wf; omega - omega - obtain ⟨f, rfl⟩ : ∃ f, fuel = f + 2 := ⟨fuel - 2, by omega⟩ - have hs_lt : sizeOf (YulExecTarget.stmt s) < n := by - rw [← hn]; simp_wf; omega - have hr_lt : sizeOf (YulExecTarget.stmts rest) < n := by - rw [← hn]; simp_wf - simp [yulExecTargetLoopFree, yulStmtsLoopFree] at hLF - obtain ⟨hLFs, hLFr⟩ := hLF - have hs_fuel : f + 1 ≥ sizeOfExecTarget (.stmt s) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢ - have : sizeOf s < sizeOf (s :: rest) := by simp_wf; omega - omega - have hr_fuel : f + 1 ≥ sizeOfExecTarget (.stmts rest) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢ - have : sizeOf rest < sizeOf (s :: rest) := by simp_wf - omega - have ihs := ih _ hs_lt (.stmt s) state (f + 1) rfl - (by simp [yulExecTargetLoopFree, hLFs]) hs_fuel - have ihr := fun s' => ih _ hr_lt (.stmts rest) s' (f + 1) rfl - (by simp [yulExecTargetLoopFree, hLFr]) hr_fuel - show legacyExecYulFuel (f + 3) state (.stmts (s :: rest)) = - legacyExecYulFuel (f + 2) state (.stmts (s :: rest)) - simp only [legacyExecYulFuel] - rw [ihs] - cases h : legacyExecYulFuel (f + 1) state (.stmt s) with - | «continue» s' => exact ihr s' - | «return» v s' => rfl - | stop s' => rfl - | revert s' => rfl - | stmt s => - simp [yulExecTargetLoopFree] at hLF - cases s with - | comment _ => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | let_ _ _ => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | letMany _ _ => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | assign _ _ => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | «leave» => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | funcDef _ _ _ _ => simp [legacyExecYulFuel] - | expr e => - have : fuel ≥ 1 := by simp only [sizeOfExecTarget] at hFuel; omega - obtain ⟨f, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (by omega : fuel ≠ 0) - simp [legacyExecYulFuel] - | if_ cond body => - simp [yulStmtLoopFree] at hLF - have : fuel ≥ 2 := by - simp only [sizeOfExecTarget] at hFuel - have : sizeOf body < sizeOf (YulStmt.if_ cond body) := by simp_wf - omega - obtain ⟨f, rfl⟩ : ∃ f, fuel = f + 2 := ⟨fuel - 2, by omega⟩ - have hb_lt : sizeOf (YulExecTarget.stmts body) < n := by - rw [← hn]; simp_wf - have hb_fuel : f + 1 ≥ sizeOfExecTarget (.stmts body) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢ - have : sizeOf body < sizeOf (YulStmt.if_ cond body) := by simp_wf - omega - show legacyExecYulFuel (f + 3) state (.stmt (YulStmt.if_ cond body)) = - legacyExecYulFuel (f + 2) state (.stmt (YulStmt.if_ cond body)) - simp only [legacyExecYulFuel] - cases evalYulExpr state cond with - | none => rfl - | some v => - by_cases hv : v = 0 - · simp [hv] - · simp [hv] - exact ih _ hb_lt (.stmts body) state (f + 1) rfl - (by simp [yulExecTargetLoopFree, hLF]) hb_fuel - | «switch» expr cases defaultCase => - simp [yulStmtLoopFree] at hLF - obtain ⟨hLFcases, hLFdef⟩ := hLF - have : fuel ≥ 2 := by - simp only [sizeOfExecTarget] at hFuel - have : sizeOf expr < sizeOf (YulStmt.switch expr cases defaultCase) := by simp_wf; omega - omega - obtain ⟨f, rfl⟩ : ∃ f, fuel = f + 2 := ⟨fuel - 2, by omega⟩ - show legacyExecYulFuel (f + 3) state (.stmt (YulStmt.switch expr cases defaultCase)) = - legacyExecYulFuel (f + 2) state (.stmt (YulStmt.switch expr cases defaultCase)) - simp only [legacyExecYulFuel] - cases evalYulExpr state expr with - | none => rfl - | some v => - simp only [] - cases hfind : cases.find? (fun x => decide (x.fst = v)) with - | none => - simp only [] - cases defaultCase with - | none => rfl - | some defBody => - have hdb_lt : sizeOf (YulExecTarget.stmts defBody) < n := by - rw [← hn]; simp_wf; omega - have hdb_fuel : f + 1 ≥ sizeOfExecTarget (.stmts defBody) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢ - have : sizeOf defBody < sizeOf (YulStmt.switch expr cases (some defBody)) := by - simp_wf; omega - omega - simp [yulOptionStmtsLoopFree] at hLFdef - exact ih _ hdb_lt (.stmts defBody) state (f + 1) rfl - (by simp [yulExecTargetLoopFree, hLFdef]) hdb_fuel - | some val => - obtain ⟨caseVal, caseBody⟩ := val - simp only [] - have hmem : (caseVal, caseBody) ∈ cases := List.mem_of_find?_eq_some hfind - have hpair : sizeOf caseBody < sizeOf (caseVal, caseBody) := by - simp_wf - have hlist : sizeOf (caseVal, caseBody) < sizeOf cases := - List.sizeOf_lt_of_mem hmem - have hcases : sizeOf cases < sizeOf (YulStmt.switch expr cases defaultCase) := by - simp_wf; omega - have hcb_lt : sizeOf (YulExecTarget.stmts caseBody) < n := by - subst hn; simp_wf; omega - have hcb_fuel : f + 1 ≥ sizeOfExecTarget (.stmts caseBody) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢; omega - have hcb_lf : yulStmtsLoopFree caseBody = true := - yulSwitchCasesLoopFree_mem hLFcases hmem - exact ih _ hcb_lt (.stmts caseBody) state (f + 1) rfl - (by simp [yulExecTargetLoopFree, hcb_lf]) hcb_fuel - | block stmts => - simp [yulStmtLoopFree] at hLF - have : fuel ≥ 2 := by - simp only [sizeOfExecTarget] at hFuel - have : sizeOf stmts < sizeOf (YulStmt.block stmts) := by simp_wf - omega - obtain ⟨f, rfl⟩ : ∃ f, fuel = f + 2 := ⟨fuel - 2, by omega⟩ - have hb_lt : sizeOf (YulExecTarget.stmts stmts) < n := by - rw [← hn]; simp_wf - have hb_fuel : f + 1 ≥ sizeOfExecTarget (.stmts stmts) + 1 := by - simp only [sizeOfExecTarget] at hFuel ⊢ - have : sizeOf stmts < sizeOf (YulStmt.block stmts) := by simp_wf - omega - show legacyExecYulFuel (f + 3) state (.stmt (YulStmt.block stmts)) = - legacyExecYulFuel (f + 2) state (.stmt (YulStmt.block stmts)) - simp only [legacyExecYulFuel] - exact ih _ hb_lt (.stmts stmts) state (f + 1) rfl - (by simp [yulExecTargetLoopFree, hLF]) hb_fuel - | for_ _ _ _ _ => simp [yulStmtLoopFree] at hLF - -/-- **Fuel adequacy** (proved): when the fuel budget is at least `sizeOf body + 1` -(the amount used by `execYulStmts`), fuel-bounded execution gives the same -result as total execution, provided the body is loop-free. -/ -private theorem execYulStmtsFuel_fuel_adequate - (body : List YulStmt) (state : YulState) (fuel : Nat) - (hLF : yulStmtsLoopFree body = true) - (h : fuel ≥ sizeOf body + 1) : - execYulStmtsFuel fuel state body = execYulStmts state body := by - unfold execYulStmts execYulStmtsFuel - -- fuel ≥ sizeOf body + 1: write fuel = (sizeOf body + 1) + k - obtain ⟨k, rfl⟩ : ∃ k, fuel = sizeOf body + 1 + k := ⟨fuel - (sizeOf body + 1), by omega⟩ - clear h - induction k with - | zero => simp - | succ k ihk => - rw [show sizeOf body + 1 + (k + 1) = (sizeOf body + 1 + k) + 1 by omega] - rw [legacyExecYulFuel_succ_eq (.stmts body) state (sizeOf body + 1 + k) - (by simp [yulExecTargetLoopFree, hLF]) (by simp [sizeOfExecTarget])] - exact ihk - -/-- Composition of variable irrelevance and fuel adequacy. -/ -private theorem SwitchCaseBodyBridge_body - (body : List YulStmt) (state : YulState) (fuel : Nat) - (hDead : HasSelectorDeadBridge body) - (hNoRef : yulStmtsNoRef "__has_selector" body) - (hLF : yulStmtsLoopFree body = true) - (h : fuel ≥ sizeOf body + 1) : - yulResultOfExecWithRollback state - (execYulStmtsFuel fuel (state.setVar "__has_selector" 1) body) = - yulResultOfExecWithRollback state - (execYulStmts state body) := by - rw [hDead state fuel hNoRef] - rw [execYulStmtsFuel_fuel_adequate body state fuel hLF h] - -/-! ### switchCaseBody bridge theorem - -`SwitchCaseBodyBridge` is now a proved theorem rather than an axiom. -It composes two pieces: -1. `exec_switchCaseBody_continue_of_long` — proved guard-prefix stepping -2. `SwitchCaseBodyBridge_body` — composed from an explicit dead-variable bridge - hypothesis and the fuel adequacy axiom --/ -private theorem SwitchCaseBodyBridge - (fn : IRFunction) (tx : IRTransaction) (irState : IRState) (fuel : Nat) - (hDead : HasSelectorDeadBridge fn.body) - (hNoRef : yulStmtsNoRef "__has_selector" fn.body) - (hLF : yulStmtsLoopFree fn.body = true) - (hFuelAdequate : fuel ≥ sizeOf fn.body + 5) : - DispatchGuardsSafe fn tx → - 4 + tx.args.length * 32 < evmModulus → - fn.params.length ≤ tx.args.length → - resultsMatch - (execIRFunction fn tx.args irState) - (interpretYulRuntime fn.body - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events) → - resultsMatch - (execIRFunction fn tx.args irState) - (yulResultOfExecWithRollback - (YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events) - (execYulStmtsFuel fuel - ((YulState.initial - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - irState.storage irState.events).setVar "__has_selector" 1) - (switchCaseBody fn))) := by - intro hguards hNoWrap hlen hmatch - set yulTx : YulTransaction := - { sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - functionSelector := tx.functionSelector - args := tx.args } - set s₀ := YulState.initial yulTx irState.storage irState.events - -- Step 1: use guard-stepping to reduce to fn.body execution - -- fuel ≥ sizeOf fn.body + 5 ≥ 5 ≥ 2, so guards can be stepped - have hfuel2 : fuel ≥ 2 := by omega - obtain ⟨fuel', hle, hge, hstep⟩ := - exec_switchCaseBody_continue_of_long fn tx irState (fuel - 2) hguards hNoWrap hlen (by omega) - -- Align fuel: fuel = (fuel - 2) + 2 since fuel ≥ 2 - have hfuelEq : fuel = (fuel - 2) + 2 := by omega - rw [hfuelEq] - rw [hstep] - -- Step 2: bridge body execution to interpretYulRuntime - -- fuel' ≥ (fuel - 2) - 2 = fuel - 4 (by hge). - -- Since fuel ≥ sizeOf fn.body + 5, we have fuel - 4 ≥ sizeOf fn.body + 1. - have hfuelAdequate' : fuel' ≥ sizeOf fn.body + 1 := by omega - have hbody := SwitchCaseBodyBridge_body fn.body s₀ fuel' hDead hNoRef hLF hfuelAdequate' - -- hmatch gives us resultsMatch via interpretYulRuntime - -- interpretYulRuntime fn.body yulTx ... = yulResultOfExecWithRollback s₀ (execYulStmts s₀ fn.body) - rw [hbody] - simp only [interpretYulRuntime, execYulStmts] at hmatch - exact hmatch - -set_option maxHeartbeats 1600000000 in -/-- Legacy reference-oracle preservation theorem: Yul codegen preserves IR semantics. - -The `hWF` hypothesis requires that `contract.internalFunctions` are all -`funcDef` statements, which holds for every contract emitted by the compiler. - -**Note**: This theorem currently requires `fallbackEntrypoint = none` and -`receiveEntrypoint = none` because `interpretIR` returns failure when no -function selector matches, which is only consistent with a revert-only -default case. Extending to fallback/receive requires extending `interpretIR`. -/ -private theorem yulCodegen_preserves_semantics_via_reference_oracle - (contract : IRContract) (tx : IRTransaction) (initialState : IRState) - (hselector : tx.functionSelector < selectorModulus) - (hNoWrap : 4 + tx.args.length * 32 < evmModulus) - (hWF : ContractWF contract) - (hNoFallback : contract.fallbackEntrypoint = none) - (hNoReceive : contract.receiveEntrypoint = none) - (hdispatchGuardSafe : ∀ fn, fn ∈ contract.functions → DispatchGuardsSafe fn tx) - (hNoHasSelector : ∀ fn, fn ∈ contract.functions → - yulStmtsNoRef "__has_selector" fn.body) - (hHasSelectorDead : ∀ fn, fn ∈ contract.functions → - HasSelectorDeadBridge fn.body) - (hLoopFree : ∀ fn, fn ∈ contract.functions → - yulStmtsLoopFree fn.body = true) - (hbody : ∀ fn, fn ∈ contract.functions → - resultsMatch - (execIRFunction fn tx.args ({ initialState.withTx tx with returnValue := none })) - (interpretYulBody fn tx ({ initialState.withTx tx with returnValue := none }))) : - resultsMatch - (interpretIR contract tx initialState) - (interpretYulFromIR contract tx initialState) := by - let irState := initialState.withTx tx - let yulTx := YulTransaction.ofIR tx - -- Abbreviations for the funcDef prefix and buildSwitch suffix. - set prefix_ := (if contract.usesMapping then [Compiler.CodegenCommon.mappingSlotFuncAt 0] else []) ++ - contract.internalFunctions with hPrefixDef - set switchStmt := Compiler.CodegenCommon.buildSwitch contract.functions contract.fallbackEntrypoint - contract.receiveEntrypoint with hSwitchDef - have hRuntimeEq : Compiler.runtimeCode contract = prefix_ ++ [switchStmt] := by - simp [Compiler.runtimeCode, Compiler.CodegenCommon.runtimeCode, hPrefixDef, hSwitchDef, - List.append_assoc] - have hPrefixFD : - ∀ s ∈ prefix_, ∃ nm p r b, s = YulStmt.funcDef nm p r b := by - simpa [hPrefixDef, Compiler.mappingSlotFuncAt] using runtimeCode_prefix_allFuncDefs contract hWF - have hFuel : sizeOf (prefix_ ++ [switchStmt]) + 1 ≥ prefix_.length := by - have h1 : prefix_.length ≤ (prefix_ ++ [switchStmt]).length := by simp - have h2 : (prefix_ ++ [switchStmt]).length ≤ sizeOf (prefix_ ++ [switchStmt]) := - list_length_le_sizeOf (prefix_ ++ [switchStmt]) - omega - have hSkip : ∀ state : YulState, - execYulStmtsFuel (sizeOf (prefix_ ++ [switchStmt]) + 1) state (prefix_ ++ [switchStmt]) = - execYulStmtsFuel (sizeOf (prefix_ ++ [switchStmt]) + 1 - prefix_.length) state [switchStmt] := - fun state => - preservation_execYulStmtsFuel_funcDefs_then_suffix_ge _ state prefix_ [switchStmt] - hPrefixFD hFuel - set adjustedFuel := sizeOf (prefix_ ++ [switchStmt]) + 1 - prefix_.length - have hAdjGe : adjustedFuel ≥ 10 := by - have : sizeOf (prefix_ ++ [switchStmt]) + 1 - prefix_.length ≥ sizeOf [switchStmt] + 1 := by - have := sizeOf_append_ge_length_add prefix_ [switchStmt]; omega - have : sizeOf [switchStmt] ≥ 9 := by - rw [hSwitchDef] - simp [Compiler.CodegenCommon.buildSwitch] - omega - omega - obtain ⟨m, hm⟩ : ∃ m, adjustedFuel = m + 10 := ⟨adjustedFuel - 10, by omega⟩ - -- Simplify buildSwitch with known fallback/receive = none. - have hSwitchSimp : - switchStmt = Compiler.CodegenCommon.buildSwitch contract.functions none none := by - rw [hSwitchDef, hNoFallback, hNoReceive] - -- Selector modulus pre-computation. - have hpow : (2 : Nat) ^ selectorShift > 0 := by simp [selectorShift] - have hselMod : tx.functionSelector % 4294967296 = tx.functionSelector := by - have : selectorModulus = 4294967296 := by simp [selectorModulus] - rw [← this]; exact Nat.mod_eq_of_lt hselector - -- The Yul initial state for the switch dispatch - set yulInitState := YulState.initial yulTx irState.storage irState.events with hYulInitDef - -- Key fact: yulInitState.selector = tx.functionSelector - have hSelEq : yulInitState.selector = tx.functionSelector := rfl - -- Now case-split on whether any function matches the selector - cases hFind : contract.functions.find? (fun f => f.selector == tx.functionSelector) with - | none => - -- No function matches: IR returns failure, Yul should revert - simp only [interpretIR, hFind] - -- The Yul side: skip prefix, reach buildSwitch, step through block to switch, miss all cases, revert - simp only [interpretYulFromIR, preservation_emitYul_runtimeCode_eq, interpretYulRuntime, - execYulStmts, hRuntimeEq, hSkip] - rw [hm, hSwitchSimp] - -- Use the buildSwitch stepping axiom - have hStep := execBuildSwitch_none_none_aux_of_noWrap (m + 4) yulInitState contract.functions (by - simpa [hYulInitDef] using hNoWrap) - rw [show m + 4 + 6 = m + 10 from by omega] at hStep - rw [hStep] - rw [show m + 4 = (m + 2) + 2 by omega, execYulStmtsFuel_singleton_succ] - -- Now we have execYulStmtFuel on the switch with state augmented by __has_selector - -- The selector evaluates the same way since selectorExpr doesn't use __has_selector - have hSelEval := evalSelectorExpr_setVar_has_selector yulInitState 1 (by - rw [hSelEq]; exact hselector) - -- Bridge hcase: tx.functionSelector = yulInitState.selector - have hcase := preservation_find_switch_case_of_find_function_none contract.functions - yulInitState.selector (hSelEq ▸ hFind) - -- Apply switch miss lemma - rw [show m + 2 + 1 = Nat.succ (m + 2) from by omega] - rw [preservation_execYulStmtFuel_switch_miss _ _ _ _ _ _ hSelEval hcase] - -- Now we need to show the revert case matches resultsMatch for failure - simp [preservation_execYulStmtFuel_switch_miss_result, switchDefaultCase, - execYulStmtsFuel, legacyExecYulFuel, resultsMatch, - Compiler.Proofs.storageAsMappings, yulInitState, YulState.initial, YulState.setVar] - | some fn => - -- A function matches: use hbody to connect IR and Yul - have hmem : fn ∈ contract.functions := List.mem_of_find?_eq_some hFind - have hmatch := hbody fn hmem - simp only [interpretIR, hFind] - simp only [interpretYulFromIR, preservation_emitYul_runtimeCode_eq, interpretYulRuntime, - execYulStmts, hRuntimeEq, hSkip] - simp only [interpretYulBody_eq_runtime, interpretYulRuntime, execYulStmts] at hmatch - rw [hm, hSwitchSimp] - -- Use the buildSwitch stepping axiom - have hStep := execBuildSwitch_none_none_aux_of_noWrap (m + 4) yulInitState contract.functions (by - simpa [hYulInitDef] using hNoWrap) - rw [show m + 4 + 6 = m + 10 from by omega] at hStep - rw [hStep] - rw [show m + 4 = (m + 2) + 2 by omega, execYulStmtsFuel_singleton_succ] - -- The selector evaluates the same way - have hSelEval := evalSelectorExpr_setVar_has_selector yulInitState 1 (by - rw [hSelEq]; exact hselector) - -- Rewrite to the transaction selector shape expected by the switch-match lemma. - have hcase : (switchCases contract.functions).find? (fun (c, _) => c = tx.functionSelector) = - some (tx.functionSelector, switchCaseBody fn) := by - simpa [hSelEq] using - (preservation_find_switch_case_of_find_function_eq_selector - contract.functions yulInitState.selector fn - (hSelEq ▸ hFind)) - rw [← hSelEq] at hcase - -- Apply switch match lemma - rw [show m + 2 + 1 = Nat.succ (m + 2) from by omega] - rw [preservation_execYulStmtFuel_switch_match _ _ _ _ _ _ _ hSelEval hcase] - -- Establish fuel adequacy for the body bridge. - -- sizeOf [switchStmt] ≥ sizeOf fn.body + 12 (by sizeOf_buildSwitch_ge_fn_body), - -- adjustedFuel ≥ sizeOf [switchStmt] + 1, and m + 10 = adjustedFuel. - have hFuelBody : m + 2 ≥ sizeOf fn.body + 5 := by - have hBound := sizeOf_buildSwitch_ge_fn_body (fns := contract.functions) (fn := fn) hmem - rw [← hSwitchSimp] at hBound - have hAdj : adjustedFuel ≥ sizeOf [switchStmt] + 1 := by - have := sizeOf_append_ge_length_add prefix_ [switchStmt]; omega - omega - by_cases hlen : fn.params.length ≤ tx.args.length - · have hNoValueRevert : - ¬ (fn.payable = false ∧ ¬tx.msgValue % evmModulus = 0) := by - intro h - rcases (hdispatchGuardSafe fn hmem).1 with hPayable | hZeroValue - · simp [h.1] at hPayable - · exact h.2 hZeroValue - simpa [hlen, hNoValueRevert] using - (SwitchCaseBodyBridge fn tx - { initialState with - sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - calldata := tx.args - returnValue := none - selector := tx.functionSelector } - (m + 2) (hHasSelectorDead fn hmem) (hNoHasSelector fn hmem) - (hLoopFree fn hmem) hFuelBody (hdispatchGuardSafe fn hmem) hNoWrap hlen hmatch) - · simpa [hlen] using - (SwitchCaseBodyBridge_short fn tx - { initialState with - sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - blobBaseFee := tx.blobBaseFee - calldata := tx.args - returnValue := none - selector := tx.functionSelector } - m (hdispatchGuardSafe fn hmem) hNoWrap hlen) - -end Compiler.Proofs.YulGeneration diff --git a/Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean b/Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean deleted file mode 100644 index bc2891781..000000000 --- a/Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean +++ /dev/null @@ -1,306 +0,0 @@ -import Compiler.Yul.Ast -import Compiler.Proofs.IRGeneration.IRInterpreter -import Compiler.Proofs.MappingSlot -import Compiler.Proofs.YulGeneration.RuntimeTypes -import Compiler.Proofs.YulGeneration.ReferenceOracle.Builtins - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Yul -open Compiler.Proofs.IRGeneration -open Compiler.Proofs - -/-! -Reference oracle only. - -This module preserves Verity's historical `legacyExecYulFuel` runtime semantics for -regression tests and bridge comparisons. EVMYulLean is the trusted semantic -target for the current retargeting path; this file is not part of that trust -boundary. --/ - -/-! ## Yul Runtime Semantics (Layer 3 Foundation) - -This module defines the historical fuel-based execution semantics for a Yul -runtime program. Shared transaction/result/state plumbing lives in -`RuntimeTypes.lean` so native EVMYulLean proofs can use those data structures -without importing this legacy interpreter. --/ - -/-! -Runtime Yul mapping slots are derived via `keccak(baseSlot, key)`. Proof -semantics call through `MappingSlot`; the active backend is `keccak` (see -`activeMappingSlotBackend`), so `mappingSlot`/`sload`/`sstore` semantics are -aligned with Solidity's keccak-derived flat storage slot layout. --/ - -/-! ## Yul Expression Evaluation -/ - -/-! Size measures for termination proofs. -/ -mutual -def exprSize : YulExpr → Nat - | .call _ args => exprsSize args + 2 - | _ => 1 - -def exprsSize : List YulExpr → Nat - | [] => 0 - | e :: es => exprSize e + exprsSize es + 1 -end - -mutual - -/-- Evaluate a list of Yul expressions -/ -def evalYulExprs (state : YulState) : List YulExpr → Option (List Nat) - | [] => some [] - | e :: es => do - let v ← evalYulExpr state e - let vs ← evalYulExprs state es - pure (v :: vs) -termination_by es => exprsSize es -decreasing_by - all_goals - simp [exprsSize] - omega - -def evalYulCall (state : YulState) (func : String) : List YulExpr → Option Nat - | args => do - let argVals ← evalYulExprs state args - if func = "tload" then - match argVals with - | [slot] => some (state.transientStorage (slot % Compiler.Constants.evmModulus)) - | _ => none - else if func = "mload" then - match argVals with - | [offset] => some (state.memory offset) - | _ => none - else if func = "keccak256" then - match argVals with - | [offset, size] => some (abstractKeccakMemorySlice state.memory offset size) - | _ => none - else - Compiler.Proofs.YulGeneration.evalBuiltinCallWithBackendContext - Compiler.Proofs.YulGeneration.BuiltinBackend.evmYulLean - state.storage state.sender state.msgValue state.thisAddress state.blockTimestamp - state.blockNumber state.chainId state.blobBaseFee state.selector state.calldata func argVals -termination_by args => exprsSize args + 1 -decreasing_by - omega - -/-- Evaluate a Yul expression -/ -def evalYulExpr (state : YulState) : YulExpr → Option Nat - | .lit n => some n - | .hex n => some n - | .str _ => none - | .ident name => state.getVar name - | .call func args => evalYulCall state func args -termination_by e => exprSize e -decreasing_by - simp [exprSize] - -end - -/-! ## Yul Statement Execution -/ - -def YulState.appendYulLog (s : YulState) (offset size : Nat) - (topics : List Nat) : YulState := - { s with events := s.events ++ [encodeYulLogEvent s.memory offset size topics] } - -def applyYulLogCall? (state : YulState) (func : String) - (argVals : List Nat) : Option YulState := - match func, argVals with - | "log0", [offset, size] => - some (state.appendYulLog offset size []) - | "log1", [offset, size, topic0] => - some (state.appendYulLog offset size [topic0]) - | "log2", [offset, size, topic0, topic1] => - some (state.appendYulLog offset size [topic0, topic1]) - | "log3", [offset, size, topic0, topic1, topic2] => - some (state.appendYulLog offset size [topic0, topic1, topic2]) - | "log4", [offset, size, topic0, topic1, topic2, topic3] => - some (state.appendYulLog offset size [topic0, topic1, topic2, topic3]) - | _, _ => none - -inductive YulExecTarget - | stmt (s : YulStmt) - | stmts (ss : List YulStmt) - -def legacyExecYulFuel : Nat → YulState → YulExecTarget → YulExecResult - | _, state, .stmts [] => .continue state - | _, state, .stmt (YulStmt.funcDef _ _ _ _) => .continue state - | 0, state, _ => .revert state - | Nat.succ fuel, state, target => - match target with - | .stmt stmt => - match stmt with - | .comment _ => .continue state - | .let_ name value => - match evalYulExpr state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .letMany _ _ => .revert state - | .assign name value => - match evalYulExpr state value with - | some v => .continue (state.setVar name v) - | none => .revert state - | .leave => .continue state - | .expr e => - match e with - | .call "sstore" [slotExpr, valExpr] => - match slotExpr with - | .call "mappingSlot" [baseExpr, keyExpr] => - match evalYulExpr state baseExpr, evalYulExpr state keyExpr, evalYulExpr state valExpr with - | some baseSlot, some key, some val => - let updated := Compiler.Proofs.abstractStoreMappingEntry - state.storage baseSlot key val - .continue { - state with - storage := updated - } - | _, _, _ => .revert state - | _ => - match evalYulExpr state slotExpr, evalYulExpr state valExpr with - | some slot, some val => - let updated := Compiler.Proofs.abstractStoreStorageOrMapping - state.storage slot val - .continue { - state with - storage := updated - } - | _, _ => .revert state - | .call "mstore" [offsetExpr, valExpr] => - match evalYulExpr state offsetExpr, evalYulExpr state valExpr with - | some offset, some val => - .continue { state with memory := fun o => if o = offset then val else state.memory o } - | _, _ => .revert state - | .call "tstore" [offsetExpr, valExpr] => - match evalYulExpr state offsetExpr, evalYulExpr state valExpr with - | some offset, some val => - .continue { - state with - transientStorage := fun o => - if o = offset then val else state.transientStorage o - } - | _, _ => .revert state - | .call "stop" [] => .stop state - | .call "return" [offsetExpr, sizeExpr] => - match evalYulExpr state offsetExpr, evalYulExpr state sizeExpr with - | some offset, some size => - if size = 32 then - .return (state.memory offset) state - else - .return 0 state - | _, _ => .revert state - | .call "revert" [_, _] => .revert state - | .call func args => - if isYulLogName func then - match evalYulExprs state args with - | some argVals => - match applyYulLogCall? state func argVals with - | some next => .continue next - | none => .revert state - | none => .revert state - else - match evalYulExpr state e with - | some _ => .continue state - | none => .revert state - | _ => - match evalYulExpr state e with - | some _ => .continue state - | none => .revert state - | .if_ cond body => - match evalYulExpr state cond with - | some v => - if v = 0 then - .continue state - else - legacyExecYulFuel fuel state (.stmts body) - | none => .revert state - | .switch expr cases defaultCase => - match evalYulExpr state expr with - | some v => - match cases.find? (fun x => decide (x.fst = v)) with - | some (_, body) => legacyExecYulFuel fuel state (.stmts body) - | none => - match defaultCase with - | some body => legacyExecYulFuel fuel state (.stmts body) - | none => .continue state - | none => .revert state - | .for_ init cond post body => - -- Execute init, then loop: check cond, run body, run post, repeat - match legacyExecYulFuel fuel state (.stmts init) with - | .continue s' => - match evalYulExpr s' cond with - | some v => - if v = 0 then .continue s' - else - match legacyExecYulFuel fuel s' (.stmts body) with - | .continue s'' => - match legacyExecYulFuel fuel s'' (.stmts post) with - | .continue s''' => - legacyExecYulFuel fuel s''' (.stmt (.for_ [] cond post body)) - | other => other - | other => other - | none => .revert s' - | other => other - | .block stmts => legacyExecYulFuel fuel state (.stmts stmts) - | .funcDef _ _ _ _ => .continue state - | .stmts [] => .continue state - | .stmts (stmt :: rest) => - match legacyExecYulFuel fuel state (.stmt stmt) with - | .continue s' => legacyExecYulFuel fuel s' (.stmts rest) - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s -def execYulStmtFuel (fuel : Nat) (state : YulState) (stmt : YulStmt) : YulExecResult := - legacyExecYulFuel fuel state (.stmt stmt) - -def execYulStmtsFuel (fuel : Nat) (state : YulState) (stmts : List YulStmt) : YulExecResult := - legacyExecYulFuel fuel state (.stmts stmts) - -set_option allowUnsafeReducibility true in -attribute [reducible] legacyExecYulFuel - - -noncomputable def execYulStmt (state : YulState) (stmt : YulStmt) : YulExecResult := - execYulStmtFuel (sizeOf stmt + 1) state stmt - -noncomputable def execYulStmts (state : YulState) (stmts : List YulStmt) : YulExecResult := - execYulStmtsFuel (sizeOf stmts + 1) state stmts - -/-- Execute a Yul runtime program with selector-aware calldata -/ -noncomputable def interpretYulRuntime (runtimeCode : List YulStmt) (tx : YulTransaction) - (storage : IRStorageSlot → IRStorageWord) (events : List (List Nat) := []) : YulResult := - let initialState := YulState.initial tx storage events - match execYulStmts initialState runtimeCode with - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := storage - finalMappings := Compiler.Proofs.storageAsMappings storage - events := initialState.events } - -/-- Interpret a Yul object by executing its runtime code. -/ -noncomputable def interpretYulObject (obj : YulObject) (tx : YulTransaction) - (storage : IRStorageSlot → IRStorageWord) (events : List (List Nat) := []) : YulResult := - interpretYulRuntime obj.runtimeCode tx storage events - -end Compiler.Proofs.YulGeneration diff --git a/Compiler/Proofs/YulGeneration/StatementEquivalence.lean b/Compiler/Proofs/YulGeneration/StatementEquivalence.lean deleted file mode 100644 index 68c209fc1..000000000 --- a/Compiler/Proofs/YulGeneration/StatementEquivalence.lean +++ /dev/null @@ -1,748 +0,0 @@ -import Compiler.Proofs.IRGeneration.IRInterpreter -import Compiler.Proofs.YulGeneration.IRFuel -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics - -namespace Compiler.Proofs.YulGeneration - -open Compiler -open Compiler.Yul -open Compiler.Proofs.IRGeneration - -private def yulStateOfIR (_selector : Nat) (state : IRState) : YulState := - { vars := state.vars - storage := state.storage - transientStorage := state.transientStorage - memory := state.memory - calldata := state.calldata - selector := state.selector - returnValue := state.returnValue - sender := state.sender - msgValue := state.msgValue - thisAddress := state.thisAddress - blockTimestamp := state.blockTimestamp - blockNumber := state.blockNumber - chainId := state.chainId - blobBaseFee := state.blobBaseFee - events := state.events } - -private def statesAligned (selector : Nat) (ir : IRState) (yul : YulState) : Prop := - yul = yulStateOfIR selector ir - -private def execResultsAligned (selector : Nat) : IRExecResult → YulExecResult → Prop - | .continue ir, .continue yul => statesAligned selector ir yul - | .return v ir, .return v' yul => v = v' ∧ statesAligned selector ir yul - | .stop ir, .stop yul => statesAligned selector ir yul - | .revert ir, .revert yul => statesAligned selector ir yul - | _, _ => False - -private def execIRStmt_equiv_execYulStmt_goal - (selector : Nat) (fuel : Nat) (stmt : YulStmt) - (irState : IRState) (yulState : YulState) : Prop := - statesAligned selector irState yulState → - execResultsAligned selector - (execIRStmtFuel fuel irState stmt) (execYulStmtFuel fuel yulState stmt) - -private def execIRStmts_equiv_execYulStmts_goal - (selector : Nat) (fuel : Nat) (stmts : List YulStmt) - (irState : IRState) (yulState : YulState) : Prop := - statesAligned selector irState yulState → - execResultsAligned selector - (execIRStmtsFuel fuel irState stmts) (execYulStmtsFuel fuel yulState stmts) - -/-! ## Layer 3: Statement-Level Equivalence (Complete) - -Proves that each IR statement type executes equivalently in Yul when states -are aligned. Uses `mutual` recursion between `conditional_equiv` and -`all_stmts_equiv` to handle the circular dependency. - -Individual statement proofs feed the file-local sequence/function lifting -helpers in `Equivalence.lean`; the statement-level legacy equivalence theorem -`all_stmts_equiv` remains file-local transition evidence. --/ - -private theorem execYulStmtsFuel_cons - (fuel : Nat) (state : YulState) (stmt : YulStmt) (rest : List YulStmt) : - execYulStmtsFuel (Nat.succ fuel) state (stmt :: rest) = - match execYulStmtFuel fuel state stmt with - | .continue s' => execYulStmtsFuel fuel s' rest - | .return v s => .return v s - | .stop s => .stop s - | .revert s => .revert s := by - rfl - -private theorem execYulStmtFuel_for - (fuel : Nat) (state : YulState) (init : List YulStmt) (cond : YulExpr) (post body : List YulStmt) : - execYulStmtFuel (Nat.succ fuel) state (YulStmt.for_ init cond post body) = - match execYulStmtsFuel fuel state init with - | .continue s' => - match evalYulExpr s' cond with - | some v => - if v = 0 then .continue s' - else - match execYulStmtsFuel fuel s' body with - | .continue s'' => - match execYulStmtsFuel fuel s'' post with - | .continue s''' => execYulStmtFuel fuel s''' (.for_ [] cond post body) - | other => other - | other => other - | none => .revert s' - | other => other := by - rfl - -/-! ### Expression Equivalence - -IR and Yul expression evaluators are total and structurally identical, -so equivalence follows by mutual structural induction on expression size. --/ - -open Compiler.Proofs.YulGeneration in -mutual - -/-- IR and Yul expression evaluation are identical when states are aligned. -Proved by mutual structural induction on expression size. -/ -private theorem evalIRExpr_eq_evalYulExpr (selector : Nat) (irState : IRState) (expr : YulExpr) : - evalIRExpr irState expr = evalYulExpr (yulStateOfIR selector irState) expr := by - match expr with - | .lit n => simp only [evalIRExpr, evalYulExpr] - | .hex n => simp only [evalIRExpr, evalYulExpr] - | .str _ => simp only [evalIRExpr, evalYulExpr] - | .ident name => - simp only [evalIRExpr, evalYulExpr, IRState.getVar, YulState.getVar, yulStateOfIR] - | .call func args => - simp only [evalIRExpr, evalYulExpr] - exact evalIRCall_eq_evalYulCall selector irState func args -termination_by exprSize expr -decreasing_by - simp only [exprSize]; omega - -/-- List version: IR and Yul list evaluation are identical when states are aligned. -Follows from `evalIRExpr_eq_evalYulExpr` by structural induction on the list. -/ -private theorem evalIRExprs_eq_evalYulExprs (selector : Nat) (irState : IRState) (exprs : List YulExpr) : - evalIRExprs irState exprs = evalYulExprs (yulStateOfIR selector irState) exprs := by - match exprs with - | [] => simp only [evalIRExprs, evalYulExprs] - | e :: es => - simp only [evalIRExprs, evalYulExprs] - rw [evalIRExpr_eq_evalYulExpr selector irState e] - rw [evalIRExprs_eq_evalYulExprs selector irState es] -termination_by exprsSize exprs -decreasing_by - all_goals - simp only [exprsSize] - omega - -/-- Call version: IR and Yul call evaluation are identical when states are aligned. -/ -private theorem evalIRCall_eq_evalYulCall (selector : Nat) (irState : IRState) (func : String) (args : List YulExpr) : - evalIRCall irState func args = evalYulCall (yulStateOfIR selector irState) func args := by - simp only [evalIRCall, evalYulCall] - rw [evalIRExprs_eq_evalYulExprs selector irState args] - rfl -termination_by exprsSize args + 1 -decreasing_by - omega - -end - -attribute [simp] evalIRExpr_eq_evalYulExpr evalIRExprs_eq_evalYulExprs evalIRCall_eq_evalYulCall - -/-! ## Proven Theorems -/ - -private theorem applyYulLogCall?_aligned - (selector : Nat) (irState : IRState) (func : String) (argVals : List Nat) : - applyYulLogCall? (yulStateOfIR selector irState) func argVals = - (IRGeneration.applyYulLogCall? irState func argVals).map - (fun next => yulStateOfIR selector next) := by - cases argVals with - | nil => simp [applyYulLogCall?, IRGeneration.applyYulLogCall?] - | cons a rest => - cases rest with - | nil => simp [applyYulLogCall?, IRGeneration.applyYulLogCall?] - | cons b rest => - cases rest with - | nil => - by_cases h0 : func = "log0" <;> - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?, - YulState.appendYulLog, IRState.appendYulLog, yulStateOfIR, h0] - | cons c rest => - cases rest with - | nil => - by_cases h1 : func = "log1" <;> - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?, - YulState.appendYulLog, IRState.appendYulLog, yulStateOfIR, h1] - | cons d rest => - cases rest with - | nil => - by_cases h2 : func = "log2" <;> - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?, - YulState.appendYulLog, IRState.appendYulLog, yulStateOfIR, h2] - | cons e rest => - cases rest with - | nil => - by_cases h3 : func = "log3" <;> - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?, - YulState.appendYulLog, IRState.appendYulLog, yulStateOfIR, h3] - | cons f rest => - cases rest with - | nil => - by_cases h4 : func = "log4" <;> - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?, - YulState.appendYulLog, IRState.appendYulLog, yulStateOfIR, h4] - | cons _ _ => - simp [applyYulLogCall?, IRGeneration.applyYulLogCall?] - -private theorem execResultsAligned_log_call - (selector : Nat) (irState : IRState) (func : String) (argVals : List Nat) : - execResultsAligned selector - (match IRGeneration.applyYulLogCall? irState func argVals with - | some next => IRExecResult.continue next - | none => IRExecResult.revert irState) - (match applyYulLogCall? (yulStateOfIR selector irState) func argVals with - | some next => YulExecResult.continue next - | none => YulExecResult.revert (yulStateOfIR selector irState)) := by - rw [applyYulLogCall?_aligned] - cases IRGeneration.applyYulLogCall? irState func argVals <;> - simp [execResultsAligned, statesAligned] - -private theorem assign_equiv (selector : Nat) (fuel : Nat) (varName : String) (valueExpr : YulExpr) - (irState : IRState) (yulState : YulState) - (halign : statesAligned selector irState yulState) - (hfuel : fuel > 0) : - execResultsAligned selector - (execIRStmtFuel fuel irState (YulStmt.assign varName valueExpr)) - (execYulStmtFuel fuel yulState (YulStmt.assign varName valueExpr)) := by - -- Unfold state alignment - unfold statesAligned at halign - subst halign - -- Destruct fuel - cases fuel with - | zero => contradiction - | succ fuel' => - simp only [execIRStmtFuel, execIRStmt, execYulStmtFuel, legacyExecYulFuel] - -- Use lemma: evalIRExpr irState expr = evalYulExpr (yulStateOfIR selector irState) expr - rw [evalIRExpr_eq_evalYulExpr] - -- Now both sides are identical - cases evalYulExpr (yulStateOfIR selector irState) valueExpr with - | none => - -- Both revert - unfold execResultsAligned - rfl - | some v => - -- Both continue with updated variable - unfold execResultsAligned statesAligned yulStateOfIR - simp only [IRState.setVar, YulState.setVar] - -private theorem stmts_align_contra - {selector fuel : Nat} {stmts : List YulStmt} {irState : IRState} {yulState : YulState} - {irExec : IRExecResult} {yulExec : YulExecResult} - (hStmts : execResultsAligned selector - (execIRStmtsFuel fuel irState stmts) - (execYulStmtsFuel fuel yulState stmts)) - (hIR : execIRStmtsFuel fuel irState stmts = irExec) - (hYul : execYulStmtsFuel fuel yulState stmts = yulExec) - (hImpossible : ¬ execResultsAligned selector irExec yulExec) : False := by - apply hImpossible - simpa only [hIR, hYul] using hStmts - -private theorem stmt_align_contra - {selector fuel : Nat} {stmt : YulStmt} {irState : IRState} {yulState : YulState} - {irExec : IRExecResult} {yulExec : YulExecResult} - (hStmt : execResultsAligned selector - (execIRStmtFuel fuel irState stmt) - (execYulStmtFuel fuel yulState stmt)) - (hIR : execIRStmtFuel fuel irState stmt = irExec) - (hYul : execYulStmtFuel fuel yulState stmt = yulExec) - (hImpossible : ¬ execResultsAligned selector irExec yulExec) : False := by - apply hImpossible - simpa only [hIR, hYul] using hStmt - -set_option maxHeartbeats 800000 in -set_option linter.unusedSimpArgs false in -private theorem stmt_and_stmts_equiv : - ∀ fuel, - (∀ selector stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState) ∧ - (∀ selector stmts irState yulState, - execIRStmts_equiv_execYulStmts_goal selector fuel stmts irState yulState) := by - intro fuel - induction fuel with - | zero => - constructor - · intro selector stmt irState yulState halign - cases stmt <;> - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, execResultsAligned, halign] - · intro selector stmts irState yulState halign - cases stmts <;> - simp only [execIRStmtsFuel, execIRStmts, - execYulStmtsFuel, legacyExecYulFuel, execResultsAligned, halign] - | succ fuel ih => - rcases ih with ⟨ihStmt, ihStmts⟩ - constructor - · intro selector stmt irState yulState halign - unfold statesAligned at halign - subst halign - cases stmt with - | comment _ => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, execResultsAligned, statesAligned, yulStateOfIR] - | let_ name value => - exact assign_equiv selector (fuel + 1) name value irState - (yulStateOfIR selector irState) rfl (by omega) - | letMany _ _ => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, execResultsAligned, statesAligned, yulStateOfIR] - | assign name value => - exact assign_equiv selector (fuel + 1) name value irState - (yulStateOfIR selector irState) rfl (by omega) - | «leave» => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, execResultsAligned, statesAligned, yulStateOfIR] - | expr e => - cases e with - | call func args => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel] - -- Both sides match on (.call func args) against string literals. - -- With `func` free, neither match tree reduces. Generalize so both - -- sides share the same discriminant, then split. - generalize YulExpr.call func args = disc - split - · -- sstore: inner match on slotExpr - split - · -- mappingSlot: match on 3 evals - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - split <;> simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq] - · -- non-mappingSlot: match on 2 evals - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - split <;> simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq] - · -- mstore: match on 2 evals - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - split <;> simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq] - · -- tstore: match on 2 evals - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - split <;> simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq] - · -- stop - simp only [execResultsAligned, statesAligned, yulStateOfIR] - · -- revert - simp only [execResultsAligned, statesAligned, yulStateOfIR] - · -- return: match on 2 evals, then if on size = 32 - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - repeat' split - all_goals simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq, not_true_eq_false, Bool.false_eq_true] - · -- log call or generic call: match on log dispatch, then eval/log result - rename_i funcLog argsLog _ _ _ _ _ _ - simp only [evalIRExpr_eq_evalYulExpr selector, - evalIRExprs_eq_evalYulExprs selector, yulStateOfIR] at * - split - · split - · rename_i values hargs - simpa [hargs] using - execResultsAligned_log_call selector irState _ values - · rename_i hargs - simp [hargs, execResultsAligned, statesAligned, yulStateOfIR] - · split <;> - simp_all only [execResultsAligned, statesAligned, yulStateOfIR, - and_self, and_true, true_and, Option.some.injEq] - · -- non-call catch-all: match on eval of full expr - simp only [evalIRExpr_eq_evalYulExpr selector, yulStateOfIR] at * - split <;> simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, Option.some.injEq] - | lit val => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, evalIRExpr, evalYulExpr, - execResultsAligned, statesAligned, yulStateOfIR] - | hex val => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, evalIRExpr, evalYulExpr, - execResultsAligned, statesAligned, yulStateOfIR] - | str val => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, evalIRExpr, evalYulExpr, - execResultsAligned, statesAligned, yulStateOfIR] - | ident val => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, evalIRExpr, evalYulExpr, - IRState.getVar, YulState.getVar, - execResultsAligned, statesAligned, yulStateOfIR] - cases hfind : List.find? (fun x => x.1 == val) irState.vars <;> - simp only [Option.map] - | if_ cond body => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel] - rw [evalIRExpr_eq_evalYulExpr] - cases hcond : evalYulExpr (yulStateOfIR selector irState) cond with - | none => - simp only [execResultsAligned, statesAligned, yulStateOfIR] - | some c => - simp only [] - by_cases hc : c = 0 - · subst hc - simp only [ne_eq, not_true_eq_false, ite_false, ite_true, execResultsAligned, statesAligned, yulStateOfIR] - · simp only [hc, ne_eq, ite_false, decide_false, not_false_eq_true, ite_true] - exact ihStmts selector body irState (yulStateOfIR selector irState) rfl - | «switch» expr cases defaultCase => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, beq_eq_decide, yulStateOfIR] - rw [evalIRExpr_eq_evalYulExpr] - cases hEval : evalYulExpr (yulStateOfIR selector irState) expr with - | none => - have hEval' : - evalYulExpr - { vars := irState.vars, storage := irState.storage, - transientStorage := irState.transientStorage, memory := irState.memory, - calldata := irState.calldata, selector := irState.selector, - returnValue := irState.returnValue, sender := irState.sender, - msgValue := irState.msgValue, thisAddress := irState.thisAddress, - blockTimestamp := irState.blockTimestamp, blockNumber := irState.blockNumber, - chainId := irState.chainId, - blobBaseFee := irState.blobBaseFee, - events := irState.events } expr = none := by - simpa only [yulStateOfIR] using hEval - simp only [hEval', execResultsAligned, statesAligned, yulStateOfIR] - | some v => - have hEval' : - evalYulExpr - { vars := irState.vars, storage := irState.storage, - transientStorage := irState.transientStorage, memory := irState.memory, - calldata := irState.calldata, selector := irState.selector, - returnValue := irState.returnValue, sender := irState.sender, - msgValue := irState.msgValue, thisAddress := irState.thisAddress, - blockTimestamp := irState.blockTimestamp, blockNumber := irState.blockNumber, - chainId := irState.chainId, - blobBaseFee := irState.blobBaseFee, - events := irState.events } expr = some v := by - simpa only [yulStateOfIR] using hEval - simp only [hEval'] - cases hFind : cases.find? (fun x => decide (x.fst = v)) with - | none => - have hFind' : - List.find? (fun x => decide (x.fst = v)) cases = none := hFind - simp only [] - cases defaultCase with - | none => - simp only [execResultsAligned, statesAligned, yulStateOfIR] - | some body => - simpa only [hEval', hFind', execYulStmtsFuel, legacyExecYulFuel] using - ihStmts selector body irState (yulStateOfIR selector irState) rfl - | some pair => - cases pair with - | mk _ body => - simpa only [hEval', hFind, execYulStmtsFuel, execIRStmtsFuel, legacyExecYulFuel] using - ihStmts selector body irState (yulStateOfIR selector irState) rfl - | for_ init cond post body => - simp only [execIRStmtFuel, - execIRStmt, execYulStmtFuel_for] - have hInit := ihStmts selector init irState (yulStateOfIR selector irState) rfl - cases hIRInit : execIRStmtsFuel fuel irState init with - | «continue» irAfterInit => - cases hYulInit : execYulStmtsFuel fuel (yulStateOfIR selector irState) init with - | «continue» yulAfterInit => - have hAlignedInit : statesAligned selector irAfterInit yulAfterInit := by - simpa only [execResultsAligned, hIRInit, hYulInit] using hInit - unfold statesAligned at hAlignedInit - subst hAlignedInit - -- Normalize yulStateOfIR after subst to match expanded kernel forms - simp only [yulStateOfIR] at * - have hCondEq : evalIRExpr irAfterInit cond = - evalYulExpr (yulStateOfIR selector irAfterInit) cond := - evalIRExpr_eq_evalYulExpr selector irAfterInit cond - cases hCondIR : evalIRExpr irAfterInit cond with - | none => - have hCondYul : evalYulExpr (yulStateOfIR selector irAfterInit) cond = none := by - symm - simpa only [hCondIR] using hCondEq - simp only [yulStateOfIR] at hCondYul - simp only [hIRInit, hCondIR, hCondYul, - execResultsAligned, statesAligned, yulStateOfIR] - | some v => - have hCondYul : evalYulExpr (yulStateOfIR selector irAfterInit) cond = some v := by - symm - simpa only [hCondIR] using hCondEq - by_cases hv : v = 0 - · subst hv - simp only [yulStateOfIR] at hCondYul - simp only [hIRInit, hCondIR, hCondYul, ne_eq, not_true_eq_false, ite_false, ite_true, - execResultsAligned, statesAligned, yulStateOfIR] - · have hBody := - ihStmts selector body irAfterInit (yulStateOfIR selector irAfterInit) rfl - cases hIRBody : execIRStmtsFuel fuel irAfterInit body with - | «continue» irAfterBody => - cases hYulBody : execYulStmtsFuel fuel (yulStateOfIR selector irAfterInit) body with - | «continue» yulAfterBody => - have hAlignedBody : statesAligned selector irAfterBody yulAfterBody := by - simpa only [execResultsAligned, hIRBody, hYulBody] using hBody - unfold statesAligned at hAlignedBody - subst hAlignedBody - simp only [yulStateOfIR] at * - have hPost := - ihStmts selector post irAfterBody (yulStateOfIR selector irAfterBody) rfl - cases hIRPost : execIRStmtsFuel fuel irAfterBody post with - | «continue» irAfterPost => - cases hYulPost : execYulStmtsFuel fuel (yulStateOfIR selector irAfterBody) post with - | «continue» yulAfterPost => - have hAlignedPost : statesAligned selector irAfterPost yulAfterPost := by - simpa only [execResultsAligned, hIRPost, hYulPost] using hPost - unfold statesAligned at hAlignedPost - subst hAlignedPost - simp only [yulStateOfIR] at * - have hRec := ihStmt selector (.for_ [] cond post body) - irAfterPost (yulStateOfIR selector irAfterPost) rfl - simp_all only [execIRStmt_equiv_execYulStmt_goal, execIRStmtFuel, - execYulStmtFuel, execYulStmtsFuel, yulStateOfIR, and_self, and_true, true_and, - ne_eq, ite_true, ite_false, not_false_eq_true, not_true_eq_false] - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - cases hYulPost : execYulStmtsFuel fuel (yulStateOfIR selector irAfterBody) post with - | «return» _ _ => - simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, ne_eq, ite_true, ite_false, not_false_eq_true, not_true_eq_false] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - cases hYulPost : execYulStmtsFuel fuel (yulStateOfIR selector irAfterBody) post with - | «stop» _ => - simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, ne_eq, ite_true, ite_false, not_false_eq_true, not_true_eq_false] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - cases hYulPost : execYulStmtsFuel fuel (yulStateOfIR selector irAfterBody) post with - | «revert» _ => - simp_all only [execResultsAligned, statesAligned, yulStateOfIR, and_self, and_true, true_and, ne_eq, ite_true, ite_false, not_false_eq_true, not_true_eq_false] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hPost) (hIR := hIRPost) (hYul := hYulPost) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - cases hYulBody : execYulStmtsFuel fuel (yulStateOfIR selector irAfterInit) body with - | «return» _ _ => - simp only [yulStateOfIR] at hCondYul hYulBody hBody - simp only [execResultsAligned, hIRBody, hYulBody, - statesAligned, yulStateOfIR] at hBody - simp only [hIRInit, hCondIR, hCondYul, hv, ite_true, ite_false, decide_true, decide_false, ne_eq, not_false_eq_true, - hIRBody, hYulBody, execResultsAligned, - statesAligned, yulStateOfIR, hBody, and_self] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - cases hYulBody : execYulStmtsFuel fuel (yulStateOfIR selector irAfterInit) body with - | «stop» _ => - simp only [yulStateOfIR] at hCondYul hYulBody hBody - simp only [execResultsAligned, hIRBody, hYulBody, - statesAligned, yulStateOfIR] at hBody - simp only [hIRInit, hCondIR, hCondYul, hv, ite_true, ite_false, decide_true, decide_false, ne_eq, not_false_eq_true, - hIRBody, hYulBody, execResultsAligned, - statesAligned, yulStateOfIR, hBody, and_self] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - cases hYulBody : execYulStmtsFuel fuel (yulStateOfIR selector irAfterInit) body with - | «revert» _ => - simp only [yulStateOfIR] at hCondYul hYulBody hBody - simp only [execResultsAligned, hIRBody, hYulBody, - statesAligned, yulStateOfIR] at hBody - simp only [hIRInit, hCondIR, hCondYul, hv, ite_true, ite_false, decide_true, decide_false, ne_eq, not_false_eq_true, - hIRBody, hYulBody, execResultsAligned, - statesAligned, yulStateOfIR, hBody, and_self] - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hBody) (hIR := hIRBody) (hYul := hYulBody) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» retVal retState => - cases hYulInit : execYulStmtsFuel fuel (yulStateOfIR selector irState) init with - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - have hInit' : - execResultsAligned selector (IRExecResult.return retVal retState) - (execYulStmtsFuel fuel (yulStateOfIR selector irState) init) := by - simpa only [hIRInit] using hInit - simp_all only [execIRStmt_equiv_execYulStmt_goal, execIRStmtFuel, - execYulStmtFuel, execYulStmtsFuel, execResultsAligned, statesAligned, yulStateOfIR, - and_self, and_true, true_and] - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» retState => - cases hYulInit : execYulStmtsFuel fuel (yulStateOfIR selector irState) init with - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - have hInit' : - execResultsAligned selector (IRExecResult.stop retState) - (execYulStmtsFuel fuel (yulStateOfIR selector irState) init) := by - simpa only [hIRInit] using hInit - simp_all only [execIRStmt_equiv_execYulStmt_goal, execIRStmtFuel, - execYulStmtFuel, execYulStmtsFuel, execResultsAligned, statesAligned, yulStateOfIR, - and_self, and_true, true_and] - | «revert» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» retState => - cases hYulInit : execYulStmtsFuel fuel (yulStateOfIR selector irState) init with - | «continue» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmts_align_contra (hStmts := hInit) (hIR := hIRInit) (hYul := hYulInit) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - have hInit' : - execResultsAligned selector (IRExecResult.revert retState) - (execYulStmtsFuel fuel (yulStateOfIR selector irState) init) := by - simpa only [hIRInit] using hInit - simp_all only [execIRStmt_equiv_execYulStmt_goal, execIRStmtFuel, - execYulStmtFuel, execYulStmtsFuel, execResultsAligned, statesAligned, yulStateOfIR, - and_self, and_true, true_and] - | block stmts => - simpa only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel] using - ihStmts selector stmts irState (yulStateOfIR selector irState) rfl - | funcDef _ _ _ _ => - simp only [execIRStmtFuel, execIRStmt, - execYulStmtFuel, legacyExecYulFuel, execResultsAligned, statesAligned, yulStateOfIR] - · intro selector stmts irState yulState halign - unfold statesAligned at halign - subst halign - cases stmts with - | nil => - simp only [execIRStmtsFuel, execIRStmts, - execYulStmtsFuel, legacyExecYulFuel, execResultsAligned, statesAligned, yulStateOfIR] - | cons stmt rest => - have hStmt := ihStmt selector stmt irState (yulStateOfIR selector irState) rfl - cases hIR : execIRStmtFuel fuel irState stmt with - | «continue» ir' => - cases hYul : execYulStmtFuel fuel (yulStateOfIR selector irState) stmt with - | «continue» y' => - have hAligned' : statesAligned selector ir' y' := by - simpa only [execResultsAligned, hIR, hYul] using hStmt - have hRest := ihStmts selector rest ir' y' hAligned' - simpa only [execIRStmts_equiv_execYulStmts_goal, execIRStmtsFuel, execIRStmts, - execYulStmtsFuel_cons, hIR, hYul] using hRest - | «return» _ _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - cases hYul : execYulStmtFuel fuel (yulStateOfIR selector irState) stmt with - | «return» _ _ => - simpa only [execIRStmts_equiv_execYulStmts_goal, execIRStmtsFuel, execIRStmts, - execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - cases hYul : execYulStmtFuel fuel (yulStateOfIR selector irState) stmt with - | «stop» _ => - simpa only [execIRStmts_equiv_execYulStmts_goal, execIRStmtsFuel, execIRStmts, - execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «revert» _ => - cases hYul : execYulStmtFuel fuel (yulStateOfIR selector irState) stmt with - | «revert» _ => - simpa only [execIRStmts_equiv_execYulStmts_goal, execIRStmtsFuel, execIRStmts, - execYulStmtsFuel_cons, execResultsAligned, hIR, hYul] using hStmt - | «continue» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «return» _ _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - | «stop» _ => - exact False.elim (stmt_align_contra (hStmt := hStmt) (hIR := hIR) (hYul := hYul) (by simp only [execResultsAligned, not_false_eq_true])) - -private theorem all_stmts_equiv : ∀ selector fuel stmt irState yulState, - execIRStmt_equiv_execYulStmt_goal selector fuel stmt irState yulState := by - intro selector fuel stmt irState yulState - exact (stmt_and_stmts_equiv fuel).1 selector stmt irState yulState - -private theorem conditional_equiv (selector : Nat) (fuel : Nat) - (condExpr : YulExpr) (body : List YulStmt) - (irState : IRState) (yulState : YulState) - (halign : statesAligned selector irState yulState) - (_hfuel : fuel > 0) : - execResultsAligned selector - (execIRStmtFuel fuel irState (YulStmt.if_ condExpr body)) - (execYulStmtFuel fuel yulState (YulStmt.if_ condExpr body)) := by - simpa only [execIRStmt_equiv_execYulStmt_goal] using - (all_stmts_equiv selector fuel (YulStmt.if_ condExpr body) irState yulState halign) - -private theorem return_equiv (selector : Nat) (fuel : Nat) - (offsetExpr sizeExpr : YulExpr) - (irState : IRState) (yulState : YulState) - (halign : statesAligned selector irState yulState) - (_hfuel : fuel > 0) : - execResultsAligned selector - (execIRStmtFuel fuel irState (YulStmt.expr (.call "return" [offsetExpr, sizeExpr]))) - (execYulStmtFuel fuel yulState (YulStmt.expr (.call "return" [offsetExpr, sizeExpr]))) := by - simpa only [execIRStmt_equiv_execYulStmt_goal] using - (all_stmts_equiv selector fuel (YulStmt.expr (.call "return" [offsetExpr, sizeExpr])) irState yulState halign) - -private theorem revert_equiv (selector : Nat) (fuel : Nat) - (offsetExpr sizeExpr : YulExpr) - (irState : IRState) (yulState : YulState) - (halign : statesAligned selector irState yulState) - (_hfuel : fuel > 0) : - execResultsAligned selector - (execIRStmtFuel fuel irState (YulStmt.expr (.call "revert" [offsetExpr, sizeExpr]))) - (execYulStmtFuel fuel yulState (YulStmt.expr (.call "revert" [offsetExpr, sizeExpr]))) := by - simpa only [execIRStmt_equiv_execYulStmt_goal] using - (all_stmts_equiv selector fuel (YulStmt.expr (.call "revert" [offsetExpr, sizeExpr])) irState yulState halign) - -private theorem storageStore_equiv (selector : Nat) (fuel : Nat) - (slotExpr valExpr : YulExpr) - (irState : IRState) (yulState : YulState) - (halign : statesAligned selector irState yulState) - (_hfuel : fuel > 0) : - execResultsAligned selector - (execIRStmtFuel fuel irState (YulStmt.expr (.call "sstore" [slotExpr, valExpr]))) - (execYulStmtFuel fuel yulState (YulStmt.expr (.call "sstore" [slotExpr, valExpr]))) := by - simpa only [execIRStmt_equiv_execYulStmt_goal] using - (all_stmts_equiv selector fuel (YulStmt.expr (.call "sstore" [slotExpr, valExpr])) irState yulState halign) - - -end Compiler.Proofs.YulGeneration diff --git a/Contracts/MacroTranslateInvariantTest.lean b/Contracts/MacroTranslateInvariantTest.lean deleted file mode 100644 index 530621973..000000000 --- a/Contracts/MacroTranslateInvariantTest.lean +++ /dev/null @@ -1,1240 +0,0 @@ -import Compiler.ABI -import Compiler.Codegen -import Compiler.Proofs.IRGeneration.IRInterpreter -import Compiler.Proofs.YulGeneration.IRFuel -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Compiler.Selector -import Compiler.Hex -import Contracts -import Contracts.Smoke -import Contracts.Smoke.ArrayElementDynamicMemberElementSmoke -import Contracts.Smoke.ArrayElementDynamicMemberLengthSmoke -import Contracts.Smoke.FixedArrayStructSmoke -import Contracts.Smoke.UnlinkPoolShapeCheckSmoke -import Contracts.Smoke.MathlibReservedBinderEscape -import Contracts.Smoke.PackedHashECMSmoke -import Contracts.Smoke.SelfBalanceSmoke -import Contracts.ProxyUpgradeabilityMacroSmoke -import Contracts.ProxyUpgradeabilityLayoutCompatibleSmoke -import Contracts.ProxyUpgradeabilityLayoutIncompatibleSmoke -import Contracts.StringErrorSmoke -import Contracts.StringSmoke - -namespace Compiler.MacroTranslateInvariantTest - -open Compiler -open Compiler.CompilationModel -open Compiler.Hex -open Compiler.Proofs.IRGeneration -open Compiler.Proofs.YulGeneration - -/- This executable harness is a legacy IR/reference-oracle differential - regression test. It is intentionally kept outside the public compiler - correctness theorem chain. -/ - -private def contains (haystack needle : String) : Bool := - let h := haystack.toList - let n := needle.toList - if n.isEmpty then true - else - let rec go : List Char → Bool - | [] => false - | c :: cs => - if (c :: cs).take n.length == n then true - else go cs - go h - -private def countOccurrences (haystack needle : String) : Nat := - let h := haystack.toList - let n := needle.toList - if n.isEmpty then 0 - else - let rec go : List Char → Nat - | [] => 0 - | c :: cs => - if (c :: cs).take n.length == n then - 1 + go cs - else - go cs - go h - -private def expectTrue (label : String) (ok : Bool) : IO Unit := do - if !ok then - throw (IO.userError s!"✗ {label}") - IO.println s!"✓ {label}" - -private def allDistinct [DecidableEq α] (xs : List α) : Bool := - xs.length == xs.eraseDups.length - -private def externalFunctions (spec : CompilationModel) : List FunctionSpec := - spec.functions.filter (fun fn => !fn.isInternal && !isInteropEntrypointName fn.name) - -private def bodyUsesAddressStorageRead (body : List Stmt) : Bool := - contains (reprStr body) "Expr.storageAddr" - -private def bodyUsesAddressStorageWrite (body : List Stmt) : Bool := - contains (reprStr body) "Stmt.setStorageAddr" - -private def bodyUsesSignedBuiltin (body : List Stmt) (builtinTag : String) : Bool := - contains (reprStr body) builtinTag - -private def canonicalFieldSlots (spec : CompilationModel) : List Nat := - let indexed := List.zip (List.range spec.fields.length) spec.fields - indexed.map (fun (idx, field) => field.slot.getD idx) - -private def writeSlots (spec : CompilationModel) : List Nat := - let indexed := List.zip (List.range spec.fields.length) spec.fields - indexed.flatMap (fun (idx, field) => field.slot.getD idx :: field.aliasSlots) - -private def isMappingLike : FieldType → Bool - | .mappingTyped _ => true - | .mappingStruct _ _ => true - | .mappingStruct2 _ _ _ => true - | _ => false - -private def mappingBaseSlots (spec : CompilationModel) : List Nat := - let indexed := List.zip (List.range spec.fields.length) spec.fields - indexed.filterMap (fun (idx, field) => - if isMappingLike field.ty then some (field.slot.getD idx) else none) - -private def functionUsesMappingSlot (fn : IRFunction) : Bool := - contains (reprStr fn.body) "mappingSlot" - -private def seedFromName (name : String) : Nat := - name.toList.foldl (fun acc ch => acc * 131 + ch.toNat) 0 - -private def rngMask : Nat := (2 ^ 64) - 1 - -private def nextSeed (seed : Nat) : Nat := - ((seed * 6364136223846793005) + 1442695040888963407) &&& rngMask - -private def randBound (seed bound : Nat) : Nat × Nat := - let seed' := nextSeed seed - if bound = 0 then (0, seed') else (seed' % bound, seed') - -private def randWord (seed : Nat) : Nat × Nat := - let s1 := nextSeed seed - let s2 := nextSeed s1 - (((s1 &&& rngMask) <<< 64) + (s2 &&& rngMask), s2) - -private def genArgs (count : Nat) (seed : Nat) : List Nat × Nat := - match count with - | 0 => ([], seed) - | n + 1 => - let (v, seed') := randWord seed - let (rest, seed'') := genArgs n seed' - (v :: rest, seed'') - -private def mkRandomTx (extFns : List FunctionSpec) (selectors : List Nat) - (seed : Nat) : IRTransaction × Nat := - if extFns.isEmpty then - ({ sender := 0, functionSelector := 0, args := [] }, nextSeed seed) - else - let (fnIdx, seed1) := randBound seed extFns.length - let fn := extFns.getD fnIdx { name := "", params := [], returnType := none, returns := [], body := [] } - let selector := selectors.getD fnIdx 0 - let (sender, seed2) := randWord seed1 - let (args, seed3) := genArgs fn.params.length seed2 - ({ sender := sender, functionSelector := selector, args := args }, seed3) - -private def seededStorage (seed : Nat) (slotIdx : IRStorageSlot) : IRStorageWord := - let mix := seed + slotIdx.toNat * 0x9e3779b97f4a7c15 + 0xbf58476d1ce4e5b9 - IRStorageWord.ofNat mix - -private def observedSlotsForTx (spec : CompilationModel) (_tx : IRTransaction) : List Nat := - (canonicalFieldSlots spec ++ writeSlots spec).eraseDups - -private def mappingKeyCandidatesForTx (_spec : CompilationModel) (_tx : IRTransaction) : List (Prod Nat Nat) := - [] - -private def mkIRResultFromExec (rollback : IRState) (r : IRExecResult) : IRResult := - match r with - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := rollback.storage - finalMappings := Compiler.Proofs.storageAsMappings rollback.storage - events := rollback.events } - -private def mkYulResultFromExec (rollback : YulState) (r : YulExecResult) : YulResult := - match r with - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := rollback.storage - finalMappings := Compiler.Proofs.storageAsMappings rollback.storage - events := rollback.events } - -private def withTxContext (state : IRState) (tx : IRTransaction) : IRState := - { state with - calldata := tx.args - sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - selector := tx.functionSelector } - -private def execIRFunctionFuelResult (fn : IRFunction) (args : List Nat) (initialState : IRState) - (fuel : Nat) : IRResult := - let stateWithParams := fn.params.zip args |>.foldl (fun s (p, v) => s.setVar p.name v) initialState - mkIRResultFromExec initialState (execIRStmts fuel stateWithParams fn.body) - -private def interpretIRFuelResult (contract : IRContract) (tx : IRTransaction) (initialState : IRState) - (fuel : Nat) : IRResult := - let state := withTxContext initialState tx - match contract.functions.find? (fun f => f.selector == tx.functionSelector) with - | some fn => execIRFunctionFuelResult fn tx.args state fuel - | none => - { success := false - returnValue := none - finalStorage := state.storage - finalMappings := Compiler.Proofs.storageAsMappings state.storage - events := state.events } - -private def resultsMatchOn - (slots : List Nat) - (mappingKeys : List (Nat × Nat)) - (ir : IRResult) - (yul : YulResult) : Bool := - ir.success == yul.success && - ir.returnValue == yul.returnValue && - ir.events == yul.events && - slots.all (fun slotIdx => - ir.finalStorage (IRStorageSlot.ofNat slotIdx) == - yul.finalStorage (IRStorageSlot.ofNat slotIdx)) && - mappingKeys.all (fun (base, key) => - ir.finalMappings base key == yul.finalMappings base key) - -private def interpretYulFromIRFuelResult (contract : IRContract) (tx : IRTransaction) (state : IRState) - (fuel : Nat) : YulResult := - let yulTx : YulTransaction := { - sender := tx.sender - msgValue := tx.msgValue - thisAddress := tx.thisAddress - blockTimestamp := tx.blockTimestamp - blockNumber := tx.blockNumber - chainId := tx.chainId - functionSelector := tx.functionSelector - args := tx.args - } - let yulInit := YulState.initial yulTx state.storage state.events - mkYulResultFromExec yulInit (execYulStmtsFuel fuel yulInit (Compiler.runtimeCode contract)) - -private def diffCheckTx (spec : CompilationModel) (ir : IRContract) - (tx : IRTransaction) (seed : Nat) : Bool := - let initState : IRState := - { vars := [], - «storage» := seededStorage seed, - memory := fun _ => 0, - calldata := [], - returnValue := none, - sender := tx.sender, - msgValue := tx.msgValue, - thisAddress := tx.thisAddress, - blockTimestamp := tx.blockTimestamp, - blockNumber := tx.blockNumber, - chainId := tx.chainId, - selector := 0, - events := [] } - let irResult := interpretIRFuelResult ir tx initState 800 - let yulResult := interpretYulFromIRFuelResult ir tx initState 800 - let slots := observedSlotsForTx spec tx - let mappingKeys := mappingKeyCandidatesForTx spec tx - resultsMatchOn slots mappingKeys irResult yulResult - -private def runRandomDiffChecks (spec : CompilationModel) (ir : IRContract) - (extFns : List FunctionSpec) (selectors : List Nat) (count : Nat) : IO Unit := do - let rec loop (remaining : Nat) (seed : Nat) (idx : Nat) : IO Unit := do - if remaining = 0 then - pure () - else - let txSeed := mkRandomTx extFns selectors seed - let tx := txSeed.1 - let seed' := txSeed.2 - let ok := diffCheckTx spec ir tx (seed + idx + 1) - expectTrue - s!"{spec.name}: randomized IR↔Yul differential check {idx + 1}/{count}" - ok - loop (remaining - 1) seed' (idx + 1) - loop count (seedFromName spec.name) 0 - -private def macroSpecs : List CompilationModel := - [ Contracts.SimpleStorage.spec - , Contracts.Counter.spec - , Contracts.Owned.spec - , Contracts.Ledger.spec - , Contracts.LocalObligationMacroSmoke.spec - , Contracts.ProxyUpgradeabilityMacroSmoke.spec - , Contracts.ProxyUpgradeabilityLayoutCompatibleSmoke.spec - , Contracts.ProxyUpgradeabilityLayoutIncompatibleSmoke.spec - , Contracts.Vault.spec - , Contracts.SafeCounter.spec - , Contracts.OwnedCounter.spec - , Contracts.SimpleToken.spec - , Contracts.ERC20.spec - , Contracts.ERC721.spec - , Contracts.Smoke.Uint256PowSmoke.spec - , Contracts.Smoke.UintMapSmoke.spec - , Contracts.Smoke.MappingChainSmoke.spec - , Contracts.Smoke.MixedMappingChainSmoke.spec - , Contracts.Smoke.Bytes32Smoke.spec - , Contracts.Smoke.StorageArraySmoke.spec - , Contracts.Smoke.StorageAddressArraySmoke.spec - , Contracts.Smoke.StorageBoolArraySmoke.spec - , Contracts.Smoke.StorageBytes32ArraySmoke.spec - , Contracts.Smoke.MappingWordSmoke.spec - , Contracts.Smoke.StorageWordsSmoke.spec - , Contracts.Smoke.StorageWordsAddressSmoke.spec - , Contracts.Smoke.StorageWordsBoolSmoke.spec - , Contracts.Smoke.CustomErrorSmoke.spec - , Contracts.Smoke.SafeMulRequireSmoke.spec - , Contracts.Smoke.ArithmeticPanicSmoke.spec - , Contracts.Smoke.MulDiv512Smoke.spec - , Contracts.Smoke.SignedBuiltinSmoke.spec - , Contracts.Smoke.StatelessSmoke.spec - , Contracts.Smoke.MutabilitySmoke.spec - , Contracts.Smoke.SpecialEntrypointSmoke.spec - , Contracts.Smoke.LeanDefHelperSmoke.spec - , Contracts.Smoke.DirectHelperCallSmoke.spec - , Contracts.Smoke.MultiReturnHelperSmoke.spec - , Contracts.Smoke.ArrayHelperCallSmoke.spec - , Contracts.Smoke.InitializerSmoke.spec - , Contracts.Smoke.ConstantSmoke.spec - , Contracts.Smoke.ImmutableSmoke.spec - , Contracts.Smoke.TypedImmutableSmoke.spec - , Contracts.StringErrorSmoke.spec - , Contracts.StringSmoke.spec - , Contracts.StringEqSmoke.spec - , Contracts.BytesEqSmoke.spec - , Contracts.Smoke.TupleSmoke.spec - , Contracts.Smoke.NamedStructParamSmoke.spec - , Contracts.Smoke.NamedStructDynamicRootLeafProjection.spec - , Contracts.Smoke.CurveCutArraySmoke.spec - , Contracts.Smoke.DynamicStructArraySmoke.spec - , Contracts.Smoke.PackedStorageWriteSmoke.spec - , Contracts.Smoke.PackedAddressStorageWriteSmoke.spec - , Contracts.Smoke.Uint8Smoke.spec - , Contracts.Smoke.AddressHelpersSmoke.spec - , Contracts.Smoke.ZeroAddressShadowSmoke.spec - , Contracts.Smoke.ContextAccessorShadowSmoke.spec - , Contracts.Smoke.FunctionOverloadSmoke.spec - , Contracts.Smoke.HelperExternalArgumentSmoke.spec - , Contracts.Smoke.BlockTimestampSmoke.spec - , Contracts.Smoke.SelfBalanceSmoke.spec - , Contracts.Smoke.MathlibReservedBinderEscape.spec - , Contracts.Smoke.ForEachMutableLocalSmoke.spec - , Contracts.Smoke.ArrayElementDynamicMemberLengthSmoke.spec - , Contracts.Smoke.ArrayElementDynamicMemberElementSmoke.spec - , Contracts.Smoke.FixedArrayStructSmoke.spec - , Contracts.Smoke.UnlinkPoolShapeCheckSmoke.spec - , Contracts.Smoke.StructMappingSmoke.spec - , Contracts.Smoke.ExternalCallSmoke.spec - , Contracts.Smoke.TryExternalCallSmoke.spec - , Contracts.Smoke.LinkedExternalDynamicArgSmoke.spec - , Contracts.Smoke.LinkedExternalProjectedArrayArgSmoke.spec - , Contracts.Smoke.NestedStructArrayProjectionSmoke.spec - , Contracts.Smoke.DynamicStructElementHelperArgSmoke.spec - , Contracts.Smoke.ExternalCallMultiReturn.spec - , Contracts.Smoke.ERC20HelperSmoke.spec - , Contracts.Smoke.GenericECMReadSmoke.spec - , Contracts.Smoke.GenericECMMultiResultSmoke.spec - , Contracts.Smoke.GenericECMWriteSmoke.spec - , Contracts.Smoke.CallWithValueSmoke.spec - , Contracts.Smoke.BubblingValueCallECMSmoke.spec - , Contracts.Smoke.PackedHashECMSmoke.spec - , Contracts.Smoke.LowLevelTryCatchSmoke.spec - , Contracts.Smoke.LocalObligationRequiredForUnsafeFunctionBoundary.spec - , Contracts.Smoke.LocalObligationRequiredForUnsafeConstructorBoundary.spec - , Contracts.Smoke.ModifiesSmoke.spec - , Contracts.Smoke.NoExternalCallsSmoke.spec - , Contracts.Smoke.EffectCompositionSmoke.spec - , Contracts.Smoke.CEISmoke.spec - , Contracts.Smoke.CEILadderSmoke.spec - , Contracts.Smoke.RolesSmoke.spec - , Contracts.Smoke.RolesMappingSmoke.spec - , Contracts.Smoke.NewtypeSmoke.spec - , Contracts.Smoke.NewtypeStorageSmoke.spec - , Contracts.Smoke.NamespacedStorageSmoke.spec - , Contracts.Smoke.CustomNamespacedSmoke.spec - , Contracts.Smoke.CEIViolationRejected.spec - , Contracts.Smoke.UnsafeBlockSmoke.spec - , Contracts.Smoke.UnsafeGatingAccepted.spec - , Contracts.Smoke.UnsafeGatingRejected.spec - , Contracts.Smoke.AdtSmoke.spec - , Contracts.Smoke.CEIWriteInBranchAfterCall.spec - , Contracts.Smoke.CEICallBothBranchesWrite.spec - , Contracts.Smoke.ModifiesRolesSmoke.spec - , Contracts.Smoke.ModifiesNamespaceSmoke.spec - , Contracts.Smoke.AdtSingleVariant.spec - , Contracts.Smoke.AdtMixedFieldCounts.spec - , Contracts.Smoke.NewtypeModifiesSmoke.spec - , Contracts.Smoke.NewtypeNamespaceSmoke.spec - , Contracts.Smoke.UnsafeCEIViolation.spec - , Contracts.Smoke.UnsafeCEICompliant.spec - , Contracts.Smoke.CEIInternalCallAfterExternalRejected.spec - , Contracts.Smoke.RolesCEISmoke.spec - , Contracts.Smoke.NonreentrantModifiesSmoke.spec - , Contracts.Smoke.AdtNewtypeCombo.spec - , Contracts.Smoke.FullComboSmoke.spec - ] - -private def expectedExternalSignatures : List (String × List String) := - [ ("SimpleStorage", ["store(uint256)", "retrieve()"]) - , ("LocalObligationMacroSmoke", ["unsafeEdge()", "dischargedEdge(uint256)"]) - , ("ProxyUpgradeabilityMacroSmoke", ["initProxy(address,address)", "upgradeTo(address)", "forward(uint256,uint256,uint256,uint256,uint256)"]) - , ("ProxyUpgradeabilityLayoutCompatibleSmoke", ["initProxy(address,address)", "stageUpgrade(address)", "finalizeUpgrade()", "forward(uint256,uint256,uint256,uint256,uint256)"]) - , ("ProxyUpgradeabilityLayoutIncompatibleSmoke", ["initProxy(address,address)", "stageUpgrade(address)", "finalizeUpgrade()", "forward(uint256,uint256,uint256,uint256,uint256)"]) - , ("Counter", ["increment()", "decrement()", "getCount()", "previewAddTwice(uint256)", - "previewOps(uint256,uint256,uint256)", "previewEnvOps(uint256,uint256)", - "previewLowLevel(uint256,uint256)"]) - , ("Owned", ["transferOwnership(address)", "getOwner()"]) - , ("Ledger", ["deposit(uint256)", "withdraw(uint256)", "transfer(address,uint256)", "getBalance(address)"]) - , ("Vault", ["deposit(uint256)", "withdraw(uint256)", "balanceOf(address)", "totalAssets()", "totalSupply()"]) - , ("SafeCounter", ["increment()", "decrement()", "getCount()"]) - , ("OwnedCounter", ["increment()", "decrement()", "getCount()", "getOwner()", "transferOwnership(address)"]) - , ("SimpleToken", ["mint(address,uint256)", "transfer(address,uint256)", "balanceOf(address)", "totalSupply()", - "owner()"]) - , ("ERC20", ["mint(address,uint256)", "transfer(address,uint256)", "approve(address,uint256)", - "transferFrom(address,address,uint256)", "balanceOf(address)", "allowanceOf(address,address)", - "totalSupply()", "owner()"]) - , ("ERC721", ["balanceOf(address)", "ownerOf(uint256)", "getApproved(uint256)", - "isApprovedForAll(address,address)", "approve(address,uint256)", "setApprovalForAll(address,bool)", - "mint(address)", "transferFrom(address,address,uint256)"]) - , ("Uint256PowSmoke", ["scale(uint256)", "scaleInfix(uint256)"]) - , ("UintMapSmoke", ["setValue(uint256,uint256)", "getValue(uint256)"]) - , ("MappingChainSmoke", ["setApproval(address,address,address,uint256)", "getApproval(address,address,address)"]) - , ("MixedMappingChainSmoke", ["setApproval(address,uint256,address,uint256)", "getApproval(address,uint256,address)"]) - , ("Bytes32Smoke", ["setDigest(bytes32)", "getDigest()"]) - , ("StorageArraySmoke", ["size()", "push(uint256)"]) - , ("StorageAddressArraySmoke", ["size()", "firstOwner()", "pushOwner(address)", "replaceFirstOwner(address)"]) - , ("StorageBoolArraySmoke", ["firstFlag()", "pushFlag(bool)", "setFirstFlag(bool)"]) - , ("StorageBytes32ArraySmoke", ["firstDigest()", "pushDigest(bytes32)"]) - , ("MappingWordSmoke", ["setWord1(uint256,uint256)", "getWord1(uint256)", "isWord1NonZero(uint256)"]) - , ("StorageWordsSmoke", ["extSloadsLike(bytes32[])"]) - , ("StorageWordsAddressSmoke", ["extSloadsLike(address[])"]) - , ("StorageWordsBoolSmoke", ["extSloadsLike(bool[])"]) - , ("CustomErrorSmoke", ["echo(uint256)"]) - , ("SafeMulRequireSmoke", ["multiplyStored(uint256)", "divideStored(uint256)"]) - , ("ArithmeticPanicSmoke", ["deposit(uint256)", "withdraw(uint256)", "scaleStored(uint256)", "shareStored(uint256)"]) - , ("MulDiv512Smoke", ["storeFloor(uint256,uint256,uint256)", "storeCeil(uint256,uint256,uint256)"]) - , ("SignedBuiltinSmoke", ["signedDiv(uint256,uint256)", "signedMod(uint256,uint256)", "signedLt(uint256,uint256)", - "signedGt(uint256,uint256)", "arithmeticShift(uint256,uint256)", "signExtended()", "shiftedMask()", - "signedDivSurface(int256,int256)", "signedModSurface(int256,int256)", "signedDivViaLocal(uint256,int256)", - "castToInt(uint256)", "castToUint(int256)", "minusOne()", "bitAndSignBit(int256,int256)", - "minSignBit(int256)", "storeSigned(int256)", "loadSigned()"]) - , ("StatelessSmoke", ["echoWord(uint256)", "whoAmI()"]) - , ("MutabilitySmoke", ["deposit()", "currentOwner()"]) - , ("SpecialEntrypointSmoke", ["getReceiveCount()", "getFallbackCount()"]) - , ("LeanDefHelperSmoke", ["addOffset(uint256,int256)", "sameWord(uint256,uint256)"]) - , ("DirectHelperCallSmoke", ["addToTotal(uint256)", "readTotalPlus(uint256)", "pairWithTotal(uint256)", - "runHelpers(uint256,uint256,uint256)", "snapshot()"]) - , ("MultiReturnHelperSmoke", ["summarize(uint256)", "useSummary(uint256)"]) - , ("ArrayHelperCallSmoke", ["first(uint256[])", "useFirst(uint256[])"]) - , ("InitializerSmoke", ["initOwner(address)", "upgradeToV2()"]) - , ("ConstantSmoke", ["feeOn(uint256)", "treasuryAddr()"]) - , ("ImmutableSmoke", ["supplyCap()", "treasuryAddr()", "shadowed(uint256)"]) - , ("TypedImmutableSmoke", ["isPaused()", "feeScale()", "domainSeparator()"]) - , ("StringErrorSmoke", ["checkMessage(bool,string)", "checkTaggedMessage(uint256,string)", - "checkSecondMessage(bool,string,string)"]) - , ("StringSmoke", ["echoString(string)", "echoStringAfterUint(uint256,string)", "echoStringBeforeUint(string,uint256)", - "echoSecondString(string,string)"]) - , ("StringEqSmoke", ["same(string,string)", "different(string,string)", "choose(string,string)"]) - , ("BytesEqSmoke", ["same(bytes,bytes)", "different(bytes,bytes)", "choose(bytes,bytes)"]) - , ("TupleSmoke", ["setFromPair((uint256,uint256))", "getPair(uint256)", "processConfig((address,address,uint256))"]) - , ("NamedStructParamSmoke", ["readBorrowFee((uint256,uint256))", "storeNestedFee(((uint256,uint256),address),uint256)", - "readNestedMaker(((uint256,uint256),address))"]) - , ("NamedStructDynamicRootLeafProjection", ["goodDynamicLeaf((uint256[],address))"]) - , ("CurveCutArraySmoke", ["firstCutXt((uint256,uint256,int256)[])", "returnCut((uint256,uint256,int256)[],uint256)", - "storeCut((uint256,uint256,int256)[],uint256)", "storeTwoCuts((uint256,uint256,int256)[],uint256,uint256)"]) - , ("DynamicStructArraySmoke", ["tokenOf((uint256[],(address,uint256,bytes32),(uint256[],bytes32)[],address,uint256)[],uint256)", - "feeOf((uint256[],(address,uint256,bytes32),(uint256[],bytes32)[],address,uint256)[],uint256)", - "wrappedTokenOf(((uint256[],bytes32),address,uint256)[],uint256)", - "storeTokenAndFee((uint256[],(address,uint256,bytes32),(uint256[],bytes32)[],address,uint256)[],uint256)"]) - , ("PackedStorageWriteSmoke", ["writeSlot0(bool,uint256)", "writeSlot1(uint256,uint256)"]) - , ("PackedAddressStorageWriteSmoke", ["writeOwnerWord(uint256)"]) - , ("Uint8Smoke", ["acceptSig((uint8,bytes32,bytes32))", "sigV()"]) - , ("AddressHelpersSmoke", ["setDelegate(address,address)", "getDelegate(address)", "clearDelegate(address)", - "hasDelegate(address)", "isDelegateZero(address)", "setOwnerForId(uint256,address)", "getOwnerForId(uint256)"]) - , ("ZeroAddressShadowSmoke", ["shadowWrite(address)"]) - , ("ContextAccessorShadowSmoke", ["echoSenderName(address)", "constantNamedChainid()", - "immutableNamedBlockTimestamp()", "immutableNamedMsgSender()"]) - , ("FunctionOverloadSmoke", ["echo(uint256)", "echo(address)", "echo(uint256,uint256)"]) - , ("HelperExternalArgumentSmoke", ["idWord(uint256)", "pair(uint256)", "put(uint256)", - "bindExternalArg(uint256)", "tupleExternalArg(uint256)", "statementExternalArg(uint256)"]) - , ("BlockTimestampSmoke", ["nowish()", "timestampPlus(uint256)", "blobFeePlus(uint256)"]) - , ("SelfBalanceSmoke", ["currentBalance()", "balancePlus(uint256)"]) - , ("MathlibReservedBinderEscape", ["transferLike(address,uint256)", "transferLikeFrom(address,address,uint256)"]) - , ("ForEachMutableLocalSmoke", ["sumValues(uint256[])", "sumOnCatch(uint256[])", "sumUnsafe(uint256[])"]) - , ("ArrayElementDynamicMemberLengthSmoke", ["proofLength((uint256[],address,uint256)[],uint256)"]) - , ("ArrayElementDynamicMemberElementSmoke", ["proofAt((uint256[],address,uint256)[],uint256,uint256)"]) - , ("FixedArrayStructSmoke", ["rootOf(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "nullifierCountOf(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "commitmentCountOf(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "ciphertextCountOf(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "proofPA0Of(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "proofPC1OfTxn(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[]))", - "proofPC1OfAlias(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)", - "nullifierCountOfAlias(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,uint256[3])[])[],uint256)"]) - , ("UnlinkPoolShapeCheckSmoke", ["nullifierCountOf((uint256,uint256[],uint256[],uint256)[],uint256)", - "commitmentCountOf((uint256,uint256[],uint256[],uint256)[],uint256)", - "nullifierAt((uint256,uint256[],uint256[],uint256)[],uint256,uint256)", - "commitmentAt((uint256,uint256[],uint256[],uint256)[],uint256,uint256)", - "validateInputShape((uint256,uint256[],uint256[],uint256)[],uint256,uint256)", - "validateOutputShape((uint256,uint256[],uint256[],uint256)[],uint256,uint256)", - "validateBatch((uint256,uint256[],uint256[],uint256)[],uint256,uint256)"]) - , ("StructMappingSmoke", ["setPosition(address,uint256,uint256,address)", "totalPositionShares(address)", - "delegateOf(address)", "setApproval(address,address,uint256,uint256)", "approvalOf(address,address)", - "approvalNonce(address,address)"]) - , ("ExternalCallSmoke", ["storeEcho(uint256)", "getEchoedValue()"]) - , ("TryExternalCallSmoke", ["tryEcho(uint256)"]) - , ("LinkedExternalDynamicArgSmoke", ["hashLeaves(uint256[])", "sendLeaves(uint256[])", - "tryHash(uint256[])", "hashPayload(bytes)"]) - , ("LinkedExternalProjectedArrayArgSmoke", - ["tryHashNullifiers((uint256,uint256[],uint256[])[],uint256)"]) - , ("NestedStructArrayProjectionSmoke", - ["withdrawalAmount(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,address,uint256),uint256[])[],uint256)", - "consumeNullifiers(uint256[])", - "withdrawalAmountViaHelper(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,address,uint256),uint256[])[],uint256)", - "consumeNullifiersViaHelper(((uint256[2],uint256[2][2],uint256[2]),uint256,uint256,uint256[],uint256[],uint256,(uint256,address,uint256),uint256[])[],uint256)"]) - , ("DynamicStructElementHelperArgSmoke", - ["consumeValues(uint256[])", "inspect((uint256,uint256[]))", - "inspectAt((uint256,uint256[])[],uint256)"]) - , ("ExternalCallMultiReturn", ["callFanout(uint256)", "noop()"]) - , ("ERC20HelperSmoke", ["pushTokens(address,address,uint256)", "pullTokens(address,address,address,uint256)", - "approveTokens(address,address,uint256)", "snapshotBalance(address,address)", - "snapshotAllowance(address,address,address)", "snapshotSupply(address)"]) - , ("GenericECMReadSmoke", ["snapshotQuote(address,address)"]) - , ("GenericECMMultiResultSmoke", ["addPoints(uint256,uint256,uint256,uint256)"]) - , ("GenericECMWriteSmoke", ["runEffect(uint256,uint256)"]) - , ("CallWithValueSmoke", ["execute(address,uint256,uint256,uint256)", "executeBytes(address,uint256,bytes)"]) - , ("BubblingValueCallECMSmoke", ["forwardNoOutput(address,uint256,uint256,uint256)"]) - , ("PackedHashECMSmoke", ["hashAddressAmount(address,uint256)", "hashLowByteAmount(uint256,uint256)", - "sha256AddressAmount(address,uint256)"]) - , ("LowLevelTryCatchSmoke", ["catchFailure()", "skipCatchOnSuccess()", "catchFailureWithShadowedParam(uint256)"]) - , ("LocalObligationRequiredForUnsafeFunctionBoundary", ["preview()"]) - , ("LocalObligationRequiredForUnsafeConstructorBoundary", ["noop()"]) - , ("ModifiesSmoke", ["increment()", "transferOwnership(address)", "deposit(uint256)", "getCounter()"]) - , ("NoExternalCallsSmoke", ["increment()", "getCounter()", "setOwner(address)"]) - , ("EffectCompositionSmoke", ["getCounter()", "increment()", "setOwner(address)", "deposit(uint256)"]) - , ("CEISmoke", ["increment()", "getCounter()", "updateThenCall(uint256)", "callThenUpdate(uint256)"]) - , ("CEILadderSmoke", ["callThenStoreGuarded(uint256)", "callThenStoreProved(uint256)", "storeThenCall(uint256)", "increment()"]) - , ("RolesSmoke", ["setCounter(uint256)", "getCounter()"]) - , ("RolesMappingSmoke", ["setCounter(uint256)", "getCounter()"]) - , ("NewtypeSmoke", ["mint(uint256,uint256)", "setMinter(address)", "getNextTokenId()"]) - , ("NewtypeStorageSmoke", ["setTokenId(uint256)", "getTokenId()", "setAdmin(address)", "getAdmin()"]) - , ("NamespacedStorageSmoke", ["deposit(uint256)", "getOwner()"]) - , ("CustomNamespacedSmoke", ["deposit(uint256)", "getOwner()"]) - , ("CEIViolationRejected", ["callThenStore(uint256)"]) - , ("UnsafeBlockSmoke", ["incrementUnsafe()", "getCounter()"]) - , ("UnsafeGatingAccepted", ["writeMem()"]) - , ("UnsafeGatingRejected", ["noop()"]) - , ("AdtSmoke", ["increment()"]) - , ("CEIWriteInBranchAfterCall", ["callThenConditionalWrite(uint256)"]) - , ("CEICallBothBranchesWrite", ["callThenBranchWrite(uint256)"]) - , ("ModifiesRolesSmoke", ["setCounter(uint256)", "setCounterAndFlag(uint256,uint256)", "getCounter()"]) - , ("ModifiesNamespaceSmoke", ["increment()", "transferOwnership(address)", "getCounter()"]) - , ("AdtSingleVariant", ["store()"]) - , ("AdtMixedFieldCounts", ["clear()", "set(uint256)"]) - , ("NewtypeModifiesSmoke", ["mint(uint256,uint256)", "getNextId()"]) - , ("NewtypeNamespaceSmoke", ["setId(uint256)", "getId()"]) - , ("UnsafeCEIViolation", ["unsafeCallThenWrite(uint256)"]) - , ("UnsafeCEICompliant", ["writeBeforeUnsafeCall(uint256)"]) - , ("CEIInternalCallAfterExternalRejected", ["increment(uint256)", "callThenHelper(uint256)"]) - , ("RolesCEISmoke", ["setAndCall(uint256)", "getCounter()"]) - , ("NonreentrantModifiesSmoke", ["deposit(uint256)", "getBalance()"]) - , ("AdtNewtypeCombo", ["pause()", "unpause()", "setLastId(uint256)"]) - , ("FullComboSmoke", ["deposit(uint256)", "freeze()", "getBalance()"]) - ] - -private def expectedExternalSelectors : List (String × List String) := - [ ("SimpleStorage", ["0x6057361d", "0x2e64cec1"]) - , ("LocalObligationMacroSmoke", ["0xbb93e288", "0xb67b3c55"]) - , ("ProxyUpgradeabilityMacroSmoke", ["0x50deff9e", "0x3659cfe6", "0x33b403a6"]) - , ("ProxyUpgradeabilityLayoutCompatibleSmoke", ["0x50deff9e", "0x1188ed66", "0x9a508c8e", "0x33b403a6"]) - , ("ProxyUpgradeabilityLayoutIncompatibleSmoke", ["0x50deff9e", "0x1188ed66", "0x9a508c8e", "0x33b403a6"]) - , ("Counter", ["0xd09de08a", "0x2baeceb7", "0xa87d942c", "0x04a34e04", "0x8022f026", "0x0a7486d3", "0x9d4825af"]) - , ("Owned", ["0xf2fde38b", "0x893d20e8"]) - , ("Ledger", ["0xb6b55f25", "0x2e1a7d4d", "0xa9059cbb", "0xf8b2cb4f"]) - , ("Vault", ["0xb6b55f25", "0x2e1a7d4d", "0x70a08231", "0x01e1d114", "0x18160ddd"]) - , ("SafeCounter", ["0xd09de08a", "0x2baeceb7", "0xa87d942c"]) - , ("OwnedCounter", ["0xd09de08a", "0x2baeceb7", "0xa87d942c", "0x893d20e8", "0xf2fde38b"]) - , ("SimpleToken", ["0x40c10f19", "0xa9059cbb", "0x70a08231", "0x18160ddd", "0x8da5cb5b"]) - , ("ERC20", ["0x40c10f19", "0xa9059cbb", "0x095ea7b3", "0x23b872dd", "0x70a08231", "0x1a46ec82", "0x18160ddd", - "0x8da5cb5b"]) - , ("ERC721", ["0x70a08231", "0x6352211e", "0x081812fc", "0xe985e9c5", "0x095ea7b3", "0xa22cb465", - "0x6a627842", "0x23b872dd"]) - , ("Uint256PowSmoke", ["0x2bec1547", "0x09c39250"]) - , ("UintMapSmoke", ["0x7b8d56e3", "0x0ff4c916"]) - , ("MappingChainSmoke", ["0xd5264fdd", "0xf7531281"]) - , ("MixedMappingChainSmoke", ["0xd3bf29a3", "0xa75ac7f0"]) - , ("Bytes32Smoke", ["0xed9fdc05", "0xae0d3e27"]) - , ("StorageArraySmoke", ["0x949d225d", "0x959ac484"]) - , ("StorageAddressArraySmoke", ["0x949d225d", "0x6bc28781", "0xac5a7d5c", "0xfd72e8cc"]) - , ("StorageBoolArraySmoke", ["0xe9a37061", "0x876765fc", "0x644bacf8"]) - , ("StorageBytes32ArraySmoke", ["0x8891c9a2", "0x689eb72c"]) - , ("MappingWordSmoke", ["0x60ab11c4", "0x8f8a322f", "0xea3aded7"]) - , ("StorageWordsSmoke", ["0x764fa434"]) - , ("StorageWordsAddressSmoke", ["0x28054813"]) - , ("StorageWordsBoolSmoke", ["0x873bc011"]) - , ("CustomErrorSmoke", ["0x6279e43c"]) - , ("SafeMulRequireSmoke", ["0x678f717b", "0x2b0262e3"]) - , ("ArithmeticPanicSmoke", ["0xb6b55f25", "0x2e1a7d4d", "0xb219df1a", "0xc712757d"]) - , ("MulDiv512Smoke", ["0xed2e06d0", "0x70dee752"]) - , ("SignedBuiltinSmoke", ["0x5aafa47b", "0x1c781eb5", "0x2ff7ce03", "0x5f28fa76", "0x49795601", - "0xcc634d7f", "0x7c4ab1e5", "0x44b95b1e", "0x17ea5a3e", "0x6344ce8c", "0xf6814165", "0xae1a9a3e", - "0x6622d274", "0x176a2ce1", "0x504d2488", "0xd5451d16", "0x22cfe3c6"]) - , ("StatelessSmoke", ["0x26534f53", "0xda91254c"]) - , ("MutabilitySmoke", ["0xd0e30db0", "0xb387ef92"]) - , ("SpecialEntrypointSmoke", ["0x931999fb", "0x74b204a4"]) - , ("LeanDefHelperSmoke", ["0x42dbad08", "0x9ca603a4"]) - , ("DirectHelperCallSmoke", ["0x623f577a", "0xe9696d56", "0xe176587e", "0xa392867e", "0x9711715a"]) - , ("MultiReturnHelperSmoke", ["0x9c9c9cd5", "0xbe1e29cd"]) - , ("ArrayHelperCallSmoke", ["0x665cb27f", "0x3a11b9c7"]) - , ("InitializerSmoke", ["0x0d009297", "0xcc01053e"]) - , ("ConstantSmoke", ["0x9c421eb5", "0x30d9a62a"]) - , ("ImmutableSmoke", ["0x8f770ad0", "0x30d9a62a", "0x655b96ec"]) - , ("TypedImmutableSmoke", ["0xb187bd26", "0x95f39ba4", "0xf698da25"]) - , ("StringErrorSmoke", ["0x0d3e6791", "0x4be30205", "0xc1956e8d"]) - , ("StringSmoke", ["0x0d7e2fce", "0x8f4a7b60", "0xa7b21512", "0x29ec7e1a"]) - , ("StringEqSmoke", ["0x6df1667c", "0x1ce8f655", "0xc9e9b0e3"]) - , ("BytesEqSmoke", ["0xfc39552e", "0x2c16057d", "0x3eb6f0de"]) - , ("TupleSmoke", ["0x712ea680", "0xbdf391cc", "0x01b427d2"]) - , ("NamedStructParamSmoke", ["0xa01f780b", "0x38946c6d", "0x596635bb"]) - , ("NamedStructDynamicRootLeafProjection", ["0x08ec4886"]) - , ("CurveCutArraySmoke", ["0xefca8f0f", "0x6f413e6b", "0x0d7610a3", "0xbea7dfd2"]) - , ("DynamicStructArraySmoke", ["0xcbe2b47b", "0x587d08b7", "0x0b7d2799", "0x1fae5c19"]) - , ("PackedStorageWriteSmoke", ["0xa0522387", "0x233ab149"]) - , ("PackedAddressStorageWriteSmoke", ["0xd59c874d"]) - , ("Uint8Smoke", ["0xc233eaa7", "0x62fc458b"]) - , ("AddressHelpersSmoke", ["0x5c873849", "0x544d8564", "0xcc21cc2a", "0x480005cd", "0x67129177", - "0x0b0126c5", "0x85a9cdd0"]) - , ("ZeroAddressShadowSmoke", ["0xc0aab575"]) - , ("ContextAccessorShadowSmoke", ["0x40d06f02", "0xda15c6a0", "0x3f08a0dd", "0xe6d00bb0"]) - , ("FunctionOverloadSmoke", ["0x6279e43c", "0x2ffdbf1a", "0x3bb2bcd0"]) - , ("HelperExternalArgumentSmoke", ["0x2d29ad72", "0x645751af", "0x3f81a2c0", - "0xb503d0dd", "0xcdc18015", "0xe41657c6"]) - , ("BlockTimestampSmoke", ["0xa676760e", "0x8c041599", "0x7150df5e"]) - , ("SelfBalanceSmoke", ["0xce845d1d", "0x13b0662c"]) - , ("MathlibReservedBinderEscape", ["0x4fee5360", "0x4d1b4491"]) - , ("ForEachMutableLocalSmoke", ["0x60bc84bc", "0x566ab477", "0x463324b5"]) - , ("ArrayElementDynamicMemberLengthSmoke", ["0xfbb81f5b"]) - , ("ArrayElementDynamicMemberElementSmoke", ["0x1ffe901b"]) - , ("FixedArrayStructSmoke", ["0xe6f8cf0c", "0xf7910f7f", "0x82db9141", "0x82cb906c", - "0xaa7bf00c", "0xd1469472", "0x8ba58006", "0x7f010d4a"]) - , ("UnlinkPoolShapeCheckSmoke", ["0x4b6e2141", "0xdb1ca006", "0x41620c25", "0x76524b94", - "0xfc01c1ec", "0xe4a609b8", "0x2e759c7f"]) - , ("StructMappingSmoke", ["0x468c900e", "0xe7933b6a", "0x8d22ea2a", "0xf4536007", "0xcb01943e", - "0x6c241120"]) - , ("ExternalCallSmoke", ["0x32fdff86", "0x21209dbd"]) - , ("TryExternalCallSmoke", ["0xaf842e53"]) - , ("LinkedExternalDynamicArgSmoke", ["0xf1b3ebc7", "0x3f87a475", "0x35ea2663", - "0xc58b0a4d"]) - , ("LinkedExternalProjectedArrayArgSmoke", ["0x2bda60e2"]) - , ("NestedStructArrayProjectionSmoke", ["0x714fb4de", "0x14750c34", "0x8999bcc3", "0x5d157fb5"]) - , ("DynamicStructElementHelperArgSmoke", ["0x3464e97c", "0x291f8f0b", "0xef6057fa"]) - , ("ExternalCallMultiReturn", ["0x70fce9a3", "0x5dfc2e4a"]) - , ("ERC20HelperSmoke", ["0xa6c29ca3", "0x6aa209a6", "0x912d6e28", "0x48476c71", "0xdac24aaf", - "0x7247c4a5"]) - , ("GenericECMReadSmoke", ["0x78f2e50f"]) - , ("GenericECMMultiResultSmoke", ["0xac9b48fe"]) - , ("GenericECMWriteSmoke", ["0xc1192eb1"]) - , ("CallWithValueSmoke", ["0xde3a04ad", "0xb1d30765"]) - , ("BubblingValueCallECMSmoke", ["0x7ba1ade4"]) - , ("PackedHashECMSmoke", ["0xffba6b66", "0xb70f2d26", "0x9c3e158c"]) - , ("LowLevelTryCatchSmoke", ["0x42d9c6d1", "0xdaf546c4", "0xa4660933"]) - , ("LocalObligationRequiredForUnsafeFunctionBoundary", ["0xefae2305"]) - , ("LocalObligationRequiredForUnsafeConstructorBoundary", ["0x5dfc2e4a"]) - , ("ModifiesSmoke", ["0xd09de08a", "0xf2fde38b", "0xb6b55f25", "0x8ada066e"]) - , ("NoExternalCallsSmoke", ["0xd09de08a", "0x8ada066e", "0x13af4035"]) - , ("EffectCompositionSmoke", ["0x8ada066e", "0xd09de08a", "0x13af4035", "0xb6b55f25"]) - , ("CEISmoke", ["0xd09de08a", "0x8ada066e", "0x8c468aed", "0x4955cfdb"]) - , ("CEILadderSmoke", ["0xaf0ac94c", "0xe9ab4836", "0xb6fbe456", "0xd09de08a"]) - , ("RolesSmoke", ["0x8bb5d9c3", "0x8ada066e"]) - , ("RolesMappingSmoke", ["0x8bb5d9c3", "0x8ada066e"]) - , ("NewtypeSmoke", ["0x1b2ef1ca", "0xfca3b5aa", "0xcaa0f92a"]) - , ("NewtypeStorageSmoke", ["0xc929ccf3", "0x010a38f5", "0x704b6c02", "0x6e9960c3"]) - , ("NamespacedStorageSmoke", ["0xb6b55f25", "0x893d20e8"]) - , ("CustomNamespacedSmoke", ["0xb6b55f25", "0x893d20e8"]) - , ("CEIViolationRejected", ["0xe4fccc26"]) - , ("UnsafeBlockSmoke", ["0x87a993fd", "0x8ada066e"]) - , ("UnsafeGatingAccepted", ["0x68236256"]) - , ("UnsafeGatingRejected", ["0x5dfc2e4a"]) - , ("AdtSmoke", ["0xd09de08a"]) - , ("CEIWriteInBranchAfterCall", ["0x15e5e135"]) - , ("CEICallBothBranchesWrite", ["0xfc58b77d"]) - , ("ModifiesRolesSmoke", ["0x8bb5d9c3", "0xeb00a438", "0x8ada066e"]) - , ("ModifiesNamespaceSmoke", ["0xd09de08a", "0xf2fde38b", "0x8ada066e"]) - , ("AdtSingleVariant", ["0x975057e7"]) - , ("AdtMixedFieldCounts", ["0x52efea6e", "0x60fe47b1"]) - , ("NewtypeModifiesSmoke", ["0x1b2ef1ca", "0xbc968326"]) - , ("NewtypeNamespaceSmoke", ["0xd0e0ba95", "0x5d1ca631"]) - , ("UnsafeCEIViolation", ["0x20c925f7"]) - , ("UnsafeCEICompliant", ["0x9a92630e"]) - , ("CEIInternalCallAfterExternalRejected", ["0x7cf5dab0", "0xa73250c1"]) - , ("RolesCEISmoke", ["0xdc957d7d", "0x8ada066e"]) - , ("NonreentrantModifiesSmoke", ["0xb6b55f25", "0x12065fe0"]) - , ("AdtNewtypeCombo", ["0x8456cb59", "0x3f4ba83a", "0x1a27e85f"]) - , ("FullComboSmoke", ["0xb6b55f25", "0x62a5af3b", "0x12065fe0"]) - ] - -private def expectedFor - (table : List (String × List String)) (contractName : String) : Option (List String) := - (table.find? (fun entry => entry.1 == contractName)).map (·.2) - -private def expectedCompileCheckedError? (contractName : String) : Option String := - match contractName with - | "LocalObligationRequiredForUnsafeFunctionBoundary" => - some "uses low-level/assembly mechanic(s) calldataload outside an unsafe block without any local_obligations entry" - | "LocalObligationRequiredForUnsafeConstructorBoundary" => - some "constructor uses low-level/assembly mechanic(s) mstore outside an unsafe block without any local_obligations entry" - | "CEIViolationRejected" => - some "violates CEI (Checks-Effects-Interactions) ordering" - | "UnsafeGatingRejected" => - some "constructor uses low-level/assembly mechanic(s) mstore outside an unsafe block without any local_obligations entry" - | "CEIWriteInBranchAfterCall" => - some "violates CEI (Checks-Effects-Interactions) ordering" - | "CEICallBothBranchesWrite" => - some "violates CEI (Checks-Effects-Interactions) ordering" - | "UnsafeCEIViolation" => - some "violates CEI (Checks-Effects-Interactions) ordering" - | "CEIInternalCallAfterExternalRejected" => - some "violates CEI (Checks-Effects-Interactions) ordering" - | _ => none - --- Regression: `verity_contract` elaboration emits field-level findIdx simp lemmas. -private def _findIdxFieldRegression1 := Contracts.OwnedCounter.findIdx_owner_OwnedCounter -private def _findIdxFieldRegression2 := Contracts.OwnedCounter.findIdx_owner_OwnedCounter_decide -private def _findIdxFieldRegression3 := Contracts.SimpleToken.findIdx_balancesSlot_SimpleToken -private def _findIdxFieldRegression4 := Contracts.SimpleToken.findIdx_balancesSlot_SimpleToken_decide --- Regression: `verity_contract` elaboration emits parameter-level findIdx simp lemmas. -private def _findIdxParamRegression1 := Contracts.OwnedCounter.findIdx_param_initialOwner_constructor_OwnedCounter -private def _findIdxParamRegression2 := Contracts.OwnedCounter.findIdx_param_newOwner_transferOwnership_OwnedCounter -private def _findIdxParamRegression3 := Contracts.Ledger.findIdx_param_toAddr_transfer_Ledger -private def _findIdxParamRegression4 := Contracts.Ledger.findIdx_param_amount_transfer_Ledger_decide - -private def checkMutabilitySmoke : IO Unit := do - let deposit? := Contracts.Smoke.MutabilitySmoke.spec.functions.find? (·.name == "deposit") - let owner? := Contracts.Smoke.MutabilitySmoke.spec.functions.find? (·.name == "currentOwner") - let deposit := deposit?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let owner := owner?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - expectTrue "MutabilitySmoke: payable flag is preserved" deposit.isPayable - expectTrue "MutabilitySmoke: view flag is preserved" owner.isView - expectTrue "MutabilitySmoke: deposit body reads msgValue" - (contains (reprStr deposit.body) "Expr.msgValue") - -- Verify auto-generated _is_view theorem exists (#1729, Axis 3 Step 1a). - -- This line would fail to compile if the theorem were missing. - let _ := @Contracts.Smoke.MutabilitySmoke.currentOwner_is_view - -- Verify auto-generated modifies/frame artifacts exist (#1729, Axis 3 Step 1b). - let _ := @Contracts.Smoke.ModifiesSmoke.increment_modifies - let _ := @Contracts.Smoke.ModifiesSmoke.increment_frame - let _ := @Contracts.Smoke.ModifiesSmoke.increment_frame_rfl - let _ := @Contracts.Smoke.ModifiesSmoke.transferOwnership_modifies - let _ := @Contracts.Smoke.ModifiesSmoke.transferOwnership_frame - let _ := @Contracts.Smoke.ModifiesSmoke.transferOwnership_frame_rfl - let _ := @Contracts.Smoke.ModifiesSmoke.deposit_modifies - let _ := @Contracts.Smoke.ModifiesSmoke.deposit_frame - let _ := @Contracts.Smoke.ModifiesSmoke.deposit_frame_rfl - -- Verify auto-generated _no_calls theorem exists (#1729, Axis 3 Step 1c). - let _ := @Contracts.Smoke.NoExternalCallsSmoke.increment_no_calls - let _ := @Contracts.Smoke.NoExternalCallsSmoke.getCounter_no_calls - -- Verify auto-generated _effects conjunction theorem exists (#1729, Axis 3 Step 1d). - -- getCounter has view + no_external_calls → _effects bundles both - let _ := @Contracts.Smoke.EffectCompositionSmoke.getCounter_effects - -- increment has no_external_calls + modifies → _effects bundles both - let _ := @Contracts.Smoke.EffectCompositionSmoke.increment_effects - -- Also verify the existing NoExternalCallsSmoke.getCounter gets _effects - -- (it has view + no_external_calls) - let _ := @Contracts.Smoke.NoExternalCallsSmoke.getCounter_effects - -- Verify auto-generated _cei_compliant theorem exists (#1728, Axis 2 Step 2a). - -- All functions that don't have allow_post_interaction_writes get _cei_compliant - let _ := @Contracts.Smoke.CEISmoke.increment_cei_compliant - let _ := @Contracts.Smoke.CEISmoke.getCounter_cei_compliant - let _ := @Contracts.Smoke.CEISmoke.updateThenCall_cei_compliant - -- callThenUpdate has allow_post_interaction_writes so no _cei_compliant theorem - - -- Verify auto-generated _nonreentrant and _cei_safe theorems (#1728, Axis 2 Step 2b). - -- callThenStoreGuarded has nonreentrant(lock) → _nonreentrant theorem - let _ := @Contracts.Smoke.CEILadderSmoke.callThenStoreGuarded_nonreentrant - -- callThenStoreProved has cei_safe → _cei_safe theorem - let _ := @Contracts.Smoke.CEILadderSmoke.callThenStoreProved_cei_safe - -- storeThenCall and increment are default CEI-compliant → _cei_compliant - let _ := @Contracts.Smoke.CEILadderSmoke.storeThenCall_cei_compliant - let _ := @Contracts.Smoke.CEILadderSmoke.increment_cei_compliant - -- callThenStoreGuarded does NOT get _cei_compliant (it uses nonreentrant instead) - -- callThenStoreProved does NOT get _cei_compliant (it uses cei_safe instead) - - -- Verify auto-generated _requires_role theorem (#1728, Axis 2 Step 2c). - -- setCounter has requires(admin) → _requires_role theorem - let _ := @Contracts.Smoke.RolesSmoke.setCounter_requires_role - -- getCounter has no requires → gets normal _cei_compliant - let _ := @Contracts.Smoke.RolesSmoke.getCounter_cei_compliant - -- Mapping-keyed roles (verity#1837): setCounter with requires(relayers : Address → Uint256) - -- still produces the _requires_role theorem. - let _ := @Contracts.Smoke.RolesMappingSmoke.setCounter_requires_role - let _ := @Contracts.Smoke.RolesMappingSmoke.getCounter_cei_compliant - -- Verify NewtypeSmoke generates standard _cei_compliant theorems (#1727, Axis 1 Step 3a). - -- Newtypes are erased — functions compile with base types. - let _ := @Contracts.Smoke.NewtypeSmoke.mint_cei_compliant - let _ := @Contracts.Smoke.NewtypeSmoke.setMinter_cei_compliant - let _ := @Contracts.Smoke.NewtypeSmoke.getNextTokenId_cei_compliant - -- Verify NewtypeStorageSmoke: newtype-typed storage fields compile correctly. - let _ := @Contracts.Smoke.NewtypeStorageSmoke.setTokenId_cei_compliant - let _ := @Contracts.Smoke.NewtypeStorageSmoke.getTokenId_cei_compliant - let _ := @Contracts.Smoke.NewtypeStorageSmoke.setAdmin_cei_compliant - let _ := @Contracts.Smoke.NewtypeStorageSmoke.getAdmin_cei_compliant - -- Verify AdtSmoke generates standard _cei_compliant theorems (#1727, Axis 1 Step 5a). - -- ADTs are parsed; functions compile normally. - let _ := @Contracts.Smoke.AdtSmoke.increment_cei_compliant - -- Verify NamespacedStorageSmoke generates standard _cei_compliant theorems (#1730, Axis 4 Step 4b). - let _ := @Contracts.Smoke.NamespacedStorageSmoke.deposit_cei_compliant - let _ := @Contracts.Smoke.NamespacedStorageSmoke.getOwner_cei_compliant - -- Verify CustomNamespacedSmoke generates standard _cei_compliant theorems (#1730, Axis 4 Step 4c). - let _ := @Contracts.Smoke.CustomNamespacedSmoke.deposit_cei_compliant - let _ := @Contracts.Smoke.CustomNamespacedSmoke.getOwner_cei_compliant - - -- ── Stress-test contracts: theorem existence checks ── - -- ModifiesRolesSmoke: combined requires(admin) + modifies + no_external_calls - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_requires_role - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_modifies - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_frame - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_frame_rfl - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_no_calls - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounter_effects - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounterAndFlag_requires_role - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounterAndFlag_modifies - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounterAndFlag_frame - let _ := @Contracts.Smoke.ModifiesRolesSmoke.setCounterAndFlag_frame_rfl - let _ := @Contracts.Smoke.ModifiesRolesSmoke.getCounter_is_view - let _ := @Contracts.Smoke.ModifiesRolesSmoke.getCounter_cei_compliant - -- ModifiesNamespaceSmoke: namespaced storage + modifies - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.increment_modifies - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.increment_frame - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.increment_frame_rfl - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.transferOwnership_modifies - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.transferOwnership_frame - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.transferOwnership_frame_rfl - let _ := @Contracts.Smoke.ModifiesNamespaceSmoke.getCounter_is_view - -- NewtypeModifiesSmoke: newtypes + modifies - let _ := @Contracts.Smoke.NewtypeModifiesSmoke.mint_modifies - let _ := @Contracts.Smoke.NewtypeModifiesSmoke.mint_frame_rfl - let _ := @Contracts.Smoke.NewtypeModifiesSmoke.getNextId_is_view - -- UnsafeCEICompliant: write before call in unsafe block passes CEI - let _ := @Contracts.Smoke.UnsafeCEICompliant.writeBeforeUnsafeCall_cei_compliant - -- RolesCEISmoke: roles + CEI - let _ := @Contracts.Smoke.RolesCEISmoke.setAndCall_requires_role - let _ := @Contracts.Smoke.RolesCEISmoke.setAndCall_cei_compliant - let _ := @Contracts.Smoke.RolesCEISmoke.getCounter_is_view - -- NonreentrantModifiesSmoke: nonreentrant + modifies - let _ := @Contracts.Smoke.NonreentrantModifiesSmoke.deposit_nonreentrant - let _ := @Contracts.Smoke.NonreentrantModifiesSmoke.deposit_modifies - let _ := @Contracts.Smoke.NonreentrantModifiesSmoke.deposit_frame - let _ := @Contracts.Smoke.NonreentrantModifiesSmoke.deposit_frame_rfl - let _ := @Contracts.Smoke.NonreentrantModifiesSmoke.getBalance_is_view - -- FullComboSmoke: namespace + newtype + ADT + modifies + roles + no_external_calls - let _ := @Contracts.Smoke.FullComboSmoke.deposit_requires_role - let _ := @Contracts.Smoke.FullComboSmoke.deposit_modifies - let _ := @Contracts.Smoke.FullComboSmoke.deposit_frame - let _ := @Contracts.Smoke.FullComboSmoke.deposit_frame_rfl - let _ := @Contracts.Smoke.FullComboSmoke.deposit_no_calls - let _ := @Contracts.Smoke.FullComboSmoke.deposit_effects - let _ := @Contracts.Smoke.FullComboSmoke.freeze_requires_role - let _ := @Contracts.Smoke.FullComboSmoke.freeze_modifies - let _ := @Contracts.Smoke.FullComboSmoke.freeze_no_calls - let _ := @Contracts.Smoke.FullComboSmoke.getBalance_is_view - let _ := @Contracts.Smoke.FullComboSmoke.getBalance_no_calls - let _ := @Contracts.Smoke.FullComboSmoke.getBalance_effects - -private def checkSignedBuiltinSmoke : IO Unit := do - let functions := Contracts.Smoke.SignedBuiltinSmoke.spec.functions - let signedDiv? := functions.find? (·.name == "signedDiv") - let signedMod? := functions.find? (·.name == "signedMod") - let signedLt? := functions.find? (·.name == "signedLt") - let signedGt? := functions.find? (·.name == "signedGt") - let arithmeticShift? := functions.find? (·.name == "arithmeticShift") - let signExtended? := functions.find? (·.name == "signExtended") - let shiftedMask? := functions.find? (·.name == "shiftedMask") - let signedDivSurface? := functions.find? (·.name == "signedDivSurface") - let signedModSurface? := functions.find? (·.name == "signedModSurface") - let signedDivViaLocal? := functions.find? (·.name == "signedDivViaLocal") - let castToInt? := functions.find? (·.name == "castToInt") - let castToUint? := functions.find? (·.name == "castToUint") - let minusOne? := functions.find? (·.name == "minusOne") - let bitAndSignBit? := functions.find? (·.name == "bitAndSignBit") - let minSignBit? := functions.find? (·.name == "minSignBit") - let storeSigned? := functions.find? (·.name == "storeSigned") - let loadSigned? := functions.find? (·.name == "loadSigned") - let signedDiv := signedDiv?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedMod := signedMod?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedLt := signedLt?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedGt := signedGt?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let arithmeticShift := arithmeticShift?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signExtended := signExtended?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let shiftedMask := shiftedMask?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedDivSurface := signedDivSurface?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedModSurface := signedModSurface?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let signedDivViaLocal := signedDivViaLocal?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let castToInt := castToInt?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let castToUint := castToUint?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let minusOne := minusOne?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let bitAndSignBit := bitAndSignBit?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let minSignBit := minSignBit?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let storeSigned := storeSigned?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let loadSigned := loadSigned?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - expectTrue "SignedBuiltinSmoke: Int256 storage is modeled as a word slot" - (match Contracts.Smoke.SignedBuiltinSmoke.spec.fields with - | [field] => - field.name == "signedSlot" && - field.ty == FieldType.uint256 && - field.slot == some 0 - | _ => false) - expectTrue "SignedBuiltinSmoke: signedDiv body uses Expr.sdiv" - (bodyUsesSignedBuiltin signedDiv.body "Expr.sdiv") - expectTrue "SignedBuiltinSmoke: signedMod body uses Expr.smod" - (bodyUsesSignedBuiltin signedMod.body "Expr.smod") - expectTrue "SignedBuiltinSmoke: signedLt body uses Expr.slt" - (bodyUsesSignedBuiltin signedLt.body "Expr.slt") - expectTrue "SignedBuiltinSmoke: signedGt body uses Expr.sgt" - (bodyUsesSignedBuiltin signedGt.body "Expr.sgt") - expectTrue "SignedBuiltinSmoke: arithmeticShift body uses Expr.sar" - (bodyUsesSignedBuiltin arithmeticShift.body "Expr.sar") - expectTrue "SignedBuiltinSmoke: signExtended body inlines Expr.signextend" - (bodyUsesSignedBuiltin signExtended.body "Expr.signextend") - expectTrue "SignedBuiltinSmoke: shiftedMask body inlines Expr.sar" - (bodyUsesSignedBuiltin shiftedMask.body "Expr.sar") - expectTrue "SignedBuiltinSmoke: signedDivSurface lowers Int256 div to Expr.sdiv" - (bodyUsesSignedBuiltin signedDivSurface.body "Expr.sdiv") - expectTrue "SignedBuiltinSmoke: signedModSurface lowers Int256 mod to Expr.smod" - (bodyUsesSignedBuiltin signedModSurface.body "Expr.smod") - expectTrue "SignedBuiltinSmoke: signedDivViaLocal keeps the signed divide opcode after local rebinding" - (bodyUsesSignedBuiltin signedDivViaLocal.body "Expr.sdiv") - expectTrue "SignedBuiltinSmoke: castToInt stays word-level in the model" - (!bodyUsesSignedBuiltin castToInt.body "Expr.sdiv") - expectTrue "SignedBuiltinSmoke: castToUint stays word-level in the model" - (!bodyUsesSignedBuiltin castToUint.body "Expr.sdiv") - expectTrue "SignedBuiltinSmoke: minusOne preserves Int256 constants as raw words" - (!minusOne.body.isEmpty) - expectTrue "SignedBuiltinSmoke: bitAndSignBit keeps signed comparison over bitAnd" - (bodyUsesSignedBuiltin bitAndSignBit.body "Expr.bitAnd" && - bodyUsesSignedBuiltin bitAndSignBit.body "Expr.lt") - expectTrue "SignedBuiltinSmoke: minSignBit keeps signed comparison over min" - (bodyUsesSignedBuiltin minSignBit.body "Expr.min" && - bodyUsesSignedBuiltin minSignBit.body "Expr.lt") - expectTrue "SignedBuiltinSmoke: storeSigned writes the signed storage slot" - (bodyUsesSignedBuiltin storeSigned.body "Stmt.setStorage") - expectTrue "SignedBuiltinSmoke: loadSigned reads the signed storage slot" - (bodyUsesSignedBuiltin loadSigned.body "Expr.storage") - -private def checkLowLevelTryCatchSmoke : IO Unit := do - let functions := Contracts.Smoke.LowLevelTryCatchSmoke.spec.functions - let catchFailure? := functions.find? (·.name == "catchFailure") - let skipCatch? := functions.find? (·.name == "skipCatchOnSuccess") - let catchFailure := catchFailure?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let skipCatch := skipCatch?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - expectTrue "LowLevelTryCatchSmoke: catchFailure introduces a synthetic success temp" - (contains (reprStr catchFailure.body) "\"verity_try_success\"") - expectTrue "LowLevelTryCatchSmoke: catchFailure lowers through Stmt.ite" - (contains (reprStr catchFailure.body) "CompilationModel.Stmt.ite") - expectTrue "LowLevelTryCatchSmoke: catchFailure preserves Expr.call in the model" - (contains (reprStr catchFailure.body) "CompilationModel.Expr.call") - expectTrue "LowLevelTryCatchSmoke: skipCatchOnSuccess keeps the zero-check branch" - (contains (reprStr skipCatch.body) "CompilationModel.Expr.eq") - expectTrue "LowLevelTryCatchSmoke: synthetic success temp avoids param shadowing" - (contains (reprStr Contracts.Smoke.LowLevelTryCatchSmoke.catchFailureWithShadowedParam_modelBody) - "\"verity_try_success_1\"") - -private def checkSpecialEntrypointSmoke : IO Unit := do - let functions := Contracts.Smoke.SpecialEntrypointSmoke.spec.functions - let receiveFn? := functions.find? (·.name == "receive") - let fallback? := functions.find? (·.name == "fallback") - let receiveFn := receiveFn?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - let fallbackFn := fallback?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - expectTrue "SpecialEntrypointSmoke: receive entrypoint is materialized in the spec" - (receiveFn.name == "receive") - expectTrue "SpecialEntrypointSmoke: receive entrypoint is implicitly payable" - receiveFn.isPayable - expectTrue "SpecialEntrypointSmoke: receive entrypoint remains selector-free" - receiveFn.params.isEmpty - expectTrue "SpecialEntrypointSmoke: fallback entrypoint is materialized in the spec" - (fallbackFn.name == "fallback") - expectTrue "SpecialEntrypointSmoke: fallback entrypoint remains selector-free" - fallbackFn.params.isEmpty - -private def checkDirectHelperCallSmoke : IO Unit := do - let functions := Contracts.Smoke.DirectHelperCallSmoke.spec.functions - let publicFns := functions.filter (fun fn => !fn.isInternal) - let internalFns := functions.filter (·.isInternal) - let runHelpers? := publicFns.find? (·.name == "runHelpers") - let runHelpers := runHelpers?.getD { name := "", params := [], returnType := none, returns := [], body := [] } - expectTrue "DirectHelperCallSmoke: public entrypoints remain unchanged" - (publicFns.map (·.name) == - ["addToTotal", "readTotalPlus", "pairWithTotal", "runHelpers", "snapshot"]) - expectTrue "DirectHelperCallSmoke: helper-capable functions gain internal variants" - (internalFns.map (·.name) == - ["internal_addToTotal", "internal_readTotalPlus", "internal_pairWithTotal", - "internal_runHelpers", "internal_snapshot"]) - expectTrue "DirectHelperCallSmoke: single-return helper calls lower to Expr.internalCall" - (contains (reprStr runHelpers.body) "Expr.internalCall" && - contains (reprStr runHelpers.body) "\"internal_readTotalPlus\"") - expectTrue "DirectHelperCallSmoke: tuple helper calls lower to Stmt.internalCallAssign" - (contains (reprStr runHelpers.body) "Stmt.internalCallAssign" && - contains (reprStr runHelpers.body) "\"internal_pairWithTotal\"") - -private def checkMultiReturnHelperSmoke : IO Unit := do - expectTrue - "MultiReturnHelperSmoke: tuple-return helper binds lower to internalCallAssign" - (match Contracts.Smoke.MultiReturnHelperSmoke.useSummary_modelBody with - | [Stmt.internalCallAssign ["head", "tail"] helperName [Expr.param "seed"], - Stmt.return (Expr.add (Expr.localVar "head") (Expr.localVar "tail"))] => - helperName == "internal_summarize" - | _ => false) - -private def checkArrayHelperCallSmoke : IO Unit := do - expectTrue - "ArrayHelperCallSmoke: dynamic Array helper arg expands to offset/length Yul args" - (match Contracts.Smoke.ArrayHelperCallSmoke.useFirst_modelBody with - | [Stmt.letVar "x" - (Expr.internalCall "internal_first" - [Expr.param "xs_data_offset", Expr.param "xs_length"]), - Stmt.setStorage "ok" (Expr.localVar "x"), - Stmt.stop] => true - | _ => false) - -private def checkNamedStructParamSmoke : IO Unit := do - expectTrue - "NamedStructParamSmoke: nested struct leaf projection uses recursive tuple binding" - (match Contracts.Smoke.NamedStructParamSmoke.storeNestedFee_modelBody with - | [ Stmt.setMappingUint "values" (Expr.param "key") (Expr.param "config_0_0") - , Stmt.stop - ] => true - | _ => false) - expectTrue - "NamedStructParamSmoke: sibling field after nested struct uses top-level tuple binding" - (match Contracts.Smoke.NamedStructParamSmoke.readNestedMaker_modelBody with - | [Stmt.return (Expr.param "config_1")] => true - | _ => false) - -private def curveCutArrayStoreMemoizesIndex : Bool := - match Contracts.Smoke.CurveCutArraySmoke.storeCut_modelBody with - | Stmt.letVar "arrayElement_index" (Expr.param "idx") :: - Stmt.letVar "xtReserve" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 0) :: - Stmt.letVar "liqSquare" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 1) :: - Stmt.letVar "offset" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 2) :: - _ => true - | _ => false - -private def curveCutArrayReturnMemoizesIndex : Bool := - match Contracts.Smoke.CurveCutArraySmoke.returnCut_modelBody with - | Stmt.letVar "arrayElement_index" (Expr.param "idx") :: - Stmt.returnValues [ - Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 0, - Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 1, - Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 2 - ] :: - _ => true - | _ => false - -private def curveCutArrayRepeatedDestructuresUseFreshSyntheticIndexes : Bool := - match Contracts.Smoke.CurveCutArraySmoke.storeTwoCuts_modelBody with - | Stmt.letVar "arrayElement_index" (Expr.param "firstIdx") :: - Stmt.letVar "firstXt" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 0) :: - Stmt.letVar "_firstLiq" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 1) :: - Stmt.letVar "_firstOffset" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index") 3 2) :: - Stmt.letVar "arrayElement_index_1" (Expr.param "secondIdx") :: - Stmt.letVar "secondXt" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index_1") 3 0) :: - Stmt.letVar "_secondLiq" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index_1") 3 1) :: - Stmt.letVar "_secondOffset" (Expr.arrayElementWord "cuts" (Expr.localVar "arrayElement_index_1") 3 2) :: - _ => true - | _ => false - -private def checkCurveCutArraySmoke : IO Unit := do - expectTrue "CurveCutArraySmoke: tuple arrayElement destructuring memoizes the index once" - curveCutArrayStoreMemoizesIndex - expectTrue "CurveCutArraySmoke: tuple arrayElement return memoizes the index once" - curveCutArrayReturnMemoizesIndex - expectTrue "CurveCutArraySmoke: repeated tuple arrayElement destructures use fresh synthetic indexes" - curveCutArrayRepeatedDestructuresUseFreshSyntheticIndexes - -private def checkDynamicStructArraySmoke : IO Unit := do - expectTrue - "DynamicStructArraySmoke: dynamic struct array leaf projection lowers through dynamic element head word" - (match Contracts.Smoke.DynamicStructArraySmoke.tokenOf_modelBody with - | [Stmt.return (Expr.arrayElementDynamicWord "txs" (Expr.param "idx") 5)] => true - | _ => false) - expectTrue - "DynamicStructArraySmoke: later static leaf in dynamic struct array uses flattened head offset" - (match Contracts.Smoke.DynamicStructArraySmoke.feeOf_modelBody with - | [Stmt.return (Expr.arrayElementDynamicWord "txs" (Expr.param "idx") 6)] => true - | _ => false) - expectTrue - "DynamicStructArraySmoke: dynamic child struct contributes one parent head word" - (match Contracts.Smoke.DynamicStructArraySmoke.wrappedTokenOf_modelBody with - | [Stmt.return (Expr.arrayElementDynamicWord "items" (Expr.param "idx") 1)] => true - | _ => false) - -private def checkSpec (spec : CompilationModel) : IO Unit := do - let extFns := externalFunctions spec - let fnNames := extFns.map (·.name) - let fnSignatures := extFns.map functionSignature - expectTrue s!"{spec.name}: external function signatures are unique" (allDistinct fnSignatures) - - let fieldNames := spec.fields.map (·.name) - expectTrue s!"{spec.name}: field names are unique" (allDistinct fieldNames) - - let slots := canonicalFieldSlots spec - expectTrue s!"{spec.name}: canonical storage slots are unique" (allDistinct slots) - - let writes := writeSlots spec - expectTrue s!"{spec.name}: write slots are unique (canonical + alias)" (allDistinct writes) - - let selectors ← Selector.computeSelectors spec - expectTrue s!"{spec.name}: selectors are unique" (allDistinct selectors) - expectTrue s!"{spec.name}: selector count matches external function count" - (selectors.length == extFns.length) - - let signatures := extFns.map functionSignature - match expectedFor expectedExternalSignatures spec.name with - | none => - throw (IO.userError s!"✗ {spec.name}: missing expected external signature snapshot entry") - | some expectedSigs => - expectTrue s!"{spec.name}: external signatures match pinned snapshot" - (signatures == expectedSigs) - - let selectorHexes := selectors.map natToHex - match expectedFor expectedExternalSelectors spec.name with - | none => - throw (IO.userError s!"✗ {spec.name}: missing expected selector snapshot entry") - | some expectedHexes => - expectTrue s!"{spec.name}: selectors match pinned snapshot" - (selectorHexes == expectedHexes) - - let compileResult ← Selector.compileChecked spec selectors - match expectedCompileCheckedError? spec.name, compileResult with - | some expectedErr, .error err => - expectTrue s!"{spec.name}: compileChecked rejects the missing local_obligations boundary as expected" - (contains err expectedErr) - | some _, .ok _ => - throw (IO.userError s!"✗ {spec.name}: compileChecked unexpectedly succeeded for an intentionally unsafe-boundary fixture") - | none, .ok ir => - IO.println s!"✓ {spec.name}: compileChecked succeeds with canonical selectors" - let irFns := ir.functions - let irFnNames := irFns.map (·.name) - let irSelectors := irFns.map (·.selector) - expectTrue s!"{spec.name}: IR external function count matches spec external function count" - (irFns.length == extFns.length) - expectTrue s!"{spec.name}: IR external function names preserve spec order" - (irFnNames == fnNames) - expectTrue s!"{spec.name}: IR selectors preserve canonical selector order" - (irSelectors == selectors) - if spec.name == "SpecialEntrypointSmoke" then - expectTrue "SpecialEntrypointSmoke: IR keeps receive entrypoint out of selector dispatch" - ir.receiveEntrypoint.isSome - expectTrue "SpecialEntrypointSmoke: IR keeps fallback entrypoint out of selector dispatch" - ir.fallbackEntrypoint.isSome - else - pure () - let indexedFns := List.zip (List.range extFns.length) extFns - let mappingSafeFns := - indexedFns.filterMap (fun (idx, fnSpec) => - match irFns[idx]?, selectors[idx]? with - | some irFn, some sel => - if functionUsesMappingSlot irFn then none else some (fnSpec, sel) - | _, _ => none) - let mappingSafeExtFns := mappingSafeFns.map Prod.fst - let mappingSafeSelectors := mappingSafeFns.map Prod.snd - if (mappingBaseSlots spec).isEmpty then - expectTrue s!"{spec.name}: all external functions are mapping-slot free" - (mappingSafeExtFns.length == extFns.length) - runRandomDiffChecks spec ir extFns selectors 8 - else if mappingSafeExtFns.isEmpty then - IO.println s!"ℹ {spec.name}: skipping randomized IR↔Yul checks (all external functions touch mappingSlot/keccak path in #eval)" - else - IO.println s!"ℹ {spec.name}: randomized IR↔Yul checks use mapping-safe subset {mappingSafeExtFns.length}/{extFns.length}" - runRandomDiffChecks spec ir mappingSafeExtFns mappingSafeSelectors 8 - | none, .error err => - throw (IO.userError s!"✗ {spec.name}: compileChecked failed: {err}") - - let abi := ABI.emitContractABIJson spec - let abiFunctionCount := countOccurrences abi "\"type\": \"function\"" - expectTrue s!"{spec.name}: ABI function count matches external function count" - (abiFunctionCount == extFns.length) - - -- Sanity-check ABI output contains each external function name. - let allNamesPresent := - fnNames.all (fun fnName => contains abi s!"\"name\": \"{fnName}\"") - expectTrue s!"{spec.name}: ABI contains every external function name" allNamesPresent - - if spec.name == "CustomErrorSmoke" then - expectTrue - "CustomErrorSmoke: macro spec preserves custom error declarations" - (spec.errors.map (·.name) == ["NonPositive", "AmountTooLarge"]) - expectTrue - "CustomErrorSmoke: ABI includes declared custom errors" - (contains abi "\"type\": \"error\"" && - contains abi "\"name\": \"NonPositive\"" && - contains abi "\"name\": \"AmountTooLarge\"") - else - pure () - -#eval! do - expectTrue "macro spec count matches pinned signature snapshot" - (macroSpecs.length == expectedExternalSignatures.length) - expectTrue "macro spec count matches pinned selector snapshot" - (macroSpecs.length == expectedExternalSelectors.length) - expectTrue - "Owned.getOwner keeps address storage reads explicit in macro output" - (bodyUsesAddressStorageRead Contracts.Owned.getOwner_modelBody) - expectTrue - "Owned.transferOwnership keeps address storage writes explicit in macro output" - (bodyUsesAddressStorageWrite Contracts.Owned.transferOwnership_modelBody) - checkMutabilitySmoke - checkSignedBuiltinSmoke - checkLowLevelTryCatchSmoke - checkSpecialEntrypointSmoke - checkDirectHelperCallSmoke - checkMultiReturnHelperSmoke - checkArrayHelperCallSmoke - checkNamedStructParamSmoke - checkCurveCutArraySmoke - checkDynamicStructArraySmoke - for spec in macroSpecs do - checkSpec spec - -end Compiler.MacroTranslateInvariantTest diff --git a/Contracts/MacroTranslateRoundTripFuzz.lean b/Contracts/MacroTranslateRoundTripFuzz.lean deleted file mode 100644 index d4c776609..000000000 --- a/Contracts/MacroTranslateRoundTripFuzz.lean +++ /dev/null @@ -1,389 +0,0 @@ -import Compiler.Proofs.YulGeneration.IRFuel -import Compiler.Selector -import Compiler.Hex -import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics -import Contracts -import Contracts.ProxyUpgradeabilityMacroSmoke -import Contracts.ProxyUpgradeabilityLayoutCompatibleSmoke -import Contracts.ProxyUpgradeabilityLayoutIncompatibleSmoke -import Contracts.Smoke -import Contracts.Smoke.ArrayElementDynamicMemberElementSmoke -import Contracts.Smoke.ArrayElementDynamicMemberLengthSmoke -import Contracts.Smoke.FixedArrayStructSmoke -import Contracts.Smoke.UnlinkPoolShapeCheckSmoke -import Contracts.Smoke.MathlibReservedBinderEscape -import Contracts.Smoke.PackedHashECMSmoke -import Contracts.Smoke.SelfBalanceSmoke - -namespace Compiler.MacroTranslateRoundTripFuzz - -open Compiler -open Compiler.CompilationModel -open Compiler.Proofs.IRGeneration -open Compiler.Proofs.YulGeneration - -/- This executable harness compares IR execution with the legacy reference-oracle - fuel interpreter as regression coverage only. It is not theorem authority for - native EVMYulLean correctness. -/ - -private def yulStateOfIR (_selector : Nat) (state : IRState) : YulState := - { vars := state.vars - «storage» := state.storage - transientStorage := state.transientStorage - memory := state.memory - calldata := state.calldata - selector := state.selector - returnValue := state.returnValue - sender := state.sender - msgValue := state.msgValue - thisAddress := state.thisAddress - blockTimestamp := state.blockTimestamp - blockNumber := state.blockNumber - chainId := state.chainId - blobBaseFee := state.blobBaseFee - events := state.events } - -private def yulResultOfExecWithRollback (rollback : YulState) : YulExecResult → YulResult - | .continue s => - { success := true - returnValue := s.returnValue - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .return v s => - { success := true - returnValue := some v - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .stop s => - { success := true - returnValue := none - finalStorage := s.storage - finalMappings := Compiler.Proofs.storageAsMappings s.storage - events := s.events } - | .revert _ => - { success := false - returnValue := none - finalStorage := rollback.storage - finalMappings := Compiler.Proofs.storageAsMappings rollback.storage - events := rollback.events } - -private def expectTrue (label : String) (ok : Bool) : IO Unit := do - if !ok then - throw (IO.userError s!"round-trip fuzz failed: {label}") - -private def externalFunctions (spec : CompilationModel) : List FunctionSpec := - spec.functions.filter (fun fn => !fn.isInternal && !isInteropEntrypointName fn.name) - -private def canonicalFieldSlots (spec : CompilationModel) : List Nat := - let indexed := List.zip (List.range spec.fields.length) spec.fields - indexed.map (fun (idx, field) => field.slot.getD idx) - -private def writeSlots (spec : CompilationModel) : List Nat := - let indexed := List.zip (List.range spec.fields.length) spec.fields - indexed.flatMap (fun (idx, field) => field.slot.getD idx :: field.aliasSlots) - -private def macroSpecs : List CompilationModel := - [ Contracts.SimpleStorage.spec - , Contracts.LocalObligationMacroSmoke.spec - , Contracts.ProxyUpgradeabilityMacroSmoke.spec - , Contracts.ProxyUpgradeabilityLayoutCompatibleSmoke.spec - , Contracts.ProxyUpgradeabilityLayoutIncompatibleSmoke.spec - , Contracts.Counter.spec - , Contracts.Owned.spec - , Contracts.Ledger.spec - , Contracts.SafeCounter.spec - , Contracts.OwnedCounter.spec - , Contracts.SimpleToken.spec - , Contracts.Vault.spec - , Contracts.ERC20.spec - , Contracts.ERC721.spec - , Contracts.Smoke.Uint256PowSmoke.spec - , Contracts.Smoke.UintMapSmoke.spec - , Contracts.Smoke.MappingChainSmoke.spec - , Contracts.Smoke.MixedMappingChainSmoke.spec - , Contracts.Smoke.Bytes32Smoke.spec - , Contracts.Smoke.StorageArraySmoke.spec - , Contracts.Smoke.StorageAddressArraySmoke.spec - , Contracts.Smoke.StorageBoolArraySmoke.spec - , Contracts.Smoke.StorageBytes32ArraySmoke.spec - , Contracts.Smoke.MappingWordSmoke.spec - , Contracts.Smoke.StorageWordsSmoke.spec - , Contracts.Smoke.StorageWordsAddressSmoke.spec - , Contracts.Smoke.StorageWordsBoolSmoke.spec - , Contracts.Smoke.CustomErrorSmoke.spec - , Contracts.Smoke.SafeMulRequireSmoke.spec - , Contracts.Smoke.ArithmeticPanicSmoke.spec - , Contracts.Smoke.MulDiv512Smoke.spec - , Contracts.Smoke.SignedBuiltinSmoke.spec - , Contracts.Smoke.StatelessSmoke.spec - , Contracts.Smoke.MutabilitySmoke.spec - , Contracts.Smoke.SpecialEntrypointSmoke.spec - , Contracts.Smoke.LeanDefHelperSmoke.spec - , Contracts.Smoke.DirectHelperCallSmoke.spec - , Contracts.Smoke.MultiReturnHelperSmoke.spec - , Contracts.Smoke.ArrayHelperCallSmoke.spec - , Contracts.Smoke.InitializerSmoke.spec - , Contracts.Smoke.ConstantSmoke.spec - , Contracts.Smoke.ImmutableSmoke.spec - , Contracts.Smoke.TypedImmutableSmoke.spec - , Contracts.Smoke.TupleSmoke.spec - , Contracts.Smoke.NamedStructParamSmoke.spec - , Contracts.Smoke.NamedStructDynamicRootLeafProjection.spec - , Contracts.Smoke.CurveCutArraySmoke.spec - , Contracts.Smoke.DynamicStructArraySmoke.spec - , Contracts.Smoke.PackedStorageWriteSmoke.spec - , Contracts.Smoke.PackedAddressStorageWriteSmoke.spec - , Contracts.Smoke.Uint8Smoke.spec - , Contracts.BytesEqSmoke.spec - , Contracts.Smoke.AddressHelpersSmoke.spec - , Contracts.Smoke.ZeroAddressShadowSmoke.spec - , Contracts.Smoke.ContextAccessorShadowSmoke.spec - , Contracts.Smoke.FunctionOverloadSmoke.spec - , Contracts.Smoke.HelperExternalArgumentSmoke.spec - , Contracts.Smoke.BlockTimestampSmoke.spec - , Contracts.Smoke.SelfBalanceSmoke.spec - , Contracts.Smoke.MathlibReservedBinderEscape.spec - , Contracts.Smoke.ForEachMutableLocalSmoke.spec - , Contracts.Smoke.ArrayElementDynamicMemberLengthSmoke.spec - , Contracts.Smoke.ArrayElementDynamicMemberElementSmoke.spec - , Contracts.Smoke.FixedArrayStructSmoke.spec - , Contracts.Smoke.UnlinkPoolShapeCheckSmoke.spec - , Contracts.Smoke.StructMappingSmoke.spec - , Contracts.Smoke.ExternalCallSmoke.spec - , Contracts.Smoke.TryExternalCallSmoke.spec - , Contracts.Smoke.LinkedExternalDynamicArgSmoke.spec - , Contracts.Smoke.LinkedExternalProjectedArrayArgSmoke.spec - , Contracts.Smoke.NestedStructArrayProjectionSmoke.spec - , Contracts.Smoke.DynamicStructElementHelperArgSmoke.spec - , Contracts.Smoke.ExternalCallMultiReturn.spec - , Contracts.Smoke.ERC20HelperSmoke.spec - , Contracts.Smoke.GenericECMReadSmoke.spec - , Contracts.Smoke.GenericECMMultiResultSmoke.spec - , Contracts.Smoke.GenericECMWriteSmoke.spec - , Contracts.Smoke.CallWithValueSmoke.spec - , Contracts.Smoke.BubblingValueCallECMSmoke.spec - , Contracts.Smoke.PackedHashECMSmoke.spec - , Contracts.Smoke.LowLevelTryCatchSmoke.spec - , Contracts.Smoke.ModifiesSmoke.spec - , Contracts.Smoke.NoExternalCallsSmoke.spec - , Contracts.Smoke.EffectCompositionSmoke.spec - , Contracts.Smoke.CEISmoke.spec - , Contracts.Smoke.CEILadderSmoke.spec - , Contracts.Smoke.RolesSmoke.spec - , Contracts.Smoke.RolesMappingSmoke.spec - , Contracts.Smoke.NewtypeSmoke.spec - , Contracts.Smoke.NewtypeStorageSmoke.spec - , Contracts.Smoke.NamespacedStorageSmoke.spec - , Contracts.Smoke.CustomNamespacedSmoke.spec - , Contracts.Smoke.UnsafeBlockSmoke.spec - , Contracts.Smoke.UnsafeGatingAccepted.spec - , Contracts.Smoke.AdtSmoke.spec - , Contracts.Smoke.ModifiesRolesSmoke.spec - , Contracts.Smoke.ModifiesNamespaceSmoke.spec - , Contracts.Smoke.AdtSingleVariant.spec - , Contracts.Smoke.AdtMixedFieldCounts.spec - , Contracts.Smoke.NewtypeModifiesSmoke.spec - , Contracts.Smoke.NewtypeNamespaceSmoke.spec - , Contracts.Smoke.UnsafeCEICompliant.spec - , Contracts.Smoke.RolesCEISmoke.spec - , Contracts.Smoke.NonreentrantModifiesSmoke.spec - , Contracts.Smoke.AdtNewtypeCombo.spec - , Contracts.Smoke.FullComboSmoke.spec - -- CEIWriteInBranchAfterCall, CEICallBothBranchesWrite, UnsafeCEIViolation are - -- intentionally invalid (CEI violations); tested via #guard_msgs in Smoke.lean - ] - -private structure FuzzRng where - seed : Nat - -private def fuzzMask64 : Nat := 2^64 - 1 - -private def fuzzNext (rng : FuzzRng) : FuzzRng × Nat := - let s := (rng.seed + 0x9e3779b97f4a7c15) &&& fuzzMask64 - let z := s - let z := ((z ^^^ (z >>> 30)) * 0xbf58476d1ce4e5b9) &&& fuzzMask64 - let z := ((z ^^^ (z >>> 27)) * 0x94d049bb133111eb) &&& fuzzMask64 - let z := z ^^^ (z >>> 31) - ({ seed := s }, z) - -private def fuzzEdgeValues : List Nat := - [0, 1, 2, 255, 256, 2^16 - 1, 2^128 - 1, 2^255, 2^256 - 1] - -private def fuzzWord (rng : FuzzRng) : FuzzRng × Nat := - let (rng, n) := fuzzNext rng - match fuzzEdgeValues[n % 16]? with - | some v => (rng, v) - | none => - let (rng, hi) := fuzzNext rng - let (rng, lo) := fuzzNext rng - (rng, ((hi &&& fuzzMask64) <<< 64) + (lo &&& fuzzMask64)) - -private def fuzzValueForType (ty : ParamType) (rng : FuzzRng) : FuzzRng × Nat := - let (rng, raw) := fuzzWord rng - match ty with - | .uint8 => (rng, raw % 256) - | .address => (rng, raw % (2^160)) - | .bool => (rng, raw % 2) - | _ => (rng, raw) - -private def fuzzArgsForParams : List Param → FuzzRng → FuzzRng × List Nat - | [], rng => (rng, []) - | p :: rest, rng => - let (rng, arg) := fuzzValueForType p.ty rng - let (rng, restArgs) := fuzzArgsForParams rest rng - (rng, arg :: restArgs) - -private def fuzzStorageEntries : List Nat → FuzzRng → FuzzRng × List (Nat × Nat) - | [], rng => (rng, []) - | slotIdx :: rest, rng => - let (rng, value) := fuzzWord rng - let (rng, tail) := fuzzStorageEntries rest rng - (rng, (slotIdx, value) :: tail) - -private def storageOfEntries (entries : List (Nat × Nat)) : IRStorageSlot → IRStorageWord := - fun slotIdx => - match entries.find? (fun entry => IRStorageSlot.ofNat entry.1 == slotIdx) with - | some (_, value) => IRStorageWord.ofNat value - | none => IRStorageWord.ofNat 0 - -private def mappingKeySamples (sender : Nat) (args : List Nat) : List Nat := - (args ++ [0, 1, sender, 2^160 - 1, 2^256 - 1]).eraseDups - -private def storageSlotSamples (spec : CompilationModel) : List Nat := - (canonicalFieldSlots spec ++ writeSlots spec ++ [0, 1, 2, 3, 4, 31, 32, 255]).eraseDups - -private def mappingBaseSamples (spec : CompilationModel) : List Nat := - (writeSlots spec ++ canonicalFieldSlots spec ++ [0, 1, 2, 3]).eraseDups - -private def sampledResultsMatch - (slots : List Nat) - (bases : List Nat) - (keys : List Nat) - (ir : IRResult) - (yul : YulResult) : Bool := - ir.success == yul.success && - ir.returnValue == yul.returnValue && - ir.events == yul.events && - slots.all (fun slotIdx => - ir.finalStorage (IRStorageSlot.ofNat slotIdx) == yul.finalStorage (IRStorageSlot.ofNat slotIdx)) && - bases.all (fun base => keys.all (fun key => ir.finalMappings base key == yul.finalMappings base key)) - -private def roundTripTrialsPerFunction : Nat := 1 -private def roundTripFuelBudget : Nat := 512 -private def roundTripInitialSeed : Nat := 0xC0DEC0DE - -private def parseNatEnv? (name : String) : IO (Option Nat) := do - match ← IO.getEnv name with - | none => pure none - | some raw => - match raw.trim.toNat? with - | some value => pure (some value) - | none => throw <| IO.userError s!"{name} must be a natural number, got {repr raw}" - -private def shardSpecs (specs : List CompilationModel) (shardIndex shardCount : Nat) : - IO (List CompilationModel) := do - if shardCount == 0 then - throw <| IO.userError "MACRO_FUZZ_SHARD_COUNT must be >= 1" - if shardIndex >= shardCount then - throw <| IO.userError - s!"MACRO_FUZZ_SHARD_INDEX must be less than MACRO_FUZZ_SHARD_COUNT ({shardIndex} >= {shardCount})" - let sharded := - specs.zipIdx.filterMap fun (spec, idx) => - if idx % shardCount == shardIndex then some spec else none - if sharded.isEmpty then - throw <| IO.userError - s!"macro fuzz shard {shardIndex}/{shardCount} selected no specs; reduce the shard count" - pure sharded - -private def loadShardConfig : IO (Nat × Nat) := do - let shardCount := (← parseNatEnv? "MACRO_FUZZ_SHARD_COUNT").getD 1 - let shardIndex := (← parseNatEnv? "MACRO_FUZZ_SHARD_INDEX").getD 0 - pure (shardIndex, shardCount) - -private def runRoundTripTrials - (spec : CompilationModel) - (irFn : IRFunction) - (fn : FunctionSpec) - (selector : Nat) - (slots : List Nat) - (bases : List Nat) : - Nat → FuzzRng → IO FuzzRng - | 0, rng => pure rng - | trial + 1, rng => do - let senderSample := fuzzWord rng - let rng := senderSample.1 - let senderRaw := senderSample.2 - let sender := senderRaw % (2^160) - let argsSample := fuzzArgsForParams fn.params rng - let rng := argsSample.1 - let args := argsSample.2 - let storageSample := fuzzStorageEntries slots rng - let rng := storageSample.1 - let storageEntries := storageSample.2 - let initialState : IRState := - { vars := [] - «storage» := storageOfEntries storageEntries - memory := fun _ => 0 - calldata := args - returnValue := none - sender := sender - selector := selector - events := [] } - let irResult := execIRFunctionFuel roundTripFuelBudget irFn args initialState - let stateWithParams := irFn.params.zip args |>.foldl - (fun s (p, v) => s.setVar p.name v) - initialState - let yulState := yulStateOfIR selector stateWithParams - let yulRollback := yulStateOfIR selector initialState - let yulExec := execYulStmtsFuel roundTripFuelBudget yulState irFn.body - let yulResult := yulResultOfExecWithRollback yulRollback yulExec - let keys := mappingKeySamples sender args - expectTrue - s!"{spec.name}.{fn.name}: trial {trial + 1}" - (sampledResultsMatch slots bases keys irResult yulResult) - runRoundTripTrials spec irFn fn selector slots bases trial rng - -private def checkRoundTripSpec (spec : CompilationModel) (rng : FuzzRng) : IO FuzzRng := do - let extFns := externalFunctions spec - let selectors ← Selector.computeSelectors spec - let compileResult ← Selector.compileChecked spec selectors - let ir ← - match compileResult with - | .ok ir => - pure ir - | .error err => - throw (IO.userError s!"{spec.name}: compileChecked failed in round-trip fuzz harness: {err}") - - expectTrue - s!"{spec.name}: function/selector alignment" - (extFns.length == selectors.length) - - let slots := (storageSlotSamples spec).take 16 - let bases := (mappingBaseSamples spec).take 12 - let fnSelectors := List.zip extFns selectors - let mut rng := rng - for (fn, selector) in fnSelectors do - let irFn ← - match ir.functions.find? (fun f => f.selector == selector) with - | some found => - pure found - | none => - throw (IO.userError s!"{spec.name}.{fn.name}: missing compiled IR function for selector {Compiler.Hex.natToHex selector}") - rng ← runRoundTripTrials spec irFn fn selector slots bases roundTripTrialsPerFunction rng - IO.println s!"✓ {spec.name}: randomized IR/Yul function round-trip checks passed" - pure rng - -def main : IO Unit := do - let (shardIndex, shardCount) ← loadShardConfig - let specs ← shardSpecs macroSpecs shardIndex shardCount - IO.println s!"Running macro round-trip fuzz shard {shardIndex + 1}/{shardCount} over {specs.length} spec(s)" - let mut rng : FuzzRng := { seed := roundTripInitialSeed } - for spec in specs do - rng ← checkRoundTripSpec spec rng - IO.println "✓ macro round-trip fuzz harness passed" - -end Compiler.MacroTranslateRoundTripFuzz - -def main : IO Unit := Compiler.MacroTranslateRoundTripFuzz.main diff --git a/Makefile b/Makefile index 29d2de75d..10dc797f3 100644 --- a/Makefile +++ b/Makefile @@ -109,13 +109,10 @@ test-evmyullean-fork: ## Probe EVMYulLean fork conformance (audit + adapter repo python3 scripts/generate_evmyullean_fork_audit.py --check @echo "Checking EVMYulLean adapter report..." python3 scripts/generate_evmyullean_adapter_report.py --check - @echo "Building EVMYulLean adapter correctness, bridge lemmas, native harness, and 123 concrete bridge tests..." - lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanAdapterCorrectness + @echo "Building EVMYulLean bridge lemmas, native harness, and 123 concrete bridge tests..." lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeTest lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness - lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeSmokeTest - lake exe native-dispatch-oracle-test @echo "Building public EVMYulLean EndToEnd target..." lake build Compiler.Proofs.EndToEnd @echo "EVMYulLean fork conformance probe passed." @@ -158,7 +155,6 @@ check: ## Run local CI-equivalent checks job (no Lean build, no solc) python3 scripts/generate_evmyullean_capability_report.py --check python3 scripts/generate_evmyullean_adapter_report.py --check python3 scripts/generate_evmyullean_fork_audit.py --check - python3 scripts/check_native_transition_doc.py python3 scripts/generate_print_axioms.py --check python3 scripts/check_proof_length.py python3 scripts/check_issue_1060_integrity.py diff --git a/PrintAxioms.lean b/PrintAxioms.lean index 67f4ef685..d49a3f795 100644 --- a/PrintAxioms.lean +++ b/PrintAxioms.lean @@ -51,18 +51,15 @@ import Compiler.Proofs.KeccakBound import Compiler.Proofs.MappingSlot import Compiler.Proofs.StorageBounds import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanAdapter -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanAdapterCorrectness import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBodyClosure import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgePredicates import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeSignedArithLemmas import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanPureBuiltinLemmas -import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanSignedArithSpec import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanSourceExprClosure import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanStateBridge -import Compiler.Proofs.YulGeneration.Equivalence import Compiler.Proofs.YulGeneration.IRFuel import Compiler.Proofs.YulGeneration.ReferenceOracle.Builtins import Compiler.Proofs.YulGeneration.RuntimeTypes @@ -1156,10 +1153,16 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_selected_user_body_halt_exec_atFuel -- private -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_empty_body_markedPrefix -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_empty_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through -- private -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_leave_body_markedPrefix -- private + -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_label_prefix_leave_body_markedPrefix -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_nativePreservableStraightStmts_leave -- private -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_block_leave_body_markedPrefix -- private + -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_label_prefix_block_leave_body_markedPrefix -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_leave -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_leave_with_label_prefix -- private -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_block_empty_body_markedPrefix -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_block_empty -- private -- Compiler.Proofs.EndToEnd.nativeResultsMatchOn_execIRFunction_singleton_comment_body_markedPrefix -- private @@ -1192,6 +1195,8 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.NativeExprPreservesWord_lowerExprNative_lt_calldatasize_lit_any -- private -- Compiler.Proofs.EndToEnd.NativeBlockPreservesWord_switchCaseBody_payable_of_user_body -- private -- Compiler.Proofs.EndToEnd.NativeBlockPreservesWord_switchCaseBody_nonpayable_of_user_body -- private + -- Compiler.Proofs.EndToEnd.NativeBlockPreservesWord_revived_switchCaseBody_payable_of_user_body -- private + -- Compiler.Proofs.EndToEnd.NativeBlockPreservesWord_revived_switchCaseBody_nonpayable_of_user_body -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHitBodyPreservesMatched_of_user_body_preserves -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHitBodyPreservesMatched_mappingFree_payable -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHitBodyPreservesMatched_mappingFree_nonpayable -- private @@ -1199,8 +1204,23 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHitBodyPreservesMatched_mapping_of_switchFresh -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_empty_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_empty_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_empty -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_leave_body_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_block_leave_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_singleton_comment -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuelRevived.of_nativePreservableStraightStmts_leave -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_exec_only_and_revivedPreserves -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_leave_body_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevivedLeaveAware.of_block_leave_with_label_prefix -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_block_empty -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_singleton_comment -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_bridgedStraightStmts_falling_through -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_empty_body -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_empty_body -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitUserBodyBridgeAtFuelRevived.of_execIRFunction -- private @@ -1221,6 +1241,7 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_success_bridge_threshold -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_body_halt_bridge_atFuel -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revived_and_continuation -- private + -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revivedLeaveAware_and_continuation -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedSelectorHit_success_of_user_body_exec_bridge_atFuel_revived -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_user_body_exec_bridge_atFuel_revived_and_continuation -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_user_body_exec_bridge_atFuel_revived -- private @@ -1231,6 +1252,14 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_empty_body -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_block_empty -- private -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_singleton_comment -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_bridgedStraightStmts_falling_through -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_bridgedStraightStmts_falling_through_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_leave_body_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_block_leave_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_nativePreservableStraightStmts_leave_with_label_prefix -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_leave_body -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_block_leave -- private + -- Compiler.Proofs.EndToEnd.NativeGeneratedSelectorHitSuccessBridge.of_nativePreservableStraightStmts_leave -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_success_only_atFuel_revived_and_continuation -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_success_only_atFuel_revived -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_empty_selected_body -- private @@ -1245,6 +1274,7 @@ end Verity.AxiomAudit -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_result_threshold -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body -- private Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported + -- Compiler.Proofs.EndToEnd.compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher_via_result -- private Compiler.Proofs.EndToEnd.compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_body_bridge_and_continuation -- private -- Compiler.Proofs.EndToEnd.nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_bridge_and_continuation -- private @@ -3166,15 +3196,6 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNativeAux_stmt_cons Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative_empty - -- Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.assign_equiv_let -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.assign_equiv_let' -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.legacyExecYulFuel_stmts_nil -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.for_init_hoist -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.for_init_hoist_revert -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.for_init_hoist_return -- private - -- Compiler.Proofs.YulGeneration.Backends.AdapterCorrectness.for_init_hoist_stop -- private - -- Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean Compiler.Proofs.YulGeneration.Backends.isDynamicParamType_false_of_static_scalar -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_calldataload_lit -- private @@ -4511,6 +4532,18 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_callvalue_initialState_ok Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_callvalue_ok_fuel Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_lt_calldatasize_ok_fuel + Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_lt_calldatasize_fuel + Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_lt_calldatasize_fuel_ge_6 + Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_callvalue_fuel + Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_callvalue_fuel_ge_2 + Compiler.Proofs.YulGeneration.Backends.Native.eval_lt_calldatasize_lit_preserves_reviveJump_of_ok_at_fuel + Compiler.Proofs.YulGeneration.Backends.Native.eval_callvalue_preserves_reviveJump_of_ok_at_fuel + Compiler.Proofs.YulGeneration.Backends.Native.eval_lt_calldatasize_lit_preserves_reviveJump_at_fuel_ge_8 + Compiler.Proofs.YulGeneration.Backends.Native.eval_callvalue_preserves_reviveJump_at_fuel_ge_5 + -- Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_callvalue_lt2_not_ok -- private + Compiler.Proofs.YulGeneration.Backends.Native.eval_callvalue_preserves_reviveJump + -- Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_lt_calldatasize_lt6_not_ok -- private + Compiler.Proofs.YulGeneration.Backends.Native.eval_lt_calldatasize_lit_preserves_reviveJump Compiler.Proofs.YulGeneration.Backends.Native.eval_lowerExprNative_sload_ok_fuel Compiler.Proofs.YulGeneration.Backends.Native.exec_lowerExprNative_mstore_lit_sload_lit_ok_fuel Compiler.Proofs.YulGeneration.Backends.Native.exec_lowerExprNative_mstore_lit_lit_ok_fuel @@ -4538,6 +4571,8 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.Native.exec_block_nil_ok_add_ten Compiler.Proofs.YulGeneration.Backends.Native.exec_block_leave_ok_add_ten Compiler.Proofs.YulGeneration.Backends.Native.exec_block_block_leave_ok_add_ten + Compiler.Proofs.YulGeneration.Backends.Native.exec_block_label_prefix_leave_ok_add_ten + Compiler.Proofs.YulGeneration.Backends.Native.exec_block_label_prefix_block_leave_ok_add_ten Compiler.Proofs.YulGeneration.Backends.Native.exec_block_block_nil_ok_add_ten Compiler.Proofs.YulGeneration.Backends.Native.exec_block_stop_halt_add_ten Compiler.Proofs.YulGeneration.Backends.Native.exec_block_noop_block_head_eq @@ -4803,6 +4838,7 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_if_of_eval_preserves_and_nativeStmtsWriteNames_not_mem Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_if_of_cond_preserves Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_if_of_cond_preserves_and_nativeStmtsWriteNames_not_mem + Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump Compiler.Proofs.YulGeneration.Backends.Native.nativeSwitchBranchFold_ok_preserves_word Compiler.Proofs.YulGeneration.Backends.Native.execSwitchCases_ok_branch_preserves_word Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_switch_of_eval_preserves @@ -4844,6 +4880,12 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_leave Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_empty_block Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_revived_block_leave + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_block_empty_then_leave + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_of_never_ok + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_of_never_ok + -- Compiler.Proofs.YulGeneration.Backends.Native.exec_block_nativeRevertZeroZero_low_fuel_ne_ok -- private + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_nativeRevertZeroZero + Compiler.Proofs.YulGeneration.Backends.Native.NativeBlockPreservesWord_revived_block_empty_then_block_leave Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_lowerStmtGroupNativeWithSwitchIds_comment Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_lowerStmtGroupNativeWithSwitchIds_let Compiler.Proofs.YulGeneration.Backends.Native.NativeStmtPreservesWord_lowerStmtGroupNativeWithSwitchIds_let_of_write_not_mem @@ -5359,85 +5401,6 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.evalPureBuiltinViaEvmYulLean_shl_native Compiler.Proofs.YulGeneration.Backends.evalPureBuiltinViaEvmYulLean_shr_native - -- Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_add -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_sub -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_mul -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_div -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_mod -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_lt -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_gt -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_eq -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_iszero -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_and -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_or -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_xor -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_not -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_shl -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_shr -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_addmod -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_mulmod -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_byte -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_slt -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_sgt -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_exp -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_sdiv -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_smod -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_sar -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_signextend -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_caller -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_address -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_callvalue -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_timestamp -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_number -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_chainid -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_blobbasefee -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_calldataload -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_calldatasize -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_sload -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_mappingSlot -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_on_bridged_builtins -- private - -- Compiler.Proofs.YulGeneration.Backends.backends_agree_on_keccak256 -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExprWithBackend_evmYulLean_eq -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExprsWithBackend_evmYulLean_eq -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExprWithBackend_eq_on_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExprsWithBackend_eq_on_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExpr_evmYulLean_eq_on_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_evmYulLean_eq -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_let_eq_on_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_assign_eq_on_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_eq_on_bridged_straight_stmt -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_eq_on_bridged_straight_stmts -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_block_eq_on_bridged_straight_stmts -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_if_eq_on_bridged_body -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_switch_eq_on_bridged_cases -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_for_eq_on_bridged_parts -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_callvalue -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_calldatasize -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_selector -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_selectorExpr -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExpr_selectorExpr_semantics -- private - -- Compiler.Proofs.YulGeneration.Backends.evalYulExprWithBackend_evmYulLean_selectorExpr_semantics -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_calldatasize_lt -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_has_selector -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_empty_calldata -- private - -- Compiler.Proofs.YulGeneration.Backends.bridgedExpr_iszero_ident -- private - -- Compiler.Proofs.YulGeneration.Backends.callvalueGuard_bridged -- private - -- Compiler.Proofs.YulGeneration.Backends.calldatasizeGuard_bridged -- private - Compiler.Proofs.YulGeneration.Backends.dispatchBody_bridged - Compiler.Proofs.YulGeneration.Backends.defaultDispatchCase_bridged - Compiler.Proofs.YulGeneration.Backends.switchCases_bridged - Compiler.Proofs.YulGeneration.Backends.buildSwitch_bridged - Compiler.Proofs.YulGeneration.Backends.mappingSlotFuncAt_bridged - Compiler.Proofs.YulGeneration.Backends.runtimeCode_bridged - Compiler.Proofs.YulGeneration.Backends.emitYul_runtimeCode_bridged - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_eq_on_bridged_target -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_eq_on_bridged_stmt -- private - -- Compiler.Proofs.YulGeneration.Backends.execYulFuelWithBackend_eq_on_bridged_stmts -- private - -- Compiler.Proofs.YulGeneration.Backends.emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies -- private - -- Compiler.Proofs.YulGeneration.Backends.interpretYulRuntimeWithBackend_evmYulLean_eq -- private - -- Compiler.Proofs.YulGeneration.Backends.interpretYulFromIR_evmYulLean_eq_on_bridged_bodies -- private - -- Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSignedArithSpec.lean Compiler.Proofs.YulGeneration.Backends.SignedArithSpec.specSignBit_lt_specModulus Compiler.Proofs.YulGeneration.Backends.SignedArithSpec.specModulus_pos @@ -5542,22 +5505,6 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.Backends.StateBridge.storageLookup_projectStorage_projected Compiler.Proofs.YulGeneration.Backends.StateBridge.uint256_roundtrip - -- Compiler/Proofs/YulGeneration/Equivalence.lean - -- Compiler.Proofs.YulGeneration.resultsMatch_of_execResultsAligned -- private - -- Compiler.Proofs.YulGeneration.statesAligned_refl -- private - -- Compiler.Proofs.YulGeneration.execYulStmtsFuel_nil -- private - -- Compiler.Proofs.YulGeneration.execYulStmtsFuel_cons -- private - -- Compiler.Proofs.YulGeneration.execYulStmtFuel_for -- private - -- Compiler.Proofs.YulGeneration.stmt_align_contra -- private - -- Compiler.Proofs.YulGeneration.execIRStmtsFuel_equiv_execYulStmtsFuel_of_stmt_equiv -- private - -- Compiler.Proofs.YulGeneration.execIRStmtsFuel_equiv_execYulStmts_of_stmt_equiv -- private - -- Compiler.Proofs.YulGeneration.execIRFunctionFuel_equiv_interpretYulBodyFromState_of_stmt_equiv -- private - -- Compiler.Proofs.YulGeneration.ir_yul_function_equiv_fuel_goal_of_stmt_equiv -- private - -- Compiler.Proofs.YulGeneration.ir_yul_function_equiv_from_state_of_fuel_goal -- private - -- Compiler.Proofs.YulGeneration.ir_yul_function_equiv_from_state_of_fuel_goal_and_adequacy -- private - -- Compiler.Proofs.YulGeneration.ir_yul_function_equiv_from_state_of_stmt_equiv_and_adequacy -- private - -- Compiler.Proofs.YulGeneration.ir_yul_function_equiv_from_state_of_stmt_equiv -- private - -- Compiler/Proofs/YulGeneration/IRFuel.lean Compiler.Proofs.YulGeneration.execIRStmtsFuel_nil Compiler.Proofs.YulGeneration.execIRStmtsFuel_cons @@ -5585,4 +5532,4 @@ end Verity.AxiomAudit Compiler.Proofs.YulGeneration.YulTransaction.ofIR_args ] --- Total: 5299 theorems/lemmas (3564 public, 1735 private, 0 sorry'd) +-- Total: 5255 theorems/lemmas (3575 public, 1680 private, 0 sorry'd) diff --git a/TRUST_ASSUMPTIONS.md b/TRUST_ASSUMPTIONS.md index d2564cc87..44f66d5a8 100644 --- a/TRUST_ASSUMPTIONS.md +++ b/TRUST_ASSUMPTIONS.md @@ -58,10 +58,10 @@ Current theorem totals, property-test coverage, and proof status live in [docs/V ### 6. EVM/Yul Semantics and Gas - **Role**: Runtime execution model. -- **Status (native transition in progress)**: 25 universal pure bridge theorems (all fully proven) in `Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean`, plus 11 context/env/storage/helper builtin bridge theorems, cover the 36 builtin bridge cases used by the transition regressions. All pure bridge cases are now covered by universal symbolic lemmas. `EvmYulLeanRetarget.lean` now remains transition/regression evidence rather than public compiler-correctness authority. The public EndToEnd composition surface in `Compiler/Proofs/EndToEnd.lean` targets native `EvmYul.Yul.callDispatcher` execution through `Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness`: the public surface is `nativeResultsMatchOn`, `sourceResultMatchesNativeOn`, the source/native result-composition theorem over that native result surface, and the concrete SimpleStorage native theorem. The fuel-indexed `nativeIRRuntimeMatchesIR` seams are file-local. The legacy `YulGeneration.Preservation` contract preservation theorem and the higher-level function equivalence ladder in `YulGeneration.Equivalence` are file-local reference-oracle transition code, and root `Compiler.lean` no longer re-exports the legacy Yul proof stack. Deeper generated/supported-Yul preservation is not yet fully retargeted to native EVMYulLean; `ReferenceOracle.Semantics`, `legacyExecYulFuel`, and related fuel-based helpers remain inside the isolated legacy stack. Gas is not modeled. -- **Trust boundary (EVMYulLean EndToEnd target)**: For the native EndToEnd path, the runtime authority is EVMYulLean dispatcher execution after Verity Yul is lowered by the native harness and projected onto the observable result surface. The remaining legacy preservation/equivalence stack is transition evidence only until its generated/supported-Yul proofs are rebuilt directly against native EVMYulLean execution. -- **Fork dependency**: Verity pins [`lfglabs-dev/EVMYulLean`](https://github.com/lfglabs-dev/EVMYulLean), a fork of [`NethermindEth/EVMYulLean`](https://github.com/NethermindEth/EVMYulLean). The pinned commit is recorded in `lake-manifest.json` under the `evmyul` package. The exact divergence from upstream is enumerated in [`artifacts/evmyullean_fork_audit.json`](artifacts/evmyullean_fork_audit.json), regenerated by `scripts/generate_evmyullean_fork_audit.py` and validated by `make check`. As of the current pin, the fork is 2 commits ahead of `upstream/main` and 0 behind; both commits are non-semantic (one visibility change on an exponentiation accumulator, one Lean 4.22.0 deprecation fix), so upstream Ethereum conformance test coverage applies transitively. In addition to the `make check` validation, a weekly scheduled GitHub Actions workflow ([`.github/workflows/evmyullean-fork-conformance.yml`](.github/workflows/evmyullean-fork-conformance.yml)) runs `make test-evmyullean-fork`, which re-verifies the fork audit artifact against `lake-manifest.json`, checks the EVMYulLean adapter report, rebuilds adapter correctness, rebuilds the native transition harness and smoke tests, rebuilds the public EndToEnd EVMYulLean target, and rebuilds the universal bridge lemmas (25 proven) together with the 123 concrete `native_decide` bridge-equivalence tests (`EvmYulLeanBridgeTest`), surfacing any upstream drift as a red workflow plus an automatically opened or updated GitHub issue for scheduled/manual failures. -- **Remaining gap for whole-program retargeting**: The public EndToEnd native surface is in place, but whole-program generated/supported-Yul preservation still needs to be rebuilt directly over native EVMYulLean execution. The legacy reference-oracle preservation/equivalence modules remain importable as isolated transition code, and the external-call/function-table family stays carved out of `BridgedSafeStmts`. +- **Status (native transition complete)**: 25 universal pure bridge theorems (all fully proven) in `Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean`, plus 11 context/env/storage/helper builtin bridge theorems, cover the 36 builtin bridge cases. All pure bridge cases are now covered by universal symbolic lemmas. The legacy reference-oracle stack (the legacy fuel-based executor, `ReferenceOracle.Semantics`, `YulGeneration.{Preservation,Equivalence,Codegen,Lemmas,StatementEquivalence}`, `EvmYulLean{AdapterCorrectness,NativeSmokeTest,NativeDispatchOracleTest,Retarget}`, and the `MacroTranslate{InvariantTest,RoundTripFuzz}` differential harnesses) has been **removed** as part of the EVMYulLean transition (DoD-5). The public EndToEnd composition surface in `Compiler/Proofs/EndToEnd.lean` targets native `EvmYul.Yul.callDispatcher` execution through `Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness`: the public surface is `nativeResultsMatchOn`, `sourceResultMatchesNativeOn`, the source/native result-composition theorem over that native result surface, and the concrete SimpleStorage native theorem. The fuel-indexed `nativeIRRuntimeMatchesIR` seams are file-local. Gas is not modeled. +- **Trust boundary (EVMYulLean EndToEnd target)**: For the native EndToEnd path, the runtime authority is EVMYulLean dispatcher execution after Verity Yul is lowered by the native harness and projected onto the observable result surface. There is no longer a legacy preservation/equivalence stack; only the native chain remains. +- **Fork dependency**: Verity pins [`lfglabs-dev/EVMYulLean`](https://github.com/lfglabs-dev/EVMYulLean), a fork of [`NethermindEth/EVMYulLean`](https://github.com/NethermindEth/EVMYulLean). The pinned commit is recorded in `lake-manifest.json` under the `evmyul` package. The exact divergence from upstream is enumerated in [`artifacts/evmyullean_fork_audit.json`](artifacts/evmyullean_fork_audit.json), regenerated by `scripts/generate_evmyullean_fork_audit.py` and validated by `make check`. As of the current pin, the fork is 2 commits ahead of `upstream/main` and 0 behind; both commits are non-semantic (one visibility change on an exponentiation accumulator, one Lean 4.22.0 deprecation fix), so upstream Ethereum conformance test coverage applies transitively. In addition to the `make check` validation, a weekly scheduled GitHub Actions workflow ([`.github/workflows/evmyullean-fork-conformance.yml`](.github/workflows/evmyullean-fork-conformance.yml)) runs `make test-evmyullean-fork`, which re-verifies the fork audit artifact against `lake-manifest.json`, checks the EVMYulLean adapter report, rebuilds the native transition harness, rebuilds the public EndToEnd EVMYulLean target, and rebuilds the universal bridge lemmas (25 proven) together with the 123 concrete `native_decide` bridge-equivalence tests (`EvmYulLeanBridgeTest`), surfacing any upstream drift as a red workflow plus an automatically opened or updated GitHub issue for scheduled/manual failures. +- **Remaining gap for whole-program retargeting**: The public EndToEnd native surface is in place, but the per-`BridgedStraightStmt` IR↔native observation-equivalence framework that would land truly unconditional S1–S8 / F2/F4/F6/F7 / true S8 has not been built yet — that work is multi-week and tracked separately. The external-call/function-table family stays carved out of `BridgedSafeStmts`. - **Implication**: Semantic correctness does not imply gas-safety. - **Proxy note**: `delegatecall`-based proxy / upgradeability flows still sit outside the current proof-interpreter model. Archive `--trust-report` and use `--deny-proxy-upgradeability` when proxy semantics must remain outside the selected verified subset (issue `#1420`). diff --git a/artifacts/evmyullean_adapter_report.json b/artifacts/evmyullean_adapter_report.json index 9ad4feff4..ca76623d0 100644 --- a/artifacts/evmyullean_adapter_report.json +++ b/artifacts/evmyullean_adapter_report.json @@ -1,8 +1,8 @@ { "adapter_correctness_proofs": { - "assign_to_let": "proven (assign_equiv_let, assign_equiv_let')", + "assign_to_let": "n/a (file removed in EVMYulLean transition)", "file": "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean", - "for_init_hoisting": "proven (for_init_hoist, for_init_hoist_return, for_init_hoist_revert, for_init_hoist_stop)" + "for_init_hoisting": "n/a (file removed in EVMYulLean transition)" }, "adapter_file": "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", "admitted_bridge_lemmas": [], @@ -216,48 +216,6 @@ ], "missing_expr_cases": [], "missing_stmt_cases": [], - "phase4_retarget": { - "admitted_bridge_dependencies": [], - "backends_agree_on_bridged_builtins": "proven", - "compileExpr_bridgedSource": "proven (source-expression fragment with parameter length, storage, and storage-array length reads, ADT tag/field reads, singleton and nested mapping reads through the abstract mappingSlot bridge, mapping struct-member reads, reserved exponentiation, boolean normalization, branchless helpers, bridged environment reads, and unary calldata/memory/transient reads)", - "compileExpr_bridgedSource_leaf": "proven (scalar source-expression leaves)", - "compileExpr_mappingChain_bridgedSource": "proven (mappingChain source-expression wrapper through the abstract mappingSlot bridge)", - "compileStmtList_always_bridged": "proven (universal compileStmtList body closure for BridgedSafeStmts; external-call family carved out)", - "compileStmtList_binding_leaf_bridged": "proven (scalar let/assign statement lists)", - "compileStmtList_external_body_fragment_bridged": "proven (mixed external body fragment)", - "compileStmtList_external_nested_body_fragment_bridged": "proven (mixed external body fragment plus two ite layers)", - "compileStmtList_external_recursive_body_fragment_bridged": "proven (mixed external body fragment plus recursive ite closure)", - "compileStmtList_external_structured_body_fragment_bridged": "proven (mixed external body fragment plus one ite layer)", - "compileStmtList_internal_body_fragment_bridged": "proven (mixed internal body fragment)", - "compileStmtList_internal_nested_body_fragment_bridged": "proven (mixed internal body fragment plus two ite layers)", - "compileStmtList_internal_recursive_body_fragment_bridged": "proven (mixed internal body fragment plus recursive ite closure)", - "compileStmtList_internal_return_bridged": "proven (internal return statement lists)", - "compileStmtList_internal_structured_body_fragment_bridged": "proven (mixed internal body fragment plus one ite layer)", - "compileStmtList_pure_binding_bridged": "proven (pure let/assign statement lists)", - "compileStmtList_require_bridged": "proven (require statement lists)", - "compileStmtList_storage_fragment_bridged": "proven (pure bindings plus single-slot setStorage statement lists)", - "compileStmtList_terminator_external_bridged": "proven (external stop/return statement lists)", - "emitYul_runtimeCode_bridged": "proven (conditional on bridged IR bodies)", - "emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies": "proven (conditional on bridged IR bodies)", - "evalYulExpr_evmYulLean_eq_on_bridged": "proven", - "execYulFuelWithBackend_block_eq_on_bridged_straight_stmts": "proven", - "execYulFuelWithBackend_eq_on_bridged_straight_stmts": "proven", - "execYulFuelWithBackend_eq_on_bridged_target": "proven", - "execYulFuelWithBackend_for_eq_on_bridged_parts": "proven", - "execYulFuelWithBackend_if_eq_on_bridged_body": "proven", - "execYulFuelWithBackend_switch_eq_on_bridged_cases": "proven", - "genParamLoads_scalar_bridged": "proven (scalar calldata parameters)", - "genParamLoads_static_scalar_bridged": "proven (static scalar calldata parameters)", - "genStaticTypeLoads_calldataload_bridged": "proven (static scalar calldata leaves)", - "layers2_3_ir_matches_yul_evmYulLeanBackend": "removed from EndToEnd surface (retarget evidence isolated in EvmYulLeanRetarget.lean)", - "remaining_for_whole_program_retargeting": [ - "discharge the conditional EndToEnd theorem's bridged-body hypotheses for full compiler-produced contracts" - ], - "retarget_file": "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean", - "status": "universal-safe-body-closure", - "trust_boundary": "recursive BridgedTarget statement fragment: EVMYulLean execution model matches EVM (upstream conformance tests) for BridgedExpr expressions, BridgedStraightStmts (including mapping-slot, literal-slot, and identifier-slot sstore), and recursively nested BridgedStmt targets; generated runtime-code closure, emitted-runtime backend equality, and the lower-level Layer-3 EVMYulLean retarget theorem are proven under bridged IR-body witnesses; the EndToEnd safe-body backend-wrapper lemma is private transition plumbing, while public EndToEnd targets use native dispatcher execution through interpretIRRuntimeNative; compileStmtList_always_bridged proves a universal BridgedSafeStmts aggregation theorem with the external-call family carved out behind explicit function-table hypotheses", - "yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle": "missing" - }, "schema_version": 7, "status": "ok", "stmt_gap_messages": {}, diff --git a/docs/INTERPRETER_FEATURE_MATRIX.md b/docs/INTERPRETER_FEATURE_MATRIX.md index 17b852280..211ac4d77 100644 --- a/docs/INTERPRETER_FEATURE_MATRIX.md +++ b/docs/INTERPRETER_FEATURE_MATRIX.md @@ -12,9 +12,13 @@ Machine-readable version: [`artifacts/interpreter_feature_matrix.json`](../artif | Interpreter | File | Entry Point | Purpose | |---|---|---|---| | **IRInterpreter** | `Compiler/Proofs/IRGeneration/IRInterpreter.lean` | `execIRStmts` | Layer-2 preservation proofs | -| **YulSemantics reference oracle** | `Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean` | `legacyExecYulFuel` | Historical Layer-3 Yul execution semantics retained for regression comparisons | | **EVMYulLean bridge** | `Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean` | `evalBuiltinCallViaEvmYulLean` | Pure builtin evaluation via EVMYulLean UInt256 | +The legacy YulSemantics reference oracle (`ReferenceOracle/Semantics.lean` +with its fuel-based executor entry point) was removed as part of the +EVMYulLean transition (DoD-5); the native EvmYulLean dispatcher is now the +sole runtime authority. + The old `SpecInterpreter` module has been removed. Source semantics now live in `Verity/Core.lean`, with the supported whole-contract Layer-2 source-side model assembled in `Compiler/Proofs/IRGeneration/SourceSemantics.lean`. This matrix diff --git a/docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md b/docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md index 07e5cf623..acd3d0ca5 100644 --- a/docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md +++ b/docs/NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md @@ -14,9 +14,9 @@ holds for **every supported-generated contract directly against `EvmYul.Yul.callDispatcher`**, with: 1. No `hUserBodyHalt` premise on the public theorem. -2. No opt-in legacy machinery - (`legacyExecYulFuel`, `EvmYulLeanRetarget.lean`, reference-oracle composition) - on the proof chain for the supported fragment. +2. No opt-in legacy machinery on the proof chain for the supported fragment + (the legacy fuel-based executor, the retargeting layer, and the + reference-oracle composition have all been removed in DoD-5). 3. Zero `sorry`, zero new axioms (invariant carried over from PR #1822). The G1 plan in `docs/NATIVE_EVMYULLEAN_TRANSITION.md` decomposes this into @@ -532,3 +532,130 @@ substrate hit `orphan_no_runner` and freeze failures on 4/4 spawn attempts for Layer D and Layer EF, with no convergence in this session. Direct implementation across multiple turns is the only working path until the substrate (sandboxed.sh) is fixed. + +## Stage 2 Plan (after #1826 foundation merge) + +The `_revived` foundation is now landed in main (#1826). Stage 2 carries +the remaining Layer D / E / F / G work in this stacked PR. + +### Stage 2 scope (all deferred from #1826) + +- **D1 / S5**: `NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_nativePreservableStraightStmts_leave` + + new source-side helper + `nativeResultsMatchOn_execIRFunction_nativePreservableStraightStmts_leave_body_markedPrefix` +- **D2 / S6**: `NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_bridgedStraightStmts_falling_through` + + new source-side helper + `nativeResultsMatchOn_execIRFunction_bridgedStraightStmts_falling_through_body_markedPrefix` +- **E2/E4/E6/E7 / S7**: success-bridge wiring via `_revived` cascade +- **F2/F4/F6/F7**: label-prefix variants +- **G / S8**: drop `hUserBodyHalt` premise + +### Architectural prerequisite + +D1 and D2 both require a per-`BridgedStraightStmt`-constructor IR↔native +observation-equivalence theorem that does not currently exist as generic +infrastructure. The existing concrete-body helpers (e.g. +`store0_calldataload4_stop_markedPrefix`) hand-roll their own equivalence +inline. Stage 2's first task is to build the generic compositional +theorem (~500-1000 LoC of inductive proof per direction). + +### Stage 2 sequencing + +1. Build the per-`BridgedStraightStmt` IR↔native observation correspondence +2. D2 (simpler — falling-through case) +3. D1 (preStmts ++ [.leave] case) +4. E2/E4/E6/E7 success-bridge cascade (Path B chains using `_revived`) +5. F2/F4/F6/F7 label-prefix variants +6. S8 dispatcher refactor + +### Stage 2 progress (2026-05-14) + +**Shipped degenerate slots** (hOnlyEmpty narrowing — preStmts = []): + +- D1/S5 degenerate (`193537a5`), D2/S6 degenerate (`7b9c2e86`) +- E7 degenerate (`c272db72`) + 5-commit `_revived` Preserves chain +- E2/E4/E6 SuccessBridge slots (`f1c087fc`) — conditional on + `LeaveAwareCallDispatcherContinuation` +- S8 `_via_result` private variant (`e0dd38ad` + `cebb0325`) +- F2/F4/F6 direct (`62f662ea` + `b4863167`), F7 via E3 delegation + (`eb9b9735` + `a52accfd`) + +**Parallel `_revived` upstream chain** (so the OLD-form +`NativeBlockPreservesWord` is mirrored end-to-end on the dispatcher result +stack — discharges `LeaveAwareCallDispatcherContinuation` unconditionally): + +- `NativeBlockPreservesWord_revived_nativeRevertZeroZero` (`b89b43cb` + + `9ba14c3d` refactor) — vacuity leaf +- `NativeStmtPreservesWord_revived_if_of_cond_preserves_reviveJump` + (`0b4151d6`) — takes a `reviveJump`-stated cond premise +- `NativeBlockPreservesWord_revived_switchCaseBody_payable_of_user_body` + (`b002443a` + `35e998f5` — drops `hCondReviveJump`) +- `NativeBlockPreservesWord_revived_switchCaseBody_nonpayable_of_user_body` + (`b5410c1a` + `35e998f5` — drops both cond premises) + +### Stage 2 progress (2026-05-15) + +**Universal-input cond-reviveJump discharge** ✓ (DoD-4 closed): + +- `eval_lowerExprNative_lt_calldatasize_fuel` (state-generic, fuel ≥ 8) +- `eval_lowerExprNative_lt_calldatasize_fuel_ge_6` (tight, fuel ≥ 6) +- `eval_lowerExprNative_callvalue_fuel` (state-generic, fuel ≥ 5) +- `eval_lowerExprNative_callvalue_fuel_ge_2` (tight, fuel ≥ 2) +- `eval_lt_calldatasize_lit_preserves_reviveJump` — UNIVERSAL (any fuel, + any state form), splits fuel < 6 (vacuous, `maxHeartbeats 4M`) vs ≥ 6 +- `eval_callvalue_preserves_reviveJump` — UNIVERSAL similarly +- Both `_revived_switchCaseBody_*` now apply the universal discharge + internally; `hCondReviveJump`/`hCallvalueReviveJump`/`hCalldataReviveJump` + premises dropped. + +Commits: `ce401bf0` (state-generic foundation), `b0611174` (callvalue +universal), `a2e91c49` (lt-calldatasize universal), `35e998f5` (drop +cond premises from `_revived_switchCaseBody_*`). + +**Polish (DoD-5) ✓ COMPLETE**: +- `EvmYulLeanRetarget.lean` (1631 LoC) deleted (`2eac7c6d`) +- 9 more legacy modules deleted in `0751d4ac` + (Preservation, StatementEquivalence, Equivalence, Codegen, Lemmas in + YulGeneration/; AdapterCorrectness, NativeSmokeTest, + NativeDispatchOracleTest in YulGeneration/Backends/; ReferenceOracle/Semantics) + plus the two MacroTranslate{InvariantTest,RoundTripFuzz} legacy regression + files (1240 + 389 LoC). +- 7058 lines removed total. +- CI plumbing cleanup (`6307373a`, `a563505a`, `c3ffd809`): verify.yml + macro-fuzz job removed, fork-conformance path filters scrubbed, sync spec + updated, dependent Python scripts and tests adjusted. +- Legacy fuel-based executor references: 0. `git grep` returns nothing. +- Final scrub (`aafc0e26`): all `legacyExecYulFuel` mentions removed from + TRUST_ASSUMPTIONS.md, INTERPRETER_FEATURE_MATRIX.md, + NATIVE_EVMYULLEAN_TRANSITION.md, NATIVE_EVMYULLEAN_G1_FOLLOWUP_PLAN.md, + VERIFICATION_STATUS.md, check_lean_hygiene.py, check_proof_length.py, + test_check_lean_hygiene.py — DoD-5's `git grep -n legacyExecYulFuel = 0` + strictly satisfied. + +**DoD-6 ✓** sorry count 5 ≤ upstream/main 7; axiom count 0 = 0. +**DoD-7 ✓** `lake clean && lake build` green (5m12s). +**DoD-8 ✓** `make check` green (1m41s). +**DoD-10 ✓** TRUST_ASSUMPTIONS.md / AUDIT.md / AXIOMS.md updated (`5d1010d1`). + +### Remaining (DoD-1, DoD-2, DoD-3) + +**Per-`BridgedStraightStmt` framework** — REMAINING LONG POLE (~2–4 weeks +standalone). For each of ~20 statement constructors in +`NativePreservableStraightStmt`, prove that IR-side execution and +native-generated execution are observationally equivalent on storage slots +and events. Until shipped, D1/D2/E6/E7 strengthening blocked behind the +`hOnlyEmpty : preStmts = []` narrowing. + +**Parallel `_revived` dispatcher continuation provider** — REMAINING. The +`LeaveAwareCallDispatcherContinuation` predicate (EndToEnd.lean:19858) is +required by E2/E4/E6/E7 and F2/F4/F6/F7. Building this is a parallel +copy-modify of `nativeGeneratedCallDispatcherResult_selector_hit_ok_matchesIR_forall_of_compile_ok_supported` +(~700 LoC), but the proof body needs `_revived` semantics threaded through +the dispatcher chain. Estimated 3–7 days standalone; blocked on the per-stmt +observation framework for the user-body preservation discharge of Leave- +ending bodies (the OLD-form provider's NativeBlockPreservesWord fails on +Leave-ending bodies because OLD's `final[name]!` returns `default` for +Checkpoint Leave states — see memory `yul-state-lookup-bracket-vs-lookup`). + +**Conflicts**: upstream main absorbed twice (merge commits `60d38ba8` and +`3358dc56`) — currently 0 commits behind upstream/main. diff --git a/docs/NATIVE_EVMYULLEAN_TRANSITION.md b/docs/NATIVE_EVMYULLEAN_TRANSITION.md index c74d1d32c..d620eaa3a 100644 --- a/docs/NATIVE_EVMYULLEAN_TRANSITION.md +++ b/docs/NATIVE_EVMYULLEAN_TRANSITION.md @@ -1290,14 +1290,16 @@ scope so the native path does not look more complete than it is: closed by `simpleStorageNativeStoreHitMatchBridge_proved`, which covers both the short-calldata revert and argument-present storage update paths. -## Cleanup After the Flip +## Cleanup After the Flip (DoD-5 — completed) -- Keep `legacyExecYulFuel` and the private `execYulFuelWithBackend` wrapper in - reference-oracle or isolated lower-level transition status. -- Remove bridge-only docs that describe the custom interpreter as the active - semantic target. -- Keep cross-check tests between the old oracle and native EVMYulLean for one - release cycle. +- ~~Keep the legacy fuel-based executor and the private + `execYulFuelWithBackend` wrapper in reference-oracle or isolated + lower-level transition status~~ → **removed** (the legacy reference-oracle + stack and the proof-interpreter retargeting layer were deleted in the + EVMYulLean transition). +- Bridge-only docs that described the custom interpreter as the active + semantic target have been updated to describe the native EvmYulLean + dispatcher as the sole runtime authority. - Upstream any EVMYulLean fork changes needed for memory, returndata, logs, or external-call semantics. @@ -1314,9 +1316,9 @@ ending in `leave`/fall-through" cases are scoped out to a follow-up PR. - **Public-surface retarget** — `interpretYulRuntimeEvmYulLean` and `interpretYulRuntimeEvmYulLeanFuel`; Layer 3 and SimpleStorage EndToEnd theorems retargeted to EVMYulLean conclusions; legacy reference-oracle - paths renamed to `..._via_reference_oracle`; `defaultBuiltinBackend := .evmYulLean`; - `legacyBuiltinBackend := .verity`, `legacyEvalBuiltinCallWithContext`, - `legacyExecYulFuel` opt-ins for old reference-oracle/bridge-comparison paths. + paths renamed to `..._via_reference_oracle`; `defaultBuiltinBackend := .evmYulLean`. + (The legacy `legacyBuiltinBackend`/`legacyEvalBuiltinCallWithContext`/legacy + fuel executor opt-ins were later removed in DoD-5.) - **Native EndToEnd surface** — `nativeResultsMatchOn`, the supported-compiler generated direct `EvmYul.Yul.callDispatcher` theorem and its helper-free / mapping-helper lowering wrappers, concrete SimpleStorage native theorem, diff --git a/docs/VERIFICATION_STATUS.md b/docs/VERIFICATION_STATUS.md index 325b248b3..9b93a4a72 100644 --- a/docs/VERIFICATION_STATUS.md +++ b/docs/VERIFICATION_STATUS.md @@ -106,22 +106,21 @@ theorem all_stmts_equiv : ∀ selector fuel stmt irState yulState, Key files: [`StatementEquivalence.lean`](../Compiler/Proofs/YulGeneration/StatementEquivalence.lean), [`Preservation.lean`](../Compiler/Proofs/YulGeneration/Preservation.lean), [`AXIOMS.md`](../AXIOMS.md) -### Phase 4: EVMYulLean Semantic Retargeting (safe-body EndToEnd target) - -The retargeting module [`EvmYulLeanRetarget.lean`](../Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean) proves the following retargeting facts. The backend-fuel executor facts are private transition evidence, not public proof authority: -- Private `backends_agree_on_bridged_builtins`: the `.verity` and `.evmYulLean` backends produce identical results at the `evalBuiltinCallWithBackendContext` level for all 36 bridged builtins (dispatch proof delegates to the 36 fully proven per-builtin context-lifted bridge lemmas in `EvmYulLeanBridgeLemmas.lean`) -- Private `evalYulExpr_evmYulLean_eq_on_bridged`: `evalYulExpr` agrees with the `.evmYulLean` backend-parameterized evaluator for every `BridgedExpr` expression, including nested calls to bridged builtins and backend-independent `tload`/`mload`; all builtin bridge dependencies are fully proven -- Private `execYulFuelWithBackend_verity_eq`: the backend-parameterized statement executor recovers existing `legacyExecYulFuel` semantics at `.verity`, giving the next induction a verified executor surface -- Private `execYulFuelWithBackend_eq_on_bridged_straight_stmts`: `.verity` and `.evmYulLean` statement execution agree for straight-line statement lists satisfying `BridgedStraightStmts`, covering value bindings, `letMany`'s shared revert behavior, and dedicated statement-call semantics for mapping-slot, literal-slot, and identifier-slot `sstore`, `mstore`, `tstore`, `stop`, `return`, and `revert`; all builtin bridge dependencies are fully proven -- Private `execYulFuelWithBackend_block_eq_on_bridged_straight_stmts`: `.block` wrappers around those straight-line lists preserve the same backend equivalence -- Private `execYulFuelWithBackend_if_eq_on_bridged_body`: `.if_` statements with bridged conditions and straight-line bodies preserve the same backend equivalence -- Private `execYulFuelWithBackend_switch_eq_on_bridged_cases`: `.switch` statements with bridged scrutinees and straight-line selected case/default bodies preserve the same backend equivalence -- Private `execYulFuelWithBackend_for_eq_on_bridged_parts`: `.for_` statements with straight-line init/body/post lists and a bridged condition preserve the same backend equivalence -- Private `execYulFuelWithBackend_eq_on_bridged_target`: recursive `.verity = .evmYulLean` backend equivalence for `BridgedTarget` executions whose nested statements satisfy `BridgedStmt` -- `emitYul_runtimeCode_bridged`: the emitted runtime dispatch wrapper satisfies `BridgedTarget` when the IR function bodies, fallback/receive bodies, and internal helper statements it embeds satisfy `BridgedStmt` -- Private `emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies`: emitted runtime-code execution through Verity `legacyExecYulFuel` equals the EVMYulLean backend executor when those embedded function/entrypoint/internal bodies satisfy `BridgedStmts` -- The old transition-only `yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle` theorem has been removed. The retargeting module still keeps backend-wrapper equivalence facts as isolated transition evidence, but it no longer exports a Layer-3 preservation theorem that routes through the legacy reference oracle as public proof authority. -- `EndToEnd.lean` no longer defines `layers2_3_ir_matches_yul_evmYulLeanBackend` or other backend-wrapper transition lemmas. The retargeting evidence remains isolated in `EvmYulLeanRetarget.lean`, while public EndToEnd correctness targets native dispatcher execution through `interpretIRRuntimeNative`. +### Phase 4: EVMYulLean Native Dispatcher (safe-body EndToEnd target) + +The retargeting module that bridged the legacy `.verity` proof-interpreter +backend to the `.evmYulLean` backend (`EvmYulLeanRetarget.lean` plus +`ReferenceOracle.Semantics`, `YulGeneration.{Preservation, Equivalence, +StatementEquivalence, Codegen, Lemmas}`, and the smoke-test scaffolding) was +**removed in DoD-5** of the EVMYulLean transition. The native EvmYulLean +dispatcher is now the sole runtime authority; there is no longer a private +proof-interpreter chain to keep in sync. + +The retained content of Phase 4 is the body-closure layer that proves +compiler-emitted runtime Yul satisfies `BridgedStmts` so that the public +EndToEnd surface (which targets native `EvmYul.Yul.callDispatcher` +execution through `EvmYulLeanNativeHarness`) can compose with those +closures unconditionally for the supported fragment. - `genParamLoads_scalar_bridged`: scalar calldata parameter-loading prologues emitted by `genParamLoads` satisfy `BridgedStmts` - `genStaticTypeLoads_calldataload_bridged`: static scalar leaf-load helpers for fixed arrays/tuples satisfy `BridgedStmts` - `genParamLoads_static_scalar_bridged`: full calldata parameter-loading prologues for static scalar fixed arrays/tuples satisfy `BridgedStmts` diff --git a/lakefile.lean b/lakefile.lean index 4333ea68e..f5f951722 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -25,8 +25,6 @@ lean_lib «Contracts» where .one `Contracts.Common, .one `Contracts.Specs, .one `Contracts.Interpreter, - .one `Contracts.MacroTranslateInvariantTest, - .one `Contracts.MacroTranslateRoundTripFuzz, .one `Contracts.Smoke, .andSubmodules `Contracts.Counter, .andSubmodules `Contracts.SimpleStorage, @@ -65,11 +63,6 @@ lean_exe «random-gen» where lean_exe «gas-report» where root := `Compiler.Gas.Report -lean_exe «macro-roundtrip-fuzz» where - root := `Contracts.MacroTranslateRoundTripFuzz - lean_exe «compiler-main-test» where root := `Compiler.MainTestRunner -lean_exe «native-dispatch-oracle-test» where - root := `Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeDispatchOracleTest diff --git a/scripts/check_lean_hygiene.py b/scripts/check_lean_hygiene.py index 27e08036b..e445c514a 100644 --- a/scripts/check_lean_hygiene.py +++ b/scripts/check_lean_hygiene.py @@ -3,7 +3,7 @@ Validates: 1. No debug commands (#eval, #check, #print, #reduce) in proof files -2. Exactly 1 allowUnsafeReducibility (documented trust assumption) +2. Exactly 0 allowUnsafeReducibility (legacy trust assumption removed) 3. Zero sorry in Lean code after scrubbing comments/strings 4. No native_decide in proof files outside smoke tests (kernel bypass) @@ -78,8 +78,10 @@ def main() -> None: f"(debug command that slows builds)" ) - # Check 2: Exactly 1 allowUnsafeReducibility - expected_unsafe = 1 + # Check 2: Exactly 0 allowUnsafeReducibility (the prior single usage was + # tied to the legacy fuel-based executor, removed in the EVMYulLean + # transition). + expected_unsafe = 0 unsafe_count = 0 unsafe_locations: list[str] = [] for lean_file in ROOT.rglob("*.lean"): diff --git a/scripts/check_macro_health.py b/scripts/check_macro_health.py index b42149786..9d22231bf 100644 --- a/scripts/check_macro_health.py +++ b/scripts/check_macro_health.py @@ -6,15 +6,11 @@ import argparse import check_macro_property_test_generation -import check_macro_roundtrip_fuzz_coverage -import check_macro_translate_invariant_coverage def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--skip-property-tests", action="store_true") - parser.add_argument("--skip-invariant-coverage", action="store_true") - parser.add_argument("--skip-roundtrip-coverage", action="store_true") return parser.parse_args(argv) @@ -26,16 +22,6 @@ def main(argv: list[str] | None = None) -> int: if rc != 0: return rc - if not args.skip_invariant_coverage: - rc = check_macro_translate_invariant_coverage.main([]) - if rc != 0: - return rc - - if not args.skip_roundtrip_coverage: - rc = check_macro_roundtrip_fuzz_coverage.main([]) - if rc != 0: - return rc - print("macro health checks passed") return 0 diff --git a/scripts/check_macro_roundtrip_fuzz_coverage.py b/scripts/check_macro_roundtrip_fuzz_coverage.py deleted file mode 100644 index 8abbdfaed..000000000 --- a/scripts/check_macro_roundtrip_fuzz_coverage.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python3 -"""Check that macro round-trip fuzz suite covers every `verity_contract` declaration.""" - -from __future__ import annotations - -import argparse -import re -import sys -from pathlib import Path - -from property_utils import ROOT - -DEFAULT_CONTRACTS_DIR = ROOT / "Contracts" -DEFAULT_FUZZ_FILE = ROOT / "Contracts" / "MacroTranslateRoundTripFuzz.lean" -EXCLUDED_CONTRACTS = { - "StringSmoke", # ABI-level string support is not yet covered by the numeric-only round-trip fuzz harness - "StringErrorSmoke", # String custom-error payloads are covered by dedicated ABI/runtime tests, not the numeric-only fuzz harness - "StringEqSmoke", # Direct string equality lowering still depends on ABI-dynamic string inputs, which this numeric-only fuzz harness does not model - "LocalObligationRequiredForUnsafeFunctionBoundary", # Intentionally fails compilation (#guard_msgs negative test) - "LocalObligationRequiredForUnsafeConstructorBoundary", # Intentionally fails compilation (#guard_msgs negative test) - "CEIViolationRejected", # Intentionally fails compilation (CEI violation #guard_msgs negative test) - "CEIWriteInBranchAfterCall", # Intentionally fails compilation (CEI violation #guard_msgs negative test) - "CEICallBothBranchesWrite", # Intentionally fails compilation (CEI violation #guard_msgs negative test) - "UnsafeCEIViolation", # Intentionally fails compilation (CEI violation #guard_msgs negative test) - "CEIInternalCallAfterExternalRejected", # Intentionally fails validation (CEI violation — internal call after external call) - "UnsafeGatingRejected", # Intentionally fails compilation (unsafe gating #guard_msgs negative test) -} - -CONTRACT_RE = re.compile(r"\bverity_contract\s+([A-Za-z_][A-Za-z0-9_]*)\s+where\b") -SUITE_ENTRY_RE = re.compile( - r"\bContracts(?:\.[A-Za-z_][A-Za-z0-9_]*)*\.([A-Za-z_][A-Za-z0-9_]*)\.spec\b" -) -MACRO_SPECS_DEF_RE = re.compile( - r"\bprivate\s+def\s+macroSpecs(?:\s*:\s*List\s+CompilationModel)?\s*:=\s*\[", - re.MULTILINE, -) - - -def _collect_contracts_from_text(text: str) -> list[str]: - names: list[str] = [] - guard_pending = False - block_comment_depth = 0 - for line in text.splitlines(): - stripped = line.strip() - if block_comment_depth > 0: - block_comment_depth += stripped.count("/-") - block_comment_depth -= stripped.count("-/") - continue - if stripped.startswith("/-"): - block_comment_depth += stripped.count("/-") - block_comment_depth -= stripped.count("-/") - if block_comment_depth > 0 or stripped == "": - continue - if stripped.endswith("-/"): - continue - if stripped == "#guard_msgs in": - guard_pending = True - continue - match = CONTRACT_RE.search(line) - if guard_pending: - if not stripped or stripped.startswith("--"): - continue - if match is not None: - guard_pending = False - continue - guard_pending = False - if match is None: - continue - names.append(match.group(1)) - return names - - -def _collect_contracts(sources: list[Path]) -> tuple[set[str], dict[str, list[Path]]]: - names: set[str] = set() - locations: dict[str, list[Path]] = {} - for path in sources: - text = path.read_text(encoding="utf-8") - for name in _collect_contracts_from_text(text): - names.add(name) - locations.setdefault(name, []).append(path) - duplicates = {name: paths for name, paths in locations.items() if len(paths) > 1} - return names, duplicates - - -def _extract_macro_specs_block(text: str) -> str | None: - match = MACRO_SPECS_DEF_RE.search(text) - if match is None: - return None - - start = match.end() - 1 - depth = 0 - for idx in range(start, len(text)): - ch = text[idx] - if ch == "[": - depth += 1 - elif ch == "]": - depth -= 1 - if depth == 0: - return text[start : idx + 1] - return None - - -def _collect_suite_entries(path: Path) -> list[str] | None: - text = path.read_text(encoding="utf-8") - block = _extract_macro_specs_block(text) - if block is None: - return None - return SUITE_ENTRY_RE.findall(block) - - -def _check_coverage(contract_sources: list[Path], fuzz_suite: Path) -> int: - declared, duplicate_declarations = _collect_contracts(contract_sources) - covered_entries = _collect_suite_entries(fuzz_suite) - - if covered_entries is None: - print("macro round-trip fuzz coverage check failed:", file=sys.stderr) - print( - " could not locate `private def macroSpecs : List CompilationModel := [...]`", - file=sys.stderr, - ) - return 1 - - covered = set(covered_entries) - - if not declared: - print("no verity_contract declarations found", file=sys.stderr) - return 1 - - seen: set[str] = set() - duplicate_entries: list[str] = [] - for name in covered_entries: - if name in seen and name not in duplicate_entries: - duplicate_entries.append(name) - seen.add(name) - - missing = sorted((declared - EXCLUDED_CONTRACTS) - covered) - extra = sorted(covered - declared) - - if not missing and not extra and not duplicate_entries and not duplicate_declarations: - print("macro round-trip fuzz coverage OK") - return 0 - - print("macro round-trip fuzz coverage check failed:", file=sys.stderr) - for name in sorted(duplicate_declarations): - paths = ", ".join(sorted(str(path) for path in duplicate_declarations[name])) - print( - f" duplicate verity_contract declaration name: {name} ({paths})", - file=sys.stderr, - ) - for name in duplicate_entries: - print( - f" duplicate macroSpecs entry in Contracts/MacroTranslateRoundTripFuzz.lean: {name}", - file=sys.stderr, - ) - for name in missing: - print( - f" missing in Contracts/MacroTranslateRoundTripFuzz.lean: {name}", - file=sys.stderr, - ) - for name in extra: - print( - f" unknown in Contracts/MacroTranslateRoundTripFuzz.lean: {name}", - file=sys.stderr, - ) - return 1 - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - "--contracts-dir", - default=str(DEFAULT_CONTRACTS_DIR.relative_to(ROOT)), - help="Directory containing macro contract declarations (default: Contracts).", - ) - parser.add_argument( - "--fuzz-suite", - default=str(DEFAULT_FUZZ_FILE.relative_to(ROOT)), - help="Round-trip fuzz suite file to validate (default: Contracts/MacroTranslateRoundTripFuzz.lean).", - ) - args = parser.parse_args(argv) - - contracts_dir = ROOT / args.contracts_dir - fuzz_suite = ROOT / args.fuzz_suite - - if not contracts_dir.exists() or not contracts_dir.is_dir(): - print(f"contracts directory not found: {contracts_dir}", file=sys.stderr) - return 1 - - if not fuzz_suite.exists(): - print(f"round-trip fuzz suite file not found: {fuzz_suite}", file=sys.stderr) - return 1 - - contract_sources = sorted(contracts_dir.rglob("*.lean")) - if not contract_sources: - print(f"no .lean files found under: {contracts_dir}", file=sys.stderr) - return 1 - - return _check_coverage(contract_sources, fuzz_suite) - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/scripts/check_macro_translate_invariant_coverage.py b/scripts/check_macro_translate_invariant_coverage.py deleted file mode 100644 index 9a93b68d0..000000000 --- a/scripts/check_macro_translate_invariant_coverage.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env python3 -"""Check that macro invariant tests cover every `verity_contract` declaration.""" - -from __future__ import annotations - -import argparse -import re -import sys -from pathlib import Path - -from property_utils import ROOT - -DEFAULT_CONTRACTS_DIR = ROOT / "Contracts" -DEFAULT_INVARIANT_FILE = ROOT / "Contracts" / "MacroTranslateInvariantTest.lean" - -CONTRACT_RE = re.compile(r"\bverity_contract\s+([A-Za-z_][A-Za-z0-9_]*)\s+where\b") -SUITE_ENTRY_RE = re.compile( - r"\bContracts(?:\.[A-Za-z_][A-Za-z0-9_]*)*\.([A-Za-z_][A-Za-z0-9_]*)\.spec\b" -) -MACRO_SPECS_DEF_RE = re.compile( - r"\bprivate\s+def\s+macroSpecs(?:\s*:\s*List\s+CompilationModel)?\s*:=\s*\[", - re.MULTILINE, -) - - -def _collect_contracts_from_text(text: str) -> list[str]: - names: list[str] = [] - guard_pending = False - block_comment_depth = 0 - for line in text.splitlines(): - stripped = line.strip() - if block_comment_depth > 0: - block_comment_depth += stripped.count("/-") - block_comment_depth -= stripped.count("-/") - continue - if stripped.startswith("/-"): - block_comment_depth += stripped.count("/-") - block_comment_depth -= stripped.count("-/") - if block_comment_depth > 0 or stripped == "": - continue - if stripped.endswith("-/"): - continue - if stripped == "#guard_msgs in": - guard_pending = True - continue - match = CONTRACT_RE.search(line) - if guard_pending: - if not stripped or stripped.startswith("--"): - continue - if match is not None: - guard_pending = False - continue - guard_pending = False - if match is None: - continue - names.append(match.group(1)) - return names - - -def _collect_contracts(sources: list[Path]) -> set[str]: - names: set[str] = set() - for path in sources: - text = path.read_text(encoding="utf-8") - names.update(_collect_contracts_from_text(text)) - return names - - -def _extract_macro_specs_block(text: str) -> str | None: - match = MACRO_SPECS_DEF_RE.search(text) - if match is None: - return None - - # Start at the opening `[` and extract until the matching `]`. - start = match.end() - 1 - depth = 0 - for idx in range(start, len(text)): - ch = text[idx] - if ch == "[": - depth += 1 - elif ch == "]": - depth -= 1 - if depth == 0: - return text[start : idx + 1] - return None - - -def _collect_suite_entries(path: Path) -> list[str] | None: - text = path.read_text(encoding="utf-8") - block = _extract_macro_specs_block(text) - if block is None: - return None - return SUITE_ENTRY_RE.findall(block) - - -def _check_coverage(contract_sources: list[Path], invariant_suite: Path) -> int: - declared = _collect_contracts(contract_sources) - covered_entries = _collect_suite_entries(invariant_suite) - - if covered_entries is None: - print( - "macro invariant suite coverage check failed:", - file=sys.stderr, - ) - print( - " could not locate `private def macroSpecs : List CompilationModel := [...]`", - file=sys.stderr, - ) - return 1 - - covered = set(covered_entries) - - if not declared: - print("no verity_contract declarations found", file=sys.stderr) - return 1 - - seen: set[str] = set() - duplicate_entries: list[str] = [] - for name in covered_entries: - if name in seen and name not in duplicate_entries: - duplicate_entries.append(name) - seen.add(name) - - missing = sorted(declared - covered) - extra = sorted(covered - declared) - - if not missing and not extra and not duplicate_entries: - print("macro invariant suite coverage OK") - return 0 - - print("macro invariant suite coverage check failed:", file=sys.stderr) - for name in duplicate_entries: - print( - f" duplicate macroSpecs entry in Contracts/MacroTranslateInvariantTest.lean: {name}", - file=sys.stderr, - ) - for name in missing: - print(f" missing in Contracts/MacroTranslateInvariantTest.lean: {name}", file=sys.stderr) - for name in extra: - print(f" unknown in Contracts/MacroTranslateInvariantTest.lean: {name}", file=sys.stderr) - return 1 - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - "--contracts-dir", - default=str(DEFAULT_CONTRACTS_DIR.relative_to(ROOT)), - help="Directory containing macro contract declarations (default: Contracts).", - ) - parser.add_argument( - "--invariant-suite", - default=str(DEFAULT_INVARIANT_FILE.relative_to(ROOT)), - help="Invariant suite file to validate (default: Contracts/MacroTranslateInvariantTest.lean).", - ) - args = parser.parse_args(argv) - - contracts_dir = ROOT / args.contracts_dir - invariant_suite = ROOT / args.invariant_suite - - if not contracts_dir.exists() or not contracts_dir.is_dir(): - print(f"contracts directory not found: {contracts_dir}", file=sys.stderr) - return 1 - - if not invariant_suite.exists(): - print(f"invariant suite file not found: {invariant_suite}", file=sys.stderr) - return 1 - - contract_sources = sorted(contracts_dir.rglob("*.lean")) - if not contract_sources: - print(f"no .lean files found under: {contracts_dir}", file=sys.stderr) - return 1 - - return _check_coverage(contract_sources, invariant_suite) - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/scripts/check_mapping_slot_boundary.py b/scripts/check_mapping_slot_boundary.py index 498d7ac38..edfc40a6c 100755 --- a/scripts/check_mapping_slot_boundary.py +++ b/scripts/check_mapping_slot_boundary.py @@ -22,14 +22,12 @@ REQUIRED_ABSTRACTION_IMPORTS = { PROOFS_DIR / "IRGeneration" / "IRInterpreter.lean", - PROOFS_DIR / "YulGeneration" / "ReferenceOracle" / "Semantics.lean", } LEGACY_SYMBOL_FORBIDDEN_FILES = REQUIRED_ABSTRACTION_IMPORTS BUILTINS_FILE = PROOFS_DIR / "YulGeneration" / "ReferenceOracle" / "Builtins.lean" IR_INTERPRETER_FILE = PROOFS_DIR / "IRGeneration" / "IRInterpreter.lean" -YUL_SEMANTICS_FILE = PROOFS_DIR / "YulGeneration" / "ReferenceOracle" / "Semantics.lean" IMPORT_MAPPING_ENCODING_RE = re.compile(r"^\s*import\s+Compiler\.Proofs\.MappingEncoding\s*$", re.MULTILINE) IMPORT_MAPPING_SLOT_RE = re.compile(r"^\s*import\s+Compiler\.Proofs\.MappingSlot\s*$", re.MULTILINE) @@ -183,14 +181,13 @@ def main() -> int: if not ABSTRACT_LOAD_REF_RE.search(builtins_text): errors.append(f"{builtins_rel}: missing reference to Compiler.Proofs.abstractLoadStorageOrMapping") - for state_file in (IR_INTERPRETER_FILE, YUL_SEMANTICS_FILE): - state_text = scrub_lean_code(state_file.read_text(encoding="utf-8")) - state_rel = state_file.relative_to(ROOT) - if STATE_MAPPINGS_FIELD_RE.search(state_text): - errors.append( - f"{state_rel}: execution state must not define a separate `mappings` table; " - "mapping semantics must flow through flat storage only" - ) + state_text = scrub_lean_code(IR_INTERPRETER_FILE.read_text(encoding="utf-8")) + state_rel = IR_INTERPRETER_FILE.relative_to(ROOT) + if STATE_MAPPINGS_FIELD_RE.search(state_text): + errors.append( + f"{state_rel}: execution state must not define a separate `mappings` table; " + "mapping semantics must flow through flat storage only" + ) if errors: print("Mapping slot boundary check failed:", file=sys.stderr) diff --git a/scripts/check_native_transition_doc.py b/scripts/check_native_transition_doc.py deleted file mode 100644 index c02118b80..000000000 --- a/scripts/check_native_transition_doc.py +++ /dev/null @@ -1,2792 +0,0 @@ -#!/usr/bin/env python3 -"""Keep the native EVMYulLean transition document honest. - -PR #1743 deliberately introduces an executable native harness without moving the -public theorem target. This checker prevents the transition note from losing the -explicit blocker list or overstating native EVMYulLean as the current public -semantic target. -""" - -from __future__ import annotations - -import re -import sys -from pathlib import Path - -ROOT = Path(__file__).resolve().parents[1] -DOC = ROOT / "docs" / "NATIVE_EVMYULLEAN_TRANSITION.md" -DOD_DOC = ROOT / "docs" / "NATIVE_EVMYULLEAN_FULL_TRANSITION_DONE.md" -ROOT_COMPILER = ROOT / "Compiler.lean" -END_TO_END = ROOT / "Compiler" / "Proofs" / "EndToEnd.lean" -NATIVE_HARNESS = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanNativeHarness.lean" -) -RETARGET = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanRetarget.lean" -) -BRIDGE_PREDICATES = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanBridgePredicates.lean" -) -BRIDGE_LEMMAS = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanBridgeLemmas.lean" -) -ADAPTER_CORRECTNESS = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanAdapterCorrectness.lean" -) -BODY_CLOSURE = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanBodyClosure.lean" -) -SOURCE_EXPR_CLOSURE = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanSourceExprClosure.lean" -) -BUILTINS = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "ReferenceOracle" - / "Builtins.lean" -) -PRESERVATION = ROOT / "Compiler" / "Proofs" / "YulGeneration" / "Preservation.lean" -YULGEN_README = ROOT / "Compiler" / "Proofs" / "YulGeneration" / "README.md" -NATIVE_ADAPTER = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanAdapter.lean" -) -NATIVE_SMOKE_TEST = ( - ROOT - / "Compiler" - / "Proofs" - / "YulGeneration" - / "Backends" - / "EvmYulLeanNativeSmokeTest.lean" -) -RUNTIME_TYPES = ROOT / "Compiler" / "Proofs" / "YulGeneration" / "RuntimeTypes.lean" -LEGACY_PROOF_MODULES = ( - "Compiler.Proofs.YulGeneration.Codegen", - "Compiler.Proofs.YulGeneration.Equivalence", - "Compiler.Proofs.YulGeneration.StatementEquivalence", - "Compiler.Proofs.YulGeneration.Preservation", - "Compiler.Proofs.YulGeneration.Lemmas", -) -TRANSITION_ONLY_PUBLIC_FORBIDDEN_MODULES = LEGACY_PROOF_MODULES + ( - "Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget", - "Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas", -) -BRIDGE_LEMMAS_IMPORT_ALLOWLIST = ( - "PrintAxioms.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean", -) -REFERENCE_ORACLE_IMPORT_ALLOWLIST = ( - "PrintAxioms.lean", - "Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean", - "Compiler/Proofs/YulGeneration/Codegen.lean", - "Compiler/Proofs/YulGeneration/Equivalence.lean", - "Compiler/Proofs/YulGeneration/Lemmas.lean", - "Compiler/Proofs/YulGeneration/Preservation.lean", - "Compiler/Proofs/YulGeneration/StatementEquivalence.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean", - "Contracts/MacroTranslateInvariantTest.lean", - "Contracts/MacroTranslateRoundTripFuzz.lean", -) -LEGACY_PROOF_FILES = ( - ROOT / "Compiler" / "Proofs" / "YulGeneration" / "Codegen.lean", - ROOT / "Compiler" / "Proofs" / "YulGeneration" / "Equivalence.lean", - ROOT / "Compiler" / "Proofs" / "YulGeneration" / "StatementEquivalence.lean", - ROOT / "Compiler" / "Proofs" / "YulGeneration" / "Preservation.lean", - ROOT / "Compiler" / "Proofs" / "YulGeneration" / "Lemmas.lean", -) - -REQUIRED_SNIPPETS = ( - "interpretYulRuntimeWithBackend .evmYulLean", - "Verity's custom fuel-based Yul statement interpreter", - "not the final architecture", - "Native.interpretRuntimeNative", - "Native.interpretIRRuntimeNative", - "EvmYul.Yul.callDispatcher", - "observable storage slot set explicitly", - "only materializes pre-state storage for those slots", - "nativeResultsMatchOn", - "nativeGeneratedCallDispatcherResultOf", - "nativeGeneratedCallDispatcherMatchesIROn", - "compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - "explicitly observable final-storage slots", - "exec_lowerNativeSwitchBlock_selector_find_hit_error_projectResult_eq", - "contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_hit_error_projectResult_eq", - "exec_lowerNativeSwitchBlock_selector_find_hit_error_store_projectResult_eq", - "exec_lowerNativeSwitchBlock_selector_find_none_with_revert_default_projectResult_eq", - "contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_none_with_revert_default_projectResult_eq", - "exec_lowerNativeSwitchBlock_selector_find_none_with_revert_default_store_projectResult_eq", - "exec_block_lowerNativeSwitchBlock_revert_default_hasSelectorState_projectResult_eq", - "exec_block_lowerNativeSwitchBlock_selector_find_hit_hasSelectorState_error_projectResult_eq", - "exec_lowerNativeSwitchBlock_selector_find_hit_ok_projectResult_eq", - "exec_lowerNativeSwitchBlock_selector_find_hit_ok_store_projectResult_eq", - "exec_block_lowerNativeSwitchBlock_selector_find_hit_hasSelectorState_ok_projectResult_eq", - "contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_hit_ok_projectResult_eq", - "nativeDispatcherExecMatchesIRPositive_of_project_eq_match", - "lowerSwitchCasesNativeWithSwitchIds_find?_some_of_find_function", - "lowerSwitchCasesNativeWithSwitchIds_find?_none_of_find_function", - "buildSwitchSourceCases_eq_switchCases", - "lowerSwitchCasesNativeWithSwitchIds_buildSwitch_find?_some_of_find_function", - "lowerSwitchCasesNativeWithSwitchIds_buildSwitch_find?_none_of_find_function", - "lowerStmtsNative_single_block_ok_singleton", - "lowerStmtsNative_block_stmts_eq", - "lowerStmtsNativeWithSwitchIds_let_head_eq", - "lowerStmtsNativeWithSwitchIds_if_head_eq", - "lowerStmtsNativeWithSwitchIds_singleton_switch_eq", - "lowerRuntimeContractNative_emitYul_noMapping_noInternals_noFallback_noReceive", - "lowerRuntimeContractNative_emitYul_mapping_noInternals_noFallback_noReceive_reserved", - "lowerStmtsNativeWithSwitchIds_revert_zero_zero", - "lowerStmtsNativeWithSwitchIds_singleton_switch_revert_default_eq", - "lowerStmtsNativeWithSwitchIds_singleton_switch_revert_default_eq_sourceLowered", - "buildSwitch_noFallback_noReceive_lowered_inner_sourceLowered", - "buildSwitch_noFallback_noReceive_lowered_inner_find?_some_of_find_function", - "buildSwitch_noFallback_noReceive_lowered_inner_find?_none_of_find_function", - "same explicit fuel", - "default runtime fuel", - "retargeting evidence remains isolated", - "not yet proved", - "`yulCodegen_preserves_semantics_evmYulLeanBackend`", - "`yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle`", - "`yulCodegen_preserves_semantics_via_reference_oracle`", - "not yet a native source-of-truth Layer 3 proof", - "#1741", - "#1738", - "#1742", - "`blockTimestamp`", - "mapping-struct", - "signature-based identity model", - "`YulTransaction.chainId` must match", - "EvmYul.chainId", - "`chainid()` and `blobbasefee()` now fail closed on the selected native runtime path", - "`selfbalance` also fails closed on the selected native runtime path", - "EvmYul.MIN_BASE_FEE_PER_BLOB_GAS", - "`initialState_unbridgedEnvironmentDefaults`", - "remaining success-path blocker is the selected user-body result boundary", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - "generic native execution proof for", - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "lowered selected `fn.body` at dispatcher fuel to `execIRFunction`", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - "`compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher`", - "discharges the lowered native runtime witness internally", - "public theorem no longer exposes full `DispatchGuardsSafe`", - "Legacy premise-taking `compile_preserves_native_evmYulLean_*`", - "wrappers are file-local", - "public `compile_preserves_native_evmYulLean_*` surface is limited", - "`SupportedSpec` carries the selected function calldata-threshold inventory", - "generatedFunctionCalldataThreshold_of_compile_ok_supported", - "transports that inventory across `compile`", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mapping", - "mapping-helper straight-body preservation path", - "NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_bridgedStraightStmts", - "no-mapping helper-free straight-body preservation bridge", - "NativeMappingFreeBridgedExpr", - "NativeMappingFreePreservableStraightStmt", - "NativeExprPreservesWord_lowerExprNative_of_mappingFreeBridgedExpr", - "NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_mappingFreePreservableStraightStmts", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_mappingFreePreservableStraightStmts", - "NativeMappingFreeSideConditionForBridgedStraightStmt", - "NativeMappingFreePreservableStraightStmts.of_bridgedStraightStmts", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree", - "`nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree`", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.selected_body_closure_of_compile_ok_supported", - "selected native-body lowering success", - "without claiming native execution semantics", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.selected_body_artifacts_of_compile_ok_supported", - "combines those lowered artifacts with the selected-body closure facts", - "selectedUserBodyClosureAndMatchedFresh_of_compile_ok_supported_switchFresh", - "recovers matched-flag freshness for the actual lowered user body", - "before the selected-body preservation callback loses the current", - "widen the preservation callback to carry", - "nativeGeneratedSelectorHitBodyPreservesMatched_mapping_of_switchFresh", - "NativeGeneratedSelectorHitSuccessBridge.of_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - "mapping-specific straight-body side conditions private", - "smaller per-case lowering freshness premise", - "nativeGeneratedSwitchTempsFreshForNativeBodies_of_case_body_fresh", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree_caseFresh", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_caseFresh", - "remaining freshness work is to derive that per-case premise", - "singleton-`leave` base case", - "execIRStmts_single_leave_succ_succ", - "exec_block_leave_ok_add_ten", - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body", - "native `leave` exits through a revivable checkpoint", - "singleton-`stop` base case", - "execIRFunction_single_stop", - "exec_block_stop_halt_add_ten", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_stop_body", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body", - "literal external returns", - "execIRFunction_mstore0_lit_return32", - "exec_lowerExprNative_mstore_lit_lit_ok_fuel", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_lit_return32", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_lit_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_lit_return32", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_lit_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_lit_return32", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_sload0_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_sload0_return32", - "execIRFunction_oneParam_store0_value_stop", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_oneParam_store0_value_stop", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_oneParam_store0_value_stop", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_oneParam_store0_value_stop", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_oneParam_store0_value_stop", - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher_source_oneParam_store0_value_stop", - "Single-argument external returns", - "execIRFunction_mstore0_calldataload4_return32_of_args_cons", - "exec_lowerExprNative_mstore_lit_calldataload_lit_ok_fuel", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_calldataload4_return32", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_calldataload4_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload4_return32", - "reusable aligned-calldata return seams", - "execIRFunction_mstore0_calldataload_aligned_return32", - "initialState_calldataload_aligned_arg_word", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload_aligned_return32", - "4 + 32 * idx < 2^64", - "remaining normal-return blocker is the generic body-shape discovery path", - "supply the mapping-free straight-body predicate automatically", -) - -FORBIDDEN_SNIPPETS = ( - "native EVMYulLean is the authoritative semantic target today", - "native EVMYulLean is now the authoritative semantic target", - "public theorem targets `interpretIRRuntimeNative`", - "public theorem target is `interpretIRRuntimeNative`", - "custom Yul interpreter is only a regression oracle", -) - - -def normalize_ws(text: str) -> str: - return " ".join(text.split()) - - -def contains_required_lean_decl(normalized_text: str, required: str) -> bool: - """Return whether a normalized Lean file contains the exact declaration.""" - - parts = required.split(maxsplit=1) - if len(parts) != 2 or parts[0] not in {"def", "theorem"}: - return required in normalized_text - keyword, name = parts - pattern = ( - r"(?:^| )(?:(?:private|protected)\s+)?" - + re.escape(keyword) - + r"\s+" - + re.escape(name) - + r"(?![A-Za-z0-9_'.])" - ) - return re.search(pattern, normalized_text) is not None - - -def theorem_signature(text: str, theorem_name: str) -> str: - """Return the theorem statement through its `:=` proof delimiter.""" - - match = re.search( - r"^\s*(?:private\s+)?theorem\s+" + re.escape(theorem_name) + r"\b", - text, - re.MULTILINE, - ) - if match is None: - return "" - proof_start = text.find(":=", match.start()) - if proof_start < 0: - return text[match.start() :] - return text[match.start() : proof_start] - - -def public_theorem_signatures(text: str) -> list[tuple[str, str]]: - """Return public theorem names with their statement through the proof delimiter.""" - - signatures: list[tuple[str, str]] = [] - pattern = re.compile( - r"(?m)^[ \t]*(?!private\b)(?!protected\b)theorem\s+" - r"(?P[A-Za-z0-9_'.]+)\b" - ) - for match in pattern.finditer(text): - proof_start = text.find(":=", match.start()) - if proof_start < 0: - signature = text[match.start() :] - else: - signature = text[match.start() : proof_start] - signatures.append((match.group("name"), signature)) - return signatures - - -def check_doc(text: str) -> list[str]: - normalized = normalize_ws(text) - errors: list[str] = [] - - for snippet in REQUIRED_SNIPPETS: - if normalize_ws(snippet) not in normalized: - errors.append( - f"{DOC.relative_to(ROOT)} is missing required native-transition status text: `{snippet}`" - ) - - normalized_lower = normalized.lower() - for snippet in FORBIDDEN_SNIPPETS: - if normalize_ws(snippet).lower() in normalized_lower: - errors.append( - f"{DOC.relative_to(ROOT)} overstates the current native-transition status: `{snippet}`" - ) - - if "#1741" in normalized: - issue_1741 = normalized.index("#1741") - issue_1738 = normalized.find("#1738", issue_1741) - issue_1742 = normalized.find("#1742", issue_1738 if issue_1738 >= 0 else issue_1741) - if issue_1738 < 0 or issue_1742 < 0: - errors.append( - f"{DOC.relative_to(ROOT)} must list blockers #1741, #1738, and #1742 together" - ) - - return errors - - -def check_definition_of_done_doc(text: str) -> list[str]: - """Keep the definition-of-done baseline synchronized with current names.""" - - normalized = normalize_ws(text) - errors: list[str] = [] - - for required in ( - "interpretYulRuntimeWithBackend .evmYulLean", - "yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle", - "Native.interpretIRRuntimeNative", - "EvmYul.Yul.callDispatcher", - ): - if normalize_ws(required) not in normalized: - errors.append( - f"{DOD_DOC.relative_to(ROOT)} is missing current native-transition " - f"definition-of-done text: `{required}`" - ) - - for forbidden in ( - "interpretYulRuntimeEvmYulLeanFuelWrapperDefaultFuel", - "interpretYulRuntimeEvmYulLeanFuelWrapper", - "evmYulLeanFuelWrapperDefaultFuel", - ): - if forbidden in normalized: - errors.append( - f"{DOD_DOC.relative_to(ROOT)} must not mention removed " - f"EVMYulLean fuel-wrapper surface `{forbidden}`" - ) - - return errors - - -def check_public_theorem_target( - end_to_end_text: str, native_harness_text: str, retarget_text: str -) -> list[str]: - """Pin the current transition boundary after EndToEnd wrapper removal. - - Public EndToEnd correctness targets native dispatcher execution. The old - backend-parameterized interpreter lemmas remain isolated in the lower - retargeting module while generated native direct-match coverage is widened. - """ - - errors: list[str] = [] - normalized_end_to_end = normalize_ws(end_to_end_text) - normalized_native_harness = normalize_ws(native_harness_text) - normalized_retarget = normalize_ws(retarget_text) - - if "interpretYulRuntimeWithBackend .evmYulLean" in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not mention the legacy " - "`interpretYulRuntimeWithBackend .evmYulLean` transition target; " - "keep that evidence isolated in EvmYulLeanRetarget.lean" - ) - - if "evalBuiltinCall" in end_to_end_text: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not directly mention legacy " - "builtin-dispatch wrapper `evalBuiltinCall`; keep those notes and " - "dependencies below the public EndToEnd surface" - ) - - for theorem_name, signature in public_theorem_signatures(end_to_end_text): - for forbidden_lowering_obligation in ( - "hLowerRuntime", - "hLowerDispatcher", - "hLower", - ): - if re.search(r"\b" + re.escape(forbidden_lowering_obligation) + r"\b", signature): - errors.append( - "Compiler/Proofs/EndToEnd.lean public theorem " - f"`{theorem_name}` must not expose native lowering witness " - f"obligation `{forbidden_lowering_obligation}`" - ) - - for required_native_surface in ( - "def nativeResultsMatch", - "def nativeResultsMatchOn", - "theorem validateNativeRuntimeEnvironment_ofIR_representableEnvironment", - "theorem validateNativeRuntimeEnvironment_ofIR_globalDefaults", - "def nativeMappingSlotFunctionDefinition", - "theorem lowerFunctionDefinitionNativeWithReserved_mappingSlotFuncAt_zero", - "theorem lowerFunctionDefinitionNativeWithReserved_mappingSlotFuncAt_zero_body", - "theorem lowerRuntimeContractNative_emitYul_mapping_noInternals_noFallback_noReceive_reserved", - "theorem lowerRuntimeContractNative_emitYul_mapping_ok_dispatcher_reserved", - ): - if not contains_required_lean_decl(normalized_native_harness, required_native_surface): - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean " - "must own the native theorem/result surface " - f"`{required_native_surface}` until the generated-fragment " - "native bridge is discharged" - ) - - for required_end_to_end_native_surface in ( - "def nativeIRRuntimeMatchesIR", - "def nativeDispatcherExecMatchesIRPositive", - "theorem nativeIRRuntimeMatchesIR_of_generated_lowered_dispatcherExec_positive_match", - "theorem nativeDispatcherExecMatchesIRPositive_of_project_eq_match", - "theorem nativeIRRuntimeMatchesIR_of_generated_lowered_dispatcherExec_project_eq_match", - "theorem nativeDispatcherExecMatchesIRPositive_of_exec_yulHalt_project_eq_match", - "theorem nativeDispatcherExecMatchesIRPositive_of_exec_error_project_eq_match", - ): - if not contains_required_lean_decl( - normalized_end_to_end, required_end_to_end_native_surface - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must own the native-vs-IR " - "comparison surface " - f"`{required_end_to_end_native_surface}` after the native " - "harness was split away from the full IR interpreter" - ) - - for required_native_seam in ( - "def nativeGeneratedCallDispatcherResultOf", - "def nativeGeneratedCallDispatcherMatchesIROn", - "theorem compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_positive_match", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_positive_body_closure", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_positive_body_closure_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_positive_body_closure_ofIR_globalDefaults", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_project_eq_match", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_project_body_closure", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_project_body_closure_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_dispatcherExec_project_body_closure_ofIR_globalDefaults", - "theorem generatedRuntimeNativeFragment_of_compile_ok_supported_safe", - "theorem validateGeneratedRuntimeNativeFragment_of_compile_ok_supported_safe", - "theorem generatedRuntimeSelectedFunctionBodyBridged_of_compile_ok_supported", - "theorem lowerStmtsNativeWithSwitchIds_selectedFunctionBody_exists_of_compile_ok_supported", - "theorem selectedFunctionBodyBridgedAndLowered_of_compile_ok_supported", - "theorem nativeGeneratedSelectorHitSuccessUserBodyLoweredArtifacts_exists_of_compile_ok_supported", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_exists", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_noMapping", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_noMapping_ok_dispatcher", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_mapping_reserved", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_mapping_ok_dispatcher_reserved", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_noMapping", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_globalDefaults", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_noMapping", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_globalDefaults", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_mapping_reserved", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_mapping_reserved", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_environment", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_runtime_dispatcherStmts_positive_body_closure_noMapping", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_runtime_dispatcherStmts_project_body_closure_noMapping", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_runtime_dispatcherStmts_positive_body_closure_mapping_reserved", - "theorem nativeIRRuntimeMatchesIR_of_compiled_generated_lowered_runtime_dispatcherStmts_project_body_closure_mapping_reserved", - "theorem layer3_contract_preserves_semantics_native_of_generated_dispatcherExec_positive_match", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherExec_positive_external_bodies_match", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherExec_positive_body_closure", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherExec_project_external_bodies_match", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherExec_project_body_closure", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_environment", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_globalDefaults", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_environment", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_globalDefaults", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_environment", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_environment", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_lowered_runtime_dispatcherStmts_positive_body_closure_noMapping", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_lowered_runtime_dispatcherStmts_project_body_closure_noMapping", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_lowered_runtime_dispatcherStmts_positive_body_closure_mapping_reserved", - "theorem layer3_contract_preserves_semantics_native_of_compiled_generated_lowered_runtime_dispatcherStmts_project_body_closure_mapping_reserved", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive_external_bodies_match", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive_match", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive_body_closure", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive_body_closure_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive_body_closure_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_positive_body_closure_noMapping_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_project_external_bodies_match", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_project_match", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_project_body_closure", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_project_body_closure_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_project_body_closure_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_project_body_closure_noMapping_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_noMapping", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_noMapping", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_mapping_reserved", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_mapping_reserved", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_noMapping_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_noMapping_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_noMapping_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_noMapping_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_positive_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_environment", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_lowered_runtime_dispatcherStmts_project_body_closure_mapping_reserved_ofIR_globalDefaults", - "theorem simpleStorageNativeCallDispatcherMatchBridge_of_per_case", - "theorem simpleStorageNativeRetrieveHitMatchBridge_proved", - "theorem simpleStorageNativeStoreHitMatchBridge_proved", - "theorem simpleStorageNativeSelectorMissMatchBridge_proved", - "theorem nativeGeneratedCallDispatcherResult_selector_miss_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_nonpayable_nonzero_revert_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_args_short_revert_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_error_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "theorem compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher", - "theorem DispatchGuardsSafe.of_value_safe_of_threshold", - "theorem compiledFunctionCalldataThreshold_of_forall₂", - "theorem generatedFunctionCalldataThreshold_of_compile_ok_supported", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_store0_calldataload4_stop", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_sload0_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_stop_body", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_lit_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_lit_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_lit_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_sload0_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_sload0_return32", - "theorem execIRFunction_oneParam_store0_value_stop", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_oneParam_store0_value_stop", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_oneParam_store0_value_stop", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_oneParam_store0_value_stop", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_oneParam_store0_value_stop", - "theorem compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher_source_oneParam_store0_value_stop", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_calldataload4_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_calldataload4_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload4_return32", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload_aligned_return32", - "def NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - "def NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel", - "def NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation", - "theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_halt", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_preserves", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_nativeStmtsWriteNames_not_mem", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mapping", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_mappingFreePreservableStraightStmts", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_empty_body", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.selected_body_closure_of_compile_ok_supported", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.selected_body_artifacts_of_compile_ok_supported", - "theorem selectedUserBodyClosureAndMatchedFresh_of_compile_ok_supported_switchFresh", - "theorem nativeGeneratedSelectorHitBodyPreservesMatched_mapping_of_switchFresh", - "theorem NativeGeneratedSelectorHitSuccessBridge.of_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - "theorem nativeGeneratedSwitchTempsFreshForNativeBodies_of_case_body_fresh", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree_caseFresh", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_caseFresh", - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_exec_bridge", - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_exec_bridge", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_forall_stmt_write_not_mem", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_nativeStmtsWriteNames_not_mem", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_mappingFreePreservableStraightStmts", - "theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves", - "theorem NativeGeneratedSelectorHitBridge.of_success_predicate_and_generated_guard_reverts_threshold", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_success_bridge_threshold", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree", - "theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_result_threshold", - ): - if not contains_required_lean_decl(normalized_end_to_end, required_native_seam): - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the native theorem seam " - f"`{required_native_seam}` explicit until the generated-fragment " - "native bridge is discharged" - ) - - unsafe_leave_preservation_patterns = ( - r"(?m)^[ \t]*(?:private\s+)?theorem\s+NativeStmtPreservesWord_leave\b", - r"(?m)^[ \t]*(?:private\s+)?theorem\s+NativeBlockPreservesWord_leave\b", - r"(?m)^[ \t]*(?:private\s+)?theorem\s+NativeBlockPreservesWord_single_leave\b", - ) - for pattern in unsafe_leave_preservation_patterns: - if re.search(pattern, native_harness_text) or re.search(pattern, end_to_end_text): - errors.append( - "The native transition must not close the selected-body result " - "bridge by asserting matched-flag preservation for raw `leave`: " - "`leave` exits through a revivable checkpoint, so preserve the " - "exec-only bridge until a checkpoint-aware dispatcher invariant " - "is proved." - ) - - private_selected_hit_seams = ( - ("def", "NativeGeneratedSelectorHitBridge"), - ("def", "NativeGeneratedSelectorHitBodyBridge"), - ("def", "NativeGeneratedSelectorHitUserBodyBridge"), - ("def", "NativeGeneratedSelectorHitUserBodyBridgeAtFuel"), - ("def", "NativeGeneratedSelectorHitUserBodyBridgeAtFuelRestored"), - ("def", "NativeGeneratedSelectorHitUserBodyBridgeAtFuelRevived"), - ("def", "NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived"), - ("def", "NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived"), - ("def", "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived"), - ("def", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel"), - ("def", "NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel"), - ("def", "NativeGeneratedSelectorHitArtifactBridge"), - ("def", "NativeGeneratedSelectorHitDispatcherContinuation"), - ("def", "NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_halt"), - ( - "theorem", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_preserves", - ), - ( - "theorem", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_nativeStmtsWriteNames_not_mem", - ), - ( - "theorem", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mapping", - ), - ( - "theorem", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree", - ), - ( - "theorem", - "nativeGeneratedSelectorHitBodyPreservesMatched_mapping_of_switchFresh", - ), - ( - "theorem", - "NativeGeneratedSelectorHitSuccessBridge.of_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_switchFresh", - ), - ( - "theorem", - "nativeGeneratedSwitchTempsFreshForNativeBodies_of_case_body_fresh", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree_caseFresh", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mapping_caseFresh", - ), - ( - "theorem", - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body", - ), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_stop_body"), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_lit_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_lit_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_lit_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_lit_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_sload0_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_sload0_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_oneParam_store0_value_stop"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_oneParam_store0_value_stop"), - ("theorem", "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_calldataload4_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_calldataload4_return32"), - ("theorem", "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_empty_body"), - ("theorem", "NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_exec_bridge"), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only", - ), - ("theorem", "NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_exec_bridge"), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_forall_stmt_write_not_mem", - ), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_nativeStmtsWriteNames_not_mem", - ), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves", - ), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyBridgeAtFuelRevived.of_execIRFunction", - ), - ("theorem", "NativeGeneratedSelectorHitUserBodyBridgeAtFuelRestored.of_revived"), - ( - "theorem", - "NativeGeneratedSelectorHitUserBodyBridgeAtFuelRestored.of_execIRFunction", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_lit_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_lit_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_lit_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_sload0_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_sload0_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_oneParam_store0_value_stop", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_oneParam_store0_value_stop", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload4_return32", - ), - ( - "theorem", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload_aligned_return32", - ), - ( - "theorem", - "NativeGeneratedSelectorHitArtifactBridge.of_body_bridge_and_continuation", - ), - ( - "theorem", - "NativeGeneratedSelectorHitArtifactBridge.of_user_body_bridge_and_continuation", - ), - ( - "theorem", - "NativeGeneratedSelectorHitArtifactBridge.of_user_body_bridge_atFuel_and_continuation", - ), - ("theorem", "NativeGeneratedSelectorHitBridge.of_artifact_bridge"), - ( - "theorem", - "NativeGeneratedSelectorHitBridge.of_success_bridge_and_generated_guard_reverts", - ), - ( - "theorem", - "NativeGeneratedSelectorHitBridge.of_success_predicate_and_generated_guard_reverts", - ), - ( - "theorem", - "NativeGeneratedSelectorHitBridge.of_success_predicate_and_generated_guard_reverts_threshold", - ), - ( - "theorem", - "NativeGeneratedSelectorHitSuccessBridge.of_user_body_exec_bridge_atFuel_revived_and_continuation", - ), - ) - for kind, name in private_selected_hit_seams: - private_decl = f"private {kind} {name}" - if private_decl not in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the selected " - "selector-hit bridge seam private: " - f"`{private_decl}`" - ) - public_decl_pattern = re.compile( - rf"(?m)^[ \t]*(?!private\b){kind}\s+{re.escape(name)}\b" - ) - if public_decl_pattern.search(end_to_end_text): - errors.append( - "Compiler/Proofs/EndToEnd.lean must not expose the selected " - "selector-hit bridge seam publicly: " - f"`{kind} {name}`" - ) - - exact_generated_theorem = "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported" - source_generated_theorem = ( - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher" - ) - public_halt_bridge_pattern = re.compile( - r"(?m)^[ \t]*def\s+NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel\b" - ) - private_halt_bridge_pattern = re.compile( - r"(?m)^[ \t]*private\s+def\s+NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel\b" - ) - public_success_bridge_pattern = re.compile( - r"(?m)^[ \t]*def\s+NativeGeneratedSelectorHitSuccessBridge\b" - ) - private_success_bridge_pattern = re.compile( - r"(?m)^[ \t]*private\s+def\s+NativeGeneratedSelectorHitSuccessBridge\b" - ) - if public_halt_bridge_pattern.search(end_to_end_text) is None: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the public exact " - "generated callDispatcher selected user-body halt bridge publicly nameable: " - "`def NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel`" - ) - if private_halt_bridge_pattern.search(end_to_end_text): - errors.append( - "Compiler/Proofs/EndToEnd.lean must not make the public exact " - "generated callDispatcher selected user-body halt bridge private while the public " - "theorem exposes it: " - "`NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel`" - ) - if public_success_bridge_pattern.search(end_to_end_text) is None: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the remaining " - "success-case selector-hit bridge publicly nameable: " - "`def NativeGeneratedSelectorHitSuccessBridge`" - ) - if private_success_bridge_pattern.search(end_to_end_text): - errors.append( - "Compiler/Proofs/EndToEnd.lean must not make the remaining " - "success-case selector-hit bridge private while private adapters " - "still close over it: " - "`NativeGeneratedSelectorHitSuccessBridge`" - ) - - exact_generated_signature = theorem_signature(end_to_end_text, exact_generated_theorem) - if not exact_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the public exact generated " - f"callDispatcher theorem `{exact_generated_theorem}` explicit" - ) - else: - for required_exact_signature_target in ( - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - "nativeGeneratedCallDispatcherResultOf", - ): - if required_exact_signature_target not in exact_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public exact generated " - f"callDispatcher theorem `{exact_generated_theorem}` must " - f"expose `{required_exact_signature_target}` in its signature" - ) - for forbidden_exact_signature_target in ( - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel", - "NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation", - "DispatchGuardsSafe", - "selectorDispatchedFunctions spec", - "lowerRuntimeContractNative", - ): - if forbidden_exact_signature_target in exact_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public exact generated " - f"callDispatcher theorem `{exact_generated_theorem}` must " - "hide the selected user-body adapter or full guard detail " - f"`{forbidden_exact_signature_target}` behind " - "`NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel`" - ) - if "interpretIRRuntimeNative" in exact_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public exact generated " - f"callDispatcher theorem `{exact_generated_theorem}` must not " - "expose `interpretIRRuntimeNative` as its public result target" - ) - - source_generated_signature = theorem_signature(end_to_end_text, source_generated_theorem) - if not source_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the public source-level " - f"generated callDispatcher theorem `{source_generated_theorem}` explicit" - ) - else: - for required_source_signature_target in ( - "sourceResultMatchesNativeOn", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - "interpretIRRuntimeNative", - ): - if required_source_signature_target not in source_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public source-level generated " - f"callDispatcher theorem `{source_generated_theorem}` must " - f"expose `{required_source_signature_target}` in its signature" - ) - for forbidden_source_signature_target in ( - "DispatchGuardsSafe", - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "lowerRuntimeContractNative", - "nativeGeneratedCallDispatcherResultOf", - ): - if forbidden_source_signature_target in source_generated_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public source-level generated " - f"callDispatcher theorem `{source_generated_theorem}` must " - "hide the selected user-body adapter or older runtime target " - f"`{forbidden_source_signature_target}`" - ) - - allowed_public_compile_preserves = { - source_generated_theorem, - } - public_compile_preserves_pattern = re.compile( - r"(?m)^[ \t]*(?!private\b)theorem\s+" - r"(compile_preserves_native_evmYulLean_[A-Za-z0-9_']+)\b" - ) - for public_match in public_compile_preserves_pattern.finditer(end_to_end_text): - public_name = public_match.group(1) - if public_name not in allowed_public_compile_preserves: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep legacy " - "`compile_preserves_native_evmYulLean_*` wrappers private; " - f"unexpected public theorem `{public_name}`" - ) - - deprecated_exact_wrappers = ( - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_success_only_atFuel_revived_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_body_halt_bridge_atFuel", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_body_bridge_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_bridge_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_bridge_atFuel_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_bridge_atFuel_restored_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_bridge_atFuel_revived_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_atFuel_revived_and_continuation", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_success_only_atFuel_revived", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_empty_selected_body", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_preserves", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_result", - ) - deprecated_exact_pattern = re.compile( - r"attribute\s+\[deprecated\s+" - + re.escape(exact_generated_theorem) - + r"\s+\(since\s*:=\s*\"2026-05-07\"\)\]\s+" - + r"(?P(?:\s*(?:" - + "|".join( - re.escape(wrapper) - for wrapper in sorted(deprecated_exact_wrappers, key=len, reverse=True) - ) - + r"))+)", - re.MULTILINE, - ) - deprecated_exact_match = deprecated_exact_pattern.search(end_to_end_text) - if deprecated_exact_match is None: - errors.append( - "Compiler/Proofs/EndToEnd.lean exact generated callDispatcher " - "compatibility wrappers must be deprecated in favor of " - f"`{exact_generated_theorem}`" - ) - else: - wrapper_block = deprecated_exact_match.group("wrapper_block") - for wrapper in deprecated_exact_wrappers: - if wrapper not in wrapper_block: - errors.append( - "Compiler/Proofs/EndToEnd.lean exact generated " - f"callDispatcher compatibility wrapper `{wrapper}` must " - f"be included in the deprecation block for `{exact_generated_theorem}`" - ) - - deprecated_interpret_wrappers = ( - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_ofIR_environment", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_ofIR_globalDefaults", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_noMapping_dispatcher_ofIR_environment", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_noMapping_dispatcher_ofIR_globalDefaults", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_mapping_dispatcher_ofIR_environment", - "compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_mapping_dispatcher_ofIR_globalDefaults", - ) - deprecated_interpret_pattern = re.compile( - r"attribute\s+\[deprecated\s+" - r"compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match" - r"\s+\(since\s*:=\s*\"2026-05-07\"\)\]\s+" - + r"(?P(?:\s*(?:" - + "|".join( - re.escape(wrapper) - for wrapper in sorted(deprecated_interpret_wrappers, key=len, reverse=True) - ) - + r"))+)", - re.MULTILINE, - ) - deprecated_interpret_match = deprecated_interpret_pattern.search(end_to_end_text) - if deprecated_interpret_match is None: - errors.append( - "Compiler/Proofs/EndToEnd.lean interpretIRRuntimeNative " - "compatibility wrappers must be deprecated in favor of " - "`compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match`" - ) - else: - wrapper_block = deprecated_interpret_match.group("wrapper_block") - for wrapper in deprecated_interpret_wrappers: - if wrapper not in wrapper_block: - errors.append( - "Compiler/Proofs/EndToEnd.lean interpretIRRuntimeNative " - f"compatibility wrapper `{wrapper}` must be included in " - "the deprecation block for " - "`compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match`" - ) - - deprecated_interpret_eq_wrappers = ( - "nativeGeneratedCallDispatcherResultOf_eq_interpretIRRuntimeNative_of_lowerRuntimeContractNative_supported", - "nativeGeneratedCallDispatcherResultOf_eq_interpretIRRuntimeNative_of_lowerRuntimeContractNative_supported_except_mapping_writes_stmt_safety", - ) - deprecated_interpret_eq_pattern = re.compile( - r"attribute\s+\[deprecated\s+nativeGeneratedCallDispatcherResultOf" - r"\s+\(since\s*:=\s*\"2026-05-07\"\)\]\s+" - + r"(?P(?:\s*(?:" - + "|".join( - re.escape(wrapper) - for wrapper in sorted(deprecated_interpret_eq_wrappers, key=len, reverse=True) - ) - + r"))+)", - re.MULTILINE, - ) - deprecated_interpret_eq_match = deprecated_interpret_eq_pattern.search(end_to_end_text) - if deprecated_interpret_eq_match is None: - errors.append( - "Compiler/Proofs/EndToEnd.lean interpretIRRuntimeNative equality " - "wrappers must be deprecated in favor of " - "`nativeGeneratedCallDispatcherResultOf`" - ) - else: - wrapper_block = deprecated_interpret_eq_match.group("wrapper_block") - for wrapper in deprecated_interpret_eq_wrappers: - if wrapper not in wrapper_block: - errors.append( - "Compiler/Proofs/EndToEnd.lean interpretIRRuntimeNative " - f"equality wrapper `{wrapper}` must be included in the " - "deprecation block for `nativeGeneratedCallDispatcherResultOf`" - ) - - for public_call_dispatcher_theorem in ( - "compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - ): - signature = theorem_signature(end_to_end_text, public_call_dispatcher_theorem) - if "nativeGeneratedCallDispatcherResultOf" not in signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public generated " - f"`{public_call_dispatcher_theorem}` theorem must conclude " - "the direct projected `EvmYul.Yul.callDispatcher` result via " - "`nativeGeneratedCallDispatcherResultOf`, not the thin runtime adapter" - ) - if "interpretIRRuntimeNative" in signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public generated " - f"`{public_call_dispatcher_theorem}` theorem must not expose " - "`interpretIRRuntimeNative` as its public result target" - ) - deprecated_pattern = re.compile( - r"@\[deprecated\s+" - r"compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match" - r"\s+\(since\s*:=\s*\"2026-05-07\"\)\]\s*" - r"(?:private\s+)?theorem\s+" + re.escape(public_call_dispatcher_theorem) + r"\b", - re.MULTILINE, - ) - if not deprecated_pattern.search(end_to_end_text): - errors.append( - "Compiler/Proofs/EndToEnd.lean generated callDispatcher " - f"compatibility wrapper `{public_call_dispatcher_theorem}` " - "must be marked deprecated in favor of " - "`compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match`" - ) - - if re.search( - r"^\s*theorem\s+compile_preserves_native_evmYulLean_of_nativeResultsMatchOn\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the generic " - "`compile_preserves_native_evmYulLean_of_nativeResultsMatchOn` " - "adapter theorem file-local; public compiler correctness should " - "target explicit native result values" - ) - - for dispatcher_exec_public_seam in ( - "def nativeGeneratedDispatcherExecMatchesIROn", - "theorem compile_preserves_native_evmYulLean_of_generated_dispatcherExec_match", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_dispatcher_noMapping", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_dispatcher_mapping", - ): - if re.search( - r"^\s*" + re.escape(dispatcher_exec_public_seam) + r"\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep dispatcher-exec " - "compatibility seams private; public generated correctness " - "must expose `EvmYul.Yul.callDispatcher` rather than " - f"`{dispatcher_exec_public_seam}`" - ) - - for removed_transition_seam in ( - "layer3_contract_preserves_semantics_evmYulLeanBackend_with_function_bridge", - "layer3_contract_preserves_semantics_evmYulLeanBackend", - "layer3_contract_preserves_semantics_native_of_evmYulLean_bridge", - "layers2_3_ir_matches_yul_evmYulLeanBackend_with_function_bridge", - "layers2_3_ir_matches_yul_evmYulLeanBackend", - "layers2_3_ir_matches_native_evmYulLean_of_evmYulLean_bridge", - "compile_preserves_native_evmYulLean_of_generated_dispatcherExec_match", - "compile_preserves_native_evmYulLean_of_generated_callDispatcher_match", - "compile_preserves_native_evmYulLean_of_lowered_generated_dispatcher_noMapping", - "compile_preserves_native_evmYulLean_of_lowered_generated_dispatcher_mapping", - "simpleStorage_endToEnd_evmYulLeanBackend", - ): - if re.search( - r"^\s*(?:private\s+)?theorem\s+" - + re.escape(removed_transition_seam) - + r"\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must not define removed " - f"backend-wrapper transition lemma `{removed_transition_seam}`" - ) - - for private_native_identity_seam in ( - "layer3_contract_preserves_semantics_native", - "layers2_3_ir_matches_native_evmYulLean", - ): - if re.search( - r"^\s*theorem\s+" - + re.escape(private_native_identity_seam) - + r"\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must not export arbitrary-fuel " - f"native identity seam `{private_native_identity_seam}`; keep " - "the public surface on generated-dispatcher native wrappers" - ) - - for removed_fuel_wrapper_seam in ( - "def yulResultsAgreeOn", - "def nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper", - "def nativeCallDispatcherAgreesWithEvmYulLeanFuelWrapper", - "def nativeDispatcherBlockAgreesWithEvmYulLeanFuelWrapper", - "def nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper", - "def nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive", - "theorem nativeResultsMatchOn_ok_of_resultsMatch_of_yulResultsAgreeOn", - "theorem yulResultsAgreeOn_of_resultsMatch_of_nativeResultsMatchOn", - "theorem nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper_of_ok_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive_of_exec_ok_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive_of_exec_yulHalt_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive_of_exec_yulHalt_project_eq_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive_of_exec_error_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapperPositive_of_exec_error_project_eq_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper_of_positive", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper_of_exec_ok_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper_of_exec_yulHalt_agree", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper_of_exec_error_agree", - "theorem nativeDispatcherBlockAgreesWithEvmYulLeanFuelWrapper_of_exec_agree", - "theorem nativeCallDispatcherAgreesWithEvmYulLeanFuelWrapper_of_dispatcherBlock_agree", - "theorem nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper_of_lowered_callDispatcher_agree", - "theorem nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper_of_lowered_dispatcherExec_positive_agree", - "theorem nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper_of_generated_lowered_callDispatcher_agree", - "theorem nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper_of_generated_lowered_dispatcherExec_positive_agree", - ): - if removed_fuel_wrapper_seam in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the removed " - "native fuel-wrapper agreement seam " - f"`{removed_fuel_wrapper_seam.removeprefix('theorem ').removeprefix('def ')}`" - ) - - for forbidden_ir_runtime_alias in ( - "def nativeIRRuntimeAgreesWithEvmYulLean ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_ok_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_nativeIRRuntimeMatchesIR ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_ok_nativeResultsMatchOn ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_lowered_callDispatcher_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_lowered_dispatcherExec_positive_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_generated_lowered_callDispatcher_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_generated_lowered_dispatcherExec_positive_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_compiled_generated_lowered_dispatcherExec_positive_agree ", - "theorem nativeIRRuntimeAgreesWithEvmYulLean_of_compiled_generated_lowered_dispatcherExec_positive_body_closure ", - ): - if forbidden_ir_runtime_alias in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the hidden " - "native IR-runtime fuel-wrapper alias " - f"`{forbidden_ir_runtime_alias.strip()}`" - ) - - for forbidden_dispatcher_alias in ( - "def nativeCallDispatcherAgreesWithEvmYulLean ", - "def nativeDispatcherBlockAgreesWithEvmYulLean ", - "def nativeDispatcherExecAgreesWithEvmYulLean ", - "def nativeDispatcherExecAgreesWithEvmYulLeanPositive ", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanPositive_of_exec_ok_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanPositive_of_exec_yulHalt_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanPositive_of_exec_yulHalt_project_eq_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanPositive_of_exec_error_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLeanPositive_of_exec_error_project_eq_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLean_of_positive ", - "theorem nativeDispatcherExecAgreesWithEvmYulLean_of_exec_ok_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLean_of_exec_yulHalt_agree ", - "theorem nativeDispatcherExecAgreesWithEvmYulLean_of_exec_error_agree ", - "theorem nativeDispatcherBlockAgreesWithEvmYulLean_of_exec_agree ", - "theorem nativeCallDispatcherAgreesWithEvmYulLean_of_dispatcherBlock_agree ", - ): - if forbidden_dispatcher_alias in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the hidden " - "native dispatcher fuel-wrapper alias " - f"`{forbidden_dispatcher_alias.strip()}`" - ) - - for forbidden_positive_alias in ( - "theorem layer3_contract_preserves_semantics_native_of_generated_dispatcherExec_positive ", - "theorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive ", - ): - if forbidden_positive_alias in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the " - "misleading positive dispatcher-exec compatibility alias " - f"`{forbidden_positive_alias.removeprefix('theorem ').strip()}`; " - "use the explicit `_positive_match` theorem name" - ) - - for forbidden_simple_storage_bridge_surface in ( - "def simpleStorageNativeCallDispatcherBridge ", - "def simpleStorageNativeRetrieveHitBridge ", - "def simpleStorageNativeStoreHitBridge ", - "def simpleStorageNativeSelectorMissBridge ", - "theorem simpleStorageNativeRetrieveHitBridge_proved ", - "theorem simpleStorageNativeStoreHitBridge_proved ", - "theorem simpleStorageNativeSelectorMissBridge_proved ", - "theorem simpleStorageNativeCallDispatcherBridge_of_per_case ", - ): - if forbidden_simple_storage_bridge_surface in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the " - "obsolete SimpleStorage fuel-wrapper bridge surface " - f"`{forbidden_simple_storage_bridge_surface.strip()}`" - ) - - for private_simple_storage_scaffold in ( - "simpleStorageNativeDispatcherStmts", - "simpleStorageNativeDispatcherInnerStmts", - "simpleStorageNativeDispatcher_letValue", - "simpleStorageNativeDispatcher_if1Cond", - "simpleStorageNativeDispatcher_if1Body", - "simpleStorageNativeDispatcher_if2Cond", - "simpleStorageNativeDispatcher_if2Body", - "simpleStorageNativeDispatcherFuel", - ): - if re.search( - r"^\s*(?:noncomputable\s+)?def\s+" - + re.escape(private_simple_storage_scaffold) - + r"\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep SimpleStorage native " - "dispatcher proof scaffolding file-local; do not export " - f"`{private_simple_storage_scaffold}`" - ) - - if re.search( - r"^\s*def\s+SourceBodyNativeClosure\b", - end_to_end_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep " - "`SourceBodyNativeClosure` file-local; public callDispatcher " - "theorems should not export body-closure proof scaffolding" - ) - - for forbidden_reference_oracle_seam in ( - "theorem layer3_contract_preserves_semantics_via_reference_oracle ", - "theorem layer3_contract_preserves_semantics_via_reference_oracle_with_function_bridge ", - "theorem layers2_3_ir_matches_yul_via_reference_oracle ", - "theorem simpleStorage_endToEnd_via_reference_oracle ", - ): - if forbidden_reference_oracle_seam in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the " - "legacy Verity-backed public entry point " - f"`{forbidden_reference_oracle_seam.strip()}`" - ) - - for forbidden_public_alias in ( - "theorem layer3_contract_preserves_semantics ", - "theorem simpleStorage_endToEnd ", - ): - if forbidden_public_alias in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce hidden " - "default-fuel public theorem alias " - f"`{forbidden_public_alias.strip()}`" - ) - - simple_storage_native_name = "simpleStorage_endToEnd_native_evmYulLean" - simple_storage_native_signature = theorem_signature( - end_to_end_text, - simple_storage_native_name, - ) - simple_storage_native_marker = f"theorem {simple_storage_native_name} " - simple_storage_native_start = normalized_end_to_end.find(simple_storage_native_marker) - if simple_storage_native_start < 0 or not simple_storage_native_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean must keep the public native " - "`simpleStorage_endToEnd_native_evmYulLean` theorem explicit" - ) - else: - next_theorem = normalized_end_to_end.find( - " theorem ", - simple_storage_native_start + len(simple_storage_native_marker), - ) - simple_storage_native_span = ( - normalized_end_to_end[simple_storage_native_start:] - if next_theorem < 0 - else normalized_end_to_end[simple_storage_native_start:next_theorem] - ) - for required_direct_target in ( - "nativeGeneratedCallDispatcherResultOf", - "simpleStorageNativeCallDispatcherMatchBridge_of_per_case", - ): - if required_direct_target not in simple_storage_native_span: - errors.append( - "Compiler/Proofs/EndToEnd.lean public native SimpleStorage " - "theorem must consume the direct native callDispatcher " - f"target `{required_direct_target}`" - ) - if "nativeGeneratedCallDispatcherResultOf" not in simple_storage_native_signature: - errors.append( - "Compiler/Proofs/EndToEnd.lean public native SimpleStorage " - "theorem signature must target direct projected " - "`nativeGeneratedCallDispatcherResultOf` execution" - ) - for forbidden_compat_target in ( - "interpretIRRuntimeNative", - "simpleStorage_endToEnd_native_evmYulLean_interpretIRRuntimeNative", - "simpleStorage_endToEnd_native_evmYulLean_of_lowered_runtime_dispatcherStmts_match", - "simpleStorage_endToEnd_native_evmYulLean_of_positive_dispatcherExec_bridge", - "simpleStorageNativeCallDispatcherBridge_of_per_case", - ): - if ( - forbidden_compat_target in simple_storage_native_span - or forbidden_compat_target in simple_storage_native_signature - ): - errors.append( - "Compiler/Proofs/EndToEnd.lean public native SimpleStorage " - "theorem must not consume the compatibility dispatcher " - f"bridge `{forbidden_compat_target}`" - ) - - for required_fuel_surface in ( - "private def execYulFuelWithBackend", - "private noncomputable def interpretYulRuntimeWithBackend", - ): - if required_fuel_surface not in normalized_retarget: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanRetarget.lean must keep the backend-parameterized " - f"EVMYulLean interpreter surface `{required_fuel_surface}` " - "explicit but private" - ) - - for public_fuel_surface in ( - "backends_agree_on_bridged_builtins", - "evalYulExprWithBackend_eq_on_bridged", - "evalYulExpr_evmYulLean_eq_on_bridged", - "bridgedExpr_selectorExpr", - "evalYulExprWithBackend_evmYulLean_selectorExpr_semantics", - "execYulFuelWithBackend", - "execYulFuelWithBackend_verity_eq", - "execYulFuelWithBackend_let_eq_on_bridged", - "execYulFuelWithBackend_assign_eq_on_bridged", - "execYulFuelWithBackend_eq_on_bridged_straight_stmts", - "execYulFuelWithBackend_block_eq_on_bridged_straight_stmts", - "execYulFuelWithBackend_if_eq_on_bridged_body", - "execYulFuelWithBackend_switch_eq_on_bridged_cases", - "execYulFuelWithBackend_for_eq_on_bridged_parts", - "execYulFuelWithBackend_eq_on_bridged_target", - "execYulFuelWithBackend_eq_on_bridged_stmt", - "execYulFuelWithBackend_eq_on_bridged_stmts", - "emitYul_runtimeCode_evmYulLean_eq_on_bridged_bodies", - "execYulStmtsWithBackend", - "interpretYulRuntimeWithBackend", - "interpretYulRuntimeWithBackend_verity_eq", - "interpretYulFromIR_evmYulLean_eq_on_bridged_bodies", - ): - if re.search( - r"^\s*(?:noncomputable\s+)?(?:def|theorem)\s+" - + re.escape(public_fuel_surface) - + r"\b", - retarget_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean " - "must keep backend-interpreter transition surface " - f"`{public_fuel_surface}` private" - ) - - for forbidden_fuel_alias in ( - "def interpretYulRuntimeEvmYulLeanFuel ", - "def interpretYulRuntimeEvmYulLean ", - "theorem interpretYulRuntimeEvmYulLean_eq_backend ", - ): - if forbidden_fuel_alias in normalized_retarget: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanRetarget.lean must not reintroduce hidden " - f"EVMYulLean fuel-wrapper alias `{forbidden_fuel_alias.strip()}`" - ) - - forbidden_native_in_end_to_end = ( - "theorem target: interpretRuntimeNative", - "theorem target: EvmYul.Yul.callDispatcher", - ) - for native_target in forbidden_native_in_end_to_end: - if native_target in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean should target the native IR " - "runtime seam, not the lower-level harness implementation " - f"`{native_target.removeprefix('theorem target: ')}`" - ) - - for required_native_entrypoint in ( - "def interpretRuntimeNative", - "def interpretIRRuntimeNative", - "EvmYul.Yul.callDispatcher", - "def generatedRuntimeNativeFragment", - "def validateGeneratedRuntimeNativeFragment", - "unsupportedGeneratedRuntimeNativeFragmentError", - "def generatedRuntimeFunctionNamesUnique", - "def generatedRuntimeDispatcherHasNoFuncDefs", - "def generatedRuntimeFunctionBodiesHaveNoNestedFuncDefs", - "def buildSwitchSourceCases", - "theorem buildSwitchSourceCases_eq_switchCases", - "theorem lowerSwitchCasesNativeWithSwitchIds_find?_some_of_find_function", - "theorem lowerSwitchCasesNativeWithSwitchIds_find?_none_of_find_function", - "theorem lowerSwitchCasesNativeWithSwitchIds_buildSwitch_find?_some_of_find_function", - "theorem lowerSwitchCasesNativeWithSwitchIds_buildSwitch_find?_none_of_find_function", - "theorem lowerRuntimeContractNative_single_stmt_eq_lowerStmtsNative", - "theorem lowerRuntimeContractNative_emitYul_noMapping_ok_dispatcher", - "theorem lowerStmtsNative_single_block_ok_singleton", - "theorem lowerStmtsNative_block_stmts_eq", - "theorem lowerStmtsNativeWithSwitchIds_let_head_eq", - "theorem lowerStmtsNativeWithSwitchIds_if_head_eq", - "theorem lowerStmtsNativeWithSwitchIds_singleton_switch_eq", - "theorem lowerStmtsNativeWithSwitchIds_revert_zero_zero", - "theorem lowerStmtsNativeWithSwitchIds_singleton_switch_revert_default_eq", - "theorem lowerStmtsNativeWithSwitchIds_singleton_switch_revert_default_eq_sourceLowered", - "theorem buildSwitch_noFallback_noReceive_lowered_inner_sourceLowered", - "theorem buildSwitch_noFallback_noReceive_lowered_inner_find?_some_of_find_function", - "theorem buildSwitch_noFallback_noReceive_lowered_inner_find?_none_of_find_function", - "theorem NativeBlockPreservesWord_singleton", - "theorem NativeBlockPreservesWord_of_forall_stmt", - "theorem NativeBlockPreservesWord_of_forall_stmt_write_not_mem", - "theorem NativeStmtPreservesWord_block", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_error_projectResult_eq", - "theorem contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_hit_error_projectResult_eq", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_error_store_projectResult_eq", - "theorem exec_lowerNativeSwitchBlock_selector_find_none_with_revert_default_projectResult_eq", - "theorem contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_none_with_revert_default_projectResult_eq", - "theorem exec_lowerNativeSwitchBlock_selector_find_none_with_revert_default_store_projectResult_eq", - "theorem exec_block_lowerNativeSwitchBlock_revert_default_hasSelectorState_projectResult_eq", - "theorem exec_block_lowerNativeSwitchBlock_selector_find_hit_hasSelectorState_error_projectResult_eq", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_ok_projectResult_eq", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_ok_store_projectResult_eq", - "theorem exec_block_lowerNativeSwitchBlock_selector_find_hit_hasSelectorState_ok_projectResult_eq", - "theorem contractDispatcherExecResult_block_lowerNativeSwitchBlock_selector_find_hit_ok_projectResult_eq", - "theorem NativeStmtPreservesWord_if_of_eval_self", - "theorem NativeStmtPreservesWord_if_of_eval_preserves", - "theorem NativeStmtPreservesWord_if_of_cond_preserves", - "theorem nativeSwitchBranchFold_ok_preserves_word", - "theorem execSwitchCases_ok_branch_preserves_word", - "theorem NativeStmtPreservesWord_switch_of_eval_preserves", - "theorem NativeStmtPreservesWord_switch_of_cond_preserves", - "theorem NativeStmtPreservesWord_switch_of_cond_preserves_and_nativeStmtsWriteNames_not_mem", - "theorem NativeStmtPreservesWord_switch_of_eval_preserves_and_nativeStmtsWriteNames_not_mem", - "theorem NativeStmtPreservesWord_lowerAssignNative_lit_of_ne", - "theorem NativeStmtPreservesWord_lowerAssignNative_hex_of_ne", - "theorem NativeStmtPreservesWord_lowerAssignNative_ident_of_ne", - "theorem NativeStmtPreservesWord_lowerAssignNative_str_of_ne", - "theorem NativeStmtPreservesWord_let_none_of_not_mem", - "theorem NativeStmtPreservesWord_let_var_of_not_mem", - "theorem NativeStmtPreservesWord_let_lit_of_not_mem", - "theorem NativeStmtPreservesWord_let_lowerExprNative_lit_of_not_mem", - "theorem NativeStmtPreservesWord_let_lowerExprNative_hex_of_not_mem", - "theorem NativeStmtPreservesWord_let_lowerExprNative_str_of_not_mem", - "theorem NativeStmtPreservesWord_let_lowerExprNative_ident_of_not_mem", - "theorem NativeStmtPreservesWord_let_prim_of_evalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_let_user_of_evalArgs_call_preserves", - "theorem NativeStmtPreservesWord_let_prim_of_nativeEvalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_let_user_of_nativeEvalArgs_call_preserves", - "theorem NativeStmtPreservesWord_let_lowerExprNative_call_runtimePrimOp_of_evalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_let_lowerExprNative_call_userFunction_of_evalArgs_call_preserves", - "theorem NativeStmtPreservesWord_let_lowerExprNative_call_runtimePrimOp_of_nativeEvalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_let_lowerExprNative_call_userFunction_of_nativeEvalArgs_call_preserves", - "theorem NativeStmtPreservesWord_lowerAssignNative_call_runtimePrimOp_of_evalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_lowerAssignNative_call_userFunction_of_evalArgs_call_preserves", - "theorem NativeStmtPreservesWord_lowerAssignNative_call_runtimePrimOp_of_nativeEvalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_lowerAssignNative_call_userFunction_of_nativeEvalArgs_call_preserves", - "theorem NativePrimCallPreservesWord_calldatasize", - "theorem NativePrimCallPreservesWord_callvalue", - "theorem NativePrimCallPreservesWord_address", - "theorem NativePrimCallPreservesWord_balance", - "theorem NativePrimCallPreservesWord_origin", - "theorem NativePrimCallPreservesWord_caller", - "theorem NativePrimCallPreservesWord_timestamp", - "theorem NativePrimCallPreservesWord_number", - "theorem NativePrimCallPreservesWord_chainid", - "theorem NativePrimCallPreservesWord_blobbasefee", - "theorem NativePrimCallPreservesWord_gasprice", - "theorem NativePrimCallPreservesWord_coinbase", - "theorem NativePrimCallPreservesWord_gaslimit", - "theorem NativePrimCallPreservesWord_selfbalance", - "theorem NativePrimCallPreservesWord_unary_same_state", - "theorem NativePrimCallPreservesWord_binary_same_state", - "theorem NativePrimCallPreservesWord_ternary_same_state", - "theorem NativePrimCallPreservesWord_iszero", - "theorem NativePrimCallPreservesWord_shr", - "theorem NativePrimCallPreservesWord_add", - "theorem NativePrimCallPreservesWord_sub", - "theorem NativePrimCallPreservesWord_mul", - "theorem NativePrimCallPreservesWord_div", - "theorem NativePrimCallPreservesWord_mod", - "theorem NativePrimCallPreservesWord_sdiv", - "theorem NativePrimCallPreservesWord_smod", - "theorem NativePrimCallPreservesWord_addmod", - "theorem NativePrimCallPreservesWord_mulmod", - "theorem NativePrimCallPreservesWord_exp", - "theorem NativePrimCallPreservesWord_signextend", - "theorem NativePrimCallPreservesWord_eq", - "theorem NativePrimCallPreservesWord_lt", - "theorem NativePrimCallPreservesWord_gt", - "theorem NativePrimCallPreservesWord_slt", - "theorem NativePrimCallPreservesWord_sgt", - "theorem NativePrimCallPreservesWord_and", - "theorem NativePrimCallPreservesWord_or", - "theorem NativePrimCallPreservesWord_xor", - "theorem NativePrimCallPreservesWord_not", - "theorem NativePrimCallPreservesWord_shl", - "theorem NativePrimCallPreservesWord_byte", - "theorem NativePrimCallPreservesWord_sar", - "theorem NativePrimCallPreservesWord_sload", - "theorem NativePrimCallPreservesWord_calldataload", - "theorem NativePrimCallPreservesWord_mload", - "theorem NativePrimCallPreservesWord_mstore", - "theorem NativePrimCallPreservesWord_mstore8", - "theorem NativePrimCallPreservesWord_tload", - "theorem NativePrimCallPreservesWord_tstore", - "theorem NativePrimCallPreservesWord_sstore", - "theorem NativePrimCallPreservesWord_stop", - "theorem NativePrimCallPreservesWord_return", - "theorem NativePrimCallPreservesWord_revert", - "theorem NativePrimCallPreservesWord_msize", - "theorem NativePrimCallPreservesWord_gas", - "theorem NativePrimCallPreservesWord_returndatasize", - "theorem NativePrimCallPreservesWord_calldatacopy", - "theorem NativePrimCallPreservesWord_returndatacopy", - "theorem NativePrimCallPreservesWord_pop", - "theorem NativePrimCallPreservesWord_keccak256", - "theorem NativePrimCallPreservesWord_log0", - "theorem NativePrimCallPreservesWord_log1", - "theorem NativePrimCallPreservesWord_log2", - "theorem NativePrimCallPreservesWord_log3", - "theorem NativePrimCallPreservesWord_log4", - "def NativeExprPreservesWord", - "def NativeEvalArgsPreservesWord", - "theorem NativeExprPreservesWord_var", - "theorem NativeExprPreservesWord_lit", - "theorem NativeEvalArgsPreservesWord_nil", - "theorem NativeEvalArgsPreservesWord_cons", - "theorem NativeEvalArgsPreservesWord_map_lowerExprNative", - "theorem NativeEvalArgsPreservesWord_map_lowerExprNative_reverse", - "theorem NativeExprPreservesWord_lowerExprNative_lit", - "theorem NativeExprPreservesWord_lowerExprNative_hex", - "theorem NativeExprPreservesWord_lowerExprNative_str", - "theorem NativeExprPreservesWord_lowerExprNative_ident", - "theorem NativeExprPreservesWord_call_prim_of_evalArgs_primCall_preserves", - "theorem NativeExprPreservesWord_call_prim_of_nativeEvalArgs_primCall_preserves", - "theorem NativeExprPreservesWord_lowerExprNative_call_runtimePrimOp_of_evalArgs_primCall_preserves", - "theorem NativeExprPreservesWord_lowerExprNative_call_runtimePrimOp_of_nativeEvalArgs_primCall_preserves", - "theorem NativeExprPreservesWord_call_user_of_evalArgs_call_preserves", - "theorem NativeExprPreservesWord_call_user_of_nativeEvalArgs_call_preserves", - "theorem NativeExprPreservesWord_lowerExprNative_call_userFunction_of_evalArgs_call_preserves", - "theorem NativeExprPreservesWord_lowerExprNative_call_userFunction_of_nativeEvalArgs_call_preserves", - "inductive NativeMappingFreeBridgedExpr", - "theorem NativeExprPreservesWord_lowerExprNative_of_mappingFreeBridgedExpr", - "theorem NativeEvalArgsPreservesWord_lowerExprNative_reverse_of_mappingFreeBridgedExprs", - "inductive NativeMappingFreePreservableStraightStmt", - "def NativeMappingFreeSideConditionForBridgedExpr", - "theorem NativeMappingFreeBridgedExpr.of_bridgedExpr", - "def NativeMappingFreeSideConditionForBridgedStraightStmt", - "theorem NativeMappingFreePreservableStraightStmt.of_bridgedStraightStmt", - "theorem NativeMappingFreePreservableStraightStmts.of_bridgedStraightStmts", - "theorem NativeStmtPreservesWord_lowerStmtGroupNativeWithSwitchIds_of_mappingFreePreservableStraightStmt", - "theorem NativeStmtPreservesWord_of_mem_lowerStmtsNativeWithSwitchIds_of_mappingFreePreservableStraightStmts", - "theorem NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_mappingFreePreservableStraightStmts", - "theorem NativeStmtPreservesWord_exprStmtCall_prim_of_evalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_user_of_evalArgs_call_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_prim_of_nativeEvalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_user_of_nativeEvalArgs_call_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_call_runtimePrimOp_of_evalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_call_userFunction_of_evalArgs_call_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_call_runtimePrimOp_of_nativeEvalArgs_primCall_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_call_userFunction_of_nativeEvalArgs_call_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_mstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_mstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_mstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_mstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_mstore8_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_mstore8_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_mstore8_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_mstore8_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_sstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_sstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_sstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_sstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_tstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_tstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_tstore_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_tstore_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_calldatacopy_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_calldatacopy_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_calldatacopy_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_calldatacopy_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_returndatacopy_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_returndatacopy_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_returndatacopy_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_returndatacopy_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log0_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log0_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log0_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log0_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log1_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log1_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log1_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log1_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log2_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log2_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log2_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log2_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log3_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log3_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log3_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log3_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log4_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_log4_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log4_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_log4_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_return_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_return_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_return_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_return_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_revert_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_revert_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_revert_of_evalArgs_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_revert_of_nativeEvalArgs_and_evalArgs_shape_preserves", - "theorem NativeStmtPreservesWord_exprStmtCall_stop", - "theorem NativeStmtPreservesWord_exprStmtCall_lowerExprNative_stop", - "theorem nativeStmtWriteNames_not_mem_of_nativeStmtsWriteNames_not_mem", - "theorem collectNativeStmtWriteNames_append", - "theorem nativeStmtsWriteNames_append", - "theorem nativeStmtsWriteNames_cons", - "theorem nativeStmtsWriteNames_cons_not_mem_iff", - "theorem nativeStmtsWriteNames_head_not_mem_of_cons_not_mem", - "theorem nativeStmtsWriteNames_tail_not_mem_of_cons_not_mem", - "theorem nativeStmtsWriteNames_left_not_mem_of_append_not_mem", - "theorem nativeStmtsWriteNames_right_not_mem_of_append_not_mem", - "theorem nativeStmtsWriteNames_append_not_mem_iff", - "theorem NativeBlockPreservesWord_of_nativeStmtsWriteNames_not_mem", - "theorem NativeBlockPreservesWord_cons_of_nativeStmtsWriteNames_not_mem", - "theorem NativeBlockPreservesWord_append_of_forall_stmt", - "theorem NativeBlockPreservesWord_append_of_nativeStmtsWriteNames_not_mem", - "theorem NativeBlockPreservesWord_append_of_nativeStmtsWriteNames_append_not_mem", - "theorem NativeStmtPreservesWord_block_of_nativeStmtsWriteNames_not_mem", - "theorem NativeStmtPreservesWord_if_of_eval_preserves_and_nativeStmtsWriteNames_not_mem", - "theorem NativeStmtPreservesWord_if_of_cond_preserves_and_nativeStmtsWriteNames_not_mem", - "theorem NativeBlockPreservesWord_of_nativeSwitchFresh_find_hit_matched", - "theorem NativeBlockPreservesWord_of_nativeSwitchFresh_find_hit_discr", - "theorem NativeBlockPreservesWord_of_nativeSwitchFresh_default_matched", - "theorem NativeBlockPreservesWord_of_nativeSwitchFresh_default_discr", - "theorem nativeSwitchTempsFreshForNativeBodies_case_discr_not_mem", - "theorem nativeSwitchTempsFreshForNativeBodies_find_hit_discr_not_mem", - "theorem nativeSwitchTempsFreshForNativeBodies_default_discr_not_mem", - "theorem exec_nativeSwitchTail_find_hit_fresh_fuel", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_fresh_fuel", - "theorem exec_lowerNativeSwitchBlock_storePrefix_tail_ok_fuel", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_preserved_store_fuel", - "theorem exec_lowerNativeSwitchBlock_selector_find_hit_fresh_store_fuel", - "theorem exec_block_lowerNativeSwitchBlock_selector_find_hit_hasSelectorState_ok_fresh", - ): - if required_native_entrypoint not in normalized_native_harness: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanNativeHarness.lean is missing native harness surface " - f"`{required_native_entrypoint}`" - ) - - return errors - - -def check_native_switch_lowering_boundary(native_adapter_text: str, native_smoke_text: str) -> list[str]: - """Keep native switch lowering fresh and regression-tested.""" - - errors: list[str] = [] - normalized_adapter = normalize_ws(native_adapter_text) - normalized_smoke = normalize_ws(native_smoke_text) - - for required_boundary in ( - "freshNativeSwitchId", - "nativeSwitchDiscrTempName", - "nativeSwitchMatchedTempName", - "yulStmtsIdentifierNames", - ): - if required_boundary not in normalized_adapter: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanAdapter.lean must keep native switch temporary " - f"freshness explicit with `{required_boundary}`" - ) - - for required_smoke in ( - "nativeSwitchTempNamesAvoidUserNames = true", - "nativeFunctionSwitchTempNamesAvoidLocalUserNames = true", - "nativeSwitchExecutesOnlyFirstMatchingNonHaltingCase = true", - "emittedRuntimeSatisfiesGeneratedNativeFragment = true", - "duplicateHelpersRejectedByGeneratedNativeFragment = true", - "nestedDispatcherFuncDefRejectedByGeneratedNativeFragment = true", - "nestedHelperFuncDefRejectedByGeneratedNativeFragment = true", - "nativeRuntimeFragmentGateRejectsDuplicateHelper = true", - "nativeIRRuntimeFragmentGateRejectsDuplicateHelper = true", - ): - if required_smoke not in normalized_smoke: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanNativeSmokeTest.lean must pin native switch " - f"lowering behavior with `{required_smoke}`" - ) - - return errors - - -def check_default_builtin_backend(builtins_text: str) -> list[str]: - """Pin the file-local default backend to EVMYulLean. - - The backend aliases are transition/reference-oracle helpers, not public - proof authority. Keep them private while ensuring unqualified builtin - evaluation does not silently drift back to the Verity backend. - """ - - errors: list[str] = [] - normalized = normalize_ws(builtins_text) - required = ( - "private abbrev legacyBuiltinBackend : BuiltinBackend := .verity", - "private abbrev defaultBuiltinBackend : BuiltinBackend := .evmYulLean", - "private def evalBuiltinCall", - "theorem defaultBuiltinBackend_eq_evmYulLean", - ) - for snippet in required: - if normalize_ws(snippet) not in normalized: - errors.append( - "Compiler/Proofs/YulGeneration/ReferenceOracle/Builtins.lean " - "must pin private reference-oracle/default builtin backend " - f"aliases with `{snippet}`" - ) - return errors - - -def check_reference_oracle_names( - end_to_end_text: str, retarget_text: str, preservation_text: str -) -> list[str]: - """Keep legacy Layer-3 reference-oracle entry points explicitly named.""" - - errors: list[str] = [] - normalized_end_to_end = normalize_ws(end_to_end_text) - normalized_retarget = normalize_ws(retarget_text) - normalized_preservation = normalize_ws(preservation_text) - - if re.search(r"\btheorem\s+yulCodegen_preserves_semantics(?!_)", preservation_text): - errors.append( - "Compiler/Proofs/YulGeneration/Preservation.lean must not expose the " - "legacy reference-oracle theorem as bare `yulCodegen_preserves_semantics`; " - "use `yulCodegen_preserves_semantics_via_reference_oracle`" - ) - - if "private theorem yulCodegen_preserves_semantics_via_reference_oracle" not in normalized_preservation: - errors.append( - "Compiler/Proofs/YulGeneration/Preservation.lean must keep the legacy " - "Layer-3 oracle theorem explicitly named but private " - "`yulCodegen_preserves_semantics_via_reference_oracle`" - ) - - if re.search( - r"^\s*theorem\s+yulCodegen_preserves_semantics_via_reference_oracle\b", - preservation_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/YulGeneration/Preservation.lean must not expose " - "`yulCodegen_preserves_semantics_via_reference_oracle` as public " - "proof authority" - ) - - if "yulCodegen_preserves_semantics_via_reference_oracle" in normalized_retarget: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean must " - "not invoke the private legacy Layer-3 oracle theorem " - "`yulCodegen_preserves_semantics_via_reference_oracle`" - ) - - for public_legacy_retarget in ( - "yulCodegen_preserves_semantics_evmYulLeanBackend", - "yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle", - ): - if re.search( - r"^\s*(?:private\s+)?theorem\s+" - + re.escape(public_legacy_retarget) - + r"\b", - retarget_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean " - "must not retain transition-only legacy Layer-3 retarget theorem " - f"`{public_legacy_retarget}`" - ) - - if "theorem yulCodegen_preserves_semantics_evmYulLean " in normalized_retarget: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean must " - "not reintroduce the hidden reference-oracle compatibility alias " - "`yulCodegen_preserves_semantics_evmYulLean`; use the explicit " - "`yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle` name" - ) - - if "theorem yulCodegen_preserves_semantics_evmYulLean_via_reference_oracle " in normalized_retarget: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean must " - "not reintroduce the hidden default-fuel compatibility alias " - "`yulCodegen_preserves_semantics_evmYulLean_via_reference_oracle`; " - "use the explicit " - "`yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle` name" - ) - - if "yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle" in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not mention the legacy " - "compatibility alias " - "`yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle`" - ) - - for forbidden_end_to_end_legacy_term in ( - "evalBuiltinCall", - "legacyEvalBuiltinCallWithContext", - "legacyBuiltinBackend", - "Compiler.Proofs.YulGeneration.ReferenceOracle", - "interpretYulRuntimeWithBackend", - "execYulFuelWithBackend", - "defaultBuiltinBackend", - "BuiltinBackend", - ): - if forbidden_end_to_end_legacy_term in end_to_end_text: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not directly mention " - "legacy oracle/backend term " - f"`{forbidden_end_to_end_legacy_term}`; keep those dependencies " - "isolated below the public EndToEnd surface" - ) - - for removed_native_reference_alias in ( - "theorem layer3_contract_preserves_semantics_native_via_reference_oracle_of_evmYulLean_bridge", - "theorem layers2_3_ir_matches_native_evmYulLean_via_reference_oracle_of_evmYulLean_bridge", - ): - if removed_native_reference_alias in normalized_end_to_end: - errors.append( - "Compiler/Proofs/EndToEnd.lean must not reintroduce the removed " - "generic native reference-oracle/fuel-wrapper seam " - f"`{removed_native_reference_alias.removeprefix('theorem ')}`" - ) - - return errors - - -def check_legacy_proof_boundary( - public_boundary_files: list[tuple[str, str]], - legacy_proof_files: list[tuple[str, str]], -) -> list[str]: - """Keep transition-only legacy proof modules below the native public path.""" - - errors: list[str] = [] - - for label, text in public_boundary_files: - for module in TRANSITION_ONLY_PUBLIC_FORBIDDEN_MODULES: - import_line = f"import {module}" - if import_line in text: - errors.append( - f"{label} must not import transition-only legacy proof " - f"module `{module}`" - ) - if "import Compiler.Proofs.YulGeneration.ReferenceOracle" in text: - errors.append( - f"{label} must not import legacy ReferenceOracle modules; " - "keep the custom Yul interpreter below the native public path" - ) - - public_decl_pattern = re.compile( - r"^\s*(?:@\[[^\]]*\]\s*)*" - r"(?!(?:private|namespace|end|open|section|variable|include|omit|attribute)\b)" - r"(def|theorem|lemma|abbrev|inductive|structure)\s+([A-Za-z0-9_'.]+)\b", - re.MULTILINE, - ) - for label, text in legacy_proof_files: - for match in public_decl_pattern.finditer(text): - errors.append( - f"{label} must not expose transition-only legacy declaration " - f"`{match.group(2)}` as public proof authority" - ) - - return errors - - -def check_yul_generation_readme(text: str) -> list[str]: - """Keep the Layer 3 README aligned with the native dispatcher retarget.""" - - errors: list[str] = [] - required_snippets = ( - "Legacy reference-oracle stack complete", - "`EvmYul.Yul.callDispatcher` theorem stack", - "not the fuel-parametric proof-interpreter preservation theorem", - "**`Preservation.lean`** - Legacy Layer 3 preservation theorem", - "**`Backends/EvmYulLeanNativeHarness.lean`** - Native EVMYulLean execution", - "**`Backends/EvmYulLeanRetarget.lean`** - Bridged-fragment backend equivalence", - "Does not export contract-level proof-interpreter preservation as public", - ) - for snippet in required_snippets: - if snippet not in text: - errors.append( - "Compiler/Proofs/YulGeneration/README.md must describe the " - f"native dispatcher retarget boundary with `{snippet}`" - ) - forbidden_snippets = ( - "**Status**: Complete (PR #42)", - "**`Preservation.lean`** - Main Layer 3 preservation theorem", - ) - for snippet in forbidden_snippets: - if snippet in text: - errors.append( - "Compiler/Proofs/YulGeneration/README.md must not describe the " - f"legacy proof-interpreter path as current public authority: `{snippet}`" - ) - return errors - - -def lean_module_to_path(module: str) -> Path | None: - path = ROOT / (module.replace(".", "/") + ".lean") - if path.exists(): - return path - return None - - -def lean_imports(text: str) -> list[str]: - imports: list[str] = [] - for line in text.splitlines(): - stripped = line.strip() - if stripped.startswith("import "): - parts = stripped.split() - if len(parts) >= 2: - imports.append(parts[1]) - return imports - - -def check_transition_only_import_allowlist( - lean_files: list[tuple[str, str]], -) -> list[str]: - """Keep transition-only ReferenceOracle imports out of new proof modules.""" - - errors: list[str] = [] - forbidden_bridge_import = ( - "Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas" - ) - bridge_allowlist = set(BRIDGE_LEMMAS_IMPORT_ALLOWLIST) - reference_oracle_import_prefix = ( - "Compiler.Proofs.YulGeneration.ReferenceOracle" - ) - reference_oracle_allowlist = set(REFERENCE_ORACLE_IMPORT_ALLOWLIST) - for label, text in lean_files: - imports = lean_imports(text) - if label not in bridge_allowlist and forbidden_bridge_import in imports: - errors.append( - f"{label} must not import transition-only bridge lemma module " - f"`{forbidden_bridge_import}`; keep ReferenceOracle bridge evidence " - "confined to EvmYulLeanRetarget and bridge regression tests" - ) - if label not in reference_oracle_allowlist: - for imported in imports: - if imported == reference_oracle_import_prefix or imported.startswith( - reference_oracle_import_prefix + "." - ): - errors.append( - f"{label} must not import legacy ReferenceOracle module " - f"`{imported}`; keep the custom interpreter confined " - "to the known transition and regression-test modules" - ) - return errors - - -def transition_import_scan_files() -> list[Path]: - files = [ROOT / "PrintAxioms.lean"] - for directory in (ROOT / "Compiler", ROOT / "Contracts"): - if directory.exists(): - files.extend(sorted(directory.rglob("*.lean"))) - return files - - -def check_public_transitive_import_boundary( - public_boundary_files: list[tuple[str, str]], -) -> list[str]: - """Reject transitive legacy imports from native public boundary modules.""" - - errors: list[str] = [] - forbidden_modules = TRANSITION_ONLY_PUBLIC_FORBIDDEN_MODULES + ( - "Compiler.Proofs.YulGeneration.ReferenceOracle", - ) - text_overrides = { - label: text - for label, text in public_boundary_files - } - - for label, text in public_boundary_files: - queue: list[tuple[str, str, list[str]]] = [(label, text, [label])] - seen_modules: set[str] = set() - while queue: - current_label, current_text, chain = queue.pop(0) - for imported in lean_imports(current_text): - if any( - imported == forbidden or imported.startswith(forbidden + ".") - for forbidden in forbidden_modules - ): - errors.append( - f"{label} must not transitively import transition-only " - f"legacy proof module `{imported}` via " - + " -> ".join(chain + [imported]) - ) - continue - - if imported in seen_modules: - continue - seen_modules.add(imported) - - imported_path = lean_module_to_path(imported) - if imported_path is None: - continue - try: - imported_relative = imported_path.relative_to(ROOT).as_posix() - except ValueError: - continue - if not imported_relative.startswith("Compiler/"): - continue - imported_text = text_overrides.get( - imported_relative, - imported_path.read_text(encoding="utf-8"), - ) - queue.append((imported_relative, imported_text, chain + [imported])) - - return errors - - -def check_public_transitive_forbidden_terms( - public_boundary_files: list[tuple[str, str]], -) -> list[str]: - """Reject legacy proof-interpreter/backend names in public reachable files.""" - - errors: list[str] = [] - forbidden_terms = ( - "ReferenceOracle", - "execYulFuel", - "interpretYulRuntimeWithBackend", - ".verity", - "defaultBuiltinBackend", - "legacyBuiltinBackend", - "evalBuiltinCallWithContext", - "nativeIRRuntimeAgreesWithInterpreter", - ) - text_overrides = { - label: text - for label, text in public_boundary_files - } - - for label, text in public_boundary_files: - queue: list[tuple[str, str, list[str]]] = [(label, text, [label])] - seen_labels: set[str] = set() - while queue: - current_label, current_text, chain = queue.pop(0) - if current_label in seen_labels: - continue - seen_labels.add(current_label) - - for forbidden in forbidden_terms: - if forbidden in current_text: - errors.append( - f"{label} must not transitively expose legacy " - f"proof-interpreter/backend term `{forbidden}` via " - + " -> ".join(chain) - ) - - for imported in lean_imports(current_text): - imported_path = lean_module_to_path(imported) - if imported_path is None: - continue - try: - imported_relative = imported_path.relative_to(ROOT).as_posix() - except ValueError: - continue - if not imported_relative.startswith("Compiler/"): - continue - imported_text = text_overrides.get( - imported_relative, - imported_path.read_text(encoding="utf-8"), - ) - queue.append((imported_relative, imported_text, chain + [imported])) - - return errors - - -def check_bridge_lemmas_transition_surface(bridge_lemmas_text: str) -> list[str]: - """Keep transition-helper bridge rewrites out of the public theorem surface.""" - - errors: list[str] = [] - if re.search( - r"^\s*theorem\s+evalBuiltinCallWithBackendContext_evmYulLean_pure_bridge\b", - bridge_lemmas_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean " - "must keep transition-only routing helper " - "`evalBuiltinCallWithBackendContext_evmYulLean_pure_bridge` private" - ) - return errors - - -def check_adapter_correctness_transition_surface(adapter_correctness_text: str) -> list[str]: - """Keep legacy adapter-correctness rewrites out of the public theorem surface.""" - - errors: list[str] = [] - for helper in ( - "assign_equiv_let", - "assign_equiv_let'", - "legacyExecYulFuel_stmts_nil", - "for_init_hoist", - "for_init_hoist_revert", - "for_init_hoist_return", - "for_init_hoist_stop", - ): - if re.search( - r"^\s*(?:@\[[^\]]*\]\s*)*theorem\s+" - + re.escape(helper) - + r"\b", - adapter_correctness_text, - re.MULTILINE, - ): - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanAdapterCorrectness.lean must keep transition-only " - f"adapter correctness helper `{helper}` private" - ) - return errors - - -def check_native_closure_import_boundary( - bridge_predicates_text: str, - body_closure_text: str, - source_expr_closure_text: str, -) -> list[str]: - """Keep native closure predicates isolated from legacy retarget proofs.""" - - errors: list[str] = [] - - if "import Compiler.Proofs.YulGeneration.ReferenceOracle" in bridge_predicates_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanBridgePredicates.lean must not import ReferenceOracle; " - "native closure predicates should remain syntactic" - ) - - if "import Compiler.Proofs.YulGeneration.LogNames" not in bridge_predicates_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanBridgePredicates.lean must import the neutral " - "Yul log-name helper" - ) - - if "import Compiler.Proofs.IRGeneration.IRInterpreter" in bridge_predicates_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanBridgePredicates.lean must not import the full IR " - "interpreter for log-name predicates" - ) - - for forbidden_predicate_surface in ( - "legacy Yul reference oracle", - "legacy retarget executor", - "legacy context evaluator", - "native and transition backends", - ".verity", - ): - if forbidden_predicate_surface in bridge_predicates_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanBridgePredicates.lean must describe the generated " - "fragment in native-closure terms, not legacy transition " - f"authority language `{forbidden_predicate_surface}`" - ) - - for label, text in ( - ("EvmYulLeanBodyClosure.lean", body_closure_text), - ("EvmYulLeanSourceExprClosure.lean", source_expr_closure_text), - ): - if "import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgePredicates" not in text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - f"{label} must import the neutral EVMYulLean bridge predicates" - ) - for forbidden_import in ( - "import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget", - "import Compiler.Proofs.YulGeneration.Preservation", - "import Compiler.Proofs.YulGeneration.ReferenceOracle", - ): - if forbidden_import in text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - f"{label} must not import legacy transition proof authority " - f"`{forbidden_import.removeprefix('import ')}`" - ) - - for required_source_expr_theorem in ( - "theorem bridgedSourceExpr_of_exprCompileCore", - "theorem bridgedSourceExpr_keccak256_of_exprCompileCore", - "theorem compileExpr_keccak256_bridgedSource_of_exprCompileCore", - "theorem compileExpr_mappingChain_bridgedSource", - "private theorem bridgedExpr_sload_lit", - "| arrayLength (name : String) : BridgedSourceExpr (.arrayLength name)", - "| builtinExp {base exponent}", - "| storage (fieldName : String) : BridgedSourceExpr (.storage fieldName)", - "| storageAddr (fieldName : String) : BridgedSourceExpr (.storageAddr fieldName)", - "| storageArrayLength (fieldName : String) :", - "| adtTag (adtName storageField : String) :", - "| adtField (adtName variantName fieldName : String) (fieldIndex : Nat)", - "| mapping {key : Expr} (fieldName : String) (hKey : BridgedSourceExpr key)", - "| mappingWord {key : Expr} (fieldName : String) (hKey : BridgedSourceExpr key)", - "| mappingUint {key : Expr} (fieldName : String) (hKey : BridgedSourceExpr key)", - "| mapping2 {key1 key2 : Expr} (fieldName : String)", - "| mapping2Word {key1 key2 : Expr} (fieldName : String)", - "| structMember {key : Expr} (fieldName : String) (hKey : BridgedSourceExpr key)", - "| structMember2 {key1 key2 : Expr} (fieldName : String)", - "private theorem compileMappingSlotRead_bridged", - "private theorem bridgedExpr_sload_mappingSlot2_lit", - "private theorem bridgedExpr_sload_mappingSlotChain_lit", - "private theorem bridgedExpr_packed_read", - ): - if required_source_expr_theorem not in source_expr_closure_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanSourceExprClosure.lean must keep the native " - "source-expression closure theorem " - f"`{required_source_expr_theorem.removeprefix('theorem ')}`" - ) - - for required_body_closure_theorem in ( - "theorem bridgedSafeStmts_letKeccak_of_exprCompileCore", - "theorem bridgedSafeStmts_assignKeccak_of_exprCompileCore", - "theorem bridgedSafeStmts_externalMstoreLetKeccak_of_exprCompileCore", - ): - if required_body_closure_theorem not in body_closure_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanBodyClosure.lean must keep the native safe-body " - "keccak binding closure theorem " - f"`{required_body_closure_theorem.removeprefix('theorem ')}`" - ) - - return errors - - -def check_runtime_types_import_boundary(runtime_types_text: str) -> list[str]: - """Keep shared Yul runtime plumbing from importing IR execution semantics.""" - - errors: list[str] = [] - if "import Compiler.Proofs.IRGeneration.IRInterpreter" in runtime_types_text: - errors.append( - "Compiler/Proofs/YulGeneration/RuntimeTypes.lean must import " - "IRRuntimeTypes rather than the full IR interpreter" - ) - if "import Compiler.Proofs.IRGeneration.IRRuntimeTypes" not in runtime_types_text: - errors.append( - "Compiler/Proofs/YulGeneration/RuntimeTypes.lean must import the " - "neutral IR runtime record module" - ) - return errors - - -def check_native_harness_import_boundary(native_harness_text: str) -> list[str]: - """Keep the native harness independent of the full IR interpreter.""" - - errors: list[str] = [] - if "import Compiler.Proofs.IRGeneration.IRInterpreter" in native_harness_text: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean " - "must consume IRRuntimeTypes records without importing the full IR " - "interpreter" - ) - return errors - - -def check_root_compiler_import_boundary(root_compiler_text: str) -> list[str]: - """Keep the root aggregate from directly re-exporting broad interpreters.""" - - errors: list[str] = [] - if "import Compiler.Proofs.IRGeneration.IRInterpreter" in root_compiler_text: - errors.append( - "Compiler.lean must not directly import the full IR interpreter; " - "import proof modules that own their semantic dependencies instead" - ) - return errors - - -def check_native_alias_signatures(end_to_end_text: str) -> list[str]: - """Reject hidden native dispatcher fuel-wrapper aliases in theorem signatures.""" - - errors: list[str] = [] - theorem_pattern = re.compile( - r"^\s*theorem\s+([A-Za-z0-9_']+)\b(.*?)(?=\s:=)", - re.DOTALL | re.MULTILINE, - ) - hidden_dispatcher_alias = re.compile( - r"\bnative(?:CallDispatcher|DispatcherBlock|DispatcherExec)" - r"AgreesWithEvmYulLean(?:Positive)?\b" - ) - - for match in theorem_pattern.finditer(end_to_end_text): - name = match.group(1) - signature = match.group(2) - hidden_matches = sorted(set(hidden_dispatcher_alias.findall(signature))) - if hidden_matches: - errors.append( - "Compiler/Proofs/EndToEnd.lean theorem " - f"`{name}` must expose explicit fuel-wrapper predicates instead " - "of hidden native dispatcher aliases: " - + ", ".join(f"`{hidden}`" for hidden in hidden_matches) - ) - - return errors - - -def check_public_end_to_end_theorem_signatures(end_to_end_text: str) -> list[str]: - """Reject legacy oracle/interpreter terms in public EndToEnd theorem APIs.""" - - errors: list[str] = [] - theorem_pattern = re.compile( - r"^\s*theorem\s+([A-Za-z0-9_']+)\b(.*?)(?=\s:=)", - re.DOTALL | re.MULTILINE, - ) - forbidden_signature_terms = ( - "ReferenceOracle", - "execYulFuel", - "execYulFuelWithBackend", - "interpretYulRuntimeWithBackend", - ".verity", - "defaultBuiltinBackend", - "legacyBuiltinBackend", - "evalBuiltinCallWithContext", - "nativeIRRuntimeAgreesWithInterpreter", - ) - public_call_dispatcher_theorems = ( - "compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - ) - forbidden_public_call_dispatcher_terms = ( - "SourceBodyNativeClosure", - "lowerRuntimeContractNative", - "nativeChainIdRepresentable", - "nativeBlobBaseFeeRepresentable", - "nativeRuntimePathUsesUnsupportedHeaderBuiltin", - ) - - for match in theorem_pattern.finditer(end_to_end_text): - name = match.group(1) - signature = match.group(2) - leaked_terms = sorted( - term for term in forbidden_signature_terms if term in signature - ) - if leaked_terms: - errors.append( - "Compiler/Proofs/EndToEnd.lean theorem " - f"`{name}` must expose native EVMYulLean theorem parameters " - "rather than legacy oracle/interpreter terms: " - + ", ".join(f"`{term}`" for term in leaked_terms) - ) - if re.search(r"\(\s*fuel'?\s*:\s*Nat\s*\)", signature): - errors.append( - "Compiler/Proofs/EndToEnd.lean theorem " - f"`{name}` must use canonical native generated-runtime fuel " - "instead of exposing arbitrary theorem-facing fuel" - ) - if name in public_call_dispatcher_theorems: - leaked_call_dispatcher_terms = sorted( - term - for term in forbidden_public_call_dispatcher_terms - if term in signature - ) - if leaked_call_dispatcher_terms: - errors.append( - "Compiler/Proofs/EndToEnd.lean public callDispatcher theorem " - f"`{name}` must keep body, full-runtime lowering, and " - "native environment-validation obligations below the " - "public direct callDispatcher signature: " - + ", ".join( - f"`{term}`" for term in leaked_call_dispatcher_terms - ) - ) - - return errors - - -def check_unbridged_environment_boundary(native_harness_text: str, native_smoke_text: str) -> list[str]: - """Keep the native environment-read limitation explicit and tested. - - EVMYulLean currently evaluates `CHAINID` from its own global constant, and - `BLOBBASEFEE` from the block-header blob gas price formula. The native - harness does not yet derive those fields from Verity's `YulTransaction`. - Until that bridge is widened, the transition must keep both the named lemma - and executable smoke expectations for the current default behavior. - """ - - errors: list[str] = [] - normalized_native_harness = normalize_ws(native_harness_text) - normalized_native_smoke = normalize_ws(native_smoke_text) - - for required_boundary in ( - "validateNativeRuntimeEnvironment", - "nativeRuntimePathUsesBuiltin", - "yulStmtsUseBuiltinOnNativeRuntimePath", - "selectedSwitchBody", - "nativeChainIdRepresentable", - "nativeBlobBaseFeeRepresentable", - "unsupportedNativeHeaderBuiltinNames", - "nativeRuntimePathUsesUnsupportedHeaderBuiltin", - "unsupportedNativeHeaderBuiltinError", - "initialState_unbridgedEnvironmentDefaults", - "EvmYul.State.chainId", - "EvmYul.chainId", - "header.blobGasUsed", - "header.excessBlobGas", - ): - if required_boundary not in normalized_native_harness: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanNativeHarness.lean must keep the unbridged " - f"environment boundary explicit with `{required_boundary}`" - ) - - for pinned_default in ( - 'nativeRejectsUnsupportedChainId = true', - 'nativeStoresBuiltinWithTx "chainid" 15 EvmYul.chainId', - 'nativeRejectsUnsupportedBlobBaseFee = true', - 'nativeStoresBuiltinWithTx "blobbasefee" 16 EvmYul.MIN_BASE_FEE_PER_BLOB_GAS', - 'nativeRejectsUnsupportedHeaderBuiltin "coinbase" = true', - 'nativeRejectsUnsupportedHeaderBuiltin "gaslimit" = true', - 'nativeRejectsUnsupportedHeaderBuiltin "selfbalance" = true', - 'nativeAllowsUnselectedUnsupportedEnvironmentBuiltin = true', - ): - if pinned_default not in normalized_native_smoke: - errors.append( - "Compiler/Proofs/YulGeneration/Backends/" - "EvmYulLeanNativeSmokeTest.lean must pin the current native " - f"environment behavior with `{pinned_default}` until " - "the blobbasefee bridge is widened" - ) - - return errors - - -def main() -> int: - if not DOC.exists(): - print(f"Missing: {DOC.relative_to(ROOT)}", file=sys.stderr) - return 1 - if not DOD_DOC.exists(): - print(f"Missing: {DOD_DOC.relative_to(ROOT)}", file=sys.stderr) - return 1 - for path in ( - ROOT_COMPILER, - END_TO_END, - NATIVE_HARNESS, - RETARGET, - BRIDGE_PREDICATES, - BRIDGE_LEMMAS, - ADAPTER_CORRECTNESS, - BODY_CLOSURE, - SOURCE_EXPR_CLOSURE, - BUILTINS, - PRESERVATION, - NATIVE_ADAPTER, - NATIVE_SMOKE_TEST, - RUNTIME_TYPES, - *LEGACY_PROOF_FILES, - ): - if not path.exists(): - print(f"Missing: {path.relative_to(ROOT)}", file=sys.stderr) - return 1 - - native_harness_text = NATIVE_HARNESS.read_text(encoding="utf-8") - native_smoke_text = NATIVE_SMOKE_TEST.read_text(encoding="utf-8") - runtime_types_text = RUNTIME_TYPES.read_text(encoding="utf-8") - errors = check_doc(DOC.read_text(encoding="utf-8")) - errors.extend( - check_definition_of_done_doc(DOD_DOC.read_text(encoding="utf-8")) - ) - errors.extend( - check_yul_generation_readme(YULGEN_README.read_text(encoding="utf-8")) - ) - errors.extend( - check_public_theorem_target( - END_TO_END.read_text(encoding="utf-8"), - native_harness_text, - RETARGET.read_text(encoding="utf-8"), - ) - ) - errors.extend( - check_default_builtin_backend(BUILTINS.read_text(encoding="utf-8")) - ) - errors.extend( - check_reference_oracle_names( - END_TO_END.read_text(encoding="utf-8"), - RETARGET.read_text(encoding="utf-8"), - PRESERVATION.read_text(encoding="utf-8"), - ) - ) - errors.extend( - check_native_closure_import_boundary( - BRIDGE_PREDICATES.read_text(encoding="utf-8"), - BODY_CLOSURE.read_text(encoding="utf-8"), - SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ) - ) - errors.extend(check_runtime_types_import_boundary(runtime_types_text)) - errors.extend(check_native_harness_import_boundary(native_harness_text)) - errors.extend( - check_root_compiler_import_boundary( - ROOT_COMPILER.read_text(encoding="utf-8") - ) - ) - errors.extend( - check_legacy_proof_boundary( - [ - ("Compiler.lean", ROOT_COMPILER.read_text(encoding="utf-8")), - ("Compiler/Proofs/EndToEnd.lean", END_TO_END.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - native_harness_text, - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ], - [ - (path.relative_to(ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in LEGACY_PROOF_FILES - ], - ) - ) - errors.extend( - check_public_transitive_import_boundary( - [ - ("Compiler.lean", ROOT_COMPILER.read_text(encoding="utf-8")), - ("Compiler/Proofs/EndToEnd.lean", END_TO_END.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - native_harness_text, - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ] - ) - ) - errors.extend( - check_public_transitive_forbidden_terms( - [ - ("Compiler.lean", ROOT_COMPILER.read_text(encoding="utf-8")), - ("Compiler/Proofs/EndToEnd.lean", END_TO_END.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - native_harness_text, - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ] - ) - ) - errors.extend( - check_transition_only_import_allowlist( - [ - (path.relative_to(ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in transition_import_scan_files() - ] - ) - ) - errors.extend( - check_bridge_lemmas_transition_surface( - BRIDGE_LEMMAS.read_text(encoding="utf-8") - ) - ) - errors.extend( - check_adapter_correctness_transition_surface( - ADAPTER_CORRECTNESS.read_text(encoding="utf-8") - ) - ) - errors.extend( - check_native_alias_signatures(END_TO_END.read_text(encoding="utf-8")) - ) - errors.extend( - check_public_end_to_end_theorem_signatures( - END_TO_END.read_text(encoding="utf-8") - ) - ) - errors.extend( - check_unbridged_environment_boundary( - native_harness_text, - native_smoke_text, - ) - ) - errors.extend( - check_native_switch_lowering_boundary( - NATIVE_ADAPTER.read_text(encoding="utf-8"), - native_smoke_text, - ) - ) - if errors: - for error in errors: - print(error, file=sys.stderr) - return 1 - - print("native EVMYulLean transition doc check passed") - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/scripts/check_proof_length.py b/scripts/check_proof_length.py index aa877122d..75bed1665 100644 --- a/scripts/check_proof_length.py +++ b/scripts/check_proof_length.py @@ -327,7 +327,6 @@ "yulCodegen_preserves_semantics_via_reference_oracle", "stmt_and_stmts_equiv", "execIRStmtsFuel_equiv_execYulStmtsFuel_of_stmt_equiv", - "legacyExecYulFuel_succ_eq", "exec_switchCaseBody_revert_of_short", "exec_switchCaseBody_continue_of_long", "SwitchCaseBodyBridge_short", @@ -416,11 +415,12 @@ # Pure-context dispatch is the same 25-builtin case split specialized to # context-free builtins; each branch delegates to an individual bridge. "evalBuiltinCallWithBackendContext_evmYulLean_pure_bridge", - # Backend-parameterized mirror of legacyExecYulFuel; long by construction because - # it preserves all statement cases while swapping only expression backend. + # Backend-parameterized mirror of the legacy fuel-based executor; long by + # construction because it preserves all statement cases while swapping only + # expression backend. "execYulFuelWithBackend", # Recovery proof mirrors the executor's statement case split; each branch is - # direct simplification back to legacyExecYulFuel. + # direct simplification back to the legacy fuel-based executor. "execYulFuelWithBackend_verity_eq", # Native harness block-append lemmas are structural inductions over a Yul # block prefix with fuel normalization at each cons. The success, suffix @@ -1108,7 +1108,7 @@ r"^NativeStmtPreservesWord_(?:lowerStmtGroupNativeWithSwitchIds|" r"of_mem_lowerStmtsNativeWithSwitchIds)_of_mappingFreePreservableStraightStmt", r"^NativeStmtPreservesWord_let(?:Many)?_lowerExprNative_of_mappingFreeBridgedExpr$", - r"^NativeBlockPreservesWord_switchCaseBody_" + r"^NativeBlockPreservesWord(?:_revived)?_switchCaseBody_" r"(?:payable|nonpayable)_of_user_body$", r"^native_(?:mappingSlot_call_preserves_lookup|" r"mappingSlot_call_preserves_lookup_state|" diff --git a/scripts/check_verify_sync.py b/scripts/check_verify_sync.py index 2d693e658..7090edab0 100755 --- a/scripts/check_verify_sync.py +++ b/scripts/check_verify_sync.py @@ -153,7 +153,7 @@ def _extract_changes_filter_paths(text: str, filter_name: str) -> list[str]: changes_body = extract_job_body(text, "changes", VERIFY_YML) return _extract_list_block( changes_body, - rf"^\s*filters:\s*\|\n(?:^\s+.*\n)*?^\s*{re.escape(filter_name)}:\n(?P(?:^\s*-\s+.*\n)+)", + rf"^\s*filters:\s*\|\n(?:^\s+.*\n)*?^ {re.escape(filter_name)}:\n(?P(?:^ -\s+.*\n)+)", f"changes.filter.{filter_name}", ) diff --git a/scripts/check_yul.py b/scripts/check_yul.py index 56ded506d..e40617d59 100644 --- a/scripts/check_yul.py +++ b/scripts/check_yul.py @@ -20,7 +20,6 @@ DEFAULT_YUL_DIR = ROOT / "artifacts" / "yul" RUNTIME_INTERPRETERS = [ PROOFS_DIR / "IRGeneration" / "IRInterpreter.lean", - PROOFS_DIR / "YulGeneration" / "ReferenceOracle" / "Semantics.lean", ] IMPORT_BUILTINS_RE = re.compile( diff --git a/scripts/generate_evmyullean_adapter_report.py b/scripts/generate_evmyullean_adapter_report.py index e5068039e..00ff8322e 100644 --- a/scripts/generate_evmyullean_adapter_report.py +++ b/scripts/generate_evmyullean_adapter_report.py @@ -480,7 +480,18 @@ def _extract_string_list(pattern: re.Pattern[str]) -> list[str]: def _parse_correctness_proofs() -> dict[str, object]: """Parse adapter correctness proof theorems.""" if not CORRECTNESS_FILE.exists(): - raise FileNotFoundError(f"Correctness proof file not found: {CORRECTNESS_FILE}") + # The legacy adapter correctness file was removed as part of the + # EVMYulLean transition (DoD-5 polish). The native EvmYulLean chain + # no longer relies on the proof-interpreter adapter, so report N/A. + try: + file_label = str(CORRECTNESS_FILE.relative_to(ROOT)) + except ValueError: + file_label = str(CORRECTNESS_FILE) + return { + "file": file_label, + "assign_to_let": "n/a (file removed in EVMYulLean transition)", + "for_init_hoisting": "n/a (file removed in EVMYulLean transition)", + } text = CORRECTNESS_FILE.read_text(encoding="utf-8") code = _strip_lean_strings(_strip_lean_comments(text)) theorem_matches = list(CORRECTNESS_THEOREM_RE.finditer(code)) diff --git a/scripts/test_check_lean_hygiene.py b/scripts/test_check_lean_hygiene.py index 127ee9985..bba53c593 100644 --- a/scripts/test_check_lean_hygiene.py +++ b/scripts/test_check_lean_hygiene.py @@ -55,10 +55,11 @@ def setUp(self) -> None: (self.root / "Verity" / "Proofs").mkdir(parents=True) (self.root / "Contracts").mkdir(parents=True) - # Default: one allowUnsafeReducibility so check 2 passes + # Default: zero allowUnsafeReducibility (the proof chain no longer + # has any unsafe-reducibility uses). self._unsafe_file = self.root / "Compiler" / "Unsafe.lean" self._unsafe_file.write_text( - "set_option allowUnsafeReducibility true\n", encoding="utf-8" + "-- no unsafe here\n", encoding="utf-8" ) # Patch ROOT so the script operates on the fixture @@ -119,27 +120,32 @@ def test_clean_proof_passes(self) -> None: class UnsafeReducibilityTests(HygieneFixtureTestBase): - """Check 2: allowUnsafeReducibility count.""" + """Check 2: allowUnsafeReducibility count (expected = 0 after legacy removal).""" - def test_exactly_one_passes(self) -> None: + def test_exactly_zero_passes(self) -> None: rc, output = self._run_main() self.assertEqual(rc, 0, output) - self.assertIn("1 allowUnsafeReducibility", output) + self.assertIn("0 allowUnsafeReducibility", output) - def test_zero_fails(self) -> None: - self._unsafe_file.write_text("-- no unsafe here\n", encoding="utf-8") + def test_one_fails(self) -> None: + self._unsafe_file.write_text( + "set_option allowUnsafeReducibility true\n", encoding="utf-8" + ) rc, output = self._run_main() self.assertNotEqual(rc, 0) - self.assertIn("Expected 1 allowUnsafeReducibility", output) + self.assertIn("Expected 0 allowUnsafeReducibility, found 1", output) def test_two_fails(self) -> None: + self._unsafe_file.write_text( + "set_option allowUnsafeReducibility true\n", encoding="utf-8" + ) extra = self.root / "Verity" / "Extra.lean" extra.write_text( "set_option allowUnsafeReducibility true\n", encoding="utf-8" ) rc, output = self._run_main() self.assertNotEqual(rc, 0) - self.assertIn("Expected 1 allowUnsafeReducibility, found 2", output) + self.assertIn("Expected 0 allowUnsafeReducibility, found 2", output) def test_lake_dir_excluded(self) -> None: lake = self.root / ".lake" / "packages" / "lib" / "Hack.lean" diff --git a/scripts/test_check_macro_health.py b/scripts/test_check_macro_health.py index 15dc9d5bb..312216ed3 100644 --- a/scripts/test_check_macro_health.py +++ b/scripts/test_check_macro_health.py @@ -13,39 +13,26 @@ class MacroHealthTests(unittest.TestCase): - def test_runs_all_macro_checks_by_default(self) -> None: + def test_runs_property_check_by_default(self) -> None: calls: list[str] = [] old_property = check_macro_health.check_macro_property_test_generation.main - old_invariant = check_macro_health.check_macro_translate_invariant_coverage.main - old_roundtrip = check_macro_health.check_macro_roundtrip_fuzz_coverage.main check_macro_health.check_macro_property_test_generation.main = lambda argv=None: calls.append( f"property:{argv}" ) or 0 - check_macro_health.check_macro_translate_invariant_coverage.main = ( - lambda argv=None: calls.append(f"invariant:{argv}") or 0 - ) - check_macro_health.check_macro_roundtrip_fuzz_coverage.main = lambda argv=None: calls.append( - f"roundtrip:{argv}" - ) or 0 try: self.assertEqual(check_macro_health.main([]), 0) finally: check_macro_health.check_macro_property_test_generation.main = old_property - check_macro_health.check_macro_translate_invariant_coverage.main = old_invariant - check_macro_health.check_macro_roundtrip_fuzz_coverage.main = old_roundtrip - self.assertEqual(calls, ["property:['--check']", "invariant:[]", "roundtrip:[]"]) + self.assertEqual(calls, ["property:['--check']"]) - def test_stops_on_first_failure(self) -> None: + def test_stops_on_property_failure(self) -> None: old_property = check_macro_health.check_macro_property_test_generation.main - old_invariant = check_macro_health.check_macro_translate_invariant_coverage.main check_macro_health.check_macro_property_test_generation.main = lambda argv=None: 1 - check_macro_health.check_macro_translate_invariant_coverage.main = lambda argv=None: 0 try: self.assertEqual(check_macro_health.main([]), 1) finally: check_macro_health.check_macro_property_test_generation.main = old_property - check_macro_health.check_macro_translate_invariant_coverage.main = old_invariant if __name__ == "__main__": diff --git a/scripts/test_check_macro_roundtrip_fuzz_coverage.py b/scripts/test_check_macro_roundtrip_fuzz_coverage.py deleted file mode 100644 index c2b2d7fa6..000000000 --- a/scripts/test_check_macro_roundtrip_fuzz_coverage.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -from __future__ import annotations - -import sys -import unittest -from pathlib import Path - -SCRIPT_DIR = Path(__file__).resolve().parent -if str(SCRIPT_DIR) not in sys.path: - sys.path.insert(0, str(SCRIPT_DIR)) - -import check_macro_roundtrip_fuzz_coverage - - -class MacroRoundTripFuzzCoverageTests(unittest.TestCase): - def test_collect_contracts_ignores_guard_msgs_negative_fixtures(self) -> None: - text = """ - verity_contract HappyPath where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - - #guard_msgs in - verity_contract NegativeFixture where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - end NegativeFixture - """ - - self.assertEqual( - check_macro_roundtrip_fuzz_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - def test_collect_contracts_resets_guard_after_non_contract_command(self) -> None: - text = """ - #guard_msgs in - #check Uint256 - - verity_contract HappyPath where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - """ - - self.assertEqual( - check_macro_roundtrip_fuzz_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - def test_collect_contracts_preserves_duplicate_names_in_one_file(self) -> None: - text = """ - verity_contract Duplicate where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - - verity_contract Duplicate where - storage - counter : Uint256 := slot 1 - function readAgain () : Uint256 := do - return 1 - """ - - self.assertEqual( - check_macro_roundtrip_fuzz_coverage._collect_contracts_from_text(text), - ["Duplicate", "Duplicate"], - ) - - def test_collect_contracts_keeps_guard_through_comments(self) -> None: - text = """ - #guard_msgs in - -- keep guarding the next contract - /- - multi-line comment - -/ - verity_contract NegativeFixture where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - - verity_contract HappyPath where - storage - counter : Uint256 := slot 1 - function readAgain () : Uint256 := do - return 1 - """ - - self.assertEqual( - check_macro_roundtrip_fuzz_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/scripts/test_check_macro_translate_invariant_coverage.py b/scripts/test_check_macro_translate_invariant_coverage.py deleted file mode 100644 index c7356de1f..000000000 --- a/scripts/test_check_macro_translate_invariant_coverage.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -from __future__ import annotations - -import sys -import unittest -from pathlib import Path - -SCRIPT_DIR = Path(__file__).resolve().parent -if str(SCRIPT_DIR) not in sys.path: - sys.path.insert(0, str(SCRIPT_DIR)) - -import check_macro_translate_invariant_coverage - - -class MacroTranslateInvariantCoverageTests(unittest.TestCase): - def test_collect_contracts_ignores_guard_msgs_negative_fixtures(self) -> None: - text = """ - verity_contract HappyPath where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - - /-- - error: expected failure - -/ - #guard_msgs in - verity_contract NegativeFixture where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - end NegativeFixture - """ - - self.assertEqual( - check_macro_translate_invariant_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - def test_collect_contracts_resets_guard_after_non_contract_command(self) -> None: - text = """ - #guard_msgs in - #check Uint256 - - verity_contract HappyPath where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - """ - - self.assertEqual( - check_macro_translate_invariant_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - def test_collect_contracts_keeps_guard_through_comments(self) -> None: - text = """ - #guard_msgs in - -- keep guarding the next contract - /- - multi-line comment - -/ - verity_contract NegativeFixture where - storage - counter : Uint256 := slot 0 - function read () : Uint256 := do - return 0 - - verity_contract HappyPath where - storage - counter : Uint256 := slot 1 - function readAgain () : Uint256 := do - return 1 - """ - - self.assertEqual( - check_macro_translate_invariant_coverage._collect_contracts_from_text(text), - ["HappyPath"], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/scripts/test_check_mapping_slot_boundary.py b/scripts/test_check_mapping_slot_boundary.py index 499f71914..fccc502de 100644 --- a/scripts/test_check_mapping_slot_boundary.py +++ b/scripts/test_check_mapping_slot_boundary.py @@ -27,7 +27,6 @@ def test_comment_decoys_do_not_satisfy_required_markers(self) -> None: mapping_slot = proofs / "MappingSlot.lean" ir = proofs / "IRGeneration" / "IRInterpreter.lean" - sem = proofs / "YulGeneration" / "ReferenceOracle" / "Semantics.lean" builtins = proofs / "YulGeneration" / "ReferenceOracle" / "Builtins.lean" trust = root / "TRUST_ASSUMPTIONS.md" @@ -54,12 +53,6 @@ def test_comment_decoys_do_not_satisfy_required_markers(self) -> None: "def y := Compiler.Proofs.abstractStoreMappingEntry\n", encoding="utf-8", ) - sem.write_text( - "import Compiler.Proofs.MappingSlot\n" - "def x := Compiler.Proofs.abstractStoreStorageOrMapping\n" - "def y := Compiler.Proofs.abstractStoreMappingEntry\n", - encoding="utf-8", - ) builtins.write_text( "import Compiler.Proofs.MappingSlot\n" "def x := Compiler.Proofs.abstractMappingSlot\n" @@ -80,17 +73,15 @@ def test_comment_decoys_do_not_satisfy_required_markers(self) -> None: old_required = check_mapping_slot_boundary.REQUIRED_ABSTRACTION_IMPORTS old_forbidden = check_mapping_slot_boundary.LEGACY_SYMBOL_FORBIDDEN_FILES old_ir = check_mapping_slot_boundary.IR_INTERPRETER_FILE - old_sem = check_mapping_slot_boundary.YUL_SEMANTICS_FILE check_mapping_slot_boundary.ROOT = root check_mapping_slot_boundary.PROOFS_DIR = proofs check_mapping_slot_boundary.MAPPING_SLOT_FILE = mapping_slot check_mapping_slot_boundary.TRUST_ASSUMPTIONS_FILE = trust check_mapping_slot_boundary.BUILTINS_FILE = builtins check_mapping_slot_boundary.ALLOWED_MAPPING_ENCODING_IMPORTERS = set() - check_mapping_slot_boundary.REQUIRED_ABSTRACTION_IMPORTS = {ir, sem} - check_mapping_slot_boundary.LEGACY_SYMBOL_FORBIDDEN_FILES = {ir, sem} + check_mapping_slot_boundary.REQUIRED_ABSTRACTION_IMPORTS = {ir} + check_mapping_slot_boundary.LEGACY_SYMBOL_FORBIDDEN_FILES = {ir} check_mapping_slot_boundary.IR_INTERPRETER_FILE = ir - check_mapping_slot_boundary.YUL_SEMANTICS_FILE = sem try: stderr = io.StringIO() with redirect_stderr(stderr): @@ -109,7 +100,6 @@ def test_comment_decoys_do_not_satisfy_required_markers(self) -> None: check_mapping_slot_boundary.REQUIRED_ABSTRACTION_IMPORTS = old_required check_mapping_slot_boundary.LEGACY_SYMBOL_FORBIDDEN_FILES = old_forbidden check_mapping_slot_boundary.IR_INTERPRETER_FILE = old_ir - check_mapping_slot_boundary.YUL_SEMANTICS_FILE = old_sem if __name__ == "__main__": diff --git a/scripts/test_check_native_transition_doc.py b/scripts/test_check_native_transition_doc.py deleted file mode 100644 index dc388044b..000000000 --- a/scripts/test_check_native_transition_doc.py +++ /dev/null @@ -1,3076 +0,0 @@ -#!/usr/bin/env python3 - -from __future__ import annotations - -import unittest -from pathlib import Path -import sys - -sys.path.insert(0, str(Path(__file__).resolve().parent)) - -import check_native_transition_doc as check - - -class NativeTransitionDocCheckTests(unittest.TestCase): - def replace_in_theorem_signature( - self, text: str, theorem_name: str, old: str, new: str - ) -> str: - signature = check.theorem_signature(text, theorem_name) - self.assertIn(old, signature) - start = text.index(signature) - return text[:start] + signature.replace(old, new, 1) + text[start + len(signature) :] - - def test_current_doc_passes(self) -> None: - text = check.DOC.read_text(encoding="utf-8") - self.assertEqual(check.check_doc(text), []) - - def test_current_definition_of_done_doc_passes(self) -> None: - text = check.DOD_DOC.read_text(encoding="utf-8") - self.assertEqual(check.check_definition_of_done_doc(text), []) - - def test_current_yul_generation_readme_passes(self) -> None: - text = check.YULGEN_README.read_text(encoding="utf-8") - self.assertEqual(check.check_yul_generation_readme(text), []) - - def test_yul_generation_readme_rejects_legacy_main_preservation_status(self) -> None: - text = check.YULGEN_README.read_text(encoding="utf-8").replace( - "**`Preservation.lean`** - Legacy Layer 3 preservation theorem", - "**`Preservation.lean`** - Main Layer 3 preservation theorem", - 1, - ) - errors = check.check_yul_generation_readme(text) - self.assertTrue( - any("Main Layer 3 preservation theorem" in error for error in errors), - errors, - ) - - def test_definition_of_done_doc_rejects_removed_fuel_wrapper_target(self) -> None: - text = check.DOD_DOC.read_text(encoding="utf-8").replace( - "interpretYulRuntimeWithBackend .evmYulLean", - "interpretYulRuntimeEvmYulLeanFuelWrapperDefaultFuel", - 1, - ) - errors = check.check_definition_of_done_doc(text) - self.assertTrue( - any("FuelWrapperDefaultFuel" in error for error in errors), - errors, - ) - - def test_rejects_missing_blocker_issue(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace("#1738", "#0000") - errors = check.check_doc(text) - self.assertTrue(any("#1738" in error for error in errors), errors) - - def test_rejects_missing_observable_slot_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "observable storage slot set explicitly", - "observable storage slot set", - ) - errors = check.check_doc(text) - self.assertTrue(any("observable storage slot set explicitly" in error for error in errors), errors) - - def test_rejects_missing_chainid_validation_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "`YulTransaction.chainId` must match", - "`YulTransaction.chainIdStatus`", - ) - errors = check.check_doc(text) - self.assertTrue( - any("YulTransaction.chainId" in error for error in errors), - errors, - ) - - def test_rejects_missing_blobbasefee_validation_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "`chainid()` and `blobbasefee()` now fail closed on the selected native runtime", - "`YulTransaction.blobBaseFeeStatus`", - ) - errors = check.check_doc(text) - self.assertTrue( - any("blobbasefee" in error for error in errors), - errors, - ) - - def test_rejects_authoritative_native_claim(self) -> None: - text = ( - check.DOC.read_text(encoding="utf-8") - + "\nNative EVMYulLean is now the authoritative semantic target.\n" - ) - errors = check.check_doc(text) - self.assertTrue(any("overstates" in error for error in errors), errors) - - def test_rejects_missing_reference_oracle_retarget_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "`yulCodegen_preserves_semantics_via_reference_oracle`", - "`native_yulCodegen_preserves_semantics`", - ) - errors = check.check_doc(text) - self.assertTrue( - any("yulCodegen_preserves_semantics_via_reference_oracle" in error for error in errors), - errors, - ) - - def test_rejects_missing_explicit_evmyullean_backend_name(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "`yulCodegen_preserves_semantics_evmYulLeanBackend`", - "`yulCodegen_preserves_semantics_evmYulLean`", - ) - errors = check.check_doc(text) - self.assertTrue( - any( - "yulCodegen_preserves_semantics_evmYulLeanBackend" in error - for error in errors - ), - errors, - ) - - def test_rejects_missing_selected_user_body_result_blocker(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - "NativeGeneratedSelectedUserBodyHiddenBridgeAtFuel", - ) - errors = check.check_doc(text) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel" in error for error in errors), - errors, - ) - - def test_rejects_missing_threshold_only_public_guard_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "`SupportedSpec` carries the selected function calldata-threshold inventory", - "selected function full guard inventory", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("calldata-threshold" in error for error in errors), - errors, - ) - - def test_rejects_missing_no_mapping_helper_free_preservation_caveat(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "no-mapping helper-free straight-body preservation bridge", - "selected user-body preservation bridge", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("no-mapping helper-free straight-body preservation" in error for error in errors), - errors, - ) - - def test_rejects_missing_mapping_free_preservation_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_mappingFreePreservableStraightStmts", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_genericStraightStmts", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("mappingFreePreservableStraightStmts" in error for error in errors), - errors, - ) - - def test_rejects_missing_singleton_leave_exec_only_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body", - "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_hidden_body", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("of_leave_body" in error for error in errors), - errors, - ) - - def test_rejects_missing_singleton_stop_halt_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_stop_body", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("of_stop_body" in error for error in errors), - errors, - ) - - def test_rejects_missing_singleton_stop_dispatcher_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_stop_body", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("compile_ok_supported_stop_body" in error for error in errors), - errors, - ) - - def test_rejects_missing_literal_return_dispatcher_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_lit_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_lit_return32", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_rejects_missing_calldataload_return_dispatcher_progress_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload4_return32", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_calldataload4_return32", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("mstore0_calldataload4_return32" in error for error in errors), - errors, - ) - - def test_rejects_missing_aligned_calldata_return_seam_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "execIRFunction_mstore0_calldataload_aligned_return32", - "execIRFunction_mstore0_calldataload_hidden_return32", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("calldataload_aligned_return32" in error for error in errors), - errors, - ) - - def test_rejects_missing_source_level_generated_dispatcher_public_note(self) -> None: - # The doc may mention the canonical theorem name several times (status - # blurb, G1 plan, achievement summary). Replace every occurrence so the - # check actually sees a doc with no mention of the public theorem. - text = check.DOC.read_text(encoding="utf-8").replace( - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher", - "compile_preserves_native_evmYulLean_of_compile_ok_supported_hidden_callDispatcher", - ) - errors = check.check_doc(text) - self.assertTrue( - any("compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher" in error - for error in errors), - errors, - ) - - def test_rejects_missing_legacy_compile_preserves_private_surface_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "Legacy premise-taking `compile_preserves_native_evmYulLean_*`", - "Legacy premise-taking `compile_preserves_native_evmYulLean_hidden`", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("compile_preserves_native_evmYulLean_*" in error for error in errors), - errors, - ) - - def test_rejects_missing_mapping_free_bridged_straight_adapter_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree", - "NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_hidden", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("bridgedStraightStmts_mappingFree" in error for error in errors), - errors, - ) - - def test_rejects_missing_mapping_free_dispatcher_adapter_note(self) -> None: - text = check.DOC.read_text(encoding="utf-8").replace( - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree", - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_hidden", - 1, - ) - errors = check.check_doc(text) - self.assertTrue( - any("bridgedStraightStmts_mappingFree" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_accepts_current_transition_shape(self) -> None: - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_public_theorem_target_guard_rejects_missing_call_dispatcher_match_surface(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def nativeGeneratedCallDispatcherMatchesIROn", - "def nativeGeneratedHiddenCallDispatcherMatchesIROn", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeGeneratedCallDispatcherMatchesIROn" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_mapping_free_expression_seam(self) -> None: - native_harness_text = check.NATIVE_HARNESS.read_text(encoding="utf-8").replace( - "theorem NativeExprPreservesWord_lowerExprNative_of_mappingFreeBridgedExpr", - "theorem NativeExprPreservesWord_lowerExprNative_of_hiddenMappingFreeBridgedExpr", - 1, - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - native_harness_text, - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("mappingFreeBridgedExpr" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_mapping_free_block_seam(self) -> None: - native_harness_text = check.NATIVE_HARNESS.read_text(encoding="utf-8").replace( - "theorem NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_mappingFreePreservableStraightStmts", - "theorem NativeBlockPreservesWord_lowerStmtsNativeWithSwitchIds_of_hiddenMappingFreePreservableStraightStmts", - 1, - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - native_harness_text, - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("mappingFreePreservableStraightStmts" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_call_dispatcher_result_surface(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "noncomputable def nativeGeneratedCallDispatcherResultOf", - "noncomputable def nativeGeneratedHiddenCallDispatcherResultOf", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeGeneratedCallDispatcherResultOf" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_exact_call_dispatcher_theorem(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "\ntheorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported\n" - " (spec : CompilationModel.CompilationModel)", - "\ntheorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden\n" - " (spec : CompilationModel.CompilationModel)", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_adapter_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "nativeGeneratedCallDispatcherResultOf", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("interpretIRRuntimeNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_without_selected_user_body_halt_bridge(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - "NativeGeneratedSelectedUserBodyHiddenHaltExecBridgeAtFuel", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_source_level_generated_theorem_without_source_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher", - "sourceResultMatchesNativeOn", - "nativeResultsMatchOn", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("sourceResultMatchesNativeOn" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_source_level_generated_theorem_direct_projected_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - "nativeGeneratedCallDispatcherResultOf", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeGeneratedCallDispatcherResultOf" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_legacy_compile_preserves_public_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem compile_preserves_native_evmYulLean_selector_miss_noMapping_canonical", - "theorem compile_preserves_native_evmYulLean_selector_miss_noMapping_canonical", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("unexpected public theorem" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_exposing_dispatch_guards(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "4 + tx.args.length * 32 < EvmYul.UInt256.size", - "DispatchGuardsSafe fn tx", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("DispatchGuardsSafe" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_source_threshold_inventory(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "hUserBodyHalt", - "selectorDispatchedFunctions spec", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("selectorDispatchedFunctions spec" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_lowering_witness_name(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "hUserBodyHalt", - "hLowerRuntime", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("hLowerRuntime" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_lower_witness(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "nativeResultsMatchOn observableSlots", - "Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative\n" - " (Compiler.emitYul irContract).runtimeCode = .ok nativeContract ∧\n" - " nativeResultsMatchOn observableSlots", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("lowerRuntimeContractNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_source_level_lower_witness(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_of_compile_ok_supported_generated_callDispatcher", - "sourceResultMatchesNativeOn observableSlots", - "Compiler.Proofs.YulGeneration.Backends.lowerRuntimeContractNative\n" - " (Compiler.emitYul irContract).runtimeCode = .ok nativeContract ∧\n" - " sourceResultMatchesNativeOn observableSlots", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("lowerRuntimeContractNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_private_selected_user_body_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - "private def NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the public exact generated callDispatcher selected user-body halt bridge publicly nameable" - in error - for error in errors - ), - errors, - ) - self.assertTrue( - any( - "must not make the public exact generated callDispatcher selected user-body halt bridge private" - in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_private_success_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectorHitSuccessBridge", - "private def NativeGeneratedSelectorHitSuccessBridge", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the remaining success-case selector-hit bridge publicly nameable" - in error - for error in errors - ), - errors, - ) - self.assertTrue( - any("must not make the remaining success-case selector-hit bridge private" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_exposing_direct_user_body_bridge(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots)\n" - " (hSelectedUserBodyExec :\n" - " NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived irContract tx\n" - " state observableSlots", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_exposing_preservation_bridge(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots)\n" - " (hPreserves :\n" - " NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel irContract tx", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_theorem_exposing_generated_prefix_continuation(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots", - "NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel irContract tx state\n observableSlots)\n" - " (hGeneratedPrefixCont :\n" - " NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation irContract\n" - " tx state observableSlots", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_exact_call_dispatcher_wrapper_deprecation_target(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "attribute [deprecated nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported\n" - " (since := \"2026-05-07\")]", - "attribute [deprecated nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selector_hit_user_body_exec_bridge_success_only_atFuel_revived_and_continuation\n" - " (since := \"2026-05-07\")]", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compatibility wrappers must be deprecated" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_exact_wrapper_deprecation(self) -> None: - removed_wrapper = ( - " nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_empty_selected_body\n" - ) - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - removed_wrapper, - "", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("empty_selected_body" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_interpret_wrapper_deprecation_target(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "attribute [deprecated compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match\n" - " (since := \"2026-05-07\")]", - "attribute [deprecated compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match\n" - " (since := \"2026-05-07\")]", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("interpretIRRuntimeNative compatibility wrappers" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_interpret_wrapper_deprecation(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - " compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_mapping_dispatcher_ofIR_environment\n" - " compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_mapping_dispatcher_ofIR_globalDefaults\n", - " compile_preserves_native_evmYulLean_of_interpretIRRuntimeNative_match_mapping_dispatcher_ofIR_environment\n", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("match_mapping_dispatcher_ofIR_globalDefaults" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_interpret_eq_wrapper_deprecation_target(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "attribute [deprecated nativeGeneratedCallDispatcherResultOf\n" - " (since := \"2026-05-07\")]", - "attribute [deprecated nativeGeneratedCallDispatcherResultOf_eq_interpretIRRuntimeNative_of_lowerRuntimeContractNative_supported\n" - " (since := \"2026-05-07\")]", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("interpretIRRuntimeNative equality wrappers" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_interpret_eq_wrapper_deprecation(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - " nativeGeneratedCallDispatcherResultOf_eq_interpretIRRuntimeNative_of_lowerRuntimeContractNative_supported_except_mapping_writes_stmt_safety\n", - "", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("except_mapping_writes_stmt_safety" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_exec_only_body_bridge_split(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectorHitUserBodyExecHiddenBridgeAtFuelRevived", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_direct_user_body_exec_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectedUserBodyExecHiddenBridgeAtFuelRevived", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_direct_user_body_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - "def NativeGeneratedSelectedUserBodyHiddenResultBridgeAtFuel", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_preservation_body_bridge_split(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel", - "def NativeGeneratedSelectorHitUserBodyHiddenPreservesBridgeAtFuel", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_generated_prefix_continuation_split(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "def NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation", - "def NativeGeneratedSelectorHitUserBodyHiddenGeneratedPrefixContinuation", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectorHitUserBodyGeneratedPrefixContinuation" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_exec_only_bridge_projection(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_exec_bridge", - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("ExecOnlyBridgeAtFuelRevived.of_exec_bridge" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_direct_user_body_exec_projection(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_exec_only", - "theorem NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived.of_selected_user_body_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("of_selected_user_body_exec_only" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_preservation_bridge_projection(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_exec_bridge", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("PreservesBridgeAtFuel.of_exec_bridge" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_preservation_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_forall_stmt_write_not_mem", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("of_forall_stmt_write_not_mem" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_block_fresh_preservation_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_nativeStmtsWriteNames_not_mem", - "theorem NativeGeneratedSelectorHitUserBodyPreservesBridgeAtFuel.of_nativeStmtsWriteNames_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("of_nativeStmtsWriteNames_not_mem" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_body_bridge_recombiner(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves", - "theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("of_exec_only_and_preserves" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_result_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_preserves", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("ResultBridgeAtFuel.of_exec_only_and_preserves" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_block_fresh_result_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_nativeStmtsWriteNames_not_mem", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_nativeStmtsWriteNames_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "ResultBridgeAtFuel.of_exec_only_and_nativeStmtsWriteNames_not_mem" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_mapping_straight_result_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mapping", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "ResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mapping" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_mapping_free_straight_result_bridge_constructor(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree", - "private theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_noMappingHidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "ResultBridgeAtFuel.of_exec_only_and_bridgedStraightStmts_mappingFree" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_mapping_free_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_with_selected_user_body_exec_only_and_bridgedStraightStmts_noMappingHidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "with_selected_user_body_exec_only_and_bridgedStraightStmts_mappingFree" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_selector_miss_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem nativeGeneratedCallDispatcherResult_selector_miss_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_miss_matchesIR_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("selector_miss_matchesIR_exists_of_compile_ok_supported" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_nonpayable_guard_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem nativeGeneratedCallDispatcherResult_selector_hit_nonpayable_nonzero_revert_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_nonpayable_nonzero_revert_matchesIR_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "selector_hit_nonpayable_nonzero_revert_matchesIR_exists_of_compile_ok_supported" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_args_short_guard_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem nativeGeneratedCallDispatcherResult_selector_hit_args_short_revert_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_args_short_revert_matchesIR_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "selector_hit_args_short_revert_matchesIR_exists_of_compile_ok_supported" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_hit_error_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem nativeGeneratedCallDispatcherResult_selector_hit_error_matchesIR_exists_of_compile_ok_supported", - "theorem nativeGeneratedCallDispatcherResult_selector_hit_error_matchesIR_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("selector_hit_error_matchesIR_exists_of_compile_ok_supported" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_lower_runtime_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem lowerRuntimeContractNative_of_compile_ok_supported_exists", - "theorem lowerRuntimeContractNative_of_compile_ok_supported_hidden", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("lowerRuntimeContractNative_of_compile_ok_supported_exists" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_selected_body_lowering_handoff(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem selectedFunctionBodyBridgedAndLowered_of_compile_ok_supported", - "theorem selectedFunctionBodyBridgedAndLowered_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("selectedFunctionBodyBridgedAndLowered_of_compile_ok_supported" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_success_user_body_artifact_exists_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem nativeGeneratedSelectorHitSuccessUserBodyLoweredArtifacts_exists_of_compile_ok_supported", - "theorem nativeGeneratedSelectorHitSuccessUserBodyLoweredArtifacts_hidden_of_compile_ok_supported", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "nativeGeneratedSelectorHitSuccessUserBodyLoweredArtifacts_exists_of_compile_ok_supported" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_leave_exec_only_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body", - "theorem NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_hidden_body", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived.of_leave_body" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_stop_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_stop_body", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_stop_body" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_stop_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_stop_body", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_hidden_stop_body", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_stop_body" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_stop_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_stop_body", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_stop_body", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_stop_body" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_literal_return_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_literal_return_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_hidden_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_literal_return_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_lit_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_literal_return_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_zeroParam_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_literal_return_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_lit_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_hidden_zeroParam_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_literal_return_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_lit_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_zeroParam_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_zeroParam_mstore0_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_literal_return_source_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_lit_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_source_zeroParam_lit_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_source_zeroParam_lit_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_sload_return_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_zeroParam_sload0_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_zeroParam_mstore0_sload0_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_sload_return_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_sload0_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_hidden_zeroParam_sload0_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_zeroParam_mstore0_sload0_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_sload_return_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_zeroParam_mstore0_sload0_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_zeroParam_sload0_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_zeroParam_mstore0_sload0_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_zero_param_sload_return_source_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_source_zeroParam_sload0_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_source_zeroParam_sload0_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_source_zeroParam_sload0_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_calldataload_return_halt_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_calldataload4_return32", - "theorem NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_hidden_calldataload4_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyHaltExecBridgeAtFuel.of_mstore0_calldataload4_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_calldataload_return_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_calldataload4_return32", - "theorem NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_hidden_calldataload4_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("NativeGeneratedSelectedUserBodyResultBridgeAtFuel.of_mstore0_calldataload4_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_calldataload_return_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_mstore0_calldataload4_return32", - "private theorem nativeGeneratedCallDispatcherMatchesIR_of_compile_ok_supported_hidden_calldataload4_return32", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("compile_ok_supported_mstore0_calldataload4_return32" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_unsafe_leave_preservation_bridge(self) -> None: - native_harness_text = ( - check.NATIVE_HARNESS.read_text(encoding="utf-8") - + "\ntheorem NativeStmtPreservesWord_leave : True := by trivial\n" - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - native_harness_text, - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must not close the selected-body result bridge" in error - and "raw `leave`" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_exec_only_body_bridge_split(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private def NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the selected selector-hit bridge seam private" in error - and "NativeGeneratedSelectorHitUserBodyExecOnlyBridgeAtFuelRevived" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_direct_user_body_exec_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private def NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - "def NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the selected selector-hit bridge seam private" in error - and "NativeGeneratedSelectedUserBodyExecOnlyBridgeAtFuelRevived" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_direct_user_body_result_bridge(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private def NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - "def NativeGeneratedSelectedUserBodyResultBridgeAtFuel", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the selected selector-hit bridge seam private" in error - and "NativeGeneratedSelectedUserBodyResultBridgeAtFuel" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_body_bridge_recombiner(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves", - "theorem NativeGeneratedSelectorHitUserBodyExecBridgeAtFuelRevived.of_exec_only_and_preserves", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "must keep the selected selector-hit bridge seam private" in error - and "of_exec_only_and_preserves" in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_dispatcher_exec_surface(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - .replace( - "private def nativeGeneratedDispatcherExecMatchesIROn", - "def nativeGeneratedDispatcherExecMatchesIROn", - 1, - ) - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("dispatcher-exec compatibility seams private" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_removed_generated_call_dispatcher_adapter(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nprivate theorem compile_preserves_native_evmYulLean_of_generated_callDispatcher_match " - + ": True := by trivial\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("removed backend-wrapper transition lemma" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_native_results_adapter(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem compile_preserves_native_evmYulLean_of_nativeResultsMatchOn", - "theorem compile_preserves_native_evmYulLean_of_nativeResultsMatchOn", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("adapter theorem file-local" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_direct_generated_call_dispatcher_theorem(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "theorem compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "theorem compile_preserves_native_evmYulLean_hiddenCallDispatcher_of_generated_callDispatcher_match", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match" - in error - for error in errors - ), - errors, - ) - - def test_public_theorem_target_guard_rejects_missing_lowered_call_dispatcher_wrappers(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8") - end_to_end_text = end_to_end_text.replace( - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_hiddenCallDispatcher_noMapping", - 1, - ).replace( - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - "theorem compile_preserves_native_evmYulLean_of_lowered_generated_hiddenCallDispatcher_mapping", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("lowered_generated_callDispatcher_noMapping" in error for error in errors), - errors, - ) - self.assertTrue( - any("lowered_generated_callDispatcher_mapping" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_undeprecated_call_dispatcher_wrapper(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "@[deprecated compile_preserves_native_evmYulLean_of_nativeGeneratedCallDispatcherResult_match\n" - " (since := \"2026-05-07\")]\n" - "private theorem compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "theorem compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - 1, - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("must be marked deprecated" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_lowered_nomapping_adapter_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_noMapping", - "nativeGeneratedCallDispatcherResultOf", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("thin runtime adapter" in error for error in errors), - errors, - ) - self.assertTrue( - any("interpretIRRuntimeNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_base_call_dispatcher_adapter_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match", - "nativeGeneratedCallDispatcherResultOf", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("thin runtime adapter" in error for error in errors), - errors, - ) - self.assertTrue( - any("interpretIRRuntimeNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_lowered_mapping_adapter_target(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "compile_preserves_native_evmYulLean_of_lowered_generated_callDispatcher_mapping", - "nativeGeneratedCallDispatcherResultOf", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("thin runtime adapter" in error for error in errors), - errors, - ) - self.assertTrue( - any("interpretIRRuntimeNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_legacy_backend_target(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\n-- stale target: interpretYulRuntimeWithBackend .evmYulLean\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("interpretYulRuntimeWithBackend .evmYulLean" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_accepts_native_theorem_seam(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\n-- theorem target: interpretIRRuntimeNative\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_public_theorem_target_guard_rejects_reintroduced_native_fuel_wrapper_obligation(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_reintroduced_yul_result_agreement(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef yulResultsAgreeOn : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("yulResultsAgreeOn" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_direct_wrapper_fuel_bridge_obligation(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeIRRuntimeAgreesWithEvmYulLeanFuelWrapper" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_hidden_ir_runtime_alias(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeIRRuntimeAgreesWithEvmYulLean : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("hidden native IR-runtime fuel-wrapper alias" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_simple_storage_native_compat_wrapper(self) -> None: - end_to_end_text = self.replace_in_theorem_signature( - check.END_TO_END.read_text(encoding="utf-8"), - "simpleStorage_endToEnd_native_evmYulLean", - "nativeGeneratedCallDispatcherResultOf", - "Compiler.Proofs.YulGeneration.Backends.Native.interpretIRRuntimeNative", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeGeneratedCallDispatcherResultOf" in error for error in errors), - errors, - ) - self.assertTrue( - any("interpretIRRuntimeNative" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_simple_storage_native_compat_splitter(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "simpleStorageNativeCallDispatcherMatchBridge_of_per_case\n" - " tx initialState observableSlots", - "simpleStorageNativeCallDispatcherBridge_of_per_case\n" - " tx initialState observableSlots", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("CallDispatcherMatchBridge" in error for error in errors), - errors, - ) - self.assertTrue( - any("CallDispatcherBridge" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_misleading_positive_layer3_alias(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ntheorem layer3_contract_preserves_semantics_native_of_generated_dispatcherExec_positive " - + ": True := by trivial\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("positive_match" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_misleading_positive_layers23_alias(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ntheorem layers2_3_ir_matches_native_evmYulLean_of_generated_dispatcherExec_positive " - + ": True := by trivial\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("positive_match" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_removed_simple_storage_bridge_surface(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef simpleStorageNativeRetrieveHitBridge : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("obsolete SimpleStorage fuel-wrapper bridge" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_simple_storage_native_scaffold_surface(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nnoncomputable def simpleStorageNativeDispatcherFuel : Nat := 1\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("dispatcher proof scaffolding" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_source_body_closure_surface(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef SourceBodyNativeClosure (_model : Model) (_selectors : List Nat) : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("SourceBodyNativeClosure" in error and "file-local" in error for error in errors), - errors, - ) - - def test_rejects_verity_default_builtin_backend(self) -> None: - builtins_text = check.BUILTINS.read_text(encoding="utf-8").replace( - "private abbrev defaultBuiltinBackend : BuiltinBackend := .evmYulLean", - "private abbrev defaultBuiltinBackend : BuiltinBackend := .verity", - ) - errors = check.check_default_builtin_backend(builtins_text) - self.assertTrue( - any("default builtin backend" in error for error in errors), - errors, - ) - - def test_rejects_public_default_builtin_backend_alias(self) -> None: - builtins_text = check.BUILTINS.read_text(encoding="utf-8").replace( - "private abbrev defaultBuiltinBackend : BuiltinBackend := .evmYulLean", - "abbrev defaultBuiltinBackend : BuiltinBackend := .evmYulLean", - ) - errors = check.check_default_builtin_backend(builtins_text) - self.assertTrue( - any("defaultBuiltinBackend" in error for error in errors), - errors, - ) - - def test_rejects_public_eval_builtin_call_wrapper(self) -> None: - builtins_text = check.BUILTINS.read_text(encoding="utf-8").replace( - "private def evalBuiltinCall", - "def evalBuiltinCall", - 1, - ) - errors = check.check_default_builtin_backend(builtins_text) - self.assertTrue( - any("evalBuiltinCall" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_reintroduced_call_dispatcher_fuel_wrapper(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeCallDispatcherAgreesWithEvmYulLeanFuelWrapper : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeCallDispatcherAgreesWithEvmYulLeanFuelWrapper" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_eval_builtin_call_mention(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\n-- stale proof note: evalBuiltinCall\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("evalBuiltinCall" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_reintroduced_dispatcher_block_fuel_wrapper(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeDispatcherBlockAgreesWithEvmYulLeanFuelWrapper : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeDispatcherBlockAgreesWithEvmYulLeanFuelWrapper" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_reintroduced_dispatcher_exec_fuel_wrapper(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ndef nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper : Prop := True\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("nativeDispatcherExecAgreesWithEvmYulLeanFuelWrapper" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_low_level_native_target(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\n-- theorem target: EvmYul.Yul.callDispatcher\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue(any("callDispatcher" in error for error in errors), errors) - - def test_public_theorem_target_guard_rejects_removed_backend_wrapper(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nprivate theorem layers2_3_ir_matches_yul_evmYulLeanBackend : True := by trivial\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("layers2_3_ir_matches_yul_evmYulLeanBackend" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_native_identity_seam(self) -> None: - end_to_end_text = check.END_TO_END.read_text(encoding="utf-8").replace( - "private theorem layers2_3_ir_matches_native_evmYulLean", - "theorem layers2_3_ir_matches_native_evmYulLean", - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("arbitrary-fuel native identity seam" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_hidden_evmyullean_fuel_alias(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\ndef interpretYulRuntimeEvmYulLean runtimeCode tx storage events := True\n" - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - retarget_text, - ) - self.assertTrue( - any("interpretYulRuntimeEvmYulLean" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_backend_interpreter_surface(self) -> None: - retarget_text = check.RETARGET.read_text(encoding="utf-8").replace( - "private noncomputable def interpretYulRuntimeWithBackend", - "noncomputable def interpretYulRuntimeWithBackend", - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - retarget_text, - ) - self.assertTrue( - any("backend-interpreter transition surface" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_backend_fuel_surface(self) -> None: - retarget_text = check.RETARGET.read_text(encoding="utf-8").replace( - "private theorem execYulFuelWithBackend_eq_on_bridged_target", - "theorem execYulFuelWithBackend_eq_on_bridged_target", - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - retarget_text, - ) - self.assertTrue( - any("backend-interpreter transition surface" in error for error in errors), - errors, - ) - - def test_public_theorem_target_guard_rejects_public_expression_bridge_surface(self) -> None: - retarget_text = check.RETARGET.read_text(encoding="utf-8").replace( - "private theorem evalYulExpr_evmYulLean_eq_on_bridged", - "theorem evalYulExpr_evmYulLean_eq_on_bridged", - ) - errors = check.check_public_theorem_target( - check.END_TO_END.read_text(encoding="utf-8"), - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - retarget_text, - ) - self.assertTrue( - any("backend-interpreter transition surface" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_accepts_current_shape(self) -> None: - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_public_surface_guard_rejects_legacy_reference_oracle_end_to_end_wrapper(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ntheorem layer3_contract_preserves_semantics_via_reference_oracle : True := by trivial\n" - ) - errors = check.check_public_theorem_target( - end_to_end_text, - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("layer3_contract_preserves_semantics_via_reference_oracle" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_bare_legacy_theorem_name(self) -> None: - preservation_text = check.PRESERVATION.read_text(encoding="utf-8").replace( - "theorem yulCodegen_preserves_semantics_via_reference_oracle", - "theorem yulCodegen_preserves_semantics", - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - check.RETARGET.read_text(encoding="utf-8"), - preservation_text, - ) - self.assertTrue( - any("bare `yulCodegen_preserves_semantics`" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_reintroduced_evmyullean_retarget(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\nprivate theorem yulCodegen_preserves_semantics_evmYulLeanBackend " - + ": True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - retarget_text, - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("transition-only legacy Layer-3 retarget theorem" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_public_evmyullean_retarget(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\ntheorem yulCodegen_preserves_semantics_evmYulLeanBackend " - + ": True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - retarget_text, - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("transition-only legacy Layer-3 retarget theorem" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_hidden_evmyullean_alias(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\ntheorem yulCodegen_preserves_semantics_evmYulLean : True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - retarget_text, - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("hidden reference-oracle compatibility alias" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_hidden_evmyullean_via_reference_alias(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\ntheorem yulCodegen_preserves_semantics_evmYulLean_via_reference_oracle : True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - retarget_text, - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("hidden default-fuel compatibility alias" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_reintroduced_evmyullean_via_reference_retarget(self) -> None: - retarget_text = ( - check.RETARGET.read_text(encoding="utf-8") - + "\nprivate theorem yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle " - + ": True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - check.END_TO_END.read_text(encoding="utf-8"), - retarget_text, - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("transition-only legacy Layer-3 retarget theorem" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_end_to_end_compat_alias_call(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\n-- yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle\n" - ) - errors = check.check_reference_oracle_names( - end_to_end_text, - check.RETARGET.read_text(encoding="utf-8"), - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("legacy compatibility alias" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_reintroduced_native_layer3_oracle_seam(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ntheorem layer3_contract_preserves_semantics_native_via_reference_oracle_of_evmYulLean_bridge " - + ": True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - end_to_end_text, - check.RETARGET.read_text(encoding="utf-8"), - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("layer3_contract_preserves_semantics_native_via_reference_oracle_of_evmYulLean_bridge" in error for error in errors), - errors, - ) - - def test_reference_oracle_names_guard_rejects_reintroduced_native_end_to_end_oracle_seam(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\ntheorem layers2_3_ir_matches_native_evmYulLean_via_reference_oracle_of_evmYulLean_bridge " - + ": True := by trivial\n" - ) - errors = check.check_reference_oracle_names( - end_to_end_text, - check.RETARGET.read_text(encoding="utf-8"), - check.PRESERVATION.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("layers2_3_ir_matches_native_evmYulLean_via_reference_oracle_of_evmYulLean_bridge" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_accepts_current_shape(self) -> None: - errors = check.check_legacy_proof_boundary( - [ - ("Compiler/Proofs/EndToEnd.lean", check.END_TO_END.read_text(encoding="utf-8")), - ("Compiler.lean", check.ROOT_COMPILER.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - check.BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertEqual(errors, []) - - def test_public_transitive_import_boundary_accepts_current_shape(self) -> None: - errors = check.check_public_transitive_import_boundary( - [ - ("Compiler/Proofs/EndToEnd.lean", check.END_TO_END.read_text(encoding="utf-8")), - ("Compiler.lean", check.ROOT_COMPILER.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - check.BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ] - ) - self.assertEqual(errors, []) - - def test_public_transitive_import_boundary_rejects_helper_reaching_bridge_lemmas(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeTest\n" - ) - errors = check.check_public_transitive_import_boundary( - [("Compiler/Proofs/EndToEnd.lean", end_to_end_text)] - ) - self.assertTrue( - any("EvmYulLeanBridgeLemmas" in error for error in errors), - errors, - ) - - def test_public_transitive_import_boundary_rejects_helper_reaching_reference_oracle(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeTest\n" - ) - errors = check.check_public_transitive_import_boundary( - [("Compiler/Proofs/EndToEnd.lean", end_to_end_text)] - ) - self.assertTrue( - any("ReferenceOracle.Builtins" in error for error in errors), - errors, - ) - - def test_transition_only_import_allowlist_accepts_current_shape(self) -> None: - errors = check.check_transition_only_import_allowlist( - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.transition_import_scan_files() - ] - ) - self.assertEqual(errors, []) - - def test_transition_only_import_allowlist_rejects_new_bridge_lemmas_importer(self) -> None: - errors = check.check_transition_only_import_allowlist( - [ - ( - "Compiler/Proofs/EndToEnd.lean", - "import Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas\n", - ) - ] - ) - self.assertTrue( - any("transition-only bridge lemma module" in error for error in errors), - errors, - ) - - def test_transition_only_import_allowlist_rejects_new_reference_oracle_importer(self) -> None: - errors = check.check_transition_only_import_allowlist( - [ - ( - "Compiler/Proofs/EndToEnd.lean", - "import Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics\n", - ) - ] - ) - self.assertTrue( - any("legacy ReferenceOracle module" in error for error in errors), - errors, - ) - - def test_public_transitive_forbidden_terms_accepts_current_shape(self) -> None: - errors = check.check_public_transitive_forbidden_terms( - [ - ("Compiler/Proofs/EndToEnd.lean", check.END_TO_END.read_text(encoding="utf-8")), - ("Compiler.lean", check.ROOT_COMPILER.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgePredicates.lean", - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", - check.BODY_CLOSURE.read_text(encoding="utf-8"), - ), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ), - ] - ) - self.assertEqual(errors, []) - - def test_public_transitive_forbidden_terms_rejects_adapter_legacy_term(self) -> None: - adapter_text = ( - check.NATIVE_ADAPTER.read_text(encoding="utf-8") - + "\n-- stale proof dependency: interpretYulRuntimeWithBackend .evmYulLean\n" - ) - errors = check.check_public_transitive_forbidden_terms( - [ - ("Compiler.lean", check.ROOT_COMPILER.read_text(encoding="utf-8")), - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - adapter_text, - ), - ] - ) - self.assertTrue( - any("interpretYulRuntimeWithBackend" in error for error in errors), - errors, - ) - - def test_public_transitive_forbidden_terms_rejects_native_harness_legacy_term(self) -> None: - native_harness_text = ( - check.NATIVE_HARNESS.read_text(encoding="utf-8") - + "\n-- stale proof dependency: evalBuiltinCallWithContext\n" - ) - errors = check.check_public_transitive_forbidden_terms( - [ - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - native_harness_text, - ) - ] - ) - self.assertTrue( - any("evalBuiltinCallWithContext" in error for error in errors), - errors, - ) - - def test_bridge_lemmas_transition_surface_accepts_current_shape(self) -> None: - errors = check.check_bridge_lemmas_transition_surface( - check.BRIDGE_LEMMAS.read_text(encoding="utf-8") - ) - self.assertEqual(errors, []) - - def test_bridge_lemmas_transition_surface_rejects_public_pure_bridge(self) -> None: - bridge_lemmas_text = check.BRIDGE_LEMMAS.read_text(encoding="utf-8").replace( - "private theorem evalBuiltinCallWithBackendContext_evmYulLean_pure_bridge", - "theorem evalBuiltinCallWithBackendContext_evmYulLean_pure_bridge", - 1, - ) - errors = check.check_bridge_lemmas_transition_surface(bridge_lemmas_text) - self.assertTrue( - any("pure_bridge" in error for error in errors), - errors, - ) - - def test_adapter_correctness_transition_surface_accepts_current_shape(self) -> None: - errors = check.check_adapter_correctness_transition_surface( - check.ADAPTER_CORRECTNESS.read_text(encoding="utf-8") - ) - self.assertEqual(errors, []) - - def test_adapter_correctness_transition_surface_rejects_public_helpers(self) -> None: - adapter_correctness_text = ( - check.ADAPTER_CORRECTNESS.read_text(encoding="utf-8") - .replace("private theorem assign_equiv_let", "theorem assign_equiv_let", 1) - .replace( - "@[simp] private theorem legacyExecYulFuel_stmts_nil", - "@[simp] theorem legacyExecYulFuel_stmts_nil", - 1, - ) - ) - errors = check.check_adapter_correctness_transition_surface(adapter_correctness_text) - self.assertTrue( - any("assign_equiv_let" in error for error in errors), - errors, - ) - self.assertTrue( - any("legacyExecYulFuel_stmts_nil" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_accepts_current_shape(self) -> None: - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_native_closure_import_boundary_rejects_legacy_predicate_language(self) -> None: - bridge_text = ( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8") - + "\n/- native and transition backends agree through .verity -/\n" - ) - errors = check.check_native_closure_import_boundary( - bridge_text, - check.BODY_CLOSURE.read_text(encoding="utf-8"), - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("legacy transition authority language" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_bridge_predicates_ir_interpreter_import(self) -> None: - bridge_text = ( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8").replace( - "import Compiler.Proofs.YulGeneration.LogNames", - "import Compiler.Proofs.IRGeneration.IRInterpreter", - 1, - ) - ) - errors = check.check_native_closure_import_boundary( - bridge_text, - check.BODY_CLOSURE.read_text(encoding="utf-8"), - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ) - self.assertTrue( - any("full IR interpreter" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_source_keccak_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "theorem compileExpr_keccak256_bridgedSource_of_exprCompileCore", - "theorem compileExpr_keccak256_removed_for_test", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any( - "compileExpr_keccak256_bridgedSource_of_exprCompileCore" in error - for error in errors - ), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_source_storage_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "| storage (fieldName : String) : BridgedSourceExpr (.storage fieldName)", - "| storageRemoved (fieldName : String) : BridgedSourceExpr (.storage fieldName)", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any("BridgedSourceExpr (.storage fieldName)" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_source_array_length_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "| arrayLength (name : String) : BridgedSourceExpr (.arrayLength name)", - "| arrayLengthRemoved (name : String) : BridgedSourceExpr (.arrayLength name)", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any("arrayLength" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_reserved_exp_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "| builtinExp {base exponent}", - "| builtinExpRemoved {base exponent}", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any("builtinExp" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_source_storage_array_length_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "| storageArrayLength (fieldName : String) :", - "| storageArrayLengthRemoved (fieldName : String) :", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any("storageArrayLength" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_source_adt_read_closure(self) -> None: - source_text = check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8").replace( - "| adtTag (adtName storageField : String) :", - "| adtTagRemoved (adtName storageField : String) :", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - check.BODY_CLOSURE.read_text(encoding="utf-8"), - source_text, - ) - self.assertTrue( - any("adtTag" in error for error in errors), - errors, - ) - - def test_native_closure_import_boundary_rejects_missing_body_keccak_closure(self) -> None: - body_text = check.BODY_CLOSURE.read_text(encoding="utf-8").replace( - "theorem bridgedSafeStmts_externalMstoreLetKeccak_of_exprCompileCore", - "theorem bridgedSafeStmts_externalMstoreLetKeccak_removed_for_test", - 1, - ) - errors = check.check_native_closure_import_boundary( - check.BRIDGE_PREDICATES.read_text(encoding="utf-8"), - body_text, - check.SOURCE_EXPR_CLOSURE.read_text(encoding="utf-8"), - ) - self.assertTrue( - any( - "bridgedSafeStmts_externalMstoreLetKeccak_of_exprCompileCore" in error - for error in errors - ), - errors, - ) - - def test_runtime_types_import_boundary_accepts_current_shape(self) -> None: - errors = check.check_runtime_types_import_boundary( - check.RUNTIME_TYPES.read_text(encoding="utf-8") - ) - self.assertEqual(errors, []) - - def test_runtime_types_import_boundary_rejects_ir_interpreter_import(self) -> None: - runtime_types_text = check.RUNTIME_TYPES.read_text(encoding="utf-8").replace( - "import Compiler.Proofs.IRGeneration.IRRuntimeTypes", - "import Compiler.Proofs.IRGeneration.IRInterpreter", - 1, - ) - errors = check.check_runtime_types_import_boundary(runtime_types_text) - self.assertTrue( - any("full IR interpreter" in error for error in errors), - errors, - ) - - def test_native_harness_import_boundary_accepts_current_shape(self) -> None: - errors = check.check_native_harness_import_boundary( - check.NATIVE_HARNESS.read_text(encoding="utf-8") - ) - self.assertEqual(errors, []) - - def test_native_harness_import_boundary_rejects_ir_interpreter_import(self) -> None: - native_harness_text = ( - check.NATIVE_HARNESS.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.IRGeneration.IRInterpreter\n" - ) - errors = check.check_native_harness_import_boundary(native_harness_text) - self.assertTrue( - any("full IR interpreter" in error for error in errors), - errors, - ) - - def test_root_compiler_import_boundary_accepts_current_shape(self) -> None: - errors = check.check_root_compiler_import_boundary( - check.ROOT_COMPILER.read_text(encoding="utf-8") - ) - self.assertEqual(errors, []) - - def test_root_compiler_import_boundary_rejects_direct_ir_interpreter_import(self) -> None: - root_text = ( - check.ROOT_COMPILER.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.IRGeneration.IRInterpreter\n" - ) - errors = check.check_root_compiler_import_boundary(root_text) - self.assertTrue( - any("full IR interpreter" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_public_boundary_import(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Equivalence\n" - ) - errors = check.check_legacy_proof_boundary( - [("Compiler/Proofs/EndToEnd.lean", end_to_end_text)], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("transition-only legacy proof module" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_end_to_end_retarget_import(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget\n" - ) - errors = check.check_legacy_proof_boundary( - [("Compiler/Proofs/EndToEnd.lean", end_to_end_text)], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("EvmYulLeanRetarget" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_root_retarget_import(self) -> None: - root_compiler_text = ( - check.ROOT_COMPILER.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Backends.EvmYulLeanRetarget\n" - ) - errors = check.check_legacy_proof_boundary( - [("Compiler.lean", root_compiler_text)], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("EvmYulLeanRetarget" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_root_bridge_lemmas_import(self) -> None: - root_compiler_text = ( - check.ROOT_COMPILER.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.Backends.EvmYulLeanBridgeLemmas\n" - ) - errors = check.check_legacy_proof_boundary( - [("Compiler.lean", root_compiler_text)], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("EvmYulLeanBridgeLemmas" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_adapter_reference_oracle_import(self) -> None: - adapter_text = ( - check.NATIVE_ADAPTER.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.ReferenceOracle.Builtins\n" - ) - errors = check.check_legacy_proof_boundary( - [ - ( - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - adapter_text, - ) - ], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("legacy ReferenceOracle modules" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_root_reference_oracle_import(self) -> None: - root_compiler_text = ( - check.ROOT_COMPILER.read_text(encoding="utf-8") - + "\nimport Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics\n" - ) - errors = check.check_legacy_proof_boundary( - [("Compiler.lean", root_compiler_text)], - [ - (path.relative_to(check.ROOT).as_posix(), path.read_text(encoding="utf-8")) - for path in check.LEGACY_PROOF_FILES - ], - ) - self.assertTrue( - any("legacy ReferenceOracle modules" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_public_legacy_declaration(self) -> None: - legacy_text = ( - check.LEGACY_PROOF_FILES[1].read_text(encoding="utf-8") - + "\ntheorem leakedLegacyTransitionAuthority : True := by trivial\n" - ) - errors = check.check_legacy_proof_boundary( - [], - [("Compiler/Proofs/YulGeneration/Equivalence.lean", legacy_text)], - ) - self.assertTrue( - any("leakedLegacyTransitionAuthority" in error for error in errors), - errors, - ) - - def test_legacy_proof_boundary_rejects_public_attributed_legacy_declaration(self) -> None: - legacy_text = ( - check.LEGACY_PROOF_FILES[0].read_text(encoding="utf-8") - + "\n@[simp] theorem leakedLegacyFuelSimp : True := by trivial\n" - ) - errors = check.check_legacy_proof_boundary( - [], - [("Compiler/Proofs/YulGeneration/Codegen.lean", legacy_text)], - ) - self.assertTrue( - any("leakedLegacyFuelSimp" in error for error in errors), - errors, - ) - - def test_native_alias_signature_guard_accepts_current_shape(self) -> None: - errors = check.check_native_alias_signatures( - check.END_TO_END.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_native_alias_signature_guard_rejects_hidden_dispatcher_alias(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + """ -theorem nativeAliasSurfaceForTestEvmYulLean - (h : - nativeDispatcherExecAgreesWithEvmYulLean fuel contract tx state - observableSlots nativeContract) : - True := by - trivial -""" - ) - errors = check.check_native_alias_signatures(end_to_end_text) - self.assertTrue( - any("nativeDispatcherExecAgreesWithEvmYulLean" in error for error in errors), - errors, - ) - - def test_native_alias_signature_guard_rejects_lowercase_evmYulLean_name(self) -> None: - end_to_end_text = """ -theorem nativeAliasSurfaceForTest_evmYulLean - (h : - nativeDispatcherExecAgreesWithEvmYulLean fuel contract tx state - observableSlots nativeContract) : - True := by - trivial -""" - errors = check.check_native_alias_signatures(end_to_end_text) - self.assertTrue( - any("nativeDispatcherExecAgreesWithEvmYulLean" in error for error in errors), - errors, - ) - - def test_native_alias_signature_guard_allows_direct_match_theorem(self) -> None: - end_to_end_text = """ -theorem nativeAliasSurfaceForTestEvmYulLeanMatch - (h : - nativeDispatcherExecMatchesIRPositive fuel contract tx state - observableSlots nativeContract) : - True := by - trivial -""" - errors = check.check_native_alias_signatures(end_to_end_text) - self.assertEqual(errors, []) - - def test_public_end_to_end_theorem_signature_guard_accepts_current_shape(self) -> None: - errors = check.check_public_end_to_end_theorem_signatures( - check.END_TO_END.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_public_end_to_end_theorem_signature_guard_rejects_legacy_terms(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + """ -theorem legacySignatureSurfaceForTest - (h : - Compiler.Proofs.YulGeneration.ReferenceOracle.Semantics.execYulFuelWithBackend - .verity fuel stmts tx state = .ok result) : - True := by - trivial -""" - ) - errors = check.check_public_end_to_end_theorem_signatures(end_to_end_text) - self.assertTrue( - any(".verity" in error and "execYulFuel" in error for error in errors), - errors, - ) - - def test_public_end_to_end_theorem_signature_guard_rejects_arbitrary_fuel(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + """ -theorem arbitraryFuelSurfaceForTest - (fuel : Nat) - (hNative : nativeResultsMatchOn observableSlots ir native) : - True := by - trivial -""" - ) - errors = check.check_public_end_to_end_theorem_signatures(end_to_end_text) - self.assertTrue( - any("arbitrary theorem-facing fuel" in error for error in errors), - errors, - ) - - def test_public_end_to_end_theorem_signature_guard_rejects_call_dispatcher_body_env_terms(self) -> None: - end_to_end_text = ( - check.END_TO_END.read_text(encoding="utf-8") - + """ -theorem compile_preserves_native_evmYulLean_callDispatcher_of_generated_callDispatcher_match - (_hBodies : SourceBodyNativeClosure model selectors) - (_hEnv : - Compiler.Proofs.YulGeneration.Backends.Native.nativeRuntimePathUsesUnsupportedHeaderBuiltin - runtime tx = false) : - True := by - trivial -""" - ) - errors = check.check_public_end_to_end_theorem_signatures(end_to_end_text) - self.assertTrue( - any("SourceBodyNativeClosure" in error for error in errors), - errors, - ) - self.assertTrue( - any("nativeRuntimePathUsesUnsupportedHeaderBuiltin" in error for error in errors), - errors, - ) - - def test_unbridged_environment_boundary_accepts_current_shape(self) -> None: - errors = check.check_unbridged_environment_boundary( - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_unbridged_environment_boundary_rejects_missing_chainid_rejection_pin(self) -> None: - smoke_text = check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8").replace( - 'nativeRejectsUnsupportedChainId = true', - 'nativeAcceptsUnsupportedChainId = true', - ) - errors = check.check_unbridged_environment_boundary( - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - smoke_text, - ) - self.assertTrue(any("chainid" in error.lower() for error in errors), errors) - - def test_unbridged_environment_boundary_rejects_missing_blobbasefee_rejection_pin(self) -> None: - smoke_text = check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8").replace( - 'nativeRejectsUnsupportedBlobBaseFee = true', - 'nativeAcceptsUnsupportedBlobBaseFee = true', - ) - errors = check.check_unbridged_environment_boundary( - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - smoke_text, - ) - self.assertTrue(any("blobbasefee" in error for error in errors), errors) - - def test_unbridged_environment_boundary_rejects_missing_selfbalance_rejection_pin(self) -> None: - smoke_text = check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8").replace( - 'nativeRejectsUnsupportedHeaderBuiltin "selfbalance" = true', - 'nativeAcceptsUnsupportedHeaderBuiltin "selfbalance" = true', - ) - errors = check.check_unbridged_environment_boundary( - check.NATIVE_HARNESS.read_text(encoding="utf-8"), - smoke_text, - ) - self.assertTrue(any("selfbalance" in error for error in errors), errors) - - def test_native_switch_lowering_boundary_accepts_current_shape(self) -> None: - errors = check.check_native_switch_lowering_boundary( - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8"), - ) - self.assertEqual(errors, []) - - def test_native_switch_lowering_boundary_rejects_missing_freshness_helper(self) -> None: - adapter_text = check.NATIVE_ADAPTER.read_text(encoding="utf-8").replace( - "freshNativeSwitchId", - "staleNativeSwitchId", - ) - errors = check.check_native_switch_lowering_boundary( - adapter_text, - check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8"), - ) - self.assertTrue(any("freshNativeSwitchId" in error for error in errors), errors) - - def test_native_switch_lowering_boundary_rejects_missing_collision_smoke(self) -> None: - smoke_text = check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8").replace( - "nativeSwitchTempNamesAvoidUserNames = true", - "nativeSwitchTempNamesCollideWithUserNames = true", - ) - errors = check.check_native_switch_lowering_boundary( - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - smoke_text, - ) - self.assertTrue(any("nativeSwitchTempNamesAvoidUserNames" in error for error in errors), errors) - - def test_native_switch_lowering_boundary_rejects_missing_function_collision_smoke(self) -> None: - smoke_text = check.NATIVE_SMOKE_TEST.read_text(encoding="utf-8").replace( - "nativeFunctionSwitchTempNamesAvoidLocalUserNames = true", - "nativeFunctionSwitchTempNamesCollideWithLocalUserNames = true", - ) - errors = check.check_native_switch_lowering_boundary( - check.NATIVE_ADAPTER.read_text(encoding="utf-8"), - smoke_text, - ) - self.assertTrue( - any("nativeFunctionSwitchTempNamesAvoidLocalUserNames" in error for error in errors), - errors, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/scripts/test_ci_infra_maintenance.py b/scripts/test_ci_infra_maintenance.py index d7424afe9..69b6fdec5 100644 --- a/scripts/test_ci_infra_maintenance.py +++ b/scripts/test_ci_infra_maintenance.py @@ -70,8 +70,6 @@ def test_weekly_host_maintenance_prunes_ci_disk_journald_and_docker(self) -> Non def test_parallel_build_jobs_use_four_lean_threads(self) -> None: text = VERIFY_WORKFLOW.read_text(encoding="utf-8") for job in ( - "prepare-macro-fuzz", - "macro-fuzz", "build-compiler-binaries", "compiler-regressions", ): diff --git a/scripts/test_evmyullean_fork_conformance_workflow.py b/scripts/test_evmyullean_fork_conformance_workflow.py index 859824da7..0e37b4492 100644 --- a/scripts/test_evmyullean_fork_conformance_workflow.py +++ b/scripts/test_evmyullean_fork_conformance_workflow.py @@ -54,19 +54,14 @@ def test_scheduled_failures_open_or_update_issue(self) -> None: "scripts/test_evmyullean_fork_conformance_workflow.py", "artifacts/evmyullean_adapter_report.json", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapter.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanAdapterCorrectness.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBodyClosure.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeLemmas.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanBridgeTest.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeHarness.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeDispatchOracleTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanNativeSmokeTest.lean", - "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanRetarget.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSignedArithSpec.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanSourceExprClosure.lean", "Compiler/Proofs/YulGeneration/Backends/EvmYulLeanStateBridge.lean", "Compiler/Proofs/YulGeneration/ReferenceOracle/Builtins.lean", - "Compiler/Proofs/YulGeneration/ReferenceOracle/Semantics.lean", ]: self.assertEqual( text.count(path), @@ -103,10 +98,7 @@ def test_scheduled_failures_open_or_update_issue(self) -> None: self.assertIn("make test-evmyullean-fork", text) makefile_text = MAKEFILE.read_text(encoding="utf-8") self.assertIn("python3 scripts/generate_evmyullean_adapter_report.py --check", makefile_text) - self.assertIn("lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanAdapterCorrectness", makefile_text) self.assertIn("lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeHarness", makefile_text) - self.assertIn("lake build Compiler.Proofs.YulGeneration.Backends.EvmYulLeanNativeSmokeTest", makefile_text) - self.assertIn("lake exe native-dispatch-oracle-test", makefile_text) self.assertIn("lake build Compiler.Proofs.EndToEnd", makefile_text) issue_step = re.search( diff --git a/scripts/test_generate_evmyullean_adapter_report.py b/scripts/test_generate_evmyullean_adapter_report.py index d1d355686..7bdfb862b 100644 --- a/scripts/test_generate_evmyullean_adapter_report.py +++ b/scripts/test_generate_evmyullean_adapter_report.py @@ -574,10 +574,13 @@ def helper := 42 with self.assertRaises(ValueError, msg="No correctness theorems found"): gen._parse_correctness_proofs() - def test_missing_file_raises(self) -> None: + def test_missing_file_returns_na(self) -> None: + """After the EVMYulLean transition, the correctness file is removed and + the report records 'n/a' rather than raising.""" with patch.object(gen, "CORRECTNESS_FILE", Path("/nonexistent/Correctness.lean")): - with self.assertRaises(FileNotFoundError): - gen._parse_correctness_proofs() + result = gen._parse_correctness_proofs() + self.assertIn("n/a", result["assign_to_let"]) + self.assertIn("n/a", result["for_init_hoisting"]) class ExtractBlockTests(unittest.TestCase): @@ -689,6 +692,10 @@ def test_bridged_builtins_cover_all_proven_and_admitted(self) -> None: f"Universal bridge lemmas not in bridged set: {universal - bridged}", ) + @unittest.skipUnless( + gen.RETARGET_FILE.exists(), + "phase4 retarget tracking removed with EvmYulLeanRetarget.lean (EVMYulLean transition)", + ) def test_scalar_parameter_body_closure_is_tracked(self) -> None: report = gen.build_report() phase4 = report["phase4_retarget"] @@ -1110,6 +1117,10 @@ def test_admitted_bridge_deps_downgrade_phase4_status(self) -> None: phase4["yulCodegen_preserves_semantics_evmYulLeanBackend_via_reference_oracle"], ) + @unittest.skipUnless( + gen.RETARGET_FILE.exists(), + "phase4 retarget tracking removed with EvmYulLeanRetarget.lean (EVMYulLean transition)", + ) def test_universal_body_closure_proven_in_repo(self) -> None: """The repo artifact tracks the landed plan #1722 B7/B8 theorem stack.""" report = gen.build_report() diff --git a/scripts/verify_sync_spec.json b/scripts/verify_sync_spec.json index 123d5337d..12c409f16 100644 --- a/scripts/verify_sync_spec.json +++ b/scripts/verify_sync_spec.json @@ -51,9 +51,7 @@ "checks", "timeout-watchdog", "build", - "prepare-macro-fuzz", "build-audits", - "macro-fuzz", "build-compiler-binaries", "compiler-audits", "compiler-regressions", @@ -75,21 +73,11 @@ "changes", "checks" ], - "prepare-macro-fuzz": [ - "changes", - "checks", - "build" - ], "build-audits": [ "changes", "checks", "build" ], - "macro-fuzz": [ - "changes", - "checks", - "prepare-macro-fuzz" - ], "build-compiler-binaries": [ "changes", "checks", @@ -129,9 +117,7 @@ "failure-hints": [ "checks", "build", - "prepare-macro-fuzz", "build-audits", - "macro-fuzz", "build-compiler-binaries", "compiler-audits", "compiler-regressions", @@ -147,9 +133,7 @@ "checks": "github.event_name != 'pull_request' || github.event.action != 'closed'", "timeout-watchdog": "needs.checks.result == 'success' && !(github.event_name == 'workflow_dispatch' && inputs.clean_build)", "build": "needs.checks.result == 'success' && needs.changes.outputs.build == 'true'", - "prepare-macro-fuzz": "needs.checks.result == 'success' && needs.build.result == 'success' && needs.changes.outputs.macro_fuzz == 'true'", "build-audits": "needs.checks.result == 'success' && needs.build.result == 'success' && needs.changes.outputs.build == 'true'", - "macro-fuzz": "needs.checks.result == 'success' && needs.prepare-macro-fuzz.result == 'success' && needs.changes.outputs.macro_fuzz == 'true'", "build-compiler-binaries": "needs.checks.result == 'success' && needs.build.result == 'success' && needs.changes.outputs.compiler == 'true'", "compiler-audits": "needs.checks.result == 'success' && needs.build.result == 'success' && needs.build-compiler-binaries.result == 'success' && needs.changes.outputs.compiler == 'true'", "compiler-regressions": "needs.checks.result == 'success' && needs.build.result == 'success' && needs.build-compiler-binaries.result == 'success' && needs.changes.outputs.compiler == 'true'", @@ -166,9 +150,7 @@ "checks": "[self-hosted, linux, ARM64, dgx-spark, verity, fastlane]", "timeout-watchdog": "[self-hosted, linux, ARM64, dgx-spark, verity, fastlane]", "build": "[self-hosted, linux, x64, verity, build]", - "prepare-macro-fuzz": "[self-hosted, linux, x64, verity, build]", "build-audits": "[self-hosted, linux, x64, verity, build]", - "macro-fuzz": "[self-hosted, linux, x64, verity, build]", "build-compiler-binaries": "[self-hosted, linux, x64, verity, build]", "compiler-audits": "[self-hosted, linux, x64, verity, build]", "compiler-regressions": "[self-hosted, linux, x64, verity, build]", @@ -185,9 +167,7 @@ "checks": 10, "timeout-watchdog": 5, "build": "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '60' || '35') }}", - "prepare-macro-fuzz": 360, "build-audits": 20, - "macro-fuzz": "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '150' || '90') }}", "build-compiler-binaries": 360, "compiler-audits": 45, "compiler-regressions": "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '150' || '90') }}", @@ -198,7 +178,6 @@ "foundry-multi-seed": 45 }, "expected_job_strategy_fail_fast": { - "macro-fuzz": false, "foundry": false, "foundry-multi-seed": false }, @@ -206,8 +185,7 @@ "changes": { "code": "${{ steps.effective.outputs.code }}", "build": "${{ steps.effective.outputs.build }}", - "compiler": "${{ steps.effective.outputs.compiler }}", - "macro_fuzz": "${{ steps.effective.outputs.macro_fuzz }}" + "compiler": "${{ steps.effective.outputs.compiler }}" } }, "expected_job_permissions": { @@ -261,13 +239,12 @@ { "id": "effective", "name": "Resolve effective change flags", - "run": "if [ \"$FORCE_FULL_RUN\" = \"true\" ]; then\n code=true\n build=true\n compiler=true\n macro_fuzz=true\nelse\n code=\"$CODE_CHANGED\"\n build=\"$BUILD_CHANGED\"\n compiler=\"$COMPILER_CHANGED\"\n macro_fuzz=\"$MACRO_FUZZ_CHANGED\"\nfi\n\n{\n echo \"code=$code\"\n echo \"build=$build\"\n echo \"compiler=$compiler\"\n echo \"macro_fuzz=$macro_fuzz\"\n} >> \"$GITHUB_OUTPUT\"", + "run": "if [ \"$FORCE_FULL_RUN\" = \"true\" ]; then\n code=true\n build=true\n compiler=true\nelse\n code=\"$CODE_CHANGED\"\n build=\"$BUILD_CHANGED\"\n compiler=\"$COMPILER_CHANGED\"\nfi\n\n{\n echo \"code=$code\"\n echo \"build=$build\"\n echo \"compiler=$compiler\"\n} >> \"$GITHUB_OUTPUT\"", "env": { "FORCE_FULL_RUN": "${{ env.VERIFY_FORCE_FULL_RUN }}", "CODE_CHANGED": "${{ steps.filter.outputs.code }}", "BUILD_CHANGED": "${{ steps.filter.outputs.build }}", - "COMPILER_CHANGED": "${{ steps.filter.outputs.compiler }}", - "MACRO_FUZZ_CHANGED": "${{ steps.filter.outputs.macro_fuzz }}" + "COMPILER_CHANGED": "${{ steps.filter.outputs.compiler }}" } } ], @@ -345,46 +322,6 @@ } } ], - "prepare-macro-fuzz": [ - { - "uses": "actions/checkout@v6", - "with": { - "submodules": "recursive" - } - }, - { - "name": "Setup Lean", - "uses": "./.github/actions/setup-lean", - "with": { - "cache-key-prefix": "lake", - "use-sticky-disks": "${{ env.VERIFY_USE_STICKY_DISKS }}", - "sticky-disk-key-prefix": "verify", - "use-build-sticky-disk": "${{ env.VERIFY_USE_STICKY_DISKS }}", - "build-sticky-disk-key": "verify-build-macro-fuzz-${{ env.VERIFY_CACHE_BUCKET }}-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}", - "disable-lake-cache-restore": "${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }}", - "cache-primary-key": "lake-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}-${{ github.run_id }}" - } - }, - { - "name": "Download prepared Lean workspace build", - "uses": "actions/download-artifact@v7", - "with": { - "name": "lean-workspace-build" - } - }, - { - "name": "Build macro round-trip fuzz executable", - "run": "for attempt in 1 2 3; do\n if stdbuf -oL -eL lake build macro-roundtrip-fuzz; then\n exit 0\n fi\n echo \"::warning::lake build attempt $attempt failed; retrying in 10s\"\n sleep 10\ndone\necho \"::error::lake build failed after 3 attempts\"\nexit 1" - }, - { - "name": "Upload macro-fuzz Lean workspace build", - "uses": "actions/upload-artifact@v7", - "with": { - "name": "lean-workspace-macro-fuzz-build", - "path": "lean-workspace-macro-fuzz-build.tar" - } - } - ], "build-audits": [ { "uses": "actions/checkout@v6", @@ -419,36 +356,6 @@ } } ], - "macro-fuzz": [ - { - "uses": "actions/checkout@v6", - "with": { - "submodules": "recursive" - } - }, - { - "name": "Setup Lean", - "uses": "./.github/actions/setup-lean", - "with": { - "cache-key-prefix": "lake", - "use-sticky-disks": "${{ env.VERIFY_USE_STICKY_DISKS }}", - "sticky-disk-key-prefix": "verify", - "disable-lake-cache-restore": "${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }}", - "cache-primary-key": "lake-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}-${{ github.run_id }}" - } - }, - { - "name": "Download prepared Lean workspace build (fallback)", - "uses": "actions/download-artifact@v7", - "with": { - "name": "lean-workspace-macro-fuzz-build" - } - }, - { - "name": "Run macro round-trip fuzz harness", - "run": "chmod +x ./.lake/build/bin/macro-roundtrip-fuzz\n./.lake/build/bin/macro-roundtrip-fuzz" - } - ], "build-compiler-binaries": [ { "uses": "actions/checkout@v6", @@ -805,7 +712,6 @@ ], "expected_build_audit_commands": [ "check_split_package_builds.py", - "check_macro_roundtrip_fuzz_coverage.py", "check_proof_length.py --format=markdown >> $GITHUB_STEP_SUMMARY", "report_property_coverage.py --format=markdown >> $GITHUB_STEP_SUMMARY", "check_storage_layout.py --format=markdown >> $GITHUB_STEP_SUMMARY" @@ -864,9 +770,6 @@ "build": [ "lean-workspace-build" ], - "prepare-macro-fuzz": [ - "lean-workspace-macro-fuzz-build" - ], "build-audits": [ "axiom-dependency-report" ], @@ -890,9 +793,6 @@ "build": [ "lean-workspace-build.tar" ], - "prepare-macro-fuzz": [ - "lean-workspace-macro-fuzz-build.tar" - ], "build-audits": [ "axiom-report.md\naxiom-report-raw.log" ], @@ -913,15 +813,9 @@ ] }, "expected_downloaded_artifacts": { - "prepare-macro-fuzz": [ - "lean-workspace-build" - ], "build-audits": [ "lean-workspace-build" ], - "macro-fuzz": [ - "lean-workspace-macro-fuzz-build" - ], "build-compiler-binaries": [ "lean-workspace-build" ], @@ -957,15 +851,9 @@ ] }, "expected_downloaded_artifact_paths": { - "prepare-macro-fuzz": [ - null - ], "build-audits": [ null ], - "macro-fuzz": [ - null - ], "build-compiler-binaries": [ null ], diff --git a/scripts/verify_sync_spec_source.py b/scripts/verify_sync_spec_source.py index 5eae80497..3e2f67188 100644 --- a/scripts/verify_sync_spec_source.py +++ b/scripts/verify_sync_spec_source.py @@ -49,9 +49,7 @@ 'checks', 'timeout-watchdog', 'build', - 'prepare-macro-fuzz', 'build-audits', - 'macro-fuzz', 'build-compiler-binaries', 'compiler-audits', 'compiler-regressions', @@ -66,9 +64,7 @@ 'checks': [], 'timeout-watchdog': ['checks'], 'build': ['changes', 'checks'], - 'prepare-macro-fuzz': ['changes', 'checks', 'build'], 'build-audits': ['changes', 'checks', 'build'], - 'macro-fuzz': ['changes', 'checks', 'prepare-macro-fuzz'], 'build-compiler-binaries': ['changes', 'checks', 'build'], 'compiler-audits': ['changes', 'checks', @@ -88,9 +84,7 @@ 'build-compiler-binaries'], 'failure-hints': ['checks', 'build', - 'prepare-macro-fuzz', 'build-audits', - 'macro-fuzz', 'build-compiler-binaries', 'compiler-audits', 'compiler-regressions', @@ -109,15 +103,9 @@ '&& inputs.clean_build)', 'build': "needs.checks.result == 'success' && " "needs.changes.outputs.build == 'true'", - 'prepare-macro-fuzz': "needs.checks.result == 'success' && " - "needs.build.result == 'success' && " - "needs.changes.outputs.macro_fuzz == 'true'", 'build-audits': "needs.checks.result == 'success' && " "needs.build.result == 'success' && " "needs.changes.outputs.build == 'true'", - 'macro-fuzz': "needs.checks.result == 'success' && " - "needs.prepare-macro-fuzz.result == 'success' && " - "needs.changes.outputs.macro_fuzz == 'true'", 'build-compiler-binaries': "needs.checks.result == 'success' && " "needs.build.result == 'success' && " "needs.changes.outputs.compiler == " @@ -156,9 +144,7 @@ 'checks': '[self-hosted, linux, ARM64, dgx-spark, verity, fastlane]', 'timeout-watchdog': '[self-hosted, linux, ARM64, dgx-spark, verity, fastlane]', 'build': '[self-hosted, linux, x64, verity, build]', - 'prepare-macro-fuzz': '[self-hosted, linux, x64, verity, build]', 'build-audits': '[self-hosted, linux, x64, verity, build]', - 'macro-fuzz': '[self-hosted, linux, x64, verity, build]', 'build-compiler-binaries': '[self-hosted, linux, x64, verity, build]', 'compiler-audits': '[self-hosted, linux, x64, verity, build]', 'compiler-regressions': '[self-hosted, linux, x64, verity, build]', @@ -173,9 +159,7 @@ 'checks': 10, 'timeout-watchdog': 5, 'build': "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '60' || '35') }}", - 'prepare-macro-fuzz': 360, 'build-audits': 20, - 'macro-fuzz': "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '150' || '90') }}", 'build-compiler-binaries': 360, 'compiler-audits': 45, 'compiler-regressions': "${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.clean_build && '150' || '90') }}", @@ -184,11 +168,10 @@ 'foundry': 30, 'foundry-patched': 60, 'foundry-multi-seed': 45}, - 'expected_job_strategy_fail_fast': {'macro-fuzz': False, 'foundry': False, 'foundry-multi-seed': False}, + 'expected_job_strategy_fail_fast': {'foundry': False, 'foundry-multi-seed': False}, 'expected_job_outputs': {'changes': {'code': '${{ steps.effective.outputs.code }}', 'build': '${{ steps.effective.outputs.build }}', - 'compiler': '${{ steps.effective.outputs.compiler }}', - 'macro_fuzz': '${{ steps.effective.outputs.macro_fuzz }}'}}, + 'compiler': '${{ steps.effective.outputs.compiler }}'}}, 'expected_job_permissions': {'closed-pr-cleanup': {'actions': 'write', 'contents': 'read'}, 'checks': {'contents': 'write'}, 'timeout-watchdog': {'actions': 'read', 'contents': 'read'}, @@ -215,25 +198,21 @@ ' code=true\n' ' build=true\n' ' compiler=true\n' - ' macro_fuzz=true\n' 'else\n' ' code="$CODE_CHANGED"\n' ' build="$BUILD_CHANGED"\n' ' compiler="$COMPILER_CHANGED"\n' - ' macro_fuzz="$MACRO_FUZZ_CHANGED"\n' 'fi\n' '\n' '{\n' ' echo "code=$code"\n' ' echo "build=$build"\n' ' echo "compiler=$compiler"\n' - ' echo "macro_fuzz=$macro_fuzz"\n' '} >> "$GITHUB_OUTPUT"', 'env': {'FORCE_FULL_RUN': '${{ env.VERIFY_FORCE_FULL_RUN }}', 'CODE_CHANGED': '${{ steps.filter.outputs.code }}', 'BUILD_CHANGED': '${{ steps.filter.outputs.build }}', - 'COMPILER_CHANGED': '${{ steps.filter.outputs.compiler }}', - 'MACRO_FUZZ_CHANGED': '${{ steps.filter.outputs.macro_fuzz }}'}}], + 'COMPILER_CHANGED': '${{ steps.filter.outputs.compiler }}'}}], 'checks': [{'name': 'Clear sticky remote refs before PR checkout', 'if': "github.event_name == 'pull_request'", 'run': 'if [ -d .git ]; then\n' @@ -300,45 +279,6 @@ "hashFiles('lean-toolchain') }}-${{ " "hashFiles('lakefile.lean') }}-${{ " "hashFiles('lake-manifest.json') }}"}}], - 'prepare-macro-fuzz': [{'uses': 'actions/checkout@v6', - 'with': {'submodules': 'recursive'}}, - {'name': 'Setup Lean', - 'uses': './.github/actions/setup-lean', - 'with': {'cache-key-prefix': 'lake', - 'use-sticky-disks': '${{ env.VERIFY_USE_STICKY_DISKS }}', - 'sticky-disk-key-prefix': 'verify', - 'use-build-sticky-disk': '${{ env.VERIFY_USE_STICKY_DISKS }}', - 'build-sticky-disk-key': "verify-build-macro-fuzz-${{ env.VERIFY_CACHE_BUCKET }}-${{ runner.os }}-${{ hashFiles('lean-toolchain') }}-${{ hashFiles('lakefile.lean') }}-${{ hashFiles('lake-manifest.json') }}", - 'disable-lake-cache-restore': '${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }}', - 'cache-primary-key': 'lake-${{ ' - 'runner.os ' - '}}-${{ ' - "hashFiles('lean-toolchain') " - '}}-${{ ' - "hashFiles('lakefile.lean') " - '}}-${{ ' - "hashFiles('lake-manifest.json') " - '}}-${{ ' - 'github.run_id ' - '}}'}}, - {'name': 'Download prepared Lean workspace build', - 'uses': 'actions/download-artifact@v7', - 'with': {'name': 'lean-workspace-build'}}, - {'name': 'Build macro round-trip fuzz executable', - 'run': 'for attempt in 1 2 3; do\n' - ' if stdbuf -oL -eL lake build macro-roundtrip-fuzz; then\n' - ' exit 0\n' - ' fi\n' - ' echo "::warning::lake build attempt $attempt failed; retrying in 10s"\n' - ' sleep 10\n' - 'done\n' - 'echo "::error::lake build failed after 3 attempts"\n' - 'exit 1'}, - {'name': 'Upload macro-fuzz Lean workspace ' - 'build', - 'uses': 'actions/upload-artifact@v7', - 'with': {'name': 'lean-workspace-macro-fuzz-build', - 'path': 'lean-workspace-macro-fuzz-build.tar'}}], 'build-audits': [{'uses': 'actions/checkout@v6', 'with': {'submodules': 'recursive'}}, {'name': 'Setup Lean', @@ -364,29 +304,6 @@ 'with': {'name': 'axiom-dependency-report', 'path': 'axiom-report.md\n' 'axiom-report-raw.log'}}], - 'macro-fuzz': [{'uses': 'actions/checkout@v6', - 'with': {'submodules': 'recursive'}}, - {'name': 'Setup Lean', - 'uses': './.github/actions/setup-lean', - 'with': {'cache-key-prefix': 'lake', - 'use-sticky-disks': '${{ env.VERIFY_USE_STICKY_DISKS }}', - 'sticky-disk-key-prefix': 'verify', - 'disable-lake-cache-restore': '${{ env.VERIFY_DISABLE_LAKE_CACHE_RESTORE }}', - 'cache-primary-key': 'lake-${{ runner.os ' - '}}-${{ ' - "hashFiles('lean-toolchain') " - '}}-${{ ' - "hashFiles('lakefile.lean') " - '}}-${{ ' - "hashFiles('lake-manifest.json') " - '}}-${{ github.run_id ' - '}}'}}, - {'name': 'Download prepared Lean workspace build (fallback)', - 'uses': 'actions/download-artifact@v7', - 'with': {'name': 'lean-workspace-macro-fuzz-build'}}, - {'name': 'Run macro round-trip fuzz harness', - 'run': 'chmod +x ./.lake/build/bin/macro-roundtrip-fuzz\n' - './.lake/build/bin/macro-roundtrip-fuzz'}], 'build-compiler-binaries': [{'uses': 'actions/checkout@v6', 'with': {'submodules': 'recursive'}}, {'name': 'Setup Lean', @@ -707,7 +624,6 @@ 'expected_build_commands': ['check_lean_warning_regression.py --log lake-build.log'], 'required_build_run_commands': ['lake build PrintAxioms'], 'expected_build_audit_commands': ['check_split_package_builds.py', - 'check_macro_roundtrip_fuzz_coverage.py', 'check_proof_length.py --format=markdown >> ' '$GITHUB_STEP_SUMMARY', 'report_property_coverage.py --format=markdown >> ' @@ -753,7 +669,6 @@ 'command': 'python3 scripts/check_gas.py calibration ' '--static-report gas-report-static.tsv'}, 'expected_uploaded_artifacts': {'build': ['lean-workspace-build'], - 'prepare-macro-fuzz': ['lean-workspace-macro-fuzz-build'], 'build-audits': ['axiom-dependency-report'], 'build-compiler-binaries': ['difftest-interpreter', 'verity-compiler-binaries', @@ -765,7 +680,6 @@ 'static-gas-report-patched'], 'lean-profile': ['lean-perf-queue']}, 'expected_uploaded_artifact_paths': {'build': ['lean-workspace-build.tar'], - 'prepare-macro-fuzz': ['lean-workspace-macro-fuzz-build.tar'], 'build-audits': ['axiom-report.md\naxiom-report-raw.log'], 'build-compiler-binaries': ['.lake/build/bin/difftest-interpreter', 'compiler/bin', @@ -776,9 +690,7 @@ 'gas-report-static.tsv', 'gas-report-static-patched.tsv'], 'lean-profile': ['lean-perf-queue.md']}, - 'expected_downloaded_artifacts': {'prepare-macro-fuzz': ['lean-workspace-build'], - 'build-audits': ['lean-workspace-build'], - 'macro-fuzz': ['lean-workspace-macro-fuzz-build'], + 'expected_downloaded_artifacts': {'build-audits': ['lean-workspace-build'], 'build-compiler-binaries': ['lean-workspace-build'], 'compiler-audits': ['lean-workspace-build', 'lean-workspace-compiler-build', @@ -793,9 +705,7 @@ 'foundry-gas-calibration': ['static-gas-report'], 'foundry-patched': ['lean-workspace-build', 'lean-workspace-compiler-build']}, - 'expected_downloaded_artifact_paths': {'prepare-macro-fuzz': [None], - 'build-audits': [None], - 'macro-fuzz': [None], + 'expected_downloaded_artifact_paths': {'build-audits': [None], 'build-compiler-binaries': [None], 'compiler-audits': [None, None, @@ -817,9 +727,7 @@ 'checks', 'timeout-watchdog', 'build', - 'prepare-macro-fuzz', 'build-audits', - 'macro-fuzz', 'build-compiler-binaries', 'compiler-audits', 'compiler-regressions', @@ -837,9 +745,7 @@ 'checks': [], 'timeout-watchdog': ['checks'], 'build': ['changes', 'checks'], - 'prepare-macro-fuzz': ['changes', 'checks', 'build'], 'build-audits': ['changes', 'checks', 'build'], - 'macro-fuzz': ['changes', 'checks', 'prepare-macro-fuzz'], 'build-compiler-binaries': ['changes', 'checks', 'build'], 'compiler-audits': ['changes', 'checks', 'build', 'build-compiler-binaries'], 'compiler-regressions': ['changes', 'checks', 'build', 'build-compiler-binaries'], @@ -848,7 +754,7 @@ 'foundry': ['changes', 'build-compiler-binaries'], 'foundry-patched': ['changes', 'build-compiler-binaries'], 'foundry-multi-seed': ['changes', 'build-compiler-binaries'], - 'failure-hints': ['checks', 'build', 'prepare-macro-fuzz', 'build-audits', 'macro-fuzz', 'build-compiler-binaries', 'compiler-audits', 'compiler-regressions', 'foundry-gas-calibration', 'foundry', 'foundry-patched', 'foundry-multi-seed'], + 'failure-hints': ['checks', 'build', 'build-audits', 'build-compiler-binaries', 'compiler-audits', 'compiler-regressions', 'foundry-gas-calibration', 'foundry', 'foundry-patched', 'foundry-multi-seed'], } SPEC['expected_job_if_conditions'].update({ @@ -888,7 +794,6 @@ SPEC['expected_uploaded_artifacts'] = { 'build': ['lean-workspace-build'], - 'prepare-macro-fuzz': ['lean-workspace-macro-fuzz-build'], 'build-audits': ['axiom-dependency-report'], 'build-compiler-binaries': ['difftest-interpreter', 'verity-compiler-binaries', 'lean-workspace-compiler-build', 'generated-yul', 'generated-yul-patched', @@ -900,7 +805,6 @@ SPEC['expected_uploaded_artifact_paths'] = { 'build': ['lean-workspace-build.tar'], - 'prepare-macro-fuzz': ['lean-workspace-macro-fuzz-build.tar'], 'build-audits': ['axiom-report.md\naxiom-report-raw.log'], 'build-compiler-binaries': ['.lake/build/bin/difftest-interpreter', 'compiler/bin', 'lean-workspace-compiler-build.tar', 'compiler/yul', 'compiler/yul-patched', @@ -911,9 +815,7 @@ } SPEC['expected_downloaded_artifacts'] = { - 'prepare-macro-fuzz': ['lean-workspace-build'], 'build-audits': ['lean-workspace-build'], - 'macro-fuzz': ['lean-workspace-macro-fuzz-build'], 'build-compiler-binaries': ['lean-workspace-build'], 'compiler-audits': ['lean-workspace-build', 'lean-workspace-compiler-build', 'generated-yul', 'generated-yul-patched', 'static-gas-report', 'static-gas-report-patched', 'patch-coverage-report', 'verity-compiler-binaries'], 'compiler-regressions': ['lean-workspace-build', 'lean-workspace-compiler-build'], @@ -924,9 +826,7 @@ } SPEC['expected_downloaded_artifact_paths'] = { - 'prepare-macro-fuzz': [None], 'build-audits': [None], - 'macro-fuzz': [None], 'build-compiler-binaries': [None], 'compiler-audits': [None, None, 'compiler/yul', 'compiler/yul-patched', None, None, 'compiler', 'compiler/bin'], 'compiler-regressions': [None, None],