home / skills / multiversx / mx-ai-skills / mvx_property_testing

mvx_property_testing skill

/antigravity/skills/mvx_property_testing

This skill helps you apply property-based testing with fuzzing in Rust to discover edge cases and verify core invariants in smart contracts.

npx playbooks add skill multiversx/mx-ai-skills --skill mvx_property_testing

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
927 B
---
name: mvx_property_testing
description: Using fuzz tests in Rust for invariants.
---

# MultiversX Property Testing

This skill guides you in using property-based testing (fuzzing) to find edge cases in Smart Contract logic.

## 1. Tools
- **`cargo fuzz`**: Standard Rust fuzzer.
- **`proptest`**: Property testing framework for Rust.

## 2. Methodology
Defining Invariants:
- "Total Supply MUST equal sum of all balances."
- "User balance MUST NOT decrease if deposit fails."

## 3. Implementation (RustVM)
Write a test that:
1.  Takes random input (random amounts, random user IDs).
2.  Executes the contract logic via `blockchain_mock`.
3.  Asserts the invariant holds.

## 4. Example
```rust
proptest! {
    #[test]
    fn test_deposit_always_increases_balance(amount in 0u64..1_000_000u64) {
        let mut setup = Setup::new();
        setup.deposit(amount);
        assert_eq!(setup.balance(), amount);
    }
}
```

Overview

This skill teaches how to apply property-based testing and fuzzing to Rust smart contracts to surface edge cases and invariant violations. It focuses on defining clear invariants for contract state and exercising contract logic with randomized inputs. The goal is faster detection of logic bugs and safer contract behavior before deployment.

How this skill works

You define invariants that must always hold for contract state, then use fuzzing and property testing to generate wide ranges of inputs. Tests execute contract operations in a mocked blockchain environment and assert invariants after each scenario. Failures reveal minimal counterexamples that can be reproduced, diagnosed, and fixed.

When to use it

  • During development of smart contract core logic to catch subtle state bugs early
  • Before major releases or audit gates to increase confidence in invariants
  • When adding new features that interact with token balances or permissions
  • To validate invariants across many edge cases not covered by example-based tests
  • When migrating or refactoring contract code to ensure behavior is preserved

Best practices

  • Start by writing a small set of high-value invariants (e.g., totalSupply equals sum of balances)
  • Keep the mocked blockchain deterministic and reproducible so failures are debuggable
  • Limit input domains initially, then expand ranges once tests are stable
  • Combine proptest for structured generation with cargo-fuzz for deep fuzz exploration
  • Record and minimize failing cases to a small reproducer for root-cause analysis

Example use cases

  • Test that deposits never decrease a user balance by fuzzing amounts and user IDs
  • Verify total token supply equals aggregated balances after random transfers and mint/burn actions
  • Stress-check permission checks by fuzzing caller identities and sequence of calls
  • Validate invariants across replayed sequences of operations to find stateful bugs
  • Use reduced failing inputs from proptest to craft regression tests and fixes

FAQ

Which Rust tools should I use for property testing?

Use proptest for structured property-based tests and cargo-fuzz for aggressive fuzz exploration; they complement each other.

How do I keep tests reproducible when fuzzing?

Seed generators deterministically and log the minimal failing input; ensure the mock blockchain and environment are fully deterministic.

What invariants are most useful for token contracts?

Start with supply-related invariants (total supply vs. balances), non-negative balances, and permission/authorization invariants.