> ## Documentation Index
> Fetch the complete documentation index at: https://docs.picon.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Accounts and PDAs

> The full account model, field-by-field, with PDA seeds

Every stateful account in the program is a PDA whose own stored fields are checked against the
address it lives at — a bin array's stored `pool`/`index`, for example, can never diverge from
the address it's actually loaded from. This closes off an entire class of bug where a wrong or
substituted account could be accepted in place of the right one.

## Pool

**Seeds**: `[b"pool", token_mint_x, token_mint_y, bin_step.to_le_bytes(), fee_rate.to_le_bytes()]`

One `Pool` account exists per `(mint_x, mint_y, bin_step, fee_rate)` combination — the same
token pair can have multiple pools at different bin steps or fee tiers, each independently
addressable.

```rust theme={null}
pub struct Pool {
    pub bin_step: u16,
    pub fee_rate: u32,                     // native units, FEE_PRECISION = 1e9
    pub protocol_share: u16,               // bps, protocol's cut of the swap fee
    pub bump: [u8; 1],
    pub active_bin_id: i32,
    pub dynamic_fee_state: DynamicFeeState,
    pub token_mint_x: Pubkey,
    pub token_mint_y: Pubkey,
    pub token_vault_x: Pubkey,
    pub token_vault_y: Pubkey,
    pub protocol_fee_x: u64,
    pub protocol_fee_y: u64,
}
```

## BinArray

**Seeds**: `[b"bin_array", pool, bin_array_index.to_le_bytes()]`

100 consecutive bins for one pool. Fixed-size, always fully allocated — no bitmap, no
variable-length packing, every bin addressable in O(1) by local index.

```rust theme={null}
pub struct BinArray {
    pub index: i32,
    pub pool: Pubkey,
    pub payer: Pubkey,          // rent payer — refunded on delete_bin_array
    pub bins: [Bin; 100],
}

pub struct Bin {
    pub amount_x: u64,
    pub amount_y: u64,
    pub price: u128,            // Q64.64, pre-computed at array creation
    pub total_shares: u128,
    pub fee_per_share_x: u128,  // Q64.64, monotonic swap-fee accumulator
    pub fee_per_share_y: u128,
}
```

## Position

**Seeds**: `[b"position", position_mint]`

A depositor's claim over a contiguous bin range, represented by an owned Token-2022 NFT
(`position_mint`). Holds one `FeeState` slot per bin in range, indexed by local position
(`bin_id - lower_bin_id`), not the pool's own bin-array indexing.

```rust theme={null}
pub struct Position {
    pub pool: Pubkey,
    pub position_mint: Pubkey,
    pub lower_bin_id: i32,
    pub upper_bin_id: i32,
    pub fee_states: [FeeState; 100],
}

pub struct FeeState {
    shares: u128,                       // this position's shares in this bin
    fee_per_share_checkpoint_x: u128,   // last-seen accumulator, for delta accrual
    fee_per_share_checkpoint_y: u128,
    fee_owed_x: u64,                    // materialized, claimable
    fee_owed_y: u64,
}
```

## AdminConfig

**Seeds**: `[b"admin_config"]` — a fixed-seed singleton; at most one `AdminConfig` can ever
exist program-wide.

```rust theme={null}
pub struct AdminConfig {
    pub authority: Pubkey,
    pub pending_authority: Pubkey,
    pub metadata_update_authority: Pubkey,
}
```

See [Governance](/concepts/governance) for the transfer/bootstrap flow this account gates.

## Coordinate system reference

| Symbol            | Formula                                      | Meaning                         |
| ----------------- | -------------------------------------------- | ------------------------------- |
| `bin_array_index` | `bin_id.div_euclid(100)`                     | Which `BinArray` a bin lives in |
| `bin_index`       | `bin_id.rem_euclid(100)` (∈ \[0, 99])        | Local slot within the array     |
| reconstruction    | `bin_id = bin_array_index × 100 + bin_index` | Holds for all valid inputs      |

`div_euclid`/`rem_euclid`, not plain `/`/`%`, are required — truncating division misclassifies
negative bin ids.
