Skip to content

docs: explain each contract's design choices - #278

Open
hpmaxi wants to merge 20 commits into
docs/contract-specfrom
docs/design-notes
Open

hpmaxi wants to merge 20 commits into
docs/contract-specfrom
docs/design-notes

Conversation

@hpmaxi

@hpmaxi hpmaxi commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #329

No contract said which choices it makes or what each one costs, so a reader had to rebuild the reasons from the code. Several docs also promised more than the code does: a proof reference on every report, an exit window from the timelock, "five authorities" in a comment that lists six, and one manager row for two different roles. Nothing said how to replace a compromised attester, what the supply and capital figures count, or that a refund worth less than one share is not reserved.

Each contract and each shared crate now opens with a short design section, and the docs say only what the code does.

Changes

  • The vault, share token, oracle, compliance stub and identity verifier open with a # Design section: five to ten choices, each with its cost.
  • The timelock, storage and bindings crates open with the same kind of section.
  • The docs no longer promise a proof reference; they say a report carries none yet.
  • The kit spec gives the order for replacing a compromised attester and splits the two manager roles.
  • The design doc calls the timelock delay an announcement period: an exit also needs a sealed epoch, a price and cash.
  • The docs say what total_economic_supply and deposited capital count (money in and out, not the vault's value), that the custodian repays through fund, and that a refund below one share base unit is not reserved, and why.
  • The kit spec's attester recovery order always clears the stored report, which would otherwise price epochs again once the NAV pause lifts.
  • A verifier that cannot answer counts as a failed check (NotAllowlisted doc, compliance matrix); the kit spec says this version is deployed fresh; the design doc gives the epoch remainder rule and the share token's timelocked upgrades, grants and hand-overs.
  • Tests pin six claims of the notes: a verifier that cannot answer is a failed check; a module failing on burn blocks wind-down claims and cannot be removed then; a plain transfer back counts twice toward the deposit cap while fund counts once; a gain paid out to leavers leaves room above the cap, while a loss at the custodian still counts toward it; a zero-share legal transfer passes and is published; an unbound compliance swap lands and stops every move.
  • The vault constructor's comment that miscounted the authorities is gone; the constructor doc already says what roles holds.
  • The authorization matrix names the four role pairs the constructor checks and says the attester is neither stored nor compared; request_redeem is refused in a wind-down; a rule change gets the delay as notice, not a finished exit; feed_valid includes the band; environments.toml lists every finish_setup check.
  • legal_transfer's doc says only the compliance rules' check is skipped, and the token's constructor doc says which moves are checked.
  • TESTING.md and AGENTS.md name the doc-length test and the error_enum! doctests.
  • Two vault guards are renamed for what they check: feed_bound_here_and_answering and valid_change.

Deviations

  • Also corrected: the Clock.exit_window doc (it called the notice "the longest an exit takes"), MIN_DELAY, MANAGER_ROLE and TREASURY_ROLE docs, the matrix's "five authorities" list, the fund rows (anyone may fund), and "two further limits" that listed three.
  • Clock.exit_window's doc is in the vault's spec, so the vault's Wasm grows by 36 bytes; its code section is unchanged.
  • The token's section sits in its lib.rs, the crate root.
  • Deposited capital counts money in and out, so the deposit cap drifts from the vault's value after gains and losses. The docs now say so; what the cap should limit is tracked in Decide what the deposit cap limits #294.

Acceptance criteria

  • Each contract's lib.rs opens with a # Design section: five to ten choices, each with its cost
  • No doc promises a proof reference, an exit window from the timelock, or another control the code lacks
  • The kit spec gives the order for replacing a compromised attester
  • The docs say what total_economic_supply and deposited capital count, and that the custodian repays through fund
  • The docs state that a refund worth less than one share is not reserved, and why
  • The design sections change no contract's Wasm

Test plan

Automated tests

  1. SOROBAN_SDK_BUILD_SYSTEM_SUPPORTS_SPEC_SHAKING_V2=1 cargo test --locked: 716 passed, including every_contract_doc_fits_the_spec and the eight new tests (a_module_failing_on_burn_blocks_wind_down_claims_and_cannot_be_removed, capital_funded_back_counts_once_toward_the_cap, a_plain_transfer_back_counts_twice_toward_the_cap, a_gain_paid_out_to_leavers_leaves_room_above_the_cap, a_loss_at_the_custodian_still_counts_toward_the_cap, a_verifier_that_cannot_answer_counts_as_a_failed_check, a_zero_share_legal_transfer_passes_and_is_published, an_unbound_compliance_swap_lands_and_stops_every_move). Each new test fails when the behaviour it pins is changed.
  2. cargo clippy --locked --all-targets -- -D warnings and cargo doc with RUSTDOCFLAGS="-D warnings" on the eight touched crates: clean.
  3. The Wasm upgrade tests (--features upgrade_wasm with_wasm): vault 5, oracle 2, passed.

Manual verification

  1. stellar contract build at the base (527620d) and after the first two design-section commits (e34e5b9): the five Wasm files are byte-identical.
  2. At ea0d661 only async_vault.wasm differs from the base. Its spec section carries the corrected Clock.exit_window doc, its code section is identical, and its data section differs only in that entry's 8-byte spec marker.
  3. At 66b60fc the token's spec section carries its two corrected docs (code unchanged), and the two guard renames reorder the vault's functions: the same 284 function bodies, in another order. The oracle, compliance and verifier are byte-identical to the base.
Contract Before (527620d) After (66b60fc)
async_vault 91,231 91,267
share_token 55,355 55,371
nav_oracle 40,133 40,133
compliance 30,667 30,667
identity_verifier 4,963 4,963

Breaking changes

None. Signatures, types, events and error codes are unchanged. Docs in the vault's and the token's specs change, and the vault's functions are reordered, so both Wasm hashes change.

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

Screenshots

None.

@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
strata-vault-kit-app Ready Ready Preview Oct 22, 2026 5:46pm UTC

Request Review

@hpmaxi
hpmaxi marked this pull request as ready for review October 20, 2026 10:23
The kit spec and the design doc said a gain or a loss at the custodian
never moves deposited capital. It does once exits pay it out: a priced
redemption takes off what it pays, gain included. After leavers are paid
a gain the figure can go negative, and the cap then admits more than its
own amount; after a loss it stays above the vault's value, and the cap
refuses deposits sooner.

Two tests pin both directions.
- The NotAllowlisted doc and the compliance matrix say that a verifier
  that cannot answer counts as a failed check, and a test pins it.
- The kit spec says this version is deployed fresh, not upgraded in place.
- The design doc gives the epoch remainder rule in the pricing section,
  and says the share token's upgrades, role grants and admin hand-overs
  wait for the vault's timelock.
Also say the deposit cap is vault-wide, and list the testnet identity
verifier's limits as limits of the stub.

This branch was successfully deployed

1 active deployment
Preview — c11e1485 Deployed Oct 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant