Saltar para o conteúdo principal

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.

Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →

O invariante

Um criador de mercado de produto constante (CPMM) mantém duas reservas x e y e garante:
x · y ≥ k       (após cada trade)
onde k é o produto das reservas antes do trade. Para um mercado sem taxas, x · y = k exatamente. Com taxas, k cresce estritamente (a parte da taxa do LP é retida nas reservas). O invariante é deliberadamente geométrico: garante que não importa quão pequena uma reserva se torne, a outra cresce ilimitadamente para compensar — ou seja, o pool nunca pode ser drenado para zero em qualquer lado.

Precificação

Preço spot

O preço marginal de y denominado em x em qualquer instante é a tangente da curva:
p = y / x
(derivação: diferenciação implícita de x · y = k fornece dy/dx = −y/x; ignorando o sinal, |dy/dx| = y/x). Este é o preço que o pool cotiza para um trade infinitesimalmente pequeno. Para qualquer trade de tamanho finito, o preço realizado é pior devido ao slippage ao longo da curva.

Swap com entrada exata (dar Δx, receber Δy)

Com taxas, seja f a taxa de comissão (ex. f = 0.0025 para 25 bps). Aplique a taxa à entrada, depois use o invariante para resolver a saída:
Δx_after_fee = Δx · (1 − f)
Δy           = y · Δx_after_fee / (x + Δx_after_fee)
Reservas após o trade:
x' = x + Δx
y' = y − Δy
O Δx completo entra nas reservas. A porção de taxa do LP permanece em x'; a porção do protocolo é excluída da curva através de um passo de contabilidade separado (veja Variantes de contabilização de taxas abaixo).

Swap com saída exata (receber Δy, pagar o mínimo Δx)

Δx_after_fee = x · Δy / (y − Δy)
Δx           = Δx_after_fee / (1 − f)
Δx é arredondado para cima para garantir que o pool não cobre a menos.

Slippage e impacto de preço

Impacto de preço mede quanto o preço spot do pool se move como resultado do trade:
p_before = y / x
p_after  = y' / x' = (y − Δy) / (x + Δx)
impact   = (p_before − p_after) / p_before
Para pequeno Δx / x, uma expansão de primeira ordem fornece:
impact ≈ 2 · Δx / x      (ignorando taxas)
Intuição: um swap de 1% causa um impacto de preço de ~2%. Este fator de 2 é a razão pela qual os pools CPMM cotizados para trades de tamanho médio parecem “finos” em comparação com mercados de livro de ordens — você não está apenas comprando contra o melhor lance atual, está caminhando seu próprio preço marginal. Preço efetivo pago pelo negociador:
effective = Δx / Δy
O spread entre p_before e effective é slippage. O slippage na UI on-chain geralmente é expresso como (effective − p_before) / p_before; a função computeAmountOut do SDK retorna tanto amountOut quanto priceImpact por essa razão.

Verificação invariante em código

Após um swap, os protocolos reverificam:
k' = x' · y'  ≥  k  =  x · y
Qualquer violação é um bug do programa ou um overflow aritmético. As instruções de swap da Raydium tornam esta verificação explícita como uma pós-condição:
let k_before = coin_reserve_before as u128 * pc_reserve_before as u128;
let k_after  = coin_reserve_after  as u128 * pc_reserve_after  as u128;
require!(k_after >= k_before, ErrorCode::InvariantViolation);

Variantes de contabilização de taxas

A verificação invariante assume que a taxa do LP permanece nas reservas. Diferentes produtos da Raydium lidam com os componentes do protocolo / fundo / criador de maneiras diferentes:

Convenção CPMM

As taxas são taxas similares a pontos base u64 em um denominador 1_000_000. A taxa de trade é dividida em trade_fee_rate (total) e depois subdividida via protocol_fee_rate, fund_fee_rate, creator_fee_rate. Em cada swap:
trade_fee     = ceil(Δx · trade_fee_rate / 1_000_000)
protocol_fee  = trade_fee · protocol_fee_rate / 1_000_000
fund_fee      = trade_fee · fund_fee_rate     / 1_000_000
creator_fee   = trade_fee · creator_fee_rate  / 1_000_000
lp_fee        = trade_fee − protocol_fee − fund_fee − creator_fee
As três partes não-LP acumulam em contadores separados (protocol_fees_*, fund_fees_*, creator_fees_*) que são excluídos das reservas usadas no invariante. É assim que as taxas podem ser retiradas sem mover a curva. Veja products/cpmm/fees.

Convenção AMM v4

As taxas são razões numerator / denominator em um denominador 10_000. A divisão é fixa na criação do pool e armazenada em AmmInfo.fees:
swap_fee  = ceil(Δx · swap_fee_numerator / swap_fee_denominator)    // ex. 0.25%
pnl_share = swap_fee · pnl_numerator / swap_fee_numerator            // ex. 0.03 / 0.25 = 12%
lp_share  = swap_fee − pnl_share                                     // 0.22% do volume
pnl_share acumula em state_data.need_take_pnl_* e é excluído das reservas; lp_share permanece no cofre. Veja products/amm-v4/fees. Ambas as convenções preservam o invariante da mesma forma — a diferença é cosmética (denominador + número de subcategorias).

Regras de arredondamento

  • O cálculo de taxa arredonda para cima. Garante que o pool nunca cobre a menos na taxa.
  • A quantidade de saída arredonda para baixo. Garante que o invariante é mantido estritamente (k' > k mesmo antes da taxa ser adicionada).
  • A quantidade de entrada de saída exata arredonda para cima. Garante que o usuário não pague menos.
Toda aritmética usa u128 para os produtos intermediários x · Δx para evitar overflow em reservas grandes. Os resultados finais são convertidos de volta para u64 com uma verificação de saturação.

Casos extremos

Pool vazio

Antes do primeiro Deposit, x = y = 0. Instruções de swap rejeitam pré-depósito.

Saída zero

Se Δx é pequeno o suficiente para que o Δy arredondado para baixo seja 0, a instrução reverte com ZeroTradingTokens. Isso previne extração de valor sem pagamento; também significa que swaps de poeira em pools altamente desbalanceados falham.

LP de poeira

O primeiro Deposit tem tratamento especial: computa a oferta inicial de LP como sqrt(x · y) e queima uma pequena quantidade de “init burn” (geralmente 100 unidades de LP) para prevenir o “ataque de inflação do primeiro depositante” (onde um invasor doa para o cofre e infla o valor do token LP). Depósitos subsequentes usam matemática pró-rata.

Relação com arbitragem

O preço do pool CPMM só muda através de:
  1. Trades através do pool em si (usuários caminhando a curva).
  2. Doações (enviando tokens para o cofre sem um swap).
Como os trades movem o preço deterministicamente com a curva, qualquer pool cujo preço diverge do preço mais amplo do mercado cria uma oportunidade de arbitragem. Arbitrageurs trazem o preço do pool de volta em direção ao preço do mercado em expectativa. É por isso que os pools CPMM são ditos “cotizarem um preço sem um oráculo”: o mercado encontra o preço através de arbitragem em vez do pool lê-lo externamente. O lado oposto: o pool em si é a contraparte do arbitrageur, então qualquer lucro de arbitragem é perda impermanente do LP (menos a taxa capturada pelos LPs).

Exemplos trabalhados

Exemplo 1 — trade pequeno, slippage negligenciável

Pool: x = 1_000_000, y = 2_000_000, k = 2·10^12. Taxa f = 0.0025. Trade Δx = 1_000:
Δx_after_fee = 1000 · 0.9975  = 997.5
Δy           = 2_000_000 · 997.5 / (1_000_000 + 997.5)
             = 1_995_000_000 / 1_000_997.5
             ≈ 1_993.01
Preço efetivo: 1000 / 1993.01 ≈ 0.5018. Spot antes: 0.5. Impacto: ~0.36%.

Exemplo 2 — trade de tamanho médio, slippage visível

Mesmo pool, Δx = 100_000 (10% de x):
Δx_after_fee = 100_000 · 0.9975 = 99_750
Δy           = 2_000_000 · 99_750 / (1_000_000 + 99_750)
             = 199_500_000_000 / 1_099_750
             ≈ 181_405
Efetivo: 100_000 / 181_405 ≈ 0.5513. Impacto: ~10.3% — aproximadamente metade da regra de bolso 2 · 10% = 20% (a regra é um teto de pior caso para uma curva de produto constante sem taxa; a taxa de trade mais a inversão na fórmula a reduz).

Referências

Fontes:
  • Whitepaper Uniswap v2 — a declaração canônica de x · y = k.
  • Código-fonte do programa CPMM da Raydium.
  • Código-fonte do programa AMM v4 da Raydium.