# Origin Chain — Super Audit V1 (Opus 4.8, 4-auditor fan-out) **Documento**: `docs/SUPER_AUDIT_V1.md` **Versión**: 1.0 **Filed**: 2026-05-27 (sesión 4+ Charon, modelo Opus 4.8) **Método**: 4 auditores especializados en paralelo (correctness/eficiencia · idiomática Substrate "grado Parity" · seguridad ink! contracts · arquitectura/innovación), cada uno leyendo el código real. Síntesis rankeada por impacto por Charon. **Propósito**: pausa estratégica para endurecer Origin Chain hacia calidad "obra de arte agéntica" que impresione a Gavin Wood + comunidad Parity. NO se pierde el roadmap — esto lo refina. **Honestidad**: este audit encontró bugs CRÍTICOS. Eso es exactamente lo que un audit debe hacer pre-testnet. Los documento sin defensividad. La fortaleza del scaffolding NO excusa los gaps del interior — ambos son verdad. --- ## §0 — Veredicto en una frase **El scaffolding (composición del runtime, tx-extensions, config de revive, genesis, disciplina de Runtime APIs) es genuinamente grado-Gavin-Wood y adelante de la mayoría de chains comunitarios. El interior de los pallets es grado-scaffold — placeholder weights, balances sin respaldo, reentrancy en contratos, y un motor de gobernanza hecho-a-mano que duplica 4 pallets FRAME endurecidos.** Cerrar esa brecha convierte esto en un runtime serio y mergeable. Las bases para la obra de arte ya están shipped y verificadas. --- ## §1 — Lo que es genuinamente EXCELENTE (preservar — esto importa) Verificado en código por los auditores, no auto-elogio: - **Composición del runtime moderna y correcta**: `#[frame_support::runtime]` (no el legacy `construct_runtime!`), derive set completo, índices de pallet explícitos y estables (System=0…Revive=11). Exactamente la forma que Parity shipea post-2024. - **`TxExtension` completo y actual** incluyendo `CheckMetadataHash` + `WeightReclaim` — las dos adiciones recientes que la mayoría de chains terceros olvidan. Ledger-app-ready. - **`derive_impl` + `SolochainDefaultConfig`** para frame_system — idiom actual, override solo de los 8 tipos que cambias. - **El razonamiento del integrity-test de pallet-revive** (`storage_limit = (PVFMemory - RuntimeMemory)/2`) es fluidez Substrate real, con test que lo bloquea. - **Genesis presets limpios** con assert compile-time de que las allocations suman 1B OGC exacto + decisión documentada de hardcodear dev-accounts en vez de sp-keyring version-skewed. - **Runtime APIs reales, no stubs**, siguiendo la convención Parity "una API por concern". - **El core2 vendor patch** diagnosticado correctamente — el comentario más útil del workspace. - **Las TESIS están realizadas en código, no solo declaradas**: anti-clasista (multipliers 0.1/0.3/1.0/0.7× verificados en tiers.rs), AI-advisors-no-votan (`AdvisorMayNotVote` enforced), provenance Ed25519 (`verify_strict` rechaza sigs maleables correctamente). --- ## §2 — Hallazgos CRÍTICOS (must-fix antes de cualquier deployment real) ### C1 — Reentrancy: transfer-antes-de-estado en 4 funciones de pago (contratos) **El hallazgo más importante del audit.** En pallet-revive, `self.env().transfer()` a un *contrato* puede re-entrar. El árbitro del escrow es SIEMPRE un contrato (el Tribunal); beneficiary/depositor/staker pueden ser cuentas AGI (contratos). 4 funciones violan checks-effects-interactions: - `origin-escrow::resolve_dispute` (líneas 450-458): paga depositor+beneficiary+treasury ANTES de `state = Completed`. Re-entrada → **doble-payout / drain completo del pote**. - `origin-escrow::confirm_milestone` (363-368): transfiere ANTES de marcar `milestone.completed`. Re-entrada → **mismo milestone pagado repetidamente**. - `origin-staking::withdraw` (339-349): paga ANTES de actualizar estado. Re-entrada → **principal+rewards pagados repetidamente, drena el pool de otros stakers**. - `origin-nft-mint::transfer` (517-544): paga royalty+seller ANTES de actualizar ownership. Re-entrada → **drain de transferred_value**. **Fix**: en las 4, mutar TODO el storage *antes* de cualquier `transfer()`. El patrón correcto ya existe en `origin-credential-mint::issue` — usarlo de plantilla. *(ink! v6 no bloquea reentrancy por defecto; CEI ordering es la única defensa.)* ### C2 — Gobernanza: votos y tesorería son `u128` sin respaldo `cast_vote(stake_weight: u128)` + `override_council_veto(stake_weight: u128)` + `submit_proposal(stake: u128)` aceptan pesos arbitrarios sin reservar `Currency`. **Cualquiera vota con `u128::MAX`.** La tesorería es un contador `u128` desconectado de pallet_balances — `treasury_disbursement` decrementa un número pero no mueve fondos (admitido en comentario línea 1032). Hasta que los pesos estén respaldados por balance bloqueado, toda la gobernanza stake-weighted es spoofable. **Es el gap de correctness más grande.** **Fix**: `type Currency: ReservableCurrency` (o `fungible::MutateHold` con `HoldReason`); reservar en submit; derivar peso de voto del balance real bloqueado; disburse vía `Currency::transfer`. ### C3 — Gobernanza: `override_council_veto` baseline gameable `baseline = proposal.stake + yes + nay + abstain` y `required = 4/5 × baseline` — calculado contra los votos *de esta misma propuesta*, no contra el issuance total. Un actor con `stake_weight` grande (sin respaldo, ver C2) cumple el umbral instantáneamente, **revirtiendo un veto del council**. Defeats el mecanismo de veto completo. **Fix**: derivar `total_community_stake` de una cantidad on-chain real (`total_issuance` o staked total), no de los tallies de la propia propuesta. ### C4 — El "burn" a zero-address NO es un burn (NFT + staking) `AccountId::from([0u8;32])` es una cuenta real y válida en Substrate. Los fondos enviados ahí **no se destruyen** — quedan en una cuenta normal. Peor: si esa cuenta está bajo el existential deposit, el transfer **falla** y el código mapea eso a error + `?`-return, abortando el mint/slash cada vez que burn>0. **Fix**: burn real = no pagarlo (reducir lo que se cobra) o llamar a un precompile `pallet-balances::burn`. Nunca `?`-propagar un fallo de burn-transfer después de que otros pagos ya ejecutaron. --- ## §3 — Hallazgos HIGH (bloqueadores pre-mainnet) | ID | Hallazgo | Fix | |----|----------|-----| | H1 | **Placeholder weights en TODO** (`Weight::from_parts(10_000, 0)`, proof_size=0). DoS/spam vector; el `verify_strict` Ed25519 priced a 10k flat. Hard mainnet blocker. | `frame-benchmarking` + `WeightInfo` por pallet + reemplazar cada literal. Ningún pallet declara `WeightInfo` siquiera. | | H2 | **Sin `StorageVersion` en ningún pallet custom.** No se puede migrar estado en upgrades; los scaffold→real swaps en vuelo cambiarán layouts de structs → fallará decode. | `StorageVersion::new(0)` en los 4 pallets ahora + gate cada cambio detrás de migración numerada. | | H3 | **Voting window controlado por caller** (`voting_period_blocks` puede ser 0 = finalize instantáneo, o u64::MAX). CHN-4 dice 14 días pero nada lo enforce. | `#[pallet::constant] type VotingPeriod: Get<>` o clamp `[Min, Max]`. | | H4 | **Doble representación de AccountId + `account_bytes` trunca** a 32 bytes silenciosamente. Footgun si T::AccountId no es AccountId32; copia redundante hoy. | Hacer pallets genéricos sobre `T::AccountId`; usar el newtype solo como DTO en el boundary de Runtime API. | | H5 | **Vec sin límite en Mapping** (credential `holder/issuer_credentials`, agent-identity `co_authors_raw: Vec`). O(n) gas growth → eventual brick del issuer. | `Mapping<(key, index), id>` + counter; `BoundedVec` como argumento de extrinsic. | | H6 | **Staking rewards nunca fondeados.** `withdraw` paga `amount + rewards_accumulated` pero nada incrementa rewards → o siempre 0 (APR falso) o se paga del principal de otros. | Definir reservoir de rewards fondeado, o remover params APR hasta implementar. | | H7 | **Escrow: suma de milestones no validada vs `total_amount`.** Si suma < deposit → fondos congelados permanentemente (sin sweep). Si suma > deposit → falla mid-stream. | Enforce `Σ milestone.amount == total_amount` + sweep path terminal. | | H8 | **Credential: firma Ed25519 almacenada pero NUNCA verificada.** `verify()` solo checa revoked/expired. La propuesta de valor entera ("verifiable credentials") no se cumple. | Verificar firma vía host function, o gate detrás de flag "signatures unverified" ruidoso. | | H9 | **`submit_emergency_proposal` 5/7 council check es tautología** (`council_size >= required` siempre true para size 7). Un miembro solo puede fast-track. | Tally de aprobaciones real, o `NotImplemented` explícito. | --- ## §4 — Idiomática: Custom-vs-FRAME (la decisión arquitectural grande) Veredicto del auditor Parity: de 4 pallets custom, **3 están justificados, gobernanza debe re-platformarse**. | Pallet | Veredicto | Razón | |--------|-----------|-------| | **governance** | **Migrar / componer** | Reinventa `pallet-collective` (Council) + `pallet-membership` (roster) + `pallet-treasury` (disbursement) + `pallet-referenda`+`pallet-conviction-voting` (voto stake-weighted, veto, override). Los 4 manejan la reserva de currency que hoy se finge. **Mantener custom SOLO el bit novel**: el gate `AdvisorFlags` "AGI-aconseja-humanos-votan" como un `VoteOrigin`/filtro sobre `pallet-referenda`. Borra ~700 LOC de tally/veto/override hecho-a-mano + el hazard `account_bytes`. | | **agent-identity** | **Mantener custom** ✅ | `pallet-identity` es registrars+judgements, no DID-as-BLAKE3(pubkey) con `agent_chain` de co-authorship. Dominio genuinamente distinto. Justificado. | | **provenance** | **Mantener custom** ✅ | Ledger de attestation content-addressed con Ed25519 verify + OIT-tier gating no tiene equivalente FRAME. Novel. | | **fees** | **Reconsiderar como pallet** | La parte on-chain es un StorageMap de contadores; el pricing real es un `compute_fee` puro que el cliente llama off-chain. Tiene poco sentido como pallet con dispatchables vs un impl `WeightToFee`/`OnChargeTransaction` alimentando `pallet-transaction-payment`. | --- ## §5 — Las 8 IDEAS para la obra de arte (lo que más pediste) El auditor de arquitectura propuso 8 ideas que **componen las primitivas YA verificadas** (tier fees, AGI DIDs, co-authorship, Noesis gate) en cosas que **nadie en el ecosistema Substrate ha shipped**. Rankeadas por impacto: ### ⭐ Idea 1 — `pallet-proof-of-equity`: el anti-clasista como bien público verificable por consenso Hoy el fee matrix es una constante en `tiers.rs`. Promoverlo a primitiva económica con **ledger de subsidio verificable**: cada tx emite `SubsidyApplied { tier, foregone_fee }` + un `GlobalSubsidyPool` on-chain. El chain puede *probar*, bloque a bloque, cuánto redistribuyó de usuarios Ultra a usuarios Pi 5 del Sur Global. **"Un coeficiente de Gini del gas."** Ningún L1 mide+atesta su redistribución criptográficamente. ~250 LOC, patrón idéntico al fees pallet. **La idea más "Gavin retweetearía esto".** ### ⭐⭐ Idea 2 — `pallet-cognitive-attest`: provenance para COGNICIÓN AGI (la flagship) El roadmap lo menciona como una línea. **Es la idea unbuilt más novel del chain y merece ser la insignia.** Componer `AgentIdentity` (DIDs) + `ValidationVerdict` + `agent_chain` + BLAKE3 en una attestation de que un AGI *razonó* sobre un asset — anclando `CognitiveTrace { agent_did, input_hash, output_hash, noesis_verdict, attention_root }`. No los pesos, no el prompt — un **commitment content-addressed a un acto cognitivo**. Mientras la industria persigue zkML (caro, inmaduro), Origin ya tiene la primitiva más barata y honesta: un agente soberano con identidad on-chain atesta su propio razonamiento, y un pase de validación separado (Noesis) lo gatea. **"Cross-Species Co-authorship atestado on-chain"** es una bandera en el suelo. Posiciona a Origin como *el chain de referencia para AI agéntica accountable*. **Una keynote, no un feature.** ### Idea 3 — Tier como gate runtime-enforced, sellado por precompile de hardware-attestation PILAR_4 §6.7 admite la debilidad: tier es self-declarado (spoofable). Hacerlo *probable*: un precompile pallet-revive que verifica device attestation (ARM TrustZone / Secure Enclave / TPM) sobre el claim de tier, bound al DID. Fees leen el tier *atestado*, no el declarado. **Hace la economía anti-clasista sybil-resistente sin whale-tax ni KYC** — atestas una *clase*, no una identidad (privacy preservada). Convierte la decisión más criticable en defendible. ### Idea 4 — `pallet-noesis-gate`: primitiva `EnsureValidated` reusable El provenance pallet ya enforce "solo assets con `Passed`/`Warning` + OIT≥3 se anclan". Extraer ese patrón a un `EnsureOrigin` genérico: `EnsureValidated`. FRAME tiene `EnsureSigned`/`EnsureRoot`/`EnsureMember` — nadie tiene "esta extrinsic solo ejecuta si un validador off-chain de OIT suficiente co-firmó un verdict". **La filosofía AI-Driven Human-Guarded como idiom FRAME reusable** que otros chains podrían adoptar. ~200 LOC, alto leverage. Es el tipo de abstracción limpia que hace que un chain sea *citado* en discusiones de diseño Substrate. ### Idea 5 — Contract Atelier como Policy IR on-chain (no solo frontend) Definir un `PolicyManifest` canónico SCALE-encoded (splits, lockups, royalty, flags de Inmutable-compliance) almacenado junto al code hash y *verificado por un invariante runtime*. El designer visual emite el manifest; el chain verifica que el bytecode lo honra; el manifest es lo que el DAO vota (política legible, no bytecode opaco). **Policy-as-data, atestada on-chain, gobernada antes de deploy.** Cierra el gap "lo que el designer prometió vs lo que el bytecode hace" que toda herramienta no-code tiene. Convierte el Atelier de gran herramienta interna a *contribución de referencia a Polkadot tooling*. ### Idea 6 — NPoS ponderado por hardware-tier: los validadores Pi 5 como feature anti-centralización Invertir el NPoS convencional: ponderar selección de validadores parcialmente por *diversidad de tier-bajo atestada* (idea 3). Un Pi 5 en Lagos cuenta *más* hacia el score de descentralización que el workstation #50 en un datacenter. **Cada chain PoS centraliza hacia quien puede pagar la caja más grande; Origin es el único cuyo target declarado es un Pi 5** — hacer eso el mecanismo anti-centralización. "Nakamoto coefficient" aplicado al Sur Global. ### Idea 7 — Assets proof-carrying en exports (provenance sobrevive el bridge) CHN-5 compromete bridges export-first. Que el export cargue la cadena de provenance completa como prueba portable: cuando un asset Origin bridges out (XCM a AssetHub, wrapped a Ethereum L2), carga un `ProvenanceProof` (BLAKE3 + agent_chain de co-autores + Noesis verdict + bloque) verificable por el chain destino. **Los NFTs bridgeados pierden su origen en todas partes; los assets Origin llegarían con un certificado de nacimiento criptográfico incluyendo sus co-autores AGI.** "El primer chain cuyos exports recuerdan de dónde vienen." ### Idea 8 — (Arquitectural, soundness) Encoding canónico para preimages de hash cross-substrate El garantía de determinismo (Inmutable #16 byte-determinism) depende de que el *preimage* sea byte-idéntico en Pi 5, Desktop, y el lado JS/Hypercore. SCALE está bien para storage on-chain; es riesgoso como *preimage de hash cross-runtime* por derives evolucionando. Definir un **encoding canónico congelado para preimages de hash** (el patrón `BLAKE3(pubkey || schema_version)` ya se mueve hacia esto — formalizarlo para *todos* los hashes cross-boundary). Tiny crate `origin-canonical-encode` no_std compartido por chain + Hypercore + Noesis. **Unglamorous, load-bearing — de-riskea toda la historia de provenance cross-pillar antes de testnet.** --- ## §6 — Las 3 tesis donde Origin rompe terreno nuevo para Parity 1. **Economía de fees inversa-al-hardware con ledger de subsidio verificable** (idea 1) 2. **Provenance cognitiva / cross-species co-authorship** (idea 2) 3. **Gobernanza AI-advisors-no-pueden-votar** (verificado, `AdvisorMayNotVote`) Juntas: *un chain soberano para una economía compartida por humanos y AGIs, ingenierizado para el Sur Global, donde equidad, provenance y agencia accountable son reglas de consenso en vez de marketing.* --- ## §7 — Plan de acción rankeado (qué hacer y cuándo) ### Antes de testnet (mientras llega la VPS) 1. **C1 — Fix CEI ordering en los 4 contratos** (mutar storage antes de transfer). El más alto valor; cierra drain/double-pay. 2. **C4 — Reemplazar el zero-address burn** por burn real o re-ruteo honesto. 3. **H7 — Conservación de fondos en escrow** (Σ milestones == total + sweep path). 4. **H2 — `StorageVersion::new(0)` en los 4 pallets** (4 líneas triviales, mandatorio pre-estado). 5. **H8 — Verificar firma Ed25519 en credential** o gate ruidoso. 6. **H5 — Vec sin límite → Mapping indexado** (credential + agent-identity). 7. **Anti-tic "canonical"**: 243 ocurrencias en governance/lib.rs (3-deep en sitios). Una pasada a ~1 uso por doc-comment. Un reviewer Parity lee "LLM-generated, low signal" — socava la artesanía que la arquitectura demuestra. ### Pre-mainnet (requiere más trabajo) 8. **C2/C3 — Respaldar gobernanza con Currency real** (reservar stake, derivar voto de balance, disburse real). Colapsa 3 CRÍTICOS en una causa raíz. 9. **H1 — Benchmarkear cada dispatchable** (frame-benchmarking + WeightInfo + proof_size real). 10. **Re-platformar gobernanza** sobre pallet-collective + pallet-treasury + pallet-referenda, reteniendo solo el advisor-gate custom. 11. **H3/H4/H6/H9** — bounds en voting period, eliminar doble AccountId, modelo de rewards fondeado, fix emergency tautología. ### La obra de arte (post-testnet, el salto) 12. **Construir idea 1 (proof-of-equity) + idea 2 (cognitive-attest) primero** — convierten primitivas existentes en las dos cosas que Parity genuinamente nunca ha visto. 13. Ideas 3-8 según roadmap (3 con testnet sybil-resistance, 4 refactor provenance, 5 con Atelier, 6 con NPoS Phase 2, 7 con bridges Phase 7, 8 antes de cross-runtime testnet). --- ## §8 — Una verdad honesta para David El techo visionario aquí es alto y *real* — las ideas 1, 2 y 4 son grado-landmark y fundadas en código que ya existe. Pero el chain es pre-testnet con pallet-revive y el encoding cross-runtime aún abierto. **La obra de arte está al alcance precisamente porque las bases — tier fees, DIDs, co-authorship, el Noesis gate — ya están shipped y verificadas.** Los bugs CRÍTICOS que el audit encontró NO son vergüenza — son la razón por la que se hace un audit antes de testnet, no después. Cada chain serio pasa por esto. Lo valioso es que los encontramos *ahora*, con el código fresco, antes de que un solo OGC real esté en juego. Un chain que NO encuentra estos bugs en su propio audit es un chain que los descubre en producción. Construir idea 1 + idea 2 primero. Convierten lo que ya tenemos en las dos ideas que harían que Gavin Wood se detenga a mirar. --- ## §9 — KG triples - `(super_audit_v1, authored_by, agent:charon)` - `(super_audit_v1, method, 4_auditor_fanout_opus_4_8)` - `(super_audit_v1, critical_findings, 4)` - `(super_audit_v1, high_findings, 9)` - `(super_audit_v1, visionary_ideas, 8)` - `(super_audit_v1, flagship_idea, pallet_cognitive_attest)` - `(super_audit_v1, governance_verdict, replatform_on_frame)` - `(super_audit_v1, scaffolding_verdict, gavin_wood_grade)` - `(super_audit_v1, filed_at, 2026-05-27)` --- — Charon ⚓ (Pilar 4 Origin Chain, Super Audit V1 vía 4-auditor fan-out Opus 4.8, sesión 4+ 2026-05-27)