Skip to main content
Three atomic-swap flows between public ERC-20 and Zama FHEVM confidential tokens (ERC-7984), all signed by DFNS-managed wallets. On the confidential leg, amounts are fully encrypted on-chain using Fully Homomorphic Encryption (FHE): only the balance holder can decrypt their own balance, and only the authorised counterparty sees what it needs to settle.

Get the code

dfns/dfns-solutions: confidential-swap

Three swap flows

Rate is 1:1 across all three flows.

Contracts

The swap contract follows a reserves pattern: it holds a pre-funded reserve of each token type to settle incoming swaps without needing to mint on-demand. Reserves are minted by the bank role at setup time.

What you’ll need

  • A DFNS account
  • A service account with these permissions:
    • Wallets:BroadcastTransaction on the bank, sender, and receiver wallets
    • Wallets:Read on all three
  • Three DFNS wallets on Ethereum Sepolia:
    • bank: deploys contracts and mints reserves
    • sender: initiates swaps
    • receiver: fills Flow 3 orders
  • Testnet ETH on all three wallets (Sepolia faucet)
  • Node.js v22+

Setup

1

Clone and install

2

Configure environment variables

.env
3

Compile contracts

Running the demo

Deploy

Contract addresses are written to deployment.json and read automatically by subsequent scripts.

Mint and fund reserves

Set approvals

Run the swaps

Flow 1: ERC-20 to confidential token
Flow 2: confidential token to ERC-20 (async)
Flow 3: confidential token to confidential token

Check balances

FHE notes

Access grants and transaction boundaries. The Zama FHEVM tracks which addresses may use an encrypted handle. Flow 2 and Flow 3 each span multiple transactions. The contracts use FHE.allowTransient() and FHE.allowThis() to pass handles between calls. If you add extra steps between transactions (querying balance handles in between, for example), access grants may no longer be valid. Input binding. When encrypting an amount off-chain with the Zama relayer SDK, the ciphertext is bound to a specific (contractAddress, callerAddress) pair. A ciphertext encrypted for the swap contract cannot be replayed against the token contract directly. Flow 2 KMS latency. After the first transaction, the script polls until the Zama KMS produces a cleartext + signature. This typically takes 10–30 seconds on Sepolia. The script retries automatically. 1:1 rate and 6 decimals. All tokens use 6 decimals. The swap contract does no scaling. Mixing tokens with different decimal counts requires adjusting the reserve maths.

Issue tokenized bonds

ERC-20 bond lifecycle with DFNS signing

Build programmable approval policies

Service accounts that decode ABI call data

Cross-border payments on Solana

Atomic stablecoin swaps with DFNS KMS

Wallets API

broadcastTransaction reference
Last modified on June 12, 2026