Try   HackMD

Compressed Token Accounts

As @sol_idity makes it clear in this tweet thread, the cost of Associated Token Account rent is too damn high. At ◎0.002 per ATA, any large-scale issuance of tokens (such as stablecoins) becomes economically infeasible to deploy. In this sRFC i hope to outline a potential solution to the problem, with some trade-offs that i think are worth making. As a preface, i'm looking to solve stablecoin deployment at the scale of about >5mm wallets (USDC on Solana only has 1.5mm holders), and i am not looking for 100% parity with existing systems.

Tiny SPL introduces a clever solution to the fungibility of compressed NFTs by wrapping a compressed NFT tree with a program that allows the splitting and combination of the "balance" associated with any given compressed NFT. However, one restriction is that the information in this tree doesn't yet interoperate with traditional SPL Tokens (e.g., USDC). Additionally, because the data structure used by state compression (a Merkle tree) cannot effectively be used to create a proof-of-exclusion, you cannot directly "send" an asset to a specific account, you just append amounts and force the end-user to combine those amounts.

There are a few possible improvements to Tiny SPL that fit into a broader vision for compressed token accounts:

  1. Allow state compression leaves to be "decompressed" into SPL Tokens, which provides some interoperability with existing integrations with SPL Tokenkeg (i.e., exchanges, wallets). A PDA of the Tiny SPL program could be the owner of an omnibus account for the SPL Tokens and each leaf acts as a "claim" on those SPL Tokens, and outbound sends from the tree end up requiring an ATA to be the destination account.
  2. By swapping the data structure of state compression to an indexed Merkle tree (h/t Noah P., Swen), one can identify the exact leaf owned by a specific user, eliminating the need to do splits and combinations and allows sends to go directly to a unified balance
  3. Create a program that manages a user-owned list of trees with relevant balances. Whenever a third-party sends to this user, they need to check that list and are otherwise responsible for adding to the list for indexers to ensure they're indexing all possible compressed token accounts

There are some key trade-offs to this approach:

  • Since we're moving away from a per-user, per-token account, it is much more difficult for indexers to know exactly how many tokens one owns, especially if that balance is split across traditional ATAs and their compressed equivalent.
  • Each tree would likely need to be tied to a specific mint, mostly for book-keeping and simplicity
  • Indexed Merkle trees require 2+ proofs for any operation

Back of the envelope math

  • At 5 million wallets, there's a one-time setup cost of ◎0.002 SOL per wallet, which comes out to ◎10,000 (~$1mm USD as of 1/5/24)
  • Compressing this comes out to ◎3 per million-tree, and ◎25 (5000 lamports * 5mm) for the transactions needed to fill those trees, a 350x improvement

Critically, though, this solution works great for products like TipLink that own the entire wallet flow. There's no real need for user balances in the managed wallet to be an actual token account, just that outbound sends need to be sent to token accounts.

Some food for thought:

  • If the relevant "compressed token account" program were to become the main locus for indexers to keep track of user balances, one idea might be create mint-specific PDAs be the signers for any relevant trees to be indexed. Since those trees need to end up escrowing SPL Tokens anyway, it should be fairly obvious how to verify whether they're legitimate trees or not.