This repository is a permissioned RWA platform, not a trust-minimised one: privileged
roles exist by design, and the issuer is trusted to hold the underlying assets and
compute NAV. Read
apps/contracts/docs/TRUST-MODEL.md first
— it inventories every residual power deliberately left in the system. The most useful
report is one showing the code (contracts or front end) doing something that document
says it cannot.
The front end (apps/web) holds no keys and stores no secrets, but it decides what a
wallet is asked to sign — so the failure modes worth reporting there are about what
reaches the signer, not about a server.
Report privately through GitHub Security Advisories on this repository rather than opening a public issue. If advisories aren't enabled yet, contact the maintainers privately before publishing any details.
Enabling private vulnerability reporting is a per-repository setting (Settings → Security → Private vulnerability reporting) — this file does not turn it on.
- Crossing the tier boundary. Any path that reaches a critical-tier action without
the 48h timelock, or re-points a role's admin —
AccessRegistryfixes the hierarchy at initialisation and exposes nosetRoleAdmin. - The price path. Posting a NAV outside the hard bounds, or past the deviation cap or
cooldown on
setRoundDataSafe; making a stale answer read as healthy. - Escrow and the exit paths.
rejectRequestandcancelRequestmust require no price and must not be gated by any pause, blacklist, or oracle failure. Anything that strands, redirects, or double-spends escrowed funds. - The privileged refund.
refundFromVaultreachable a second time, from any path other than the RedemptionVault's single-use ticket, or bypassing the sanctions check. - Mint/burn separation.
DepositVaultholdingBURNER_ROLE,RedemptionVaultholdingMINTER_ROLE, or any mint not backed by a settled deposit. - Compliance bypass. Evading a blacklist, greenlist, or sanctions check — including an address lifting its own blacklist status.
- Upgrades. Storage-layout collisions, an
initializeleft callable on a deployed implementation, or_authorizeUpgradereachable withoutUPGRADER_ROLE. - Accounting. Decimals conversion, fee, or rounding logic that resolves in the caller's favour against the vault.
Out of scope: the accepted residual risks and the six registered deviations in
TRUST-MODEL.md §3–4 — among them the calendar-bucket daily limit, NAV front-running
within the caps, and fail-closed behaviour during an oracle outage. If one of those looks
wrongly sized for a particular deployment, that is a configuration discussion for
apps/contracts/docs/FORKING.md, not a
vulnerability report.
- Wrong target. Anything that could send a call or an approval to an address other
than the one in the validated config — a bypass of
apps/web/src/lib/config.ts, an address read from an untrusted source, or a hardcoded address slipping past the CI check. - Wrong amount. A denomination error that makes the signed amount differ from the one displayed. The two vaults use different scales for identically named values, and a mistake here is silent: the UI reads correct and the transaction is not.
- Slippage and
minOut. A path whereminOutis computed from a stale preview, sent as0, or otherwise leaves the user unprotected against a NAV move — including the preview simulation being confused with the one that guards the send. - Unbounded approval. Approving more than the operation needs, or approving a spender that is not the vault being called.
- Misleading state. A successful receipt presented as a successful outcome when the
contract says otherwise —
cancelRequestis the known case: it succeeds while leaving the request open and the refund blocked. - Compliance and pause gates. An action offered as available when
isVaultOpAllowed,canSend, or an operation pause says it is not. - Supply chain. A dependency or build step that could inject code into the served bundle.
Out of scope: a public RPC endpoint rate-limiting or returning stale data (the UI is expected to degrade, not to be correct in spite of it); the mock USDC faucet being mintable by anyone, which is deliberate on a testnet; and anything requiring the user to paste a malicious address into a field that is theirs to fill.
This is an actively developed application, not a versioned library — treat main as the
only supported branch. The deployment it targets is Sepolia testnet. Before pointing
a fork at mainnet, re-read the trust model: the addresses are configurable, and nothing
in this code will stop you aiming it somewhere real.