Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions smartcontract/.github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,112 @@ jobs:
run: |
ls -lh target/wasm32-unknown-unknown/release/*.wasm
echo "All contracts built successfully"

fuzz-invariant:
name: Fuzz & Invariant Tests
runs-on: ubuntu-latest
# Run fuzz tests on every push/PR; they are deterministic via PROPTEST_SEED.
env:
# Fixed seed ensures reproducible failures. Override with
# cargo test -- --proptest-seed=<new-seed>
# to explore different parts of the input space.
PROPTEST_SEED: "0x5a3f9c1d7b2e4068"

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.85.0"

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-fuzz-${{ hashFiles('**/Cargo.lock') }}

- name: Pin incompatible dependencies
working-directory: smartcontract
run: |
cargo update serde_with@3.18.0 --precise 3.17.0 || true
cargo update serde_with_macros@3.18.0 --precise 3.17.0 || true
cargo update darling@0.23.0 --precise 0.21.3 || true
cargo update darling_core@0.23.0 --precise 0.21.3 || true
cargo update darling_macro@0.23.0 --precise 0.21.3 || true
cargo update indexmap@2.14.0 --precise 2.6.0 || true

# ── Rotational (extends existing coverage) ──────────────────────────────
- name: Fuzz – Rotational contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/rotational/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-rotational.log
grep -q "test result: ok" /tmp/fuzz-rotational.log || \
{ echo "::error::Rotational fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Microloan (highest priority) ────────────────────────────────────────
- name: Fuzz – Microloan contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/microloan/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-microloan.log
grep -q "test result: ok" /tmp/fuzz-microloan.log || \
{ echo "::error::Microloan fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Yield Strategy (highest priority) ───────────────────────────────────
- name: Fuzz – Yield Strategy contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/yield-strategy/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-yield.log
grep -q "test result: ok" /tmp/fuzz-yield.log || \
{ echo "::error::Yield Strategy fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Governance ──────────────────────────────────────────────────────────
- name: Fuzz – Governance contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/governance/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-governance.log
grep -q "test result: ok" /tmp/fuzz-governance.log || \
{ echo "::error::Governance fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Flexible Pool ───────────────────────────────────────────────────────
- name: Fuzz – Flexible Pool contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/flexible/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-flexible.log
grep -q "test result: ok" /tmp/fuzz-flexible.log || \
{ echo "::error::Flexible Pool fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Target Pool ─────────────────────────────────────────────────────────
- name: Fuzz – Target Pool contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/target/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-target.log
grep -q "test result: ok" /tmp/fuzz-target.log || \
{ echo "::error::Target Pool fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Reputation Tracker ──────────────────────────────────────────────────
- name: Fuzz – Reputation Tracker contract
working-directory: smartcontract
run: |
cargo test prop_ --manifest-path=contracts/reputation/Cargo.toml --release \
-- --nocapture 2>&1 | tee /tmp/fuzz-reputation.log
grep -q "test result: ok" /tmp/fuzz-reputation.log || \
{ echo "::error::Reputation fuzz tests FAILED (seed: $PROPTEST_SEED)"; exit 1; }

# ── Upload counterexample logs on failure ───────────────────────────────
- name: Upload fuzz failure logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-failure-logs
path: /tmp/fuzz-*.log
retention-days: 30
6 changes: 6 additions & 0 deletions smartcontract/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions smartcontract/contracts/flexible/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ soroban-sdk = { version = "21.0.0", features = ["alloc"] }

[dev-dependencies]
soroban-sdk = { version = "21.0.0", features = ["testutils", "alloc"] }
proptest = "1.4"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 61f67ce7571e369a7bc502157c97f25843318568e1d271fd32c5e9b709a3cd78 # shrinks to fee_bps = 0, min_deposit = 1, member_count = 2, operations = [(2, 0, 22377), (2, 0, 22552)]
Loading