Skip to content

Add event-schema conformance tests asserting emitted topics and payloads match EVENT_SCHEMA.md #407

@greatest0fallt1me

Description

@greatest0fallt1me

Description

EVENT_SCHEMA.md is the canonical contract that indexers, frontends, and auditors build against — it pins exact topics and payload shapes for every event across all three crates. Today only a subset of events is asserted in tests (per SECURITY.md, deposit/deduct topics and the revenue-pool admin_changed event are pinned), and several documented events have no conformance test, so a payload-shape regression (like the kind that already documented stale string panics in docs/interfaces/vault.json) could ship undetected. This issue adds focused tests that read env.events().all() and assert the emitted topics/data byte-for-byte against the schema.

Requirements and context

Functional — events to pin (sampling across crates):

  • Vault (contracts/vault/src/lib.rs): init, deposit, deduct (3-topic form with the empty-Symbol sentinel for None, per the EVENT_SCHEMA.md request_id note), withdraw, withdraw_to, vault_paused / vault_unpaused, ownership_nominated / ownership_accepted, admin_nominated / admin_accepted, set_authorized_caller (old/new tuple), metadata_set / metadata_updated / metadata_removed.
  • Settlement (contracts/settlement/src/lib.rs): payment_received and balance_credited ordering and payload (to_pool=false always emits payment_received before balance_credited), plus developer_withdraw.
  • Revenue pool (contracts/revenue_pool/src/lib.rs): distribute, batch_distribute (one event per leg, in order), admin_changed + admin_transfer_started pairing.

Non-functional / repo conventions

  • Use the soroban_sdk test API (Env::events().all() returning Vec<(Address, Vec<Val>, Val)>) and assert both topic symbols and decoded data structs (e.g. PaymentReceivedEvent, BalanceCreditedEvent, WithdrawEventData).
  • Each assertion must cite the EVENT_SCHEMA.md section it enforces, so a schema change forces a test update (and vice-versa).
  • Where the test reveals a mismatch between code and EVENT_SCHEMA.md, fix the document (the code is the source of truth for emitted events) and note it in the PR.
  • Tests must not drop coverage below 95%.

Acceptance criteria

  • A dedicated test_events.rs module per crate (or one consolidated module where practical), registered under #[cfg(test)].
  • deduct conformance test asserts exactly 3 topics and the empty-Symbol sentinel when request_id is None.
  • Settlement test asserts payment_received precedes balance_credited for to_pool=false and that no events are emitted on the documented panic paths.
  • Revenue-pool batch_distribute test asserts one event per leg in submission order.
  • Any discrepancy found is reconciled in EVENT_SCHEMA.md and referenced in the PR description.
  • cargo test --workspace passes; ./scripts/coverage.sh stays >= 95%.

Suggested execution

1. Fork the repo and create a branch

git checkout -b test/event-schema-conformance

2. Implement changes

  • Add #[cfg(test)] mod test_events; registrations in the three lib.rs files (or extend existing test*.rs modules).

3. Write/extend tests in contracts/vault/src/test_events.rs, contracts/settlement/src/test_events.rs, contracts/revenue_pool/src/test_events.rs:

  • capture env.events().all() after each operation and assert topic symbols + decoded data;
  • assert event ordering for settlement and batch operations;
  • assert no events on panic/error paths (e.g. deduct without settlement set).

4. Test and commit

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --workspace
./scripts/check-wasm-size.sh
./scripts/coverage.sh

Example commit message

test: assert emitted events conform to EVENT_SCHEMA.md across all crates

Guidelines

  • Coverage must stay >= 95% (scripts/coverage.sh), CI-enforced via .github/workflows/coverage.yml.
  • Treat contract code as the source of truth for events; update EVENT_SCHEMA.md to match and keep it authoritative.
  • Timeframe: 96 hours.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions