[Move][Spec] Fix specs and other miscs#19310
Merged
Merged
Conversation
Contributor
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
224c115 to
2de9d0b
Compare
rahxephon89
commented
Apr 6, 2026
fcafe59 to
b729db4
Compare
rahxephon89
commented
Apr 6, 2026
ce7ac43 to
e294909
Compare
wrwg
reviewed
Apr 14, 2026
| spec fun spec_create_from_rational(numerator: num, denominator: num): FixedPoint64 { | ||
| FixedPoint64{value: (numerator << 128) / (denominator << 64)} | ||
| // Directly mirrors the body: (numerator as u256) << 64 / (denominator as u256). | ||
| // The original (numerator << 128) / (denominator << 64) is mathematically equivalent |
Contributor
There was a problem hiding this comment.
I guess it should have a lager error because of the division?
Contributor
Author
There was a problem hiding this comment.
Sorry I don't get the hints here. As suggested by Claude, two expressions are equivalent?
080ccb7 to
966ab0a
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
added 2 commits
April 24, 2026 23:53
966ab0a to
a25da91
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a25da91 to
e1a9a5b
Compare
Remove the FunctionPurenessChecker fourth-check in try_as_pure_spec_call and the impure_callee inference test from this branch. These belong on teng/fix-spec-infer (spec inference improvements) rather than teng/fix-spec (spec correctness fixes). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
e1a9a5b to
0c248bc
Compare
Open
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Contributor
✅ Forge suite
|
Contributor
✅ Forge suite
|
Contributor
✅ Forge suite
|
vineethk
approved these changes
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
This PR improves formal verification coverage for
aptos-stdlibandmove-stdlib, fixes two pre-existing spec bugs that were silently skipping verification, and fixes bugs in the Move Prover's Boogie code generation.Spec coverage improvements
New spec files created:
storage_slots_allocator.spec.move— specs for 9 public functions usingpragma opaque+pragma aborts_if_is_partialfor enum-pattern/loop paths:add,remove,borrow,borrow_mut,fill_reserved_slot,remove_and_reserve,free_reserved_slot,allocate_spare_slots,reserve_slot. Specs use enumis/.valuefield access syntax andtable_with_length::spec_contains/spec_get.math_fixed.spec.move— specs forsqrt(aborts_if false, proved),pow_raw(requires x < 2^96; no ensures — recursivespec_bexphits MBQI timeout at full-package scale), andmul_div(aborts_if z==0 + overflow);exp/log2_plus_32/ln_plus_32ln2unspecced (non-linear iteration, unprovable abort conditions)math_fixed64.spec.move— specs forsqrt(aborts_if x==0, proved) andmul_div(aborts_if z==0 + overflow);exp/log2_plus_64/ln_plus_32ln2unspeccedmath_fixed8.move— new small fixed-point module in prover unit test withpow_rawfully verified viapragma unroll = 4+ closed-formspec_pow_rawreference implementationSignificantly expanded:
ed25519.spec.move— 6 new specs for delegating functions:public_key_validate,signature_verify_strict,signature_verify_strict_t,new_signed_message,unvalidated_public_key_to_authentication_key,validated_public_key_to_authentication_key(allpragma opaque)big_vector.spec.move— strong struct invariant (bucket consistency,end_indexaccounting); full function specs includingpush_back/pop_back/swap_remove/swap(pragma opaque);pop_backwith bucket-level postconditions (nested forall over bucket/position);appendwith length ensures;removewithpragma opaqueand full postconditions;index_ofwithpragma opaqueand bucket-level no-element formulation;contains(aborts_if false). Addedglobal initial_end_index: u64for use inremoveloop invariants. Replaced division-based bucket-count invariant (spec_table_len == ceil(end_index/bucket_size)) with arithmetic identity (bucket-length sum == end_index) + explicit trigger{spec_table_contains(buckets, i)}on the out-of-bounds invariant to avoidTypeDomaincascade.smart_vector.spec.move— full struct invariant; addedspec_gethelper (delegates to inline vec or big_vec);new/empty/empty_with_configensures;is_empty(pragma opaque);lengthresult ensures;borrowresult ensures;borrow_mutspec;push_back(pragma opaque; pragma verify = false) with completeaborts_ifenumeration (6 cases covering inline/big_vec branches, size arithmetic, and option::fill guard);pop_backresult ensures;swap_removeresult ensures;swapspec (pragma aborts_if_is_partial);remove(pragma opaque);singletonensures.smart_table.spec.move— fixedborrow_kv,borrow_kv_mut(removedpragma verify = false, added properaborts_if false/ensures); removed staleborrow_with_defaultpragma verify = falseblockpool_u64.spec.move— restructured struct invariant from ∀∃ to ∀∀ (forward containment + cardinality + no-duplicates) to fix Z3 quantifier alternation timeout; replacedeq_push_backwith element-level ensuresLoop invariants added to function bodies (post-while
spec { invariant ... }blocks):big_vector.move:append— two-phase loop: first loop tracksother.length() == other_len - iandself.length() == length(old(self)) + i; second loop same invariants withhalf_other_len <= ibig_vector.move:remove— post-while invariant trackingcur_bucket_indexbounds,end_index(-1 from old),bucket_size, andforall j in 0..spec_len: spec_table_contains(buckets, j); usesglobal initial_end_indexset before the loopMinor additions:
capability.spec.move—aborts_iftodelegate(when neither delegate cap exists nor cap held) andrevoke(when delegate cap exists but cap not held)comparator.spec.move,hash.spec.move,simple_map.spec.move,type_info.spec.move— additional conditionsmath128.spec.move improvements:
floor_log2: upgradedaborts_if x == 0from[abstract](axiom) to concretely proved via three linear loop invariants inmath128.move; added provedensures result <= 127sqrt: added concretely provedensures x == 0 ==> result == 0(previously only abstract ensures for the x > 0 case)log2/log2_64: left with onlypragma opaque— their abort condition (x == 0) and loop properties depend on the normalization stepfloor_log2(x) >= 32 iff x >= 1<<32, which requires evaluatingspec_pow(2, 32)=1<<32as a concrete integer; Z3 MBQI cannot evaluate this depth of recursive unfolding within timeoutSpec bug fixes in
fixed_point32andfixed_point64Two long-standing spec bugs that were silently skipped via
pragma verify_duration_estimate(which acts as a skip guard whenestimate > vc_timeout):fixed_point32::ceil,fixed_point32::round—spec_floorhad an unnecessary conditional: both branches reduce toself.value >> 32, since right-shifting discards the lower 32 bits regardless of their value. Whenceilcallsflooropaquely, the prover had to connect(spec_floor(self)) << 32back toself.value - fractional, requiring Z3 to prove((x - x%2^32) >> 32) << 32 == x - x%2^32— non-linear modulo reasoning. Simplifiedspec_floortoself.value >> 32(unconditional) and rewrotespec_ceil/spec_roundin terms offloor_valwith only shift and add. Both now verify in < 5s.fixed_point64::create_from_rational— The spec used(numerator << 128) / (denominator << 64)while the body computes(numerator << 64) / denominator. Mathematically equivalent, but Z3 must prove cancellation of2^64in unbounded integer division — non-linear reasoning that exceeds 40s. Changed spec to(numerator << 64) / denominatorto directly mirror the body. Verifies in < 5s. The original spec was written by analogy with thefixed_point32pattern(n << 2*bits) / (d << bits)without accounting for the body's simplified computation.Prover bug fixes
BV-mode vector length double-emission (
bytecode_translator.rs): Fix double-emission ofvector::length()calls when the result is assigned into a BV-typed destination. Adds a supportingbv2int(int2bv(n)) == nroundtrip axiom to the Boogie prelude and a new regression testbv_vector_length_bv_dest.move.BV/int mode conversion for spec function calls (
spec_translator.rs): Fix per-parameter bv-mode conversion intranslate_spec_fun_call— insert$bv2int/$int2bvwrappers when a spec function's parameter mode differs from the call-site mode. Useget_node_type_optto avoid panic on typeless synthetic nodes.move-flow MCP tool fixes
package_verify.rs+package_spec_infer.rs: Addedaptos_framework::prover::configure_aptos_custom_nativescall when building prover/inference options. Without this, full-package verification of any package that transitively depends onmove-stdlib(which includescmpwithpragma intrinsictypes) failed with Boogie compilation errors:undeclared type: $1_cmp_Ordering. The framework'sProverOptions::prove_toalready called this; the move-flow MCP tools were the missing callers.package_verify.rs: Updated max VC timeout from 10s to 60s in the tool parameter description.How Has This Been Tested?
aptos-stdlibandmove-stdlibprover runs pass at 40s timeoutfixed_point32::ceil,fixed_point32::round,fixed_point64::create_from_rationalnow actually verify (not skipped) at 40sbv_vector_length_bv_dest.movepasses viacargo test -p move-prover --test testsuite -- bv_vector_length_bv_dest$1_cmp_OrderingBoogie errorsType of Change
Which Components or Systems Does This Change Impact?
Checklist
Note
Medium Risk
Touches prover code generation and verification configuration, which can affect correctness of formal verification results and tool stability, though runtime Move behavior is largely unchanged.
Overview
Improves Move Prover robustness and verification coverage by fixing Boogie/BV translation issues and expanding/repairing specs across
aptos-stdlibandmove-stdlib.Key functional changes: Move-flow MCP tools (
move_package_verify,move_package_wp) now configure Aptos-specific Boogie natives via a sharedaptos_framework::prover::configure_aptos_custom_nativeshelper (also refactored intoframework/src/prover.rs), and the tool schema reflects a higher max VC timeout (60s).Spec work is substantial: adds new spec files (e.g.
storage_slots_allocator.spec.move,math_fixed*.spec.move,transaction_limits.spec.move), strengthens/rewrites specs and invariants for core data structures (big_vector,smart_vector,pool_u64,smart_table), and fixes previously-skipped or hard-to-prove specs (notablyfixed_point32andfixed_point64) by aligning spec math with implementation and adding loop invariants/ensures. Prover backend changes include preventing double-emission of certain BV-mode calls, adding BV/int bridge axioms in the Boogie prelude, and adjusting spec-call translation behavior; new regression tests cover the BV vector length case and small fixed-point verification.Reviewed by Cursor Bugbot for commit 0c248bc. Bugbot is set up for automated code reviews on this repo. Configure here.