Skip to content

Security: RedDuckTeam/rwa

Security

SECURITY.md

Security Policy

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.

Reporting a Vulnerability

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.

Scope — contracts (apps/contracts)

  • Crossing the tier boundary. Any path that reaches a critical-tier action without the 48h timelock, or re-points a role's admin — AccessRegistry fixes the hierarchy at initialisation and exposes no setRoleAdmin.
  • 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. rejectRequest and cancelRequest must 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. refundFromVault reachable a second time, from any path other than the RedemptionVault's single-use ticket, or bypassing the sanctions check.
  • Mint/burn separation. DepositVault holding BURNER_ROLE, RedemptionVault holding MINTER_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 initialize left callable on a deployed implementation, or _authorizeUpgrade reachable without UPGRADER_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.

Scope — front end (apps/web)

  • 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 where minOut is computed from a stale preview, sent as 0, 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 — cancelRequest is 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.

Important Notes

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.

There aren't any published security advisories