System Design

Threat Model & Trust

A precise accounting of what each component can and cannot do, what properties are enforced by cryptography, and what assumptions the system relies on.


Security properties

Balance confidentiality

Guaranteed

All balances are stored as ElGamal ciphertexts. No plaintext amount is ever written to either chain. A passive observer of either ledger learns nothing about any account balance.

Enforced by: Cryptography

Transfer amount confidentiality

Guaranteed

The transferred amount in a confidential transfer is encrypted under both the sender's and recipient's public keys. Even the relayer sees only proof data not the plaintext amount.

Enforced by: Cryptography

No theft of funds

Guaranteed

Tokens are held in the Stellar Soroban contract, which only releases them on a valid withdraw callback from the relayer. The relayer cannot forge an approval it can only relay what Fairyring approved.

Enforced by: Contract logic + ZK proofs

No invalid balance creation

Guaranteed

A range proof accompanies every withdrawal and transfer, proving the sender's resulting balance is ≥ 0. The Fairyring contract rejects any proof that fails verification.

Enforced by: ZK range proof (Bulletproofs-style)

Sender authorization

Guaranteed

The Soroban contract enforces owner.require_auth() before accepting any action. Only the account owner can initiate deposit, transfer, apply, or withdraw.

Enforced by: Soroban auth framework

Replay protection

Guaranteed

Each account maintains a monotonically increasing tx_id on Fairyring. Duplicate messages are detected and re-synthesize the prior response without mutating state.

Enforced by: Contract state (last_processed_id)

Relayer liveness

Assumption

If FairyPort is offline, user operations will not finalize. The relayer is a liveness assumption, not a safety assumption it can censor but not steal.

Enforced by: Operational (not cryptographic)

Relayer off-chain proof correctness

Mode-dependent

When use_offchain_verify=true, the relayer verifies ZK proofs via its Rust FFI library. A malicious or buggy relayer could accept invalid proofs. onchain verification removes this assumption.

Enforced by: Depends on mode

What the relayer (FairyPort) can and cannot do

FairyPort is a trusted but not trusted-with-funds component. It is trusted for liveness and (in off-chain mode) proof verification. It has no ability to steal user tokens.

What it CAN do

  • Observe all events on both chains (read-only)
  • Censor operations by refusing to relay events
  • In off-chain mode: accept or reject ZK proofs
  • View the structure of proof data (not plaintext amounts)
  • Retry failed transactions automatically
  • Reorder messages within the bounded event queue

What it CANNOT do

  • Steal or redirect user tokens (contract holds escrow)
  • Forge a valid ZK proof (computationally infeasible)
  • Decrypt any user balance (no access to private keys)
  • Execute on behalf of a user (Soroban require_auth enforced)
  • Process a duplicate tx_id (Fairyring replay guard)
  • Create a withdrawal without a valid range proof
  • Alter Fairyring contract state without a whitelisted key

Trust assumptions (ranked by impact)

01

Relayer liveness

High affects liveness, not safety

FairyPort must be online and functioning to process user operations. A crashed or censoring relayer blocks all activity. Mitigation: run multiple independent relayer instances; anyone with the relayer key can run a backup.

02

Relayer off-chain proof verification (optional)

High in off-chain mode can be eliminated by using onchain mode

When use_offchain_verify=true, the relayer's Rust FFI library verifies ZK proofs before forwarding to Fairyring. A compromised relayer could skip verification and forward invalid proofs. Use onchain verification (use_offchain_verify=false) to remove this assumption entirely.

03

Fairyring relayer allowlist

Medium affects who can submit, not what is accepted

The Fairyring contract enforces a whitelist of allowed addresses that can submit transactions. Only addresses added by the admin can interact with the contract. The admin key represents a trust assumption for the initial allowlist configuration.

04

Cryptographic soundness

Low standard cryptographic assumptions

The security of all guarantees depends on the hardness of the discrete logarithm problem on Ristretto255, the soundness of the Bulletproofs range proof system, and the binding property of the Pedersen commitment scheme.

05

Client-side key custody

Low standard key custody risk

The user's ElGamal private key is generated client-side and never transmitted. Loss of the private key means permanent loss of balance decryption capability (though the onchain ciphertext remains). Secure key storage is the user's responsibility.

Zero-knowledge proofs used

Proof typeOperationWhat it proves
Equality proofTransfer, WithdrawThe same plaintext is encrypted under both the sender's and recipient's keys (consistency proof)
Range proofTransfer, WithdrawThe resulting sender balance after deduction is ≥ 0 (no overdraft), without revealing the balance
Ciphertext validity proofTransferThe transfer amount ciphertext is well-formed and encrypted under valid public keys
Withdraw nonce bindingWithdrawThe proof is bound to a specific tx_id, preventing proof reuse across different withdrawal operations

Audit status

The Stellar Soroban contract, Fairyring CosmWasm contract, and FairyPort relayer have not yet been formally audited. The codebase should be treated as a pre-production system and not used with material value until an audit is complete.