vault

09 — Open Questions

docs/09-Open Questions.mdtype: question-logupdated: 2026-08-09

Open Questions

Decisions waiting on stakeholders. Each item names the owner, the decision needed, and the target by which we need it.

Mission

Launch market

  • Owner: CEO
  • Decision: which jurisdiction(s) for soft launch — Estonia, Lithuania, Cyprus, all-EU, or non-EU?
  • Target: before 10-Roadmap#Beta
  • Why blocked: drives MiCA scope, KYC vendor choice, fiat banking partner.

KPI thresholds

  • Owner: PM
  • Decision: replace placeholder targets in 01-Overview with board-approved numbers.
  • Target: end of MVP cycle.

Custody & Banking

Custody

  • Owner: CTO
  • Decision: Fireblocks vs Bitgo vs self-custody (HSM).
  • Trade-off: vendor cost vs operational complexity vs insurance coverage.

Sell payout rail

  • Owner: Finance lead
  • Decision: which fiat rail flips sell orders from pending to completed. SEPA + manual? Modulr? Banking Circle?
  • Blocking 03-Domains#Sell beta.

Acquirer ✅ resolved (2026-05-03)

  • Decision: Mercuryo is the contracted card acquirer + on/off-ramp partner. PCI scope sits with Mercuryo.
  • Why: licensed EU CASP, single integration covers card-acquiring + on-ramp + off-ramp + crypto-to-crypto; lets us avoid building a card relationship.
  • Follow-ups: SEPA payout rail for Sell still open under Sell payout rail.

AML & Compliance

AML provider ✅ resolved (2026-05-03)

  • Decision: Elliptic. One vendor covers wallet-AML risk and address-level sanctions via the same API.
  • Why: consolidated AML + sanctions reduces integration surface; well-supported case-management UI for ops; suits MiCA / FATF expectations.
  • Engineering: keep EllipticProvider interface; cache-aside 24 h per (address, network, currency).

Sanctions ✅ resolved (2026-05-03)

  • Decision: delivered via Elliptic (combined product). Lists in scope: OFAC SDN, EU consolidated, UK HMT, UN — Elliptic refreshes them upstream.
  • Why: avoids separate Refinitiv-style feed + reconciliation between two vendors.
  • Follow-up: confirm per-jurisdiction list additions per launch market with Compliance lead.

KYC vendor ✅ resolved in practice (Sumsub)

  • Built: SumsubService (lib/providers/kyc/sumsub.ts) selected by KYC_MODE=live, with applicant metadata columns (0028_add_sumsub_metadata) and an inbound review webhook at /api/webhooks/kyc.
  • ⚠️ The decision was never formally ratified here — the integration landed ahead of the sign-off this entry was tracking. Compliance lead should confirm Sumsub against Onfido / Veriff retrospectively, or accept it.
  • Remaining: contract + DPA before live signup.

Travel Rule integration

  • Owner: Compliance + Eng lead
  • Decision: vendor / protocol — Notabene vs Sumsub Travel Rule vs Veriscope vs Shyft vs TRP-direct.
  • Trade-off: counterparty-VASP coverage (which regulated counterparties speak the same protocol) vs vendor lock-in vs per-message cost.
  • What it gates: any custodial outbound from EU launch — Send, Payouts, API-order settle. EU TFR has no de minimis.
  • Required schema additions documented at 15-Compliance#Engineering surface — what this changes.
  • Target: before 10-Roadmap#Beta.

Self-hosted wallet handling

  • Owner: Compliance + PM
  • Decision: when the destination is a self-custodial wallet, do we (a) ask the user to attest "this address is mine" + take a proof, or (b) always treat the receiver as a third-party beneficiary and capture identity for them?
  • Why blocked: TFR Art. 14(5) gives both options; option (a) is friendlier to power users, option (b) is friendlier to compliance review.

CASP path

  • Owner: Compliance + Finance + CEO
  • Decisions (one stack, all need answering before 10-Roadmap#Beta):
    1. Own license vs co-CASP — file our own CASP application or partner with a licensed CASP (white-label / tied-agent). Trade-off: speed-to-launch + lower capital under co-CASP; product control + margin under own license.
    2. Class — Class 2 (€125k, custody + exchange + transfer) is the working assumption for the shipped MVP. Moving to Class 3 (€150k, trading platform) only if we add an order-matching surface — not currently in scope.
    3. NCA / member state — choose the National Competent Authority. Trade-offs: Estonia (FSA, fast, real-substance bar), Lithuania (Bank of Lithuania, English-speaking, heavier scrutiny than pre-MiCA), Cyprus (CySEC, cheap setup, reputation cost), Malta (MFSA, slow, expensive), Ireland (CBI, banking-grade reputation, heavy lift), France (AMF, toughest, best reputation), Germany (BaFin, EU-market-access, heavy substance bar).
    4. Co-CASP partner shortlist — only relevant if (1) lands on co-CASP. Need to pick 2–3 candidates and run diligence in parallel.
  • Hard deadlines:
    • 30 December 2024 — MiCA already fully applicable. New entrants need an authorisation before serving EU customers.
    • 1 July 2026 — many EU member states require existing local-VASP registrations to file a CASP application by this date. Per-state grandfathering windows differ; this is the latest common cutoff.
    • End of 2026 — most national VASP regimes phased out.
  • Why blocked: drives the entirety of 15-Compliance, shapes who files DAC8 (DAC8 build), and gates the Travel Rule vendor choice (Travel Rule integration) since the chosen NCA may have a preferred protocol.

Capital plan

  • Owner: Finance + CEO
  • Decision: how much initial paid-in capital to inject — €125k (Class 2 floor) is the minimum, but real-world filings hold more for risk-weighted exposure (custody float, AML/sanctions reserves, working capital cushion).
  • Why blocked: capital adequacy is part of the CASP application and must be demonstrable via audited statements at filing time. NCAs have rejected applications for under-capitalisation despite hitting the legal floor.
  • Target: before 10-Roadmap#Beta application filing.

DAC8 build

  • Owner: Compliance + Eng lead
  • Decision: build in-house vs adopt a CARF-aware vendor (Notabene Tax, BitOK, Tax Bit Crypto). Reporting timeline + ownership.
  • Why blocked: DAC8 applies from 1 January 2026; first reporting cycle 2027 covers calendar 2026. The aggregation has to start at year-start of the first applicable year, so this can't be left to the last quarter.
  • Schema sketch at 15-Compliance#Engineering surface — what this changes.

Backfill TIN

  • Owner: PM + Compliance
  • Decision: when (and how) do we collect TIN + tax-residence from users who signed up before DAC8 enforcement? In-product nag, email campaign, or hard-block at next sensitive action?
  • Trade-off: friction vs reporting completeness.

Tax & regulatory (legacy entry — see split above)

PII storage

  • Owner: Eng lead
  • Decision: encryption-at-rest scope. PII in users and payees is plain. DAC8-collected TIN must be encrypted at rest — see 15-Compliance#Engineering surface — what this changes.
  • Scope: auth secrets are app-stored. users.totp_secret is plaintext today, alongside password_hash and totp_recovery_code_hash (both hashed, which is correct). The TOTP secret is the one that needs encryption, not hashing, since it must be recoverable to verify.

Engineering

Background queue ✅ largely resolved — pg-boss shipped

  • Built: worker/worker.ts runs a dedicated pg-boss worker over 11 queues (payout.execute, send.submitted, buy.submitted, webhook.deliver, provider.webhook.process, dev-only.provider.webhook.dispatch, mail.send, order.expire.verify/order.expiry.tick, invoice.reminders.tick, fireblocks.poll.pending, reconcile.balances). The in-process runJob runner is gone.
  • Still open: worker topology under load (how many workers, how they're placed in the AWS target), retry/backoff policy per queue, cron ownership, and dead-letter visibility beyond /admin/jobs.

Webhook resumer ✅ resolved

  • Built: delivery runs on the webhook.deliver pg-boss queue, so retries are durable across deploys, autoscale and crashes rather than living in an in-process loop. Inbound provider callbacks get the same treatment via provider_webhook_events + provider.webhook.process.
  • Still open: the published delivery SLA and dead-letter review surface — tracked at Webhook reliability.

Multi-region

  • Owner: Eng lead
  • Decision: when to promote Prod from single-region (Multi-AZ) AWS to active-active multi-region. Postgres read replicas + cross-region failover are scoped under the AWS target (11-Target-Architecture).

Payout perf

  • Owner: Eng lead
  • Decision: ship with sequential per-row execution or pipeline 4–8 in parallel.

Secrets at rest

  • Owner: Eng lead
  • Decision: encrypt webhook_secret and high-risk PII with a KMS key.

Email deliverability

  • Owner: Eng lead
  • Decision: Resend is the live transactional sender (EMAIL_PROVIDER=resend); mock writes to mock_emails. Postmark remains deferred unless Resend deliverability is insufficient post-warmup.

Oracle ✅ resolved — CEX.IO

  • Decision: CEX.IO is the rate source for quotes, invoice rate-freeze and conversion previews.
  • Shipped: CexioOracle (lib/providers/cexio.ts) calling https://cex.io/api/last_prices/EUR with a 5 s timeout and a 30 s batch TTL, with stale-on-failure fallback. MockOracle remains the local-development default.
  • Consideration: CEX.IO does not differentiate USDT/USDC by network — USDT_ETH and USDT_TRX resolve to the same ticker. Acceptable for pricing, worth stating explicitly if quotes are ever contested.
  • Why: broad pair coverage, simple integration, sufficient for launch volumes; behind the OracleProvider abstraction so any future swap is non-breaking.
  • Re-evaluate at GA: Kaiko / CryptoCompare / Chainlink — driven by uptime SLA, regional pair coverage, and licensed-feed requirements (esp. for invoice rate-freeze under MiCA).

Outbound network gas economics

  • Owner: Finance + Eng lead
  • Decision: who funds the on-chain network fee for outbound transactions, and how that cost is recovered per product surface.
  • Context: network gas (BTC miner fee, ETH gas, ERC-20 gas paid in ETH, TRX energy/bandwidth, etc.) still has to be paid to broadcast the transaction even when the customer-facing asset is not the gas asset.
  • Current payout stance: merchant Mass Payouts are excluded from any per-recipient network-fee commission change. The platform charges merchants only their per-tier percentage on the payout total; there is no per-recipient flat fee charged to the merchant. Payout network gas remains an operator/treasury economics question for Fireblocks live cutover.
  • Open framing:
    1. Keep product-specific policies. Individual Sends can charge or reserve network fee differently from Mass Payouts.
    2. Unify all outbound fee policy. Simpler accounting, but conflicts with the current Mass Payout product decision.
  • Cross-surface funding mechanisms to evaluate:
    1. Operator-funded vault. A platform-owned hot vault per chain holds gas (ETH for ERC-20 sends, TRX for TRX sends, BTC for BTC sends). Cost is absorbed into the platform's margin. Simplest UX; biggest treasury exposure (gas inventory across N chains, top-up cadence, FX risk on volatile gas markets).
    2. Pre-funded customer/merchant gas pocket. Users or merchants top up a separate gas balance per chain alongside token balances. More transparent; pushes operational burden onto customers who may not want to think about gas.
    3. Per-transaction surcharge. Viable for individual Sends only if disclosed clearly; rejected for Mass Payouts by the current "no per-recipient charge" product decision.
    4. Fireblocks Gas Station / vault auto-top-up. Live integration only; buys time but does not remove the underlying economics question.
  • Why blocked: the choice changes (a) the wallet UX (one balance vs two), (b) the platform's working capital requirement at GA volumes, (c) the per-tier percentage we can sustainably charge, and (d) the reconciliation surface (gas spend per chain has to land in TRES).
  • Engineering touchpoint: lib/payouts/network.PAYOUT_FEE_MINOR_BY_ASSET is currently zeroed across the board for payouts; individual Send fee metadata must remain separate from payout fee policy.
  • Target: before 10-Roadmap#Beta (Fireblocks live cutover).

Individual outbound transfer network-fee commission

  • Owner: Finance + Product + Eng lead
  • Decision: fix the commission model for individual outbound Send transfers so the user-facing quote separates principal, platform fee, and network fee recovery. This must not change the Mass Payout fee model above.
  • Context: single Sends currently quote amount + network fee + platform fee, but the business rule for network-fee recovery is not final: should Daxchain pass through exact provider-estimated gas, add a spread, use a fixed network-fee schedule, or absorb gas into the platform fee?
  • Options:
    1. Exact pass-through. User pays the provider/network estimate with no spread. Most transparent; may leave Daxchain exposed when actual gas exceeds estimate.
    2. Pass-through plus buffer. User pays estimated network fee plus a configurable safety margin; unused surplus is either refunded or retained as fee income. Needs precise disclosure and reconciliation.
    3. Fixed fee schedule by asset/network. Predictable UX; can undercharge during congestion and overcharge in quiet markets.
    4. Absorb into platform fee. Simplest quote surface; weakest margin control for volatile gas assets.
  • Non-goal: do not introduce per-recipient network-fee commission for Mass Payouts as part of this decision.
  • Engineering touchpoint: individual sends should keep separate metadata for networkFeeMinor and platform/send fee so TRES can record principal, network fee, and platform fee independently.
  • Target: before live Fireblocks individual Send cutover.

Gas asset funding for token transfers

  • Owner: Finance + Custody ops + Eng lead
  • Decision: how wallets obtain and manage the required gas asset when transferring a token that cannot pay its own network fee, e.g. USDT/USDC on Ethereum require ETH for gas.
  • Context: a user may hold enough USDT_ETH to send the token but no ETH in the same custody wallet. Fireblocks can only broadcast the ERC-20 transfer if the source vault has enough ETH or another approved gas-funding mechanism is available.
  • Options:
    1. User-maintained gas balance. Require users to hold ETH/TRX/etc. for token sends on the same network. Clear custody accounting; worse UX.
    2. Operator gas station / auto-fuel. Platform funds gas assets into source vaults or via Fireblocks Gas Station. Better UX; requires treasury limits, alerts, top-up policy, and abuse controls.
    3. On-demand gas conversion. Convert a small part of the user's token or other balance into the gas asset before broadcast. Complex, adds price/slippage and regulatory/accounting questions.
    4. Block token send until gas is available. Safest implementation; creates failed-send support load unless the UI explains the shortfall before confirmation.
  • Product requirement: the quote/confirm UI must show both "asset being sent" and "gas asset required" when they differ, including a clear error when the gas asset is missing.
  • Reconciliation requirement: actual gas spend must land in the ledger/TRES as network fee in the gas asset, not silently netted from the token principal.
  • Target: before live ERC-20 Send cutover.

Target architecture

TRES alignment

  • Owner: CTO + Finance
  • Decision: scope of TRES vs Postgres-side accounting. Keep TRES purely for accounting interpretation, or also as the operational ledger?
  • Why blocked: shapes the cutover plan in 11-Target-Architecture and the reconciliation runbook in 14-Operations.
  • Target: before 10-Roadmap#Beta.

AWS edge hardening

  • Owner: Eng lead
  • Decision: when we promote the MVP ALB + regional WAF entry to the full AWS-native edge stack (Route 53 + CloudFront + AWS WAF + AWS Shield in front of API Gateway) and onboard admin to AWS IAM Identity Center (SSO + MFA) with a dedicated AWS WAF ruleset.
  • Trade-off: full edge security posture vs hardening cost (DNS change, traffic re-pointing, edge cache warm-up).
  • Target: pre-Beta.

CoSigner topology

  • Owner: Eng lead
  • Decision: Dev CoSigner profile — sandbox-only or simplified production-like? Final per-AZ topology in Test/Prod?
  • Why blocked: drives 12-Environments sizing and 13-Network-Model SG-COSIGNER scope.

NAT topology

  • Owner: Eng lead
  • Decision: Multi-AZ NAT vs single NAT in Test (Prod is Multi-AZ regardless).
  • Trade-off: cost vs failure-domain reduction.

Sizing

  • Owner: Eng lead
  • Decision: final compute + DB sizing per environment.
  • Why blocked: drives the 10-Roadmap#Beta cost envelope.

Admin & merchant scope

Admin role split

  • Owner: PM + COO
  • Decision: do all admins get all sections, or split into roles (support / finance / risk / engineering)?
  • Why blocked: 14-Operations#Privileged actions presumes role-based gating; the split needs ownership.
  • Target: before 10-Roadmap#GA.

Subaccount revocation

  • Owner: PM
  • Decision: when a parent merchant is disabled, what happens to active subaccount sessions and pending invitations? Hard cut, grace period, or per-action recheck?
  • Surface: 03-Domains#Subaccounts.

Product

Refunds

  • Owner: PM
  • Decision: refund flow for buy orders that settle but customer disputes the card charge.

Webhook reliability

  • Owner: PM + Eng
  • Decision: SLA + backoff for webhook_events. Pre-GA we should publish: ≥99.9% delivery within 24h, exponential backoff to 7d, dead-letter view.

Admin gaps

  • Owner: PM
  • Decision: scope of bulk export, refund/reverse affordances, notification preferences UI.

Fee schedule public commitment

  • Owner: PM
  • Decision: do we publish the per-tier fee schedule on a marketing page? If yes, tier edits become a marketing/legal change.

Customer dispute resolution

  • Owner: COO
  • Decision: in-product ticket flow vs Zendesk integration vs email-only.