Skip to content

Security: ct1212/self-healing-reserve

Security

SECURITY.md

Security Architecture

This document explains the security model of the Self-Healing Reserve system, distinguishing between what runs inside the CRE workflow and CCC enclaves in production versus what is simulated in the demo.

Overview

┌─────────────────────────────────────────────────┐
│  CRE Workflow (Chainlink DON)                    │
│                                                 │
│  ┌───────────────┐    ┌──────────────────────┐  │
│  │ ConfidentialHTTP│──▶│  Reserve comparison  │  │
│  │ fetch reserves │    │  ratio >= threshold? │  │
│  └───────────────┘    └──────────┬───────────┘  │
│                                  │              │
│            Only boolean leaves   │              │
└──────────────────────────────────┼──────────────┘
                                   ▼
                        ┌────────────────────┐
                        │  Onchain:         │
                        │  isSolvent = bool  │    ◀── public
                        │  ReserveStatusUpdated()│
                        └────────┬───────────┘
                                 │ event
                                 ▼
                        ┌────────────────────┐
                        │  Recovery Agent    │    ◀── off-chain, dry-run in demo
                        │  MPC wallet        │
                        └────────────────────┘

Key principle: This system is an alternative to transparent Proof of Reserve, not a layer on top of it. Reserve balances flow from the custodian's private API directly into the CRE workflow via ConfidentialHTTP. They never touch a public feed. Only a boolean isSolvent attestation is published onchain. For dark pool recovery, CCC private token transfers ensure that settlement amounts, counterparties, and transfer details also remain confidential. Onchain state contains only an encrypted balance hash + boolean + quorum-signed CCC attestation.

What Runs in the CRE Workflow (Production)

In a production deployment using Chainlink CRE (Chainlink Runtime Environment):

  • ConfidentialHTTP fetches reserve data from the custodian API. The HTTP request and response are encrypted end-to-end and only visible inside the CRE workflow.
  • Secret API keys are stored in the DON vault, referenced via {{.SECRET_HEADER}} template syntax. Keys are never present in source code or workflow configuration.
  • Reserve comparison (totalReserve / totalLiabilities >= threshold) executes entirely off-chain within the CRE workflow. No DON node operator can observe the intermediate values.
  • Consensus uses consensusIdenticalAggregation where multiple DON nodes independently compute the same result inside their respective CRE runtime environments and reach agreement.
  • Output: Only the boolean isSolvent result leaves the CRE workflow, encoded into an onchain transaction via onReport().

What's Simulated in the Demo

The demo (npm run demo) replicates the full architecture locally without real CRE or CCC infrastructure:

  • demo/simulate-workflow.ts performs the same fetch-compare-attest logic that the CRE workflow would, but runs as a regular Node.js process. There is no CRE workflow isolation.
  • Hardhat node uses the well-known test mnemonic (test test test ... junk). These are deterministic test accounts with no real value.
  • Mock API (mock-api/server.ts) runs on localhost:3001 with no authentication. In production, the API would require credentials stored in the DON vault.
  • Recovery agent runs in dry-run mode. Wallet commands are logged but never executed. No real funds are involved.

Demo vs Production Comparison

Component Demo Production
Reserve data source Public wBTC PoR feed (simulation anchor) Private custodian API (confidential end-to-end)
Reserve data fetch Plain HTTP to localhost mock ConfidentialHTTP inside CRE workflow
API authentication None DON vault secret ({{.SECRET_HEADER}})
Reserve comparison Local Node.js process Inside CRE workflow (off-chain)
Consensus Single process, no consensus Multi-node DON consensus
Blockchain Hardhat (test mnemonic) Ethereum mainnet/L2
Attestation write updateAttestation() direct call onReport() via DON
Wallet operations Dry-run (logged only) MPC wallet (real tx)
Private keys Hardhat test accounts No raw keys (MPC wallet)
Dark pool encryption Simulated (correct interfaces) CCC threshold encryption via Vault DON
Dark pool settlement Simulated private token transfer CCC enclave matching + encrypted balance table
Key management No real keys Vault DON threshold shares, proactive rotation

Wallet Security

The recovery agent uses an MPC wallet for wallet operations:

  • Dry-run mode is the default. All wallet commands are logged but not executed. This is always enabled in the demo.
  • MPC custody: in production, the wallet uses Multi-Party Computation so no raw private keys are ever exposed to the agent process.
  • Constrained actions: the agent only executes three predefined recovery steps:
    1. balance: check available funds
    2. trade: swap ETH to USDC
    3. send: transfer USDC to the reserve address
  • No arbitrary execution: the agent does not accept or execute arbitrary commands. Recovery logic is hardcoded in agent/recovery.ts.

CCC Security Model (Dark Pool Settlement)

The dark pool settlement uses Chainlink Confidential Compute (CCC), which provides stronger privacy guarantees than CRE alone:

Threshold Encryption

  • Deficit amounts are encrypted under the CCC master public key, which is threshold-shared across the Vault DON
  • No single Vault DON node can decrypt the data. A quorum of nodes must cooperate to provide re-encrypted key shares to the assigned compute enclave
  • Even if individual Vault DON nodes are compromised, the encrypted data remains secure as long as the threshold is maintained

Vault DON (Decryption Nodes)

  • The Vault DON holds threshold-shared fragments of the master secret key
  • When a computation is needed, the Vault DON re-encrypts inputs for the specific assigned compute enclave
  • Re-encryption is done without ever reconstructing the full master secret key
  • Key shares are rotated periodically (proactive secret sharing)

Compute Enclaves

  • CCC computations run inside TEE (Trusted Execution Environment) enclaves
  • The enclave receives re-encrypted inputs from the Vault DON, decrypts locally, performs computation
  • The enclave produces an attestation proving the computation was performed correctly inside a genuine TEE
  • The Workflow DON verifies the attestation and quorum-signs the result before writing to chain

Private Token Transfers

  • CCC private token transfers use an account-based model (more efficient than UTXO-based privacy)
  • The contract stores an encrypted balance table with balances encrypted under the CCC master public key
  • Transfers happen entirely inside the CCC enclave: decrypt balances → apply debits/credits → re-encrypt
  • Onchain, only the encrypted balance table blob and a hash are stored
  • No plaintext amounts, sender/receiver identities, or transfer details are ever visible onchain

Data Visibility After CCC Integration

Data Visibility
isSolvent boolean Public onchain (ReserveAttestation.sol)
Reserve amounts Never onchain (stays in CRE workflow)
Dark pool order amount Never onchain (CCC threshold encrypted)
Market maker identities Never onchain (inside CCC enclave only)
Fill prices Never onchain (inside CCC enclave only)
Token transfer amounts Never onchain (CCC private token transfer)
Updated balance table Onchain as encrypted blob + hash only
Recovery succeeded Public onchain (boolean)
CCC attestation Public onchain (proves computation was correct)

Simulation Note

CCC is in Early Access (launched early 2026). The CCC private token transfer operations in this project are simulated with the same interface patterns. The ConfidentialHTTPClient for reserve verification is already live. Full CCC GA with decrypt/encrypt primitives is planned for later in 2026.

Threat Model

CRE-Only vs CCC Threshold Encryption

The move from CRE-only workflows to CCC threshold encryption fundamentally changes the threat model:

Threat CRE Only Threshold Encryption (CCC)
Compromised enclave Attacker sees all data processed by that enclave Attacker sees only data assigned to that enclave after compromise. Master key is never present
Compromised DON node Node operator could observe inputs/outputs Node holds only a key share and cannot decrypt alone. Quorum required.
Key extraction Single enclave key is the single point of failure Master secret key is never reconstructed. Vault DON re-encrypts via threshold shares.
Key rotation Must re-deploy enclave Proactive secret sharing rotates key shares without changing the master public key

The key property: Compromising a single compute enclave only leaks data for requests assigned to it after compromise. The CCC master decryption key is never held by any single node. It exists only as threshold shares across the Vault DON. An attacker would need to simultaneously compromise a quorum of Vault DON nodes to reconstruct it.

CCC-Specific Considerations

  • Enclave assignment: The Workflow DON assigns compute enclaves from a pool. An attacker who compromises one enclave cannot predict which future requests will be routed to it, limiting the blast radius.
  • Attestation verification: The Workflow DON quorum-signs CCC results before they reach the chain. A compromised enclave producing incorrect results would fail attestation verification. The quorum acts as a second line of defense.
  • Encrypted state onchain: The CREDarkPool contract stores only encrypted balance table blobs. Even with full chain access, an observer cannot determine individual market maker balances, order sizes, or transfer amounts.
  • Graceful failure privacy: When the dark pool fails (insufficient liquidity), the failure is reported without revealing the order size or the pool's total capacity. An observer learns only that a recovery was attempted and failed, not why or how large the gap was.

Demo-Specific Considerations

  • Mock API manipulation: In the demo, anyone on localhost can call /toggle or /set-reserves to change the reported reserve state. In production, the custodian API is authenticated and ConfidentialHTTP prevents MITM attacks on the data path.
  • Contract ownership: The ReserveAttestation contract restricts updateAttestation() to the deployer. In production, only the DON's onReport() callback can update the attestation.
  • Agent autonomy: The agent acts only on verified onchain events (not on API data directly). An undercollateralized API response alone does not trigger recovery. It must first be attested onchain by the CRE workflow.
  • Simulated CCC operations: In the demo, CCC threshold encryption and private token transfers are simulated with the correct interfaces but without real cryptographic operations. The security properties described above apply only to production CCC deployments.

There aren't any published security advisories