Smart Contracts
Senddy's on-chain contracts — pool, verifiers, and yield strategies.
Overview#
Senddy's smart contracts are deployed on Base (Coinbase's Layer 2). The system is centered around a single pool contract that manages all deposits, shields, spends, and withdrawals.
Core Contracts#
Pool Contract#
The main contract. All user funds are held here.
Key capabilities:
- Deposit USDC into the pool (public)
- Batch multiple deposits in a single transaction
- Gasless deposits using Permit2 or EIP-3009 authorization
- Shield a deposit into private notes using an attestation
- Combined deposit + shield in one transaction
- Execute private spends (transfers between users)
- Execute spends with a public withdrawal
- Accrue yield from the strategy
- Screen deposits against the Chainalysis sanctions oracle — OFAC-sanctioned addresses are blocked at the contract level
State:
- Known Merkle tip ring (
currentRoot+ recent roots) — the full commitment tree is maintained in the attestor enclave; the pool checks membership viaisKnownRoot - Nullifier accumulator (tracks spent notes)
- Deposit registry (pending deposits)
- Asset configuration and strategy addresses
- Attestor address (authorized proof verifier)
Verifier Contracts#
Senddy uses dedicated verifier contracts for each proof type:
- Shield Verifier — Verifies zero-knowledge proofs for shield operations, generated from the Noir shield circuit using the UltraHonk proving system
- Spend Verifier — Verifies zero-knowledge proofs for spend operations
- Association Verifier — Verifies association proofs that link funds to approved deposit sources, enabling compliance without breaking privacy
Yield Strategy#
The pool deploys funds to trusted DeFi lending protocols for yield generation. The strategy contract manages deposits, withdrawals, and yield reporting back to the pool.
The pool supports a modular strategy interface, allowing multiple yield strategies to be used in the future.
Security#
- Contracts are upgradeable with access-controlled owner functions (production should place ownership behind a timelock or multisig)
- Spends require a known Merkle tip (
isKnownRoot) bound in the attestor EIP-712 digest - Audited by independent security researchers; open findings tracked internally
- Bug bounty program for responsible disclosure