Build the async vault: epochs, claims, treasury and roles - #70
Conversation
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.
There was a problem hiding this comment.
🟡 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-vaultcontract 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 apending_redeem_assets/free_reservesolvency guard. - New
nav-oraclecontract (attest/state/ripcord, config validation, symmetric deviation cap) and sharedstorage(TTL-extending helpers) andbindings(oracle + share clients) crates. - Removal of
docs/roadmap-m1.mdanddocs/m1-brief.md, plus deploy config for the oracle and vault inenvironments.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.
luchobonatti
left a comment
There was a problem hiding this comment.
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.
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
Deviations
complianceandattesterare taken by the constructor for the distinctness check and hold no roleon 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
managersymbol and the two constructor arguments that hold no role here.Acceptance criteria
request_depositandrequest_redeemregister against the open epoch and reject a second request from the same investor.close_epochrequires the manager role, seals the current epoch and opens the next.fulfill_epochrequires a consumable feed, and refuses when the vault cannot cover the epoch's redemptions.claim_depositandclaim_redeempay at the epoch's fixed price and reject a second claim.deploy_to_custodianrequires the treasury role and cannot touch assets owed to a priced redemption.Test plan
Automated tests
cargo test --workspace— 101 tests pass.cargo clippy --workspace --all-targets— no warnings.cargo fmt --all -- --check— clean.Manual verification
stellar contract build— five wasm modules.Breaking changes
None. The vault is new.
Checklist
Screenshots
None.