Skip to content

Build the async vault: epochs, claims, treasury and roles - #70

Open
hpmaxi wants to merge 21 commits into
mainfrom
feat/async-vault-contract
Open

Build the async vault: epochs, claims, treasury and roles#70
hpmaxi wants to merge 21 commits into
mainfrom
feat/async-vault-contract

Conversation

@hpmaxi

@hpmaxi hpmaxi commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #65

The vault contract: an epoch-based deposit and redeem lifecycle, role-based access control, treasury
movements to an off-chain custodian, and the oracle wiring. Responsibilities are split across
per-flow modules and two library crates.

Changes

  • A storage crate wraps instance and persistent access, extending the entry lifetime on every read and write.
  • Cross-contract clients for the oracle feed and the share token live in one crate, so every caller decodes the same types.
  • The vault splits into deposit, redeem, epoch, treasury, state, roles, error and event modules.
  • Deposits and redemptions join the open epoch. One request per investor per epoch.
  • Closing an epoch seals it and opens the next. The manager role closes.
  • Fulfilling reads the oracle, fixes the epoch's share price, and reserves what its redemptions owe. Anyone may call it.
  • Claims mint shares or pay assets at the epoch's fixed price, once each.
  • A redemption request moves shares with a forced transfer, so a de-listed holder can still queue an exit.
  • The treasury deploys free reserve to a configured custodian and funds the vault back.
  • The guardian pauses deposits. Claims, redemption requests and funding stay open.
  • Five authorities, with the constructor rejecting overlapping pairs.

Deviations

compliance and attester are taken by the constructor for the distinctness check and hold no role
on the vault. Compliance is enforced on the identity verifier and the compliance dispatcher, and
attestation on the oracle, so neither authority is exercised here.

Deferred, each tracked as its own issue:

The authority model is reviewed as a whole in #78, which covers the two roles that share the
manager symbol and the two constructor arguments that hold no role here.

Acceptance criteria

  • request_deposit and request_redeem register against the open epoch and reject a second request from the same investor.
  • close_epoch requires the manager role, seals the current epoch and opens the next.
  • fulfill_epoch requires a consumable feed, and refuses when the vault cannot cover the epoch's redemptions.
  • claim_deposit and claim_redeem pay at the epoch's fixed price and reject a second claim.
  • Conversions round in the vault's favour.
  • deploy_to_custodian requires the treasury role and cannot touch assets owed to a priced redemption.
  • The constructor rejects each overlapping authority pair.
  • Pausing stops deposits and leaves claims, redemption requests and funding open.
  • A de-listed holder can queue and claim an exit.

Test plan

Automated tests

  1. cargo test --workspace — 101 tests pass.
  2. cargo clippy --workspace --all-targets — no warnings.
  3. cargo fmt --all -- --check — clean.

Manual verification

  1. stellar contract build — five wasm modules.

Breaking changes

None. The vault is new.

Checklist

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

Screenshots

None.

The suite asserted a monotonic-date guard attest never implemented, so the
workspace tests were red. Assert the cooldown and deviation guards it does
enforce, and pin the contract-stamped timestamp so changing it is deliberate.
Pin the crate version and resolve bindings and pricing from the workspace
root, so cargo can load the member at all. The crate needs a library
target to exist; it carries no entrypoints yet.
@hpmaxi hpmaxi self-assigned this Sep 7, 2026
@hpmaxi hpmaxi changed the title Feat/async vault contract Build the async vault: epochs, claims, treasury and roles Sep 7, 2026
@hpmaxi
hpmaxi marked this pull request as ready for review September 8, 2026 11:55
@hpmaxi
hpmaxi requested a review from luchobonatti September 8, 2026 11:55
@luchobonatti
luchobonatti requested a balanced review from Copilot September 8, 2026 12:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Two token transfer calls (deposit.rs:43, treasury.rs:66) pass e.current_contract_address() by value where the client expects &Address, a type mismatch that blocks compilation.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR builds the async (ERC‑7540‑style) vault at the heart of the Strata Vault Kit: an epoch-based deposit/redeem lifecycle with claims at a fixed per-epoch share price, a NAV oracle with a three-state health model, treasury movements to an off-chain custodian, and role-based access control. It also removes two now-superseded planning docs and adds two shared library crates (storage, bindings) plus deploy config for the new contracts. It fits into milestone M1 as the core on-chain money logic that the frontend and operator tooling will later wire up.

Changes:

  • New async-vault contract split into per-flow modules (deposit, redeem, epoch, treasury, state, roles, error, event, keys) with one request per investor per epoch, forced-transfer redemption escrow, and a pending_redeem_assets/free_reserve solvency guard.
  • New nav-oracle contract (attest/state/ripcord, config validation, symmetric deviation cap) and shared storage (TTL-extending helpers) and bindings (oracle + share clients) crates.
  • Removal of docs/roadmap-m1.md and docs/m1-brief.md, plus deploy config for the oracle and vault in environments.toml.
File summaries
File Description
contracts/async-vault/src/lib.rs Vault entrypoints, constructor role wiring, pausable impl
contracts/async-vault/src/deposit.rs Deposit request/claim flow (has a by-value transfer arg)
contracts/async-vault/src/redeem.rs Redeem request (forced transfer)/claim flow
contracts/async-vault/src/epoch.rs Epoch open/close/fulfill with oracle pricing + liquidity guard
contracts/async-vault/src/treasury.rs Custodian deploy/fund and free-reserve accounting (by-value transfer arg)
contracts/async-vault/src/state.rs, keys.rs, roles.rs, error.rs, event.rs Storage schema, keys, role symbols, error codes, events
contracts/async-vault/Cargo.toml Crate deps (includes an unused pricing dep)
contracts/async-vault/src/test/* Extensive unit tests across all flows
contracts/nav-oracle/src/{lib,state,test}.rs, Cargo.toml NAV oracle contract + tests
crates/storage/{src/lib.rs,src/test.rs,Cargo.toml} TTL-extending instance/persistent storage helpers
crates/bindings/src/lib.rs Oracle/share cross-contract client signatures
contracts/{identity-verifier,compliance}/src/lib.rs Formatting-only changes
environments.toml Deploy config for nav_oracle and async_vault
docs/roadmap-m1.md, docs/m1-brief.md Removed superseded planning docs
Cargo.lock Adds new crates
Review details
  • Files reviewed: 34/35 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread contracts/async-vault/src/deposit.rs
Comment thread contracts/async-vault/src/treasury.rs
Comment thread contracts/async-vault/Cargo.toml Outdated
Comment thread contracts/async-vault/src/error.rs Outdated

@luchobonatti luchobonatti left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid PR, and the deferred list is the right one. Four questions in the code around pricing timing, coverage accounting, mint timing and pause scope. Curious what you think before merging.

Comment thread contracts/async-vault/src/epoch.rs
Comment thread contracts/async-vault/src/epoch.rs
Comment thread contracts/async-vault/src/deposit.rs
Comment thread contracts/async-vault/src/lib.rs
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.

Port the async vault

3 participants