fix(runtime+emission): audit ultra 2026-07-02 — 3 fixes verificados en fuente (RV 5→6)
Audit ultra-profundo (Fable 5, refute-by-default): 3 dimensiones completadas
(economía, fee-path, attestation) → 23 hallazgos crudos → verificación manual
en fuente de los HIGH. Los 3 inequívocos, corregidos:
(a) FeeMultiplierUpdate = () COLAPSABA NextFeeMultiplier a 0 tras el bloque 1
[HIGH]: impl<A, B: Default> Convert<A,B> for () devuelve Default (=0) y
on_finalize hace *fm = convert(*fm) — el componente weight-fee desaparecía
de TODA la cadena desde el bloque 2. Verificado en pallet-transaction-
payment-43.0.0 src (líneas 158-171, 446-448). Fix: ConstFeeMultiplier<1>
+ test de regresión fee_multiplier_update_never_collapses_to_zero.
(b) NativeToEthRatio = 1_000_000 con comentario "OGC 12 decimals" [HIGH]:
OGC tiene 18 decimales (Ogc::DECIMALS=18) = precisión ETH ⇒ ratio 1:1.
El 10^6 (herencia del template de 12 dec) distorsionaba TODO valor visto
por la capa EVM ×10^6. Fix: ConstU32<1> + test derivado de la delta de
decimales (guard de coherencia, no número mágico).
(c) Emisión: let _ = mint_into ×3 descartaba resultados [MEDIUM] mientras
TotalEmitted y el evento BlockRewardMinted registraban incondicionalmente
⇒ la contabilidad podía mentir si un mint fallaba (e.g. bajo ED). Fix:
TotalEmitted + evento registran SOLO lo realmente acuñado.
RUNTIME_VERSION 5→6 (cambios de comportamiento; TRANSACTION_VERSION intacto).
Workspace verde: 272 checks, 0 fallos. Pendientes de decisión de David (Level
A economía): emisión-mint vs Ecosystem 400M pool (doble fuente del mismo
propósito) · IdentityFee dust con 18 decimales (calibración WeightToFee).
Audit continúa post-reset (6 dimensiones + verify formal de los 23).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1a0364db99
commit
7b8863fd47
3 files changed
+82
-23
No files matched your search
@@ -164,18 +164,31 @@ pub mod pallet {
|
||||
.saturating_sub(author_amount)
|
||||
.saturating_sub(treasury_amount);
|
||||
|
||||
// mint_into aumenta el total issuance (emisión real).
|
||||
let _ = T::Currency::mint_into(&author, author_amount);
|
||||
let _ = T::Currency::mint_into(&Self::treasury_account(), treasury_amount);
|
||||
let _ = T::Currency::mint_into(&Self::subsidy_account(), subsidy_amount);
|
||||
// mint_into aumenta el total issuance (emisión real). Puede
|
||||
// fallar (e.g. destino por debajo del existential deposit):
|
||||
// TotalEmitted y el evento SOLO registran lo que de verdad
|
||||
// se acuñó, o la contabilidad miente (audit ultra 2026-07-02).
|
||||
let author_minted =
|
||||
T::Currency::mint_into(&author, author_amount).unwrap_or_default();
|
||||
let treasury_minted =
|
||||
T::Currency::mint_into(&Self::treasury_account(), treasury_amount)
|
||||
.unwrap_or_default();
|
||||
let subsidy_minted =
|
||||
T::Currency::mint_into(&Self::subsidy_account(), subsidy_amount)
|
||||
.unwrap_or_default();
|
||||
|
||||
TotalEmitted::<T>::mutate(|t| *t = t.saturating_add(reward));
|
||||
Self::deposit_event(Event::BlockRewardMinted {
|
||||
author,
|
||||
author_amount,
|
||||
treasury_amount,
|
||||
subsidy_amount,
|
||||
});
|
||||
let total_minted = author_minted
|
||||
.saturating_add(treasury_minted)
|
||||
.saturating_add(subsidy_minted);
|
||||
if total_minted > 0 {
|
||||
TotalEmitted::<T>::mutate(|t| *t = t.saturating_add(total_minted));
|
||||
Self::deposit_event(Event::BlockRewardMinted {
|
||||
author,
|
||||
author_amount: author_minted,
|
||||
treasury_amount: treasury_minted,
|
||||
subsidy_amount: subsidy_minted,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Placeholder de minteo (pendiente benchmarking real, leftover FIX-2) +
|
||||
|
||||
Reference in new issue
Block a user