Transactwithout a trace
Ethereum is getting private transfers. Mask gives it private trades — unshield, swap on Uniswap v4 and re-shield in a single atomic call, so no address of yours ever touches the DEX.
- 0.30%
- shielded swap fee
- 0 ETH
- gas from your wallet
- 1 tx
- unshield · swap · re-shield
The only account that touches Uniswap is a shared, stateless router used by every Mask trader. A bonded relayer submits the transaction and is reimbursed out of the swap output.
EIP-8182 makes transfers private
A shielded pool as a system contract at 0x…081820. Global note-commitment tree, nullifier set, policy registry, native ZK verification. No proxy, no admin, no upgrade path.
It doesn't make trades private
The moment a shielded balance touches a DEX it lands on a public address that links the note to the swap — and you need a funded address to pay gas from. Mask closes exactly that gap.
One call. Three legs. No link.
The note is spent straight into MaskVeil, the swap executes, and the output is deposited back under a fresh owner commitment — or paid out to a clean address if you want to leave the pool.
The note is spent straight into the shared router — never onto your address.
The hook prices the swap at 0.30% because the flow arrived shielded.
Output lands under a fresh owner commitment. No link to the input note.
A relayer can't steal your trade
MaskAuthVerifierEvery spend is gated on two independent bindings: the signature must come from the session key you committed to inside your EIP-8182 policy set, and it must cover the exact swap intent the router holds in transient storage for that transaction. Retargeting the recipient or loosening slippage makes the pool reject the spend outright.
Non-custodial between transactions
MaskVeilMaskVeil unshields, swaps and re-shields inside a single call. It holds no balances afterwards, and the only place dust can ever go is the treasury. Owner powers are limited to registering pools, a hard-capped fee, and sweeping that dust.
Public flow subsidises private flow
The hook runs the pool in dynamic-fee mode and prices each swap by provenance. The fee is the pool's LP fee — it goes to liquidity providers, not to the protocol. The hook takes no delta and holds no funds.
Transparent flow pays the full LP fee.
Flow that arrived shielded gets the discount.
- Protocol feehard-capped at 0.50%0.10%
- Relayer feesigned by you, per swap≤ 1.00%
Both come out of the swap output — which is why you never need a funded public address.
Bandwidth for private flow is bought with staked supply
Private swaps are submitted by relayers, because a shielded user has no funded address to pay gas from. That makes the relayer set the one place the system can be griefed — so it is bonded.
- 25,000 MASKMinimum bond to serve private flowStake, become active, start relaying.
- 7 daysUnbonding cooldownMisbehaviour stays slashable after you leave.
- ≤ 20%Slash cap per actionA compromised guardian can't zero a bond.
- 8,182,000Fixed supplyNo mint, no tax, no pause, no blacklist.
Six contracts. 36 tests. Zero admin keys on the money path.
| MaskVeil | Unshield → v4 swap → re-shield, atomically |
| MaskAuthVerifier | EIP-8182 authorization policy, staticcalled by the pool |
| MaskHook | v4 hook · flags AFTER_INITIALIZE | BEFORE_SWAP |
| MaskRelayerRegistry | Bonded relayer set, the $MASK sink |
| MaskToken | Fixed-supply ERC-20, 8,182,000 |
| MaskLpManager | Single-side v4 liquidity |
36/36 tests green — 18 locally, the same 18 against the real Uniswap v4 PoolManager on a mainnet fork.
No custody, no upgrade path. MaskVeil holds nothing between transactions, the hook takes no delta, and the token has no mint, tax, pause or blacklist.
Protocol fee hard-capped at 0.50%, relayer fee at 1.00%, slashing at 20% per action — enforced in bytecode, not by policy.