Documentation
Technical specification for the first quantum-resistant token on Solana.
What is LATTICE
LATTICE is a token on Solana where every operation — minting, buying, selling, transferring — is authorized by quantum-resistant cryptographic signatures instead of the standard Ed25519 used by the rest of the Solana ecosystem.
It uses Winternitz One-Time Signatures (WOTS), a hash-based signature scheme whose security depends on the preimage resistance of Keccak-256 — not on elliptic curve math that quantum computers can break.
BackendZero
Admin KeysNone
ContractImmutable
The program is deployed with upgrade authority revoked. The liquidity pool is owned by a PDA — a program-derived address with no private key. There is no server, no admin panel, no way for anyone to modify the protocol. The code runs exactly as deployed, forever.
Quantum Resistance Explained
The Problem with Ed25519
Every blockchain today — Bitcoin, Ethereum, Solana — relies on elliptic curve cryptography (ECDSA or Ed25519) to authorize transactions. These schemes depend on the mathematical difficulty of the discrete logarithm problem on elliptic curves.
In 1994, Peter Shor proved that a sufficiently large quantum computer can solve this problem in polynomial time. When that happens, any public key on any blockchain can be reversed into its private key, and all funds become stealable.
How WOTS Solves It
WOTS signatures are hash-based. Their security relies entirely on the preimage resistance of hash functions (Keccak-256). No quantum algorithm — including Shor's — provides an efficient attack against hash preimage resistance. Grover's algorithm offers a quadratic speedup (reducing Keccak-256 from 2256 to 2128 operations), but 2128 is still computationally infeasible.
What Is and Isn't Protected
ComponentQuantum-SafeNotes
$LATTICE token balance✅ YesProtected by WOTS (hash-based)
Mint / Buy / Sell / Transfer✅ YesWOTS verification on-chain (~472K CU)
Wallet encryption (AES-256-GCM)✅ Yes128-bit quantum security under Grover's
Key derivation (HMAC-SHA256)✅ YesHash-based, no ECC dependency
SOL gas wallet❌ NoEd25519 — vulnerable to Shor's algorithm
Solana base layer❌ NoInherent to Solana, outside protocol scope
Key TakeawayA quantum attacker who breaks Ed25519 could steal SOL from your gas wallet — but cannot steal your $LATTICE tokens. Keep only enough SOL for transaction fees.
How WOTS Works
WOTS (Winternitz One-Time Signatures) is conceptually simple: instead of relying on hard math problems, it relies on one-way hash functions. If you can hash something, you can sign. If you can't reverse a hash, you can't forge a signature.
Parameters
ParameterValue
Hash functionKeccak-256 (truncated to 28 bytes)
Components per key32
Hash iterations per component256 (matching byte range 0–255)
Signature size32 × 28 = 896 bytes
Public key size32 × 28 = 896 bytes
Merklized hash (stored on-chain)32 bytes
Key Derivation
From a 32-byte master secret, an infinite chain of WOTS keypairs is derived using HMAC-SHA256:
Key Derivation
For each key at index i, 32 components are derived:

  For component j in 0..32:
    input  = "QPL-WOTS" ‖ i (8 bytes LE) ‖ j (1 byte)
    seed[j] = HMAC-SHA256(master_secret, input)[0..28]

  Private key  = seed[0] ‖ seed[1] ‖ ... ‖ seed[31]     → 896 bytes
  Public key   = hash²⁵⁶(seed[0]) ‖ ... ‖ hash²⁵⁶(seed[31])  → 896 bytes
  On-chain hash = merkle_root(public_key_components)     → 32 bytes
Signing
To sign a message, the signer hashes each private key component a variable number of times based on the message digest:
Signing Algorithm
digest = keccak256(message)           → 32 bytes

For each component j in 0..31:
  n = digest[j]                        (byte value 0–255)
  sig[j] = hash^(256-n)(seed[j])       (hash seed 256-n times)

signature = sig[0] ‖ sig[1] ‖ ... ‖ sig[31]  → 896 bytes
Verification
The verifier completes the remaining hash steps to recover the full public key:
Verification Algorithm
digest = keccak256(message)           → 32 bytes

For each component j in 0..31:
  n = digest[j]
  recovered[j] = hash^n(sig[j])       (hash signature n more times)
  
  Total hashes: (256-n) by signer + n by verifier = 256 ✓

recovered_hash = merkle_root(recovered[0..31])
VERIFY: recovered_hash == stored next_key_hash
Visual Flow
WOTS Sign + Verify — One Component
  ┌── 256-n hashes (SIGNER) ──┐┌──── n hashes (VERIFIER) ────┐
  ●───────────────────────────●─────────────────────────────●
seed[j]                     sig[j]                    recovered[j]
(private key)             (signature)                 (public key)
                                                          │
  digest[j] = n                                     merkle root
  Total: (256-n) + n = 256 hashes                  compared with
                                                    on-chain hash
One-Time Use & Key Chain
Each WOTS key is used exactly once. Using a key twice with different messages would leak partial preimage information, enabling signature forgery. The protocol enforces this with a hash chain:
Key Chain Advancement
Before operation:  user.next_key_hash = hash(key[5])
                   user.key_index     = 5

Transaction includes:
  - WOTS signature using key[5]        (896 bytes)
  - new_next_hash = hash(key[6])       (32 bytes)

After operation:   user.next_key_hash = hash(key[6])   ← advanced
                   user.key_index     = 6               ← incremented

Key[5] is consumed. Even if the signature is replayed,
it won't match the new next_key_hash. Each key is one-use.
Merklization
The 32 public key components (28 bytes each) are compressed into a single 32-byte hash via a binary Merkle tree. This is the next_key_hash stored on-chain in each User PDA — only 32 bytes instead of the full 896-byte public key.
Transaction Example
Here's what actually happens when you buy $LATTICE tokens. Every trade carries an 896-byte WOTS signature — the quantum-resistant proof of authorization.
Real TransactionView on Solscan →
Buy Instruction Layout
Transaction Data — 943 bytes
Byte 0        [0x03]                   ← Discriminator (3 = Buy)
Bytes 1–896   [896 bytes]              ← WOTS signature (32 components × 28 bytes)
Bytes 897–928 [32 bytes]               ← new_next_hash (commitment to key[i+1])
Bytes 929–936 [8 bytes, u64 LE]        ← sol_amount (lamports to spend)
Bytes 937–942 [6 bytes, u48 LE]        ← min_tokens_out (slippage protection)
Step-by-Step Flow
1. Build WOTS message
message = keccak256("buy" ‖ user_pda ‖ key_index ‖ sol_amount) — 51 bytes input, then double-keccak for the final 32-byte digest.
2. Sign with current WOTS key
For each of 32 digest bytes, hash the corresponding private key component (256 - n) times. Output: 896-byte signature.
3. Derive next key hash
Derive WOTS key at index + 1 from master secret, merklize its public key into a 32-byte hash. This is the new_next_hash included in the transaction.
4. Submit transaction
The Solana TX is signed with Ed25519 (for gas). The instruction data carries the WOTS signature (for token authorization). Two layers of authentication.
5. On-chain verification
The program recovers the public key by hashing each signature component n more times, merklizes the result, and compares it to the stored next_key_hash. Match → authorized. Then next_key_hash is updated to point to key[i+1]. Cost: ~480,000 CU.
Why 896 Bytes?
A standard Ed25519 signature is 64 bytes. A WOTS signature is 896 bytes — 14× larger. This is the tradeoff for quantum resistance: more data per transaction, but the security doesn't depend on math that quantum computers can break. The 896 bytes push LATTICE transactions close to Solana's 1,232-byte TX limit, requiring Address Lookup Tables and careful byte-packing (e.g. u48 for slippage instead of u64).
Wallet & Key Chain
The LATTICE wallet runs entirely in your browser. No extensions, no servers, no backend. One 24-word BIP-39 seed phrase controls everything.
From Seed to Keys
24-word BIP-39 mnemonic (256 bits entropy)
  │
  ▼
mnemonicToSeed(mnemonic) → 64 bytes
  │
  ▼
master_secret = seed[0..32]                    (first 32 bytes)
  │
  ├──► Ed25519 keypair (for SOL gas)           Standard Solana wallet
  │
  └──► WOTS key chain (for token operations)   Quantum-resistant
       │
       ├── key[0] → initial_hash              (registration)
       ├── key[1] → first operation
       ├── key[2] → second operation
       └── key[N] → current (from on-chain key_index)
Encryption at Rest
ParameterValue
CipherAES-256-GCM
Key derivationPBKDF2-SHA256, 600,000 iterations
Salt16 bytes, random per encryption
IV / Nonce12 bytes, random per encryption
StorageBrowser localStorage (encrypted)
The master secret is encrypted with your password and stored locally. Same password + same seed produces different ciphertext every time (random salt + IV). The GCM authentication tag detects any tampering. All cryptography runs via the browser's native WebCrypto API — no external libraries, hardware-accelerated.
Recovery
Your 24-word seed phrase is the complete backup. To recover:
Enter 24-word mnemonic → derive master_secret and Ed25519 pubkey
Derive WOTS key[0] → compute initial_hash → find User PDA on-chain
Read key_index, balance, mints_done from PDA → wallet fully restored
No data is ever stored server-side. If you lose your seed phrase, your funds are gone forever — no one can help you recover them.
Fair Mint
The mint phase (Phase 0) distributes 0% of the total supply at a fixed price. No presale, no VC allocation, no team tokens. Everyone pays the same price, enforced on-chain.
Price per mint... SOL
Tokens per mint...
Total mints40,000
Anti-Whale Protection
RuleValue
Max mints per wallet10
Max tokens per wallet200,000
Max % of supply per wallet0.02%
EnforcementOn-chain (mints_done in User PDA)
Creating multiple wallets (Sybil) is possible but costs ~0.002 SOL rent per User PDA + 0.02 SOL registration fee + ... SOL per mint. Large-scale accumulation is expensive by design.
Real Cost Per Identity
User PDA rent: ~0.002 SOL
Registration fee: 0.02 SOL
10 mints × ... SOL = ... SOL
Total per identity: ~... SOL for 200,000 tokens
Pool Activation
When all 40,000 mints are claimed (total_minted == mint_supply), the protocol automatically transitions to Phase 1 (Trading). The pool is seeded with ... tokens and all SOL raised from mints (~276 SOL). No manual action required — the last mint instruction triggers the transition atomically.
Bonding Curve DEX
After the mint completes, all trading happens through an internal constant product AMM — the same formula as Uniswap V2. The pool is a PDA with no private key. Nobody can drain it.
AMM Formulax × y = k
x = SOL reserve (lamports)  ·  y = token reserve  ·  k = computed live from reserves on each trade
Fee Structure
FeeRateDestinationEffect
Pool fee0.3% (30 bps)Stays in poolIncreases k → deeper liquidity
Protocol fee0.2% (20 bps)Fee walletProtocol revenue
Total0.5%
The pool fee is never withdrawn — it stays in reserves permanently, making liquidity deeper over time. The minimum fee is 1 unit (1 lamport or 1 token) for any non-zero trade, preventing dust attacks.
Buy Calculation
Buy: SOL → LATTICE
1. protocol_fee    = max(1, sol_in × 20 / 10,000)     → 0.2% to fee wallet
2. sol_to_pool     = sol_in - protocol_fee
3. k               = sol_reserve × token_reserve       (u128 math)
4. new_sol_reserve = sol_reserve + sol_to_pool
5. new_token_res   = k / new_sol_reserve
6. gross_tokens    = token_reserve - new_token_res
7. pool_fee        = max(1, gross_tokens × 30 / 10,000)  → stays in pool
8. tokens_out      = gross_tokens - pool_fee            → to user
Sell Calculation
Sell: LATTICE → SOL
1. new_token_res   = token_reserve + tokens_in
2. new_sol_reserve = k / new_token_res
3. gross_sol       = sol_reserve - new_sol_reserve
4. pool_fee        = max(1, gross_sol × 30 / 10,000)   → stays in pool
5. protocol_fee    = max(1, gross_sol × 20 / 10,000)   → to fee wallet
6. sol_out         = gross_sol - pool_fee - protocol_fee → to user
Worked Example: Buy 1 SOL
At pool activation (276 SOL + 200M tokens):
Protocol fee: 0.002 SOL → fee wallet
SOL to pool: 0.998 SOL
Tokens out: ~718,857 tokens
Pool fee: ~2,163 tokens stay in pool
Effective price: ~0.00000139 SOL/token
Price impact: ~0.36%
Protections
50% Max TradeNo single trade can move more than 50% of either reserve. Prevents single-TX pool drain attacks.
Slippage Protectionmin_tokens_out / min_sol_out encoded as u48. Default frontend slippage: 1%.
Rent-Exempt FloorSells cannot drain the Pool PDA below 1,002,240 lamports (rent-exempt minimum for a 16-byte account).
Zero-Output RejectionTrades that would yield 0 tokens or 0 SOL are rejected on-chain. No dust exploits.
Token Distribution
Fair Mint — 0%
Pool — 0%
... tokens — distributed via fair mint at fixed price
... tokens — seeded into bonding curve liquidity pool
MetricValue
Total supply...
Mint allocation... (0%)
Pool allocation... (0%)
Team / VC / Advisor allocation0
Mint price... SOL (fixed, same for everyone)
Tokens per mint...
Max per wallet200,000 (0.02% of supply)
Total SOL raised~276 SOL (all goes to pool)
100% Community-OwnedThere is no team allocation, no vesting schedule, no pre-mine. All SOL from mints flows directly into the bonding curve pool. The deployer's authority field in ConfigState has no special powers after initialization.
Security
Audit Results
The on-chain program and frontend wallet underwent a full security audit by a Senior Blockchain Security Auditor (Solana/PQC specialist). All findings were fixed and verified in a re-audit.
SeverityCountStatus
🔴 Critical2✅ Fixed
🟠 High4✅ Fixed
🟡 Medium6✅ Fixed
🟢 Low6✅ Fixed
Re-audit discovered 3 additional frontend findings (2 Medium, 1 Low) — all fixed. The audit covered WOTS verification logic, PDA validation, overflow handling, fee routing, pool activation, rent-exempt protections, and wallet encryption.
Immutability
Upgrade authority revoked — the on-chain program cannot be modified by anyone
Pool PDA-owned — no private key exists for the liquidity pool; only the program logic can move funds
Deployer has no powers — the authority field in ConfigState is checked only during create_token (one-time initialization)
Hardcoded PDAs — Config, Pool, and Fee Wallet addresses are byte-array constants in the program; no account substitution possible
On-Chain Protections
Anti-ReplayMonotonic key_index + next_key_hash chain. Operation-specific message prefixes ("buy", "sell", etc.) prevent cross-operation replay.
Overflow PreventionAll arithmetic uses checked_add, checked_sub, checked_mul, checked_div. No silent overflow.
Account Ownershipowner == program_id check on all program-owned accounts. System program explicitly verified in all CPI instructions.
Phase EnforcementMint only in Phase 0, trading only in Phase 1. The transition is atomic and irreversible.
Frontend Security
Seed Never Leaves BrowserAll cryptography runs locally via WebCrypto API. Zero network calls with sensitive data.
Memory CleanupSensitive Uint8Arrays are zeroed after use (zeroBuffer()). Minimizes exposure window.
Program Details
AccountDetails
Program IDFoaiihVt4Eh5Pi6U3PCWTFzGnZRVFeXsAD5zmpp2DS8s
Config PDASeeds: ["config"] — 90 bytes (supply, phase, mint params)
Pool PDASeeds: ["pool"] — 16 bytes (SOL + token reserves)
User PDASeeds: ["user", initial_hash] — 81 bytes (balance, key chain, mints)
Instruction Set
DiscInstructionPhaseWOTSCU Cost
0CreateTokenNo~10K
1RegisterAnyNo~10K
2Mint0Yes~480K
3Buy1Yes~480K
4Sell1Yes~480K
5TransferAnyYes~480K
The program is built with Pinocchio (raw Rust, no Anchor). Manual byte-packing for all instruction data and account deserialization. All WOTS-authenticated instructions consume ~480,000 CU due to 256 × 32 keccak hash rounds during verification.
FAQ
Do I need Phantom or another Solana wallet?
No. LATTICE has its own built-in wallet that generates a WOTS key chain alongside a standard Ed25519 keypair. Phantom and other wallets only support Ed25519 — they cannot sign WOTS transactions. You'll need to send a small amount of SOL to your LATTICE wallet address for gas fees.
Can the team rug pull?
No. The program upgrade authority is revoked — the code is immutable. The liquidity pool is owned by a PDA with no private key — nobody can withdraw funds. There is no admin function, no backend, no multisig. The deployer's authority is only used once during create_token and has no power after that.
When will quantum computers actually be a threat?
Expert estimates vary between 2030 and 2045 for a cryptographically relevant quantum computer (one that can break RSA-2048 or ECDSA-256). NIST has already finalized post-quantum standards (CRYSTALS, SPHINCS+). LATTICE uses WOTS, which relies on hash security — the most conservative and well-understood approach. The point isn't that quantum computers exist today, but that cryptographic migration takes years and it's better to be ready early.
Why isn't LATTICE on Jupiter or Raydium?
LATTICE uses WOTS signatures instead of SPL token transfers, so it's not compatible with standard DEX aggregators that expect Ed25519-signed token swaps. Trading happens through the built-in bonding curve DEX, which uses the same x×y=k formula as Uniswap V2.
What happens if I lose my seed phrase?
Your funds are gone forever. There is no server, no recovery service, no admin who can help. The seed phrase is the only way to derive your master secret, and the master secret is the only way to generate your WOTS keys. Write it down on paper and store it securely.
Is my SOL safe?
Your SOL gas wallet uses standard Ed25519, which is not quantum-safe. A future quantum computer could theoretically extract your private key from your public key. This is a Solana-level limitation — no token on Solana can protect its SOL wallet. Mitigation: keep only enough SOL for gas fees. Your $LATTICE tokens are the protected asset.
Why not use Dilithium (CRYSTALS) instead of WOTS?
Dilithium signatures are ~2,420 bytes (vs 896 for WOTS) and require complex lattice math that exceeds Solana's compute budget for on-chain verification. Some projects use off-chain provers (like Bonsol), but that introduces server dependencies and trust assumptions. WOTS verifies entirely on-chain at ~472K CU with zero external dependencies.
Why are transactions so large?
WOTS signatures are 896 bytes (vs 64 bytes for Ed25519). This pushes transactions close to Solana's 1,232-byte limit. LATTICE uses Address Lookup Tables, u48 encoding for slippage, and 16-byte recipient hash prefixes to fit everything within the limit. It's tight — the Transfer instruction uses exactly 1,232 bytes.
Can I send LATTICE to someone else?
Yes. The Transfer instruction moves tokens between User PDAs. The sender signs with their WOTS key and commits the recipient's initial_hash in the WOTS message. Both parties must have a registered User PDA.
What if the website goes down?
The protocol runs entirely on-chain. The website is just a frontend. Anyone can build a new frontend that talks to the same program. Your funds are on the blockchain, not on a server. With your seed phrase, you can recover everything from any compatible interface.