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

# Matemática do Stable AMM

> Busca binária e interpolação linear para cotação de preços a partir da tabela de consulta. Aplicação de taxas idêntica ao AMM v4. Contabilidade pura de pool AMM após o desacoplamento do OpenBook.

<Info>
  **Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.**

  [Ver versão em inglês →](/products/stable/math)
</Info>

## A curva da tabela de consulta

O Stable AMM substitui a fórmula x·y=k por uma **tabela de consulta esparsa** de tuplas (x, y, price). Ao precificar um swap, o programa:

1. Calcula a razão atual do pool a partir das reservas.
2. **Busca binariamente** na tabela para encontrar as duas entradas que delimitam essa razão.
3. **Interpola linearmente** entre elas para obter um preço intermediário.
4. Aplica taxas e retorna a cotação.

Essa abordagem troca o determinismo de uma fórmula pela **flexibilidade do administrador** na modelagem de preços, e é eficiente o suficiente para caber no orçamento de computação da Solana.

## Layout da tabela e busca binária

O `ModelDataInfo` contém até 50.000 entradas `DataElement`, indexadas pelo administrador. Apenas as primeiras `valid_data_count` estão ativas. Cada entrada:

```
DataElement {
  x: u64,      // Coordenada X (quantidade do lado da moeda, escalada)
  y: u64,      // Coordenada Y (quantidade do lado do PC, escalada)
  price: u64,  // price = x/y, escalado pelo multiplicador
}
```

Para encontrar um preço nas reservas atuais do pool (x\_real, y\_real):

1. Calcule a razão: `target_ratio = (x_real * multiplier) / y_real`.
2. Busque binariamente por entradas onde `(element.x * multiplier) / element.y` delimita `target_ratio`.
3. Quando um intervalo `[min_idx, max_idx]` é encontrado, interpole.

O código de busca binária do programa ocupa \~150 linhas em `state.rs::ModelDataInfo::get_mininum_range_by_xy_real`. O invariante chave: **as entradas devem estar ordenadas** (x ascendente, y descendente, price ascendente) para que a busca funcione.

## Interpolação linear

Quando dois pontos da tabela delimitam a razão, a interpolação calcula um preço intermediário e um par de reservas:

```
target = (x_real * multiplier) / y_real

[x1, y1, p1] = table[min_idx]
[x2, y2, p2] = table[max_idx]

// Interpolar preço
p = p1 + (p2 - p1) * (target - ratio1) / (ratio2 - ratio1)

// Interpolar reserva
x = x1 + (x2 - x1) * (target - ratio1) / (ratio2 - ratio1)
y = y1 + (y2 - y1) * (target - ratio1) / (ratio2 - ratio1)
```

O resultado é uma curva linear por partes que conecta suavemente os pontos da tabela.

## Escala: o multiplicador

As reservas do pool e os preços são armazenados em escalas diferentes. O campo `multiplier` em `ModelDataInfo` lida com isso. Um padrão comum:

* Moeda tem 6 decimais, PC tem 18 decimais.
* Multiplicador = 10^6 (ou similar).
* As entradas da tabela são armazenadas em uma escala reduzida para caber nos limites de u64.

O programa reescala na leitura/escrita via:

```
real_value = table_value * ratio / multiplier
table_value = real_value * multiplier / ratio
```

## Precificação de swap: `SwapBaseIn` e `SwapBaseOut`

### SwapBaseIn (entrada exata)

Dado o valor de entrada `amount_in`:

1. Obtenha a razão atual de `(coin_vault, pc_vault)`.
2. Encontre as entradas da tabela que delimitam e interpole para obter a razão no espaço da tabela.
3. Converta a entrada para o espaço da tabela: `dx_table = amount_in * multiplier / ratio`.
4. Consulte a tabela na nova coordenada X para encontrar o novo Y.
5. `dy_table = y_old - y_new`.
6. Converta de volta: `dy_real = dy_table * ratio / multiplier`.
7. Aplique a taxa de negociação: `dy_output = dy_real - (dy_real * trade_fee_numerator / trade_fee_denominator)`.
8. Retorne `dy_output`.

### SwapBaseOut (saída exata)

Simétrico: dado o `amount_out` desejado, resolva para o `amount_in` necessário.

Ambos os caminhos leem as reservas efetivas diretamente dos vaults do pool. O pool não mantém ordens abertas do OpenBook há anos, portanto não há nada para liquidar primeiro — os saldos dos vaults são a história completa. (A [atualização de 2026-06-22](/pt/reference/changelog) removeu o código de mercado restante.)

## Aplicação de taxas

Idêntica ao AMM v4: veja [`products/amm-v4/math`](/pt/products/amm-v4/math) para a derivação completa.

```
gross_fee = amount_in * (swap_fee_numerator / swap_fee_denominator)    // ex: 0,25%
lp_portion = gross_fee - (gross_fee * pnl_numerator / pnl_denominator) // ex: 0,22%
pnl_portion = gross_fee * (pnl_numerator / pnl_denominator)            // ex: 0,03%
```

A `pnl_portion` vai para `need_take_pnl_*` e é retirada pelo administrador via `WithdrawPnl`. A `lp_portion` permanece no vault, inflacionando `k` e beneficiando os detentores de tokens LP.

## Contabilidade de ativos do pool

A fórmula historicamente adicionava os fundos que o pool mantinha como ordens abertas em sua conta OpenOrders do OpenBook. Esse termo tem sido zero na prática desde que o pool parou de postar ordens, e a atualização de 2026-06-22 o removeu completamente da fórmula, deixando apenas o cálculo baseado em vaults:

```
Antigo: total assets = saldos de vault + fundos de ordens abertas (native_coin_total / native_pc_total) − PnL pendente (need_take_pnl)
Novo: total assets = saldos de vault − PnL pendente (need_take_pnl)
```

Este é o valor que a matemática da curva trata como reservas efetivas (a porção `need_take_pnl` acumulada mas não retirada fica fisicamente no vault mas é excluída da precificação). O código de cotação e indexadores que anteriormente liam saldos de OpenOrders devem descartar esse termo.

## MonitorStep (removido)

`MonitorStep` era a **instrução de crank** que liquidava preenchimentos pendentes do OpenBook, recomputava `AmmInfo.target_orders` e repostava a grade de ordens limitadas derivada da tabela de consulta. O pool parou de postar ordens no OpenBook há anos, então o crank não tinha mais nada a fazer; foi **removido na atualização de 2026-06-22**. Integradores não precisam fazer crank em pools Stable.

## Resumo: por que isso funciona

O design de tabela de consulta + interpolação é **eficiente e flexível**:

* **Eficiência:** A busca binária é O(log 50.000) ≈ 16 iterações, cada uma \~ 300–500 CU. A interpolação é algumas multiplicações/divisões. O custo total de cotação é \~5k–15k CU, muito mais barato do que recomputar uma fórmula a cada swap.
* **Flexibilidade:** O administrador pode codificar qualquer curva linear por partes. Pares de stablecoin obtêm alta densidade em torno de 1:1; pares colateralizados obtêm curvas personalizadas.
* **Liquidez autossuficiente:** Todos os fundos vivem nos vaults do pool e a precificação os lê diretamente — sem crank, sem livro de ordens externo, menos contas por transação.

Para análises profundas da lógica de interpolação, veja `raydium-stable/program/src/state.rs`, métodos `get_data_by_x`, `get_data_by_y`, `get_dy_by_dx_base_in`, etc.

## Próximos passos

* [Contas](/pt/products/stable/accounts) — referência de campos `ModelDataInfo` e `DataElement`.
* [Instruções](/pt/products/stable/instructions) — o conjunto chamável (swap, deposit, withdraw, `WithdrawPnl`) e as instruções removidas.
* [Taxas](/pt/products/stable/fees) — aplicação de taxas e `WithdrawPnl`.
* [`products/amm-v4/math`](/pt/products/amm-v4/math) — para a lógica de precificação de ordens inclusiva de taxas do OpenBook.

Fontes:

* `raydium-stable/program/src/state.rs` (implementações de interpolação e busca binária)
* `raydium-stable/program/src/math.rs` (utilitários de calculadora)
