How Shell works
Shell is a shielded pool for stock tokens issued by the Robinhood StockFactory. Inside the pool the chain records hashes; it does not record who holds what.
How notes work
A note is a private record of value: an amount, a token, a label inherited from the deposit, and an owner key. The chain stores only its commitment, a Poseidon hash of those fields with a random blinding factor, and an encrypted copy of the note that only the owner's viewing key can open.
- Shield is public. Your wallet sends tokens to the pool and the contract inserts a commitment. The depositor, token and amount are visible in that one transaction.
- Send spends one note and creates two: one for the recipient and one for your change. The chain sees a nullifier and two new commitments. It does not see the sender, the recipient, the token or the amount.
- Unshell spends a note and pays a public amount to an address of your choice. The chain sees the recipient, the token and the amount, plus a nullifier. It cannot tell which deposit the note came from.
A note can be spent once. Its nullifier is a hash of your nullifying key and the note's position in the tree, so the contract can reject a second spend without learning which note it was.
Proofs are Groth16 proofs generated in your browser from the circuit in circuits/. The relayer that submits them sees the proof and your IP, nothing else.
Keys and viewing keys
Everything derives from a 12-word recovery phrase that exists only on your device, encrypted with your password. From it come three things:
- a spending key, which proves ownership when you send or unshell;
- a nullifying key, which derives nullifiers so spends can be detected;
- a viewing key, which decrypts notes sent to you.
Your shell address is 134 characters and contains two public keys. Anyone with it can send to you. Nothing in it can spend.
A viewing key export contains the nullifying key and the viewing private key. A device with it sees every note you hold and every spend, and can never spend. Give it to an accountant, or to yourself on another device. It cannot be revoked; make a new set of keys and move your notes if you need to.
If you lose the phrase and the device, the notes are gone. Shell has no account and no recovery.
What the issuer can do
Stock tokens are contracts controlled by their issuer, Robinhood Assets (Jersey) Limited. Shell hides holders from the chain. It cannot change what the issuer can do:
- Pause every transfer of a token, globally. While paused, shields and unshells of that token revert.
- Block any address on every transfer. If the pool's address is blocked for a token, nothing of that token can leave the pool until it is unblocked. If your recipient is blocked, your unshell reverts and your note stays spendable.
- Burn tokens from any holder, including the pool. If that happens the last notes in that token cannot be redeemed in full.
- Upgrade the token implementation, which can change any of the above.
Shell itself has none of these powers and no owner. Nobody can pause it, upgrade it or take from it. The same is true of its bugs.
Relayers
A relayer is a server with a funded key that submits your proof so your own wallet never has to sign an unshell. It sees the proof, the recipient and your IP. It cannot spend your notes, redirect the withdrawal or change the amount: all of that is bound into the proof. It can refuse or delay, and it takes a fee you agree to in advance. Anyone can run one; the app accepts any URL.
Association sets
When you unshell you also prove that your original deposit belongs to a set of deposits published by a set provider, without saying which one. The set's root and the provider's address go on chain with the withdrawal. Providers publish lists of deposit labels; which provider to trust is between you and whoever receives the funds. Transfers inside the pool need no set.