feat(economía): techo duro 1B + fees con dientes (David Level A 2026-07-03, RV 6→7)

Dos decisiones económicas ratificadas por David, verificadas en fuente:

1. TECHO DURO 1B (Opción A) — la emisión TRANSFIERE del pool Ecosystem finito
   (og/ecosy, 400M pre-asignado en génesis), JAMÁS mint_into. La aserción de
   compilación de 1.000M deja de ser promesa de génesis y se vuelve ley que la
   producción de bloques obedece: el total issuance nunca crece, el pool se
   agota en ~7.6 años (10 OGC/bloque), después economía circular pura. Cuando el
   pool no cubre el reward completo, libera el remanente y emite
   EcosystemPoolDepleted una vez. Evento renombrado BlockRewardMinted →
   BlockRewardReleased (honestidad: es redistribución, no acuñación).
   - origin-chain-emission: Currency.transfer (Expendable) desde ecosystem_account;
     +EcosystemPalletId config, +DepletionAnnounced storage one-shot, +2 tests
     (hard_cap_pool_se_agota_y_para, depletion_event_se_anuncia_una_sola_vez).
   - runtime: EmissionEcosystemPalletId (og/ecosy) wired; génesis asigna el 40%
     a la cuenta PalletId determinista (sin llave humana), no al placeholder ECO!.

2. FEES CON DIENTES — WeightToFee/LengthToFee de IdentityFee (polvo ~10^-10 OGC,
   #16 = adorno) a ConstantMultiplier calibrado: un transfer simple ≈ 1 MILLI_OGC
   (0.001 OGC). Consecuencias: el descuento Pi5 (0.1×) = ahorro real (0.0001 OGC);
   la quema del 100% de gas es deflación medible desde el testnet; el spam cuesta
   OGC real. Factor 7e6 (weight) + 1e11 (length). Test de regresión
   weight_to_fee_transfer_tiene_dientes_no_polvo blinda contra revertir a polvo.
   Calibrado a pesos placeholder — re-tunear con benchmarks reales (leftover FIX-2).

RUNTIME_VERSION 6→7. Workspace 275 tests verde, 0 fallos. TRANSACTION_VERSION intacto.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Fable 5 committed 2026-07-03 11:58:55 -05:00
1 parent 7b8863fd47
commit 1fdc47e859
4 files changed
+282 -65

No files matched your search

+34 -7
View File
@@ -243,7 +243,15 @@ pub const IMPL_NAME: &str = "origin-chain-charon";
/// `TotalEmitted` + evento registran SOLO lo realmente acuñado (resultados de
/// `mint_into` ya no se descartan). Cambia comportamiento ⇒ spec bump;
/// TRANSACTION_VERSION intacto.
pub const RUNTIME_VERSION: u32 = 6;
/// v7: economía Level A (David 2026-07-03, 2 decisiones) — (a) **TECHO DURO 1B**:
/// la emisión TRANSFIERE del pool Ecosystem finito (og/ecosy, 400M) en vez de
/// `mint_into`; el total issuance jamás crece, el pool se agota en ~7.6 años,
/// después economía circular (evento `BlockRewardReleased` + `EcosystemPoolDepleted`
/// one-shot). (b) **fees con dientes**: `WeightToFee`/`LengthToFee` de `IdentityFee`
/// (polvo ~10^-10 OGC) a `ConstantMultiplier` calibrado — un transfer ≈ 1 MILLI_OGC,
/// el #16 Pi5 0.1× = ahorro real, quema deflacionaria medible. Comportamiento ⇒
/// spec bump; TRANSACTION_VERSION intacto.
pub const RUNTIME_VERSION: u32 = 7;
/// Canonical authoring version per Substrate semver canonical.
pub const AUTHORING_VERSION: u32 = 1;
@@ -835,12 +843,12 @@ mod tests {
use super::*;
#[test]
fn runtime_version_v6_ultra_audit_fixes() {
// v6 = 3 fixes del audit ultra 2026-07-02: ConstFeeMultiplier (el `()`
// colapsaba NextFeeMultiplier a 0), NativeToEthRatio=1 (OGC 18 dec),
// y emisión con contabilidad honesta de mint_into. Cambios de
// comportamiento, no de formato de extrinsic ⇒ TRANSACTION_VERSION intacto.
assert_eq!(RUNTIME_VERSION, 6);
fn runtime_version_v7_hard_cap_and_fee_teeth() {
// v7 = economía Level A (David 2026-07-03): techo duro 1B (emisión =
// transfer del pool Ecosystem, no mint) + fees con dientes (ConstantMultiplier
// calibrado, transfer ≈ 1 MILLI_OGC). Cambios de comportamiento, no de
// formato de extrinsic ⇒ TRANSACTION_VERSION intacto.
assert_eq!(RUNTIME_VERSION, 7);
assert_eq!(TRANSACTION_VERSION, 1);
}
@@ -952,6 +960,25 @@ mod tests {
assert!(!next.is_zero());
}
#[test]
fn weight_to_fee_transfer_tiene_dientes_no_polvo() {
// Calibración David 2026-07-03 (v7): un transfer simple debe costar ~1
// MILLI_OGC, NO el polvo ~10^-10 OGC de IdentityFee (que anulaba el #16).
// Guard de regresión: si alguien revierte a IdentityFee, el fee cae a
// ~1.5×10^8 base units (muy por debajo de MILLI_OGC/2) y esto rompe.
use frame_support::weights::{Weight, WeightToFee as _};
// transfer ≈ ExtrinsicBaseWeight (108.157M) + transfer_keep_alive (~39M).
let transfer_weight = Weight::from_parts(108_157_000 + 39_051_000, 0);
let fee = <<Runtime as pallet_transaction_payment::Config>::WeightToFee>::weight_to_fee(
&transfer_weight,
);
assert!(
fee >= MILLI_OGC / 2 && fee <= MILLI_OGC * 3,
"fee de transfer = {fee} base units; esperado ~1 MILLI_OGC ({MILLI_OGC}), \
ni polvo ni exorbitante"
);
}
#[test]
fn revive_deposit_per_byte_canonical_milli_ogc() {
// Asset Hub pattern adapted OGC tokenomics — 1 MILLI_OGC per byte canonical.