feat(vault): add Kani harnesses for transfer correctness + fix compile errors (#490)#523
Merged
greatest0fallt1me merged 2 commits intoJun 27, 2026
Conversation
…errors Closes CalloraOrg#490 ## Compilation fixes - Fix StorageKey::MetaKey → StorageKey::Meta (5 occurrences in lib.rs) - Add missing get_max_deduct() method to CalloraVault - Add #[allow(dead_code)] to orphaned migrate() helper ## Correctness fixes - deduct(): add require_not_paused() check (deposit/batch_deduct already had it) - deposit event: add caller Address as topic[1] to match EVENT_SCHEMA.md (2 topics) ## Test fixes - deduct_while_paused_succeeds → deduct_while_paused_fails (#[should_panic]) - batch_deduct_while_paused_succeeds → batch_deduct_while_paused_fails (#[should_panic]) - deposit_event_schema_alignment: update to assert 2 topics + caller address - owner_deposit_increases_balance_and_emits_event: same update - owner_can_deposit: unwrap on topic[1] now resolves correctly - fuzz tests: remove duplicate else-branch that caused parse error - settlement/test.rs: fix _third_party → third_party in setup_contract() - Fix unused variable warnings (settlement, step_cap) ## Kani formal verification (closes CalloraOrg#490) Add contracts/vault/src/kani_proofs.rs with 7 adversarial harnesses: 1. kani_deduct_balance_non_negative – balance ≥ 0 after any valid deduct 2. kani_deduct_strictly_reduces_balance – deduct always decreases balance 3. kani_deposit_no_overflow – deposit checked_add succeeds in-range 4. kani_deposit_overflow_detected – checked_add returns None on overflow 5. kani_max_deduct_enforced – amount > max_deduct rejected before mutation 6. kani_batch_deduct_total_no_overflow – batch total accumulation stays valid 7. kani_withdraw_balance_non_negative – withdraw mirrors deduct invariant Harnesses compile only under cfg(kani); normal cargo test/CI unaffected. Vault Cargo.toml declares cfg(kani) as a known check-cfg to silence rustc warning. ## CI status - cargo fmt --check: ✅ - cargo clippy -D warnings: ✅ - cargo test --workspace: ✅ (270 tests: 179 vault + 52 settlement + 39 revenue-pool)
|
@ZuLu0890 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
4 tasks
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.
Summary
Closes #490 — Add Kani harness for
vault.transfercorrectness under adversarial input.Compilation fixes
The vault contract had several bugs preventing compilation:
StorageKey::MetaKey→StorageKey::Meta— 5 occurrences replaced;MetaKeyvariant does not exist in the enum.get_max_deduct()method — referenced bydeductandbatch_deductbut never defined; added as a public view function.#[allow(dead_code)]to the orphanedmigrate()helper.Correctness fixes
deduct()did not check pause state —depositandbatch_deductboth calledrequire_not_paused();deductdid not, allowing deductions through the circuit-breaker. Fixed.EVENT_SCHEMA.mdspecifies topic[0] = Symbol("deposit"), topic[1] = caller Address. The implementation only emitted 1 topic. Fixed to match schema.Test fixes
deduct_while_paused_succeeds→deduct_while_paused_fails(#[should_panic])batch_deduct_while_paused_succeeds→batch_deduct_while_paused_fails(#[should_panic])elsebranch that caused parse errorsettlement/test.rs: fixed_third_party→third_partyinsetup_contract()settlement,step_cap)Kani formal verification (issue #490)
Added
contracts/vault/src/kani_proofs.rswith 7 adversarial harnesses:kani_deduct_balance_non_negativebalance ≥ 0after any valid deductionkani_deduct_strictly_reduces_balancekani_deposit_no_overflowchecked_addsucceeds for all in-range depositskani_deposit_overflow_detectedchecked_addreturnsNoneon overflow (panic path sound)kani_max_deduct_enforcedamount > max_deductis rejected before any mutationkani_batch_deduct_total_no_overflowkani_withdraw_balance_non_negativeAll harnesses use symbolic inputs via
kani::any()+kani::assume()to cover the full input space, including adversarial edge cases (e.g. neari128::MAX, zero boundaries).The file is guarded with
#[cfg(kani)]— normalcargo test/ CI runs skip it entirely. VaultCargo.tomldeclarescfg(kani)as a known check-cfg to suppress the rustcunexpected_cfgswarning.Running harnesses locally
CI verification
cargo fmt --checkcargo clippy -D warningscargo test --workspace