Aritmética Segura
Valores de token, taxas e cálculos de participação nunca devem fazer wrap silenciosamente. On-chain, use checked_*, saturating_* ou checagens explícitas de limites e mapeie falhas para ProgramError.
Busque em todas as páginas da documentação
Valores de token, taxas e cálculos de participação nunca devem fazer wrap silenciosamente. On-chain, use checked_*, saturating_* ou checagens explícitas de limites e mapeie falhas para ProgramError.
let total = base
.checked_add(fee)
.ok_or(ProgramError::InvalidArgument)?;Quando usar:
use solana_program::program_error::ProgramError;
pub fn apply_fee(amount: u64, bps: u64) -> Result<u64, ProgramError> {
if bps > 10_000 {
return Err(ProgramError::InvalidArgument);
}
let fee = amount
.checked_mul(bps)
.and_then(|v| v.checked_div(10_000))
.ok_or(ProgramError::InvalidArgument)?;
amount
.checked_sub(fee)
.ok_or(ProgramError::InvalidArgument)
}O que isso demonstra:
bps antes da math.InvalidArgument para decodificação do cliente.| Método | Comportamento |
|---|---|
checked_add | None em overflow |
saturating_add | Limita em MAX |
wrapping_add | Raro on-chain - red flag de auditoria |
let wide = (a as u128).checked_mul(b as u128)?;a + b faz wrap em release sem overflow checks em alguns contextos. Correção: Sempre checked_* para fundos de usuário.saturating_sub pode esconder insolvência. Correção: Use checked_sub quando saldo não pode underflow./ 0 mesmo on-chain. Correção: Guarde divisor explicitamente.as u64 de u128 trunca silenciosamente. Correção: Cheque limites com try_into.i64 a menos que necessário. Correção: indefinido| Alternativa | Use quando | Não use quando |
|---|---|---|
| spl-math / crates fixed-point | Math de curva DEX | Contadores simples |
| u128 em todo lugar | Precisão intermediária | Loops apertados sensíveis a CU |
| Pré-compute off-chain | Valores só de display | Saldos autoritativos |
Não confie nisso - use math verificada explícita.
Caps em stats de gameplay, não saldos de token.
mul depois div 10000 com ops verificados.
Ligeiramente maior - ainda mais barato que exploits.
Use checked std Rust nos handlers de instrução.
Ainda use checked_sub após compare por segurança de race.
Evite f64 para valores de token - ataques de arredondamento.
Verifique divisor não zero.
Busque +, -, * em u64 em caminhos de instrução.
Sem valores negativos de token - rejeite inputs signed.
Fold verificado: padrão try_fold.
Teste unitário edge cases u64::MAX no host.
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026