How it works
A plain account of the five contracts, in the order you meet them. Numbers are measured on a mainnet fork; limits are stated where they apply.
Lattice signatures, and why
An Ethereum account is an ECDSA key on the secp256k1 curve. Its safety rests on the discrete logarithm problem, which Shor's algorithm solves on a large enough quantum computer. No such machine exists today; the point of LATTICE is that coins in a lattice account would not depend on that staying true.
ML-DSA is the signature NIST standardised in 2024 as FIPS 204. Its safety rests on module lattice problems (MLWE and MSIS), for which no efficient quantum algorithm is known. LATTICE uses the middle parameter set, ML-DSA-65. A signature is, roughly, a short vector: verification rebuilds a point from the public key and checks that the signer's vector z is short (every coefficient under 524,092) and lands where the message says it must.
The price is size and gas. That is why a lattice account is a place to keep coins, not a place to trade from every minute.
The key, written in three parts (0 1 0)
Your key is made in the wallet page from 32 random bytes of your browser's crypto.getRandomValues.
Those 32 bytes are the whole secret: ML-DSA-65 rebuilds the 4,032-byte signing key and the 1,952-byte public key
from them. The page never sends them anywhere. You keep them in a key file sealed with your passphrase
(PBKDF2-SHA-256 with 600,000 rounds, then AES-GCM).
Your lattice id is the keccak256 hash of the public key. Before the chain can check a signature, the public key must be expanded (its matrix sampled from SHAKE128, the rest moved into the NTT domain) and stored. That costs more than one Ethereum transaction may use, so it is three:
An order (1 0 0)
A lattice account's coins sit inside the LATTICE contract. They move only by an order the account's key signed:
- 1 Withdraw coins to an Ethereum address. 2 Send to another lattice id. 3 Sell through the Door, ETH to an address. 4 Claim the account's ETH yield. 5 Guard: set a delay, a recovery key and a haven. 6 Cancel a waiting order. 7 Sweep everything to the haven (recovery key only).
- The key signs the exact bytes
Lattice.message(id, role, order)returns: a tag, the chain id, the coin's address, the account, the role and the order, with the context string "LATTICE". The wallet page builds those bytes itself, compares them with the chain's, signs, verifies the signature in your browser, and asksLatticeKeys.checkon chain before offering to send anything. - Every order carries a nonce and a deadline, so each signature works once and not forever.
- Anyone may relay a signed order and pay its gas (about 3.6M). On the wallet page your own MetaMask relays it. An order can tip, in LATTICE, whoever makes it run.
The guard: delay, recovery key, haven
A Guard order sets a delay of up to 30 days. From then on every order but Cancel waits in a queue (16 at most) for that delay, then anyone may execute it until its own deadline. The account's recovery key, another lattice id, may Cancel any waiting order at once, or Sweep every coin and all the ETH, at once, to the haven: a lattice id the account's own key named in its Guard order. The recovery key cannot choose where the coins go, takes no tips and has its own nonce. A stolen account key then shows up as an order in the queue, and the recovery key has the whole delay to stop it.
The recovery key must be written on chain (its own three parts) before it can sign. Keep its file apart from the account's.
The hold
A deposit worth a tenth or more of the receiving account's new balance freezes that account's Withdraw, Sell and tips for one hour. It stops coins being locked just before a large swap, to catch its yield, and taken out just after. A smaller deposit freezes nothing. Holding someone's account frozen costs a tenth of its balance, which becomes theirs.
The pool and the fee (1 1 0)
All 1,000,000,000 LATTICE are minted once, to the hook, which puts every coin into one Uniswap v4 position at opening: ETH / LATTICE, LP fee 0, tick spacing 200, from tick -887200 up to tick 207200, all coins below the opening price. The opening price is a constant: 1.0001207200 LATTICE per ETH, the whole supply at 1.0043 ETH. Nobody can open this pool at another price.
The hook takes 1% of the ETH side of every swap, in ETH. Half is owed to the owner. Half rains on the coins in lattice accounts, by weight, at that moment; while fewer than 1,000 coins are in them, it goes to the owner too. The Uniswap app cannot route a pool whose hook returns deltas, so the site's Buy page goes through the Door, a small contract that swaps straight against the pool. Trades of LATTICE anywhere else pay no fee here.
What it does not protect
- Ethereum. Consensus, and the ETH in your wallet that pays the gas for every relay, are classical cryptography. A lattice account protects the coins in it, nothing more.
- The pool. The position NFT is minted to the owner, who can withdraw the pool's liquidity with it. That is trust in the owner, stated in the hook's own header.
- Ordinary balances. LATTICE in your Ethereum wallet is held by your Ethereum key.
- A lost key. Without a recovery key and haven set beforehand, a lost key file or passphrase means the coins cannot move again. Nobody can reset it.
- This browser. The key is made and used in this page. A compromised computer or browser extension can read it while it is open, as with any software wallet.
- New code. The on-chain ML-DSA-65 verifier is new. It is tested against
@noble/post-quantumand NIST's ACVP ML-DSA signature-verification vectors; it is not audited.