Skip to content

Add accreditation registry, invoice metadata registry, document CID registry, and pause contracts - #630

Open
Wycode569 wants to merge 4 commits into
StellarState:devfrom
Wycode569:feat/ss-contracts-assigned-batch
Open

Wycode569 wants to merge 4 commits into
StellarState:devfrom
Wycode569:feat/ss-contracts-assigned-batch

Conversation

@Wycode569

Copy link
Copy Markdown

Summary

Batches four assigned issues, each a new Soroban contract: an investor accreditation tier registry, an on-chain invoice metadata registry, an immutable IPFS document CID registry, and an emergency pause contract with a timelocked resume.

A significant number of existing contracts in this workspace (roughly half) are not listed in the root Cargo.toml's workspace.members, including several that look similar to these four by name (invoice-registry, ipfs_registry, circuit-breaker, timelock, timelock-controller). None of them currently build or test (cargo check on any of them fails with "current package believes it's in a workspace when it's not"). This PR registers the four new contracts it adds, but does not attempt to fix the pre-existing orphaned ones, since that's a separate, larger cleanup unrelated to these issues.

#519: Investor accreditation registry

contracts/accreditation-registry. Stores each wallet's accreditation tier (Unaccredited, Accredited, Qualified) on-chain, defaulting to Unaccredited for any wallet never explicitly set. check_eligible(wallet, invoice_risk_tier) compares the wallet's tier against an invoice's risk tier (Low/Medium/High) so a caller can gate investment eligibility by tier.

Escrow integration not included. The issue asks for the escrow contract to call check_eligible before accepting investments. invoice-escrow is roughly 19,000 lines across five separate investment-accepting entry points (invest, invest_with_currency, fund_escrow, fund_escrow_with_token, fund_escrow_signed), and no contract anywhere in this workspace currently performs real on-chain cross-contract invocation (every contract is self-contained; the apparent "client" usages elsewhere are just the auto-generated test clients #[contractimpl] produces for the contract's own tests). Wiring a first-of-its-kind cross-contract call into the most mature, heavily-tested contract in the repo is a separate, higher-risk change better scoped on its own once this registry is live and reviewed. check_eligible is built, tested, and ready for that integration whenever it's taken on.

#520: Invoice metadata registry

contracts/invoice-metadata-registry. Stores face value, yield, maturity date, issuer, and lifecycle status for each invoice. Named to avoid colliding with the existing invoice-registry contract, which classifies invoices by category and risk tier and does not store any of these fields. Enforces a state machine: Pending -> Live -> Funded -> Settled, with Pending -> Expired and Live -> Expired as the other valid exits; Settled and Expired are terminal, and a self-transition (re-applying the current status) is rejected rather than treated as a no-op.

#521: Immutable document CID registry

contracts/document-cid-registry. Stores IPFS CIDs for invoice supporting documents, with verify_document returning whether a given CID is registered for an invoice. Named to avoid colliding with the existing ipfs_registry contract, which allows updating a document's CID via update_document (it exists for a different purpose: versioned document history) and has no verify_document check at all. This contract has no update path: a CID is immutable once registered, and re-registering the same CID for the same invoice is rejected. Registration is restricted to the admin or an issuer explicitly bound to that invoice via set_issuer.

#522: Emergency pause with timelocked resume

contracts/platform-pause. pause_platform halts activity immediately. resume_platform requires two calls 24 hours apart: the first queues the timelock, and a later call only clears the pause once that window has elapsed; calling it again before the deadline is rejected. Pausing again, or cancel_resume, clears any queued resume, so a fresh resume decision always starts its own 24-hour window instead of inheriting a stale deadline. set_invoice_paused/is_invoice_paused add a per-invoice override independent of the platform-wide switch.

Neither circuit-breaker (automatic, metric-threshold-triggered pausing) nor timelock/timelock-controller (generic 48-hour delay for arbitrary parameter changes) cover this specific admin-manual pause/24h-resume/per-invoice-override shape, so this is additive rather than a duplicate.

Verification

Per-contract (this workspace's cargo test --all and cargo clippy --all -- -D warnings are both already broken on a clean checkout of dev, unrelated to this change, so each new contract was verified individually):

  • cargo test -p <contract>: all pass (14 + 19 + 17 + 20 = 70 tests across the four contracts)
  • cargo fmt -p <contract> -- --check: clean
  • cargo clippy -p <contract> -- -D warnings: clean
  • cargo build -p <contract> --release --target wasm32v1-none: succeeds for all four (19.8KB, 30.9KB, 41.1KB, 35.1KB respectively)

Confirmed pre-existing and unrelated to this PR:

  • cargo fmt --all -- --check reports diffs in yield-vesting, invoice-escrow, invoice-token, payment-distributor, referral, and several others, none of which this PR touches
  • cargo clippy --all -- -D warnings reports 21 pre-existing errors (deprecated Events::publish calls, dead code, a len() == 0 lint) in other contracts, identical count on a clean checkout of dev
  • cargo test --all fails to even compile (soroban-env-host / ed25519-dalek / rand_core trait bound error), identical on a clean checkout of dev

closes #519
closes #520
closes #521
closes #522

…rState#519)

Stores each wallet's accreditation tier (unaccredited, accredited,
qualified) on-chain. check_eligible compares a wallet's tier against an
invoice's risk tier so an escrow or other eligibility checker can gate
high-value investments by tier. Also registers this and three sibling
contracts (invoice-metadata-registry, document-cid-registry,
platform-pause) in the workspace members list, since none of them were
previously buildable or testable without it.
…#520)

Stores face value, yield, maturity date, issuer, and lifecycle status
for each invoice on-chain, named invoice-metadata-registry to avoid
colliding with the existing invoice-registry contract, which classifies
invoices by category and risk tier rather than storing these
parameters. Enforces a pending -> live -> funded -> settled state
machine (with pending/live -> expired as the other valid exits);
settled and expired are terminal.
…rState#521)

Named document-cid-registry to avoid colliding with the existing
ipfs_registry contract, which allows updating a document's CID (it
exists for a different purpose: versioned document updates) and has no
verify_document check. This contract has no update path at all: a CID
is immutable once registered, and re-registering the same CID for the
same invoice is rejected. register_document is restricted to the
admin or an issuer explicitly bound to that invoice via set_issuer.
…tellarState#522)

pause_platform halts activity immediately; resume_platform requires
two calls 24 hours apart, queuing the timelock on the first call and
only clearing the pause once that window has elapsed on a later call.
Pausing again, or cancel_resume, clears any queued resume so a fresh
decision always starts its own 24h window rather than inheriting a
stale deadline. Per-invoice pause overrides (set_invoice_paused,
is_invoice_paused) work independently of the platform-wide switch.
@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@Wycode569 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant