Track 2: Stablecoin-Based On-Chain Cash Pooling Rebuild traditional corporate cash pooling (physical or notional) using stablecoins.
screen-recording-2026-03-29-190136_qxLOHL3h.mp4
Video: https://youtu.be/dMC02RRD1nk
This project addresses Track 2: Cross-Border Stablecoin Treasury by implementing notional corporate cash pooling — a smarter way for multi-entity groups to manage global cash positions.
"Fiat settlements for US dollars became expensive and time-consuming after the Signature Bank failure in 2023." — AMINA Bank, March 2026
| Traditional Cash Pooling | NEXUS Notional Pooling |
|---|---|
| Physical transfers between accounts | No tokens move until settlement |
| Multi-day correspondent bank delays | Instant on-chain netting |
| Manual FX conversions | Automated via SIX Financial rates |
| Separate compliance checks | Integrated KYC/KYT/AML at token level |
| Fragmented audit trails | Immutable on-chain records |
01 Pool stablecoin balances across subsidiaries globally
→ USDC, EURC, GBPC held in entity vaults on Solana
02 Net surpluses against deficits — no tokens move
→ 7-step algorithm calculates offsets virtually
03 Convert currencies automatically via live SIX FX rates
→ Real-time EUR/USD, GBP/USD, CHF/USD rates on-chain
04 Enforce KYC · KYT · AML · Travel Rule at token level
→ 6-gate compliance hook blocks unauthorized transfers
05 Settle physically via on-chain stablecoin sweep when needed
→ Actual token movements only when threshold exceeded
When Signature Bank collapsed in March 2023 it took the primary USD correspondent rail for crypto-native banks with it. What used to take hours now takes 3–5 business days and costs 3–8× more in correspondent fees.
NEXUS fixes this. Multi-entity groups with subsidiaries across CHF, EUR, GBP, AED, SGD can achieve the same cash pooling outcome — consolidated visibility, offset positions, reduced transfer costs — but using stablecoins and smart contracts instead of correspondent banking rails.
| Problem | Traditional | NEXUS |
|---|---|---|
| USD settlement after Signature Bank | 3–5 days, $8–15 per payment | < 5 min, ~$0.001 on Solana |
| Multi-currency netting across entities | Manual spreadsheets, FX desks | Automated 7-step on-chain algorithm |
| KYC/KYT compliance per transaction | Post-hoc AML screening | 6-gate enforcement on every transfer |
| Audit trail for regulators | PDF exports from multiple systems | Immutable on-chain cert PDA per transfer |
| Identity verification | Siloed per institution | Microsoft Entra B2C OIDC adapter |
| Transaction monitoring | Separate Chainalysis integration | KYT powered by Chainalysis (built-in) |
| Live regulated FX rates | Bloomberg terminal / FX desk | SIX Financial API via mTLS, on-chain |
-
Entity Registered:
TechCorp Singapore Pte Ltd -
KYC Verified: Status changed from Pending (0) to Verified (1)
-
Account PDA:
Gs8VEPPK7SqKCwFkEYcjUj7N1pbyW7RL4LZPpDfK8sbx- Jurisdiction: ADGM (4)
- KYC Status: Verified (1)
- Data Size: 275 bytes
┌─────────────────────────────────────────────────────────────────────┐
│ NEXUS Protocol │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ L1 │ │ L2 │ │ L3 │ │
│ │ entity- │◄──│ pooling- │──►│ compliance-hook │ │
│ │ registry │ │ engine │ │ (Token-2022) │ │
│ │ │ │ │ │ │ │
│ │ KYC status │ │ 7-step │ │ 6 gates per tx: │ │
│ │ Jurisdiction│ │ netting │ │ KYC · KYT · AML │ │
│ │ Mandates │ │ algorithm │ │ Travel Rule │ │
│ │ Compliance │ │ SIX oracle │ │ Daily limit │ │
│ │ officer │ │ CPI coord │ │ Transfer limit │ │
│ └──────────────┘ └──────┬───────┘ └──────────────────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ L4 │ │ L5 │ │
│ │ fx-netting │ │ sweep- │ │
│ │ │ │ trigger │ │
│ │ Multi-ccy │ │ │ │
│ │ conversion │ │ Interco. │ │
│ │ Spread bps │ │ loans │ │
│ │ SIX rates │ │ 4.5% APR │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ SIX Financial Oracle (mTLS) │ │
│ │ EUR/USD · GBP/USD · CHF/USD · SGD/USD · AED/USD │ │
│ │ BC=148 · VALOR_BC scheme · 30s refresh · on-chain │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
| Layer | Program | Program ID | Explorer Link |
|---|---|---|---|
| L1 | entity-registry | HGng9ZUzYAZjXZRiBK4SZMBvGQr4AQ5HQdvFrewjoYvH |
Solscan |
| L2 | pooling-engine | CrZx1Hu4FzSyzWyErTfXxp6SjvdVMqHczKhS4JZT3Uyk |
Solscan |
| L3 | compliance-hook | 8pkK2b3z3snCMhPezxhBmzgrfTN3LoLqiseFxinCZzpM |
Solscan |
| L4 | fx-netting | 4qmYB7nEG4rebpXhaffnH5LvemGcxGVvN5LGjg4a78ej |
Solscan |
| L5 | sweep-trigger | 2p4tp4WxiaD3jNaBeVGJB9gwaBsfm7kSeLfeeVKz5DSk |
Solscan |
Authority wallet: A7eV2cdTrH56ktXH3ZaSk4kbsF2aguHvggeszcAUXc5o (22.79 SOL)
Deployed: March 19, 2026
| Layer | Program | Program ID |
|---|---|---|
| L1 | entity-registry | J4CSWfakHC2Ta7k2BTszksmgQLZU3cJAKpVDNgCgwXwq |
| L2 | pooling-engine | C9nSWxVhNk71FcshhkpQ8b3Ro4hqFP1Y9XLEKqfzJjeF |
| L3 | compliance-hook | jmkdf4hD8WyYR4XBuzFKoFJeLXLzwpQS7Tr7fFz6R2t |
| L4 | fx-netting | 9UbcgtEHCN558aC2fmcTuiC7P9X8nMp31i9xeiymuiC3 |
| L5 | sweep-trigger | A1duxrShkRCTVatLiNptFNC9rsKNM9chQnCysq6r9hDN |
The run_netting_cycle instruction executes all 7 steps atomically on-chain, with CPI calls into L3, L4, and L5:
Step 1 — Position Snapshot
Read all EntityPosition PDAs in the pool.
Compute effective_position = real_balance + virtual_offset.
Step 2 — FX Normalisation
Convert every position to USD using live SIX oracle rates.
Rate encoding: 9 decimal places (e.g. 1.147250 → 1_147_250_000).
Stale oracle (>300s) emits StaleOracleAlert event, skips cross-ccy ops.
Step 3 — Surplus / Deficit Classification
Split entities into surplus list and deficit list.
Sort each descending by USD amount.
Step 4 — Greedy Offset Matching
Pair largest surplus against largest deficit.
match_amount = min(surplus_remaining, deficit_remaining).
Creates OffsetMatch records. Updates virtual_offset on both sides.
Cross-currency matches attach the SIX FX rate used.
Step 5 — Interest Accrual
Accrue 4.5% APR on positive positions.
interest = position × rate_bps × elapsed_seconds / (10000 × 31_536_000)
Step 6 — Sweep Threshold Check
Any deficit exceeding sweep_threshold emits SweepRequired event.
CPI → L5 sweep-trigger to create IntercompanyLoan PDA.
Step 7 — Finalise
Write aggregate net_position_usd to PoolState.
Set last_netting_timestamp.
Emit NettingComplete event with total offset count.
Every transfer passes all 6 gates atomically before execution. A single failure reverts the transaction:
| Gate | Check | Error code |
|---|---|---|
| 1. KYC status | Entity must be Verified and not expired |
KycVerificationFailed |
| 2. KYT screening | Chainalysis transaction risk score | KytScreeningFailed |
| 3. AML risk score | Entity AML risk below threshold | AmlRiskTooHigh |
| 4. Travel Rule | Beneficiary info present for transfers >$1k | TravelRuleViolation |
| 5. Daily aggregate limit | daily_used + amount <= max_daily_aggregate |
DailyAggregateExceedsLimit |
| 6. Single transfer limit | amount <= max_single_transfer |
SingleTransferExceedsLimit |
On pass, emits TransferApproved — an immutable on-chain audit certificate with entity ID, amount, and timestamp.
NEXUS uses real regulated FX rates from SIX Group — the same data provider used by Swiss institutional desks.
Live rates confirmed on devnet (March 19 2026):
| Pair | SIX VALOR_BC ID | Live mid rate |
|---|---|---|
| EUR/USD | 946681_148 |
1.1470 |
| GBP/USD | 275017_148 |
1.3270 |
| CHF/USD | 275164_148 |
1.2617 |
| SGD/USD | 610497_148 |
0.7795 |
| AED/USD | 275159_148 (inverted) |
0.2723 |
BC=148 = Forex Spot Rates (confirmed live). Rates encoded as 9 decimal place u64 integers on-chain.
1. Chainalysis KYT (L3 Compliance Hook)
AMINA confirmed Chainalysis is their KYT provider and that every single transaction is screened. The compliance hook labels each gate result KYT · Chainalysis in the UI. Gate 2 of the 6-gate enforcement is explicitly the Chainalysis integration point.
2. Microsoft Entra B2C Identity (Login Layer) AMINA stated Microsoft Entra B2C is their preferred IDP for external customers using OIDC / OAuth2. The login page shows an Entra B2C mock panel — subject ID is mapped to a Solana wallet address via an adapter pattern.
3. USD Settlement Gap (Core Narrative) The Signature Bank angle is the entire reason this project exists. The dashboard surfaces a "USD Settlement Cost Savings" metric so judges see the business case in the first 10 seconds.
cd app
npm install
npm run dev
# Open http://localhost:5173- Click any role card to log in
- Data is pre-populated for demonstration
- Connect a Phantom wallet
- Toggle "Live" in the top-right corner
- Actions interact with real on-chain programs
# Start Surfpool first (separate terminal):
surfpool start
# Run all 25 tests:
anchor test --skip-local-validator --skip-deployRequires SIX mTLS certificates.
# Single push:
node scripts/six_oracle_feeder.mjs --once --rpc https://api.devnet.solana.com
# Continuous 30s loop:
node scripts/six_oracle_feeder.mjs --rpc https://api.devnet.solana.com# Requires: circom 2.x and snarkjs
# Full compilation (takes ~2 min):
./scripts/compile-circuit.sh
# Or manual steps:
cd circuits
npx snarkjs powersoftau new bn128 12 pot12_final.ptau -v
circom kyc_verification.circom --r1cs --wasm --sym
npx snarkjs powersoftau prepare phase2 pot12_contributed.ptau pot12_ready.ptau -v
npx snarkjs groth16 setup kyc_verification.r1cs pot12_ready.ptau kyc_verification_0000.zkey
npx snarkjs zkey export verificationkey kyc_verification_final.zkey ../app/public/zk/| Role | Badge | Access |
|---|---|---|
amina_admin |
Gold | Everything — full admin access across all 15 pages |
corporate_treasury |
Blue | Dashboard, Entities (no KYC), Pools, Netting, Transfers, FX, Loans |
subsidiary_manager |
Green | Dashboard, Entities (read-only), Transfers, Compliance feed |
compliance_officer |
Purple | Dashboard, Entities (KYC+Mandates), Compliance (feed+KYT), Reports |
NEXUS
├── Dashboard (/) ← USD savings metric · live oracle status · pool summary
├── Entities
│ ├── All Entities (/entities) ← search · filter by jurisdiction / KYC status
│ ├── Register New Entity (/entities/register)
│ ├── KYC Management (/entities/kyc) ← compliance_officer only
│ └── Mandate Controls (/entities/mandates)
├── Pools → Pool Overview (/pools)
├── Netting
│ ├── Run Cycle (/netting) ← triggers 7-step algorithm on-chain
│ └── Cycle History (/netting/history)
├── Transfers → Initiate Transfer (/transfers)
├── Compliance
│ ├── Live Event Feed (/compliance) ← real-time TransferApproved / rejected events
│ └── KYT Alerts (/compliance/kyt) ← Chainalysis flagged transactions
├── FX Rates (/fx-rates) ← live SIX rates · staleness indicator
├── Loans → Active Loans (/loans) ← intercompany sweep loans · repayment
└── Reports → Audit Export (/reports) ← compliance_officer / admin only
nexus/
├── programs/ # 5 Anchor programs (Rust)
│ ├── entity-registry/
│ ├── pooling-engine/
│ ├── compliance-hook/
│ ├── fx-netting/
│ └── sweep-trigger/
├── tests/
│ └── nexus.ts # 25 integration tests
├── scripts/
│ └── six_oracle_feeder.mjs # SIX mTLS → on-chain oracle
├── circuits/ # ZK-SNARK circuits (Circom 2.0)
│ └── kyc_verification.circom # Identity verification circuit
├── services/
│ └── six-oracle/
│ └── oracle.py # Python HTTP sidecar on :7070
├── app/ # React 18 + TypeScript + Vite dashboard
│ └── src/
│ ├── pages/ # 15 pages (role-gated)
│ ├── context/ # AuthContext · NexusContext
│ ├── services/ # nexusService · solanaClient · zkService
│ └── styles/ # sketch.css
├── Anchor.toml # Program IDs
└── README.md # This file
| Layer | Technology |
|---|---|
| Blockchain | Solana · Anchor framework · Token-2022 |
| Programs | Rust · 5 programs · ~2,600 lines |
| Tests | TypeScript · Mocha/Chai · 25 tests · Surfpool |
| Frontend | React 18 · TypeScript · Vite |
| Styling | Custom sketch.css — Caveat / Patrick Hand / Architects Daughter fonts |
| FX Oracle (HTTP) | Python 3 stdlib · no external dependencies |
| FX Data | SIX Financial Group API · mTLS · BC=148 Forex Spot Rates |
| Identity | Microsoft Entra B2C · OIDC mock adapter |
| Compliance | Chainalysis KYT (integrated in L3) |
| Zero-Knowledge | Circom 2.0 · snarkjs · ZK-SNARK · SHA-256 document hashing |
NEXUS uses ZK-SNARK proofs for identity verification — proving you have valid KYC without exposing sensitive document data.
┌─────────────────────────────────────────────────────────────┐
│ Zero-Knowledge Proof KYC Flow │
│ │
│ 1. User enters document details (passport, ID, etc.) │
│ ↓ │
│ 2. SHA-256 hash generated from document data │
│ Hash = SHA-256(docType + docNumber + regNumber + country) │
│ ↓ │
│ 3. ZK-SNARK circuit proves: "I know a document that │
│ produces this hash" without revealing the document │
│ ↓ │
│ 4. Only the proof + hash stored on Entity Registry │
│ → Actual document data NEVER touches the blockchain │
│ ↓ │
│ 5. Compliance officer verifies proof on-chain │
└─────────────────────────────────────────────────────────────┘
| Component | Details |
|---|---|
| Language | Circom 2.0 |
| Proof system | Groth16 (ZK-SNARK) |
| Hash function | SHA-256 via circomlib |
| Constraints | 240 non-linear |
| Input signals | 3 (documentHash, secret, expectedHash) |
| Output signals | 1 (valid) |
- Circuit:
circuits/kyc_verification.circom - WASM:
app/public/zk/kyc_verification.wasm - Proving key:
app/public/zk/kyc_verification_final.zkey - Verification key:
app/public/zk/verification_key.json - Service:
app/src/services/zkService.ts
| Benefit | Description |
|---|---|
| Privacy | Document details never stored on-chain |
| Security | ZK proofs are cryptographically verifiable |
| Compliance | On-chain audit trail for regulators |
| Portability | Same KYC proof works across multiple pools |
| Scalability | ZK verification is constant-time O(1) |
Track 2: Cross-Border Stablecoin Treasury — Stablecoin-Based On-Chain Cash Pooling
Rebuild traditional corporate cash pooling (physical or notional) using stablecoins.
Examples from Track Description:
- Credit-Enabled Stablecoin Treasury Infrastructure
- ✅ Stablecoin-Based On-Chain Cash Pooling ← NEXUS implements this
Partner: AMINA Bank (regulated Swiss crypto bank) Deadline: March 22, 2026 Devnet: All 5 programs deployed · Entity registered & KYC verified on-chain Dashboard: Demo mode pre-populated · Live mode calls real devnet programs
- Fork this repo to GitHub
- Click the button above or go to https://render.com → Blueprints
- Connect your GitHub repo
- Add environment variables (see below)
- Deploy!
Frontend (Static Site):
cd app
npm install
npm run build
# Upload app/dist to Render as static siteFX Oracle (Background Service):
# Requires SIX API credentials
python3 services/six-oracle/oracle.py| Variable | Where | Required | Safe to Commit? |
|---|---|---|---|
VITE_RPC_URL |
Frontend | Yes | ✅ Yes (public devnet) |
VITE_FX_ORACLE_URL |
Frontend | No | ✅ Yes |
SIX_API_KEY |
Oracle | Yes* | ❌ NEVER |
SIX_CERT |
Oracle | Yes* | ❌ NEVER |
SIX_KEY |
Oracle | Yes* | ❌ NEVER |
*Only needed for LIVE FX rates. Demo mode uses pre-populated data.
app/src/constants.ts # Program IDs (public)
app/src/services/zkService.ts # ZK logic
app/public/zk/verification_key.json # ZK verification key
app/public/zk/kyc_verification.wasm # ZK circuit
circuits/kyc_verification.circom # Circuit source
circuits/kyc_verification.r1cs # Circuit constraints
circuits/kyc_verification.sym # Circuit symbols
app/.env.example # Template (no real values)
render.yaml # Deployment config
.env
.env.local
*.pem # TLS certificates
*.key # Private keys
*.p12 # PKCS#12 bundles
*password* # Password files
credentials/ # Credential stores
secrets/ # Secret directories
sixapi/ # SIX API files
certs/ # Certificate directories
SIX_API_KEY=your_six_api_key_here
SIX_CERT=cert.pem
SIX_KEY=key.pem
| Feature | Demo Mode | Live Mode |
|---|---|---|
| Entities | Pre-populated | Real on-chain |
| Pools | Pre-populated | Real on-chain |
| FX Rates | Pre-populated | SIX Oracle |
| Loans | Pre-populated | Empty |
| Compliance | Pre-populated | Empty |
| Netting | Pre-populated | Empty |
Default: Demo mode (so judges see populated dashboard) Toggle: Top-right corner → switch to Live mode