Account model & lifecycle
A single pool PDA holds canonical reserves and fee accumulators. Two vault PDAs hold the tokens. Each bloom is its own PDA, owned by its depositor.
Seeds
Pool PDA seeds = ["pool", token_a_mint, token_b_mint]
vault_a (PDA) seeds = ["vault_a", pool]
vault_b (PDA) seeds = ["vault_b", pool]
BloomPosition PDA seeds = ["bloom", pool, owner, nonce_le_bytes]The token_a_mint / token_b_mint ordering is canonical (lexicographically ascending by pubkey). This guarantees there is exactly one pool per pair regardless of how the caller orders them at initialize_pool.
Pool state
| Field | Type | Notes |
|---|---|---|
token_a_mint | Pubkey | Lex-min of pair |
token_b_mint | Pubkey | Lex-max of pair |
vault_a / vault_b | Pubkey | SPL token accounts owned by the pool PDA |
reserve_a / reserve_b | u64 | Reserves excluding accrued fees |
total_liquidity | u128 | Sum of all bloom shares |
cumulative_fee_per_share_a/b | u128 | Q64.64 fixed-point fee accumulator |
active_blooms | u64 | Number of unsettled blooms |
fee_bps | u16 | Swap fee, max 10% |
Bloom lifecycle
deposit -> active -> matured -> settled
\-> chirigiwa (early exit)- create_bloom mints LP shares and snapshots the cumulative-fee-per-share accumulators at entry.
- While the bloom lives, swaps update the accumulators based on
total_liquidityat that moment. - After
end_slot, anyone can callsettle_bloom; the position's owner receivesshare_of_reserves + (cumulative_fee_delta * shares >> 64). - Before
end_slot, the owner can callchirigiwaand receives0.95 * share_of_reserves + fees. The 5% penalty stays in the pool and accrues to remaining LPs.
Why per-bloom snapshots
A naive AMM credits all fees to all current LPs, which means a late entrant receives a share of fees that were earned before they were even at risk. By snapshottingcumulative_fee_per_share_* at deposit time and only paying out the delta at exit, late entrants only earn fees from swaps that happened during their bloom window.
This invariant is the executable specification of thetests/fee-isolation.ts integration test.