seal. Docs Try the sandbox ↗
Mainnet is not yet live. Explore with demo funds or test tokens. Review status ↗

Ethereum and Base production readiness

This is the working audit and remediation plan, started on 2026-10-14. It is an internal engineering review, not independent security acceptance. The guardian address is configured on Ethereum and Base; Base deployment remains outstanding. Production verifier and release gates remain mandatory.

Acceptance criteria

Execution order

  1. Baseline and scope. Preserve existing working-tree changes; inventory entry points, deployments and trust boundaries. Run TypeScript, SDK, browser, Rust, contract and release checks and record existing failures.
  2. Browser and privacy. Review CSP and hosting headers, CORS and request provenance, OAuth, cookies, storage, workers, external scripts, links, logs, proof asset integrity and service metadata. Remove unnecessary disclosure and add adversarial browser and request tests.
  3. Contracts. Trace every value-moving entry point through assets/vaults, fees, proofs, swaps and margin. Inspect reentrancy, token behavior, deadlines, signatures, rounding, partial failures, permission changes and insolvency.
  4. Circuits and cryptography. Review range and boolean constraints, note conservation, Merkle membership, nullifiers, owner/domain/action binding, checkpoint continuity, witness generation and verifier/prover agreement.
  5. Relayer and recovery. Audit admission, quotes, encryption, idempotency, nonces, transaction simulation, persistence, delivery, expiry and restarts.
  6. Maintainability and gas. Simplify code where it reduces error-prone duplication; retain explicit security boundaries. Measure gas changes and deployment sizes before accepting optimizations.
  7. Release verification. Run the complete applicable checks, real proofs, Ethereum/Base fork scenarios and hosted browser checks against the final build. Record immutable artifact identities and outstanding external evidence.
  8. Delivery. Review the complete diff, commit tested changes and push to main as requested. Do not create PRs or external messages. Do not mark the protocol production-ready while independent acceptance or exact-release qualification remains outstanding.

Initial findings and evidence

Area Observation Status
Release At baseline, no qualified four-circuit release was present; production pins were zero. Automated qualification now passes; acceptance remains outstanding.
Review Independent review of the exact deployed circuits, prover, verifier, contracts and client is outstanding. External acceptance required.
Baseline TypeScript check passes. Repository tests: 69 pass, 2 fail (dependency compatibility and margin gas expectation). Fixed; current repository suite passes.
Workspace Existing UI performance/proof-cache changes were present before this audit. Preserved, reviewed and covered by regression runs.
Browser Hosted config lacks opener/resource isolation; local preview headers differ from hosted headers. Fixed in both hosting roots, development and preview.
Privacy App loads analytics JavaScript in the same execution context as private account data. Removed from private app; public sites retain analytics.
Session gateway Google session gateway delegates browser request-origin validation to an upstream service. Added local fail-closed checks and hostile-origin tests.

Remediation record

The opener policy deliberately supports OAuth popups opened by the app while isolating foreign pages that open the app. See the browser vendors' descriptions of COOP and CORP. Optional Google Identity Services remains trusted executable code. CSP permits HTTPS connections for user-selected RPCs; it is not an egress allowlist for a compromised application. The privacy guide records these limits.

Validation ledger

Check Result so far
TypeScript Pass.
Repository policy tests 73 pass.
Web unit tests 1,005 pass; one fork-dependent test skipped.
SDK tests 161 pass.
Browser isolation Four hostile-origin tests pass in Chromium and WebKit; all four also pass against the built preview in Chromium.
Targeted browser regressions 50 pass; four unavailable-WebGPU cases skipped.
Full UI suite 239 pass in the full local run; five skips (four unavailable-WebGPU cases and one local-fork case). CI repeats the suite on each push.
Saved-account startup 42 account-access and Google flows pass. Controlled decryption regression fails before the fix and passes afterward; deposit layouts pass repeated runs.
Cross-browser built preview 159 pass across the full run and targeted fixture reruns; three WebKit wallet cases blocked by the native keychain wait described below.
Dedicated browser security suite All 16 checks pass in Linux CI, including WebKit device-key persistence. The local macOS keychain limitation is recorded below.
Exact-candidate browser proofs All eight pass: four circuits in normal and single-worker fallback modes, including CSPRNG failure and encoding rejection checks.
Exact-candidate native/EVM qualification All four pass stock/optimized equivalence, fresh-randomness and browser proof verification. All 24 Solidity cases pass in two clean builds with identical runtimes.
Relayer end-to-end rehearsal Pass: eight confirmed transactions with real proofs, restart recovery, encrypted earnings and deletion of confirmed queue entries.
Contract state suite All 519 pass after the fixture and gas changes.
Account/multi-asset real proofs All nine tests pass across two suites, with no skips, including multi-asset claims, delayed reclaim, swaps and vault-donation accounting.
Contract standards Lint, formatting, 22 compatibility checks, diagnostics and entry-point checks pass after the gas change.
Gas regression All 27 scenarios pass after the checkpoint optimization.
Verifier fuzzing Four campaigns pass, each with 10,000 cases.
Circuit baseline 27 valid, 205 invalid, 225 serialized mutations and 12 seeded relation cases pass.
Account circuit 11 valid statements and 41 malicious witnesses checked against R1CS.
Deep circuit constraints and real proofs 50 recomputed malicious witnesses rejected with calculator assertions disabled; three real proofs pass 71 public-input tampering checks each.
Rust 97 normal tests pass; 21 database tests also pass in disposable TLS PostgreSQL. Clippy passes.
Dependency advisories npm audit and cargo-audit report zero known vulnerabilities. Rust maintenance notices are recorded below.
Builds Preview web, hosted testnet, landing and docs pass. Preview JavaScript budget passes.
Release deployment plumbing Two tests pass using a local EVM and synthetic acceptance records. This grants no production approval.
Ethereum/Base margin forks All 222 scenarios pass on the two pinned chains.

Additional checks: all eight verifier-generation tests and four source reference reproductions pass. The invariant suite rejected all 11 directed accounting and lifecycle mutations; the verifier suite rejected all ten directed verifier mutations. The separate extended invariant campaign passed all ten invariants. Artifact checks pass (17 tests plus one separately enabled local-EVM case), as do seven relayer deployment-script tests. All eight selected real-proof Ethereum/Base fork scenarios pass across six suites.

The dependency-policy audit, two proof-encoding checks and all 12 Sepolia qualification/preparation checks also pass. The root-hosted Google API entry point type-checks with Node types. Source formatting and Rust formatting pass.

Exact candidate evidence

Two fresh builds in .local/release-2026-10-14-audit/candidate-a and candidate-b produce the same SETUP.json SHA-256: 3feb12278fe58db9cb61c0cf217d6e05bce0a065db1e31094724af117604d5f8. They include all four current circuits (71/71/71/11 public signals). Every generated verifier source matches its committed production source byte for byte. Both builds use the retained, hash-verified public SRS verification record.

All eight exact-bundle browser proofs pass in Chromium. Each circuit runs in normal and single-worker fallback modes, rejects missing secure randomness and nine invalid encodings, and checks its public signals against the fixture. This evidence uses synthetic public inputs and grants no production acceptance.

Native qualification completed on 2026-10-14. All four circuits match stock verification keys and complete fixed-blinding proofs in two cases each. Two fresh randomized proofs per circuit verify with stock snarkjs and have distinct commitments. The account-only cases cover initial and continued states. All eight browser proofs also verify with stock snarkjs.

All 24 generated Solidity cases pass in each of two clean builds. They replay valid proofs, mutate every public signal and proof word, and reject noncanonical field aliases against both optimized and reference verifiers. Runtime hashes are identical across builds and match the repository's compiled production artifacts. Runtime sizes are 19,060/19,058/19,060/7,453 bytes, below EIP-170.

The local review packet is .local/release-2026-10-14-audit/review-packet/. It retains the exact compact browser bundle, setup manifest, verified SRS receipt and log, dependency lock, all 25 hash-bound qualification files and an explicitly local reproduction record. Large reproducible stock keys and synthetic witness intermediates were removed after completion; their stock-key hashes, complete proof vectors and replay evidence remain. No approval or accepted manifest was created. The two candidate builds ran on the same machine and do not constitute independent review.

These identities let an independent reviewer evaluate this exact candidate. Production pins remain zero pending acceptance and supported-device validation.

Reproducing the long-running checks

Use the pinned Foundry 1.5.1 and Rust 1.94.1 toolchains. This review used Node 24.21.0 on macOS. Unit and browser interaction commands are in package.json; the following commands exercise actual proofs rather than mock verifiers:

SEAL_ACCOUNT_STATE_PROOFS=1 forge test --root seal-pool/packages/contracts --match-contract '^(AccountStateRealProofTest|MultiAssetRealProofTest)$' --ffi --threads 2
SEAL_ACCOUNT_STATE_PROOFS=1 forge test --root seal-pool/packages/contracts --match-path 'test/fork/*RealProofFork.t.sol' --match-test '^(testFork_RealProofPrivateOpenAndClose|testFork_RealProofLongRoundTrip|testFork_RealProofShortRoundTrip|testFork_UsdcToWeth)' --ffi --threads 2
RUSTUP_TOOLCHAIN=1.94.1 SEAL_TESTNET_RPC_URL=https://sepolia.gateway.tenderly.co npm run test:relayer:e2e
npm run build:e2e
npm run test:preview -w @seal/web
npm run test:security -w @seal/web

Run heavy proof suites separately on resource-constrained machines. These fork tests write only to local EVM state and use development proof artifacts. They do not qualify or approve a production release.

Browser qualification gap on this machine

Three iPhone/WebKit wallet cases stall while persisting the non-extractable AES-GCM device key. An isolated page with no SEAL code reproduces the stall in WebKit revision 2359; Chromium persists, restores and uses the same synthetic key successfully. Native process samples place the WebContent thread in SerializeAndWrapCryptoKey and the browser's WebCryptoMasterKey queue in macOS SecItemCopyMatching / SecurityServer decryption. This is evidence of a native keychain wait on this test machine, not proof of Safari compatibility.

The tests remain enabled in CI. Do not replace non-extractable keys with exported key bytes or waive the tests. A passing WebKit run on a functioning keychain/test environment and a supported Safari/iOS device remain required before release.

The RustSec database was checked at commit 6aed84668c23d7f535077a9fe918bf1fa0f6a5bc (2026-10-13). It retains maintenance notices for paste, a transitive build-time macro used by Alloy/arkworks, and derivative, which is in the lockfile but absent from this target's resolved build. These are maintenance notices, not reported vulnerabilities; do not hide them with blanket advisory exclusions or replace cryptographic dependencies without compatibility review.

Static analysis and manual review

Slither 0.11.6 completed with 990 raw reports across generated verifiers, vendored libraries and first-party contracts. It also reported IR/parser failures for the transient reentrancy guard and inherited EIP-712 code, so this is not a clean or complete static-analysis result. Do not suppress all reports or treat the process exit status as security acceptance.

Reviewed high-risk report families include signature-authorized transferFrom, transiently guarded pool/vault entry points, adapter-only margin execution, one-shot Aave flash callbacks, canonical Uniswap callbacks, and deliberate assembly returns inside external Poseidon/verifier code. Existing adversarial tests cover token reentrancy, callback spoofing, signatures/nonces, failed payout rollback and account/backing isolation. The exact generated verifier and custom prover still require independent cryptographic review.

Private account ciphertext and remembered non-extractable device keys use origin-scoped IndexedDB. Google tokens are encrypted locally, with additional data binding the account identity. Proof caches contain public artifacts only and recheck hashes before use; witness data is sent only to the dedicated local proof worker. Same-origin script compromise, malicious extensions, misleading wallet signature requests, and service traffic correlation remain outside the cross-origin browser protections.

Test counts describe specific runs and do not establish absence of vulnerabilities. Automated exact-artifact qualification is complete. Independent acceptance and the supported-browser/device validation described above remain deployment blockers.

Local passkey account follow-up

The subsequent local-account change adds independent random account keys, WebAuthn PRF wrapping with mandatory user verification, local encrypted file export/import, a separate high-entropy recovery key and replacement-passkey enrollment. Passkey accounts cannot persist an unwrapped remembered device key or enter the Google backup path. Existing wallet and Google account formats remain supported. No contract, circuit, verifier or relayer change is required.

Regression coverage includes authenticated-header/ciphertext tampering, wrong recovery keys, multi-network restore, older-file merges, missing storage, cancelled creation, mandatory approval on reopening and recovery without the original credential. Browser tests exercise Chromium's actual WebAuthn API with a virtual USB PRF authenticator at desktop/mobile viewport sizes, including a fresh browser context and replacement credential. These are not physical-device compatibility results.

Before production, review this added client encryption surface and qualify create, reopen, file restore and replacement on actual Ubuntu/Linux browsers and compatible security keys/providers, macOS, iOS Safari and Android. Verify PRF across synchronized copies of the same credential where synchronization is advertised. Unsupported combinations must fail without creating an unprotected account. Use a stable private-app relying-party hostname with no untrusted subdomains. The earlier exact-candidate qualification does not independently accept this later UI code.

Password-protected portable export is implemented for random-key Google-created and passkey accounts. The self-contained local file restores all saved networks without Google or the original authenticator, using AES-256-GCM and WebCrypto PBKDF2-SHA256 with a fixed 600,000-iteration profile. Export validates the generated file before download; import authenticates its keys and complete history before writing account state. Tests cover wrong passwords, ciphertext changes, unsupported KDF parameters, fresh-device restoration and preservation of passkey unlock requirements.

Google Drive backup can be explicitly disabled without changing the account, address or available actions. Enabled backups still fail closed on upload or authorization failure. Funding wallets are separate from private identity; deposits bind the actual funding address and selected chain, and relayed swaps support independent accounts. The UI exposes all six overview actions, with deployment availability checked when selected.

These client changes need independent review and physical-device qualification before a production release. Production pins and acceptance gates remain unchanged.