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:
- Gasless deposit and shield in one transaction, authorized by an EIP-3009 signature whose nonce is bound to the new note. This is the only deposit path: there is no approval step, no Permit2, no escrow and no separate shield call.
- Two entry points for it:
depositAndShieldWithEIP3009(EOAs,v/r/s) anddepositAndShieldWithEIP3009Sig(smart wallets, ERC-1271) - 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)
- 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
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. The owner is a single key with no on-chain delay; hardening it is tracked internally as an open item.
- Spends require a known Merkle tip (
isKnownRoot) bound in the attestor EIP-712 digest - Spend authorization: spending a note requires the recipient's spend key, not merely knowledge of the note's secrets
- Reviewed in internal security audits; open findings tracked internally