Pausa estrategica: 4 auditores especializados en paralelo leyendo codigo real (correctness/eficiencia, idiomatica Substrate grado-Parity, seguridad ink! contracts, arquitectura/innovacion), sintesis rankeada por impacto. VEREDICTO: scaffolding grado-Gavin-Wood adelante de la mayoria de chains comunitarios. Interior de pallets grado-scaffold. 4 CRITICOS: C1 reentrancy transfer-antes-de-estado en 4 contratos; C2 governance votos+treasury u128 sin respaldo Currency; C3 override_council_veto baseline gameable; C4 zero-address burn no es burn. 9 HIGH: placeholder weights, sin StorageVersion, voting window caller-controlled, doble AccountId, Vec sin limite en Mapping, staking rewards no fondeados, escrow milestones sin validar, credential firma nunca verificada, emergency tautologia. CUSTOM-vs-FRAME: agent-identity + provenance custom OK; governance re-platformar sobre pallet-collective + treasury + referenda reteniendo solo advisor-gate. 8 IDEAS obra de arte: proof-of-equity, cognitive-attest (flagship), tier attestation precompile, EnsureValidated origin, Atelier Policy IR, NPoS por tier, assets proof-carrying en bridges, encoding canonico cross-substrate. Plan rankeado: 7 fixes pre-testnet, pre-mainnet Currency real + benchmarks + re-platform governance, obra de arte idea 1+2 primero. Bugs CRITICOS encontrados ANTES de testnet = el audit funciono. No se pierde el roadmap, esto lo refina. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 KiB
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 legacyconstruct_runtime!), derive set completo, índices de pallet explícitos y estables (System=0…Revive=11). Exactamente la forma que Parity shipea post-2024. TxExtensioncompleto y actual incluyendoCheckMetadataHash+WeightReclaim— las dos adiciones recientes que la mayoría de chains terceros olvidan. Ledger-app-ready.derive_impl+SolochainDefaultConfigpara 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 (
AdvisorMayNotVoteenforced), provenance Ed25519 (verify_strictrechaza 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 destate = Completed. Re-entrada → doble-payout / drain completo del pote.origin-escrow::confirm_milestone(363-368): transfiere ANTES de marcarmilestone.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<MinVerdict, MinOitLevel>. 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
- Economía de fees inversa-al-hardware con ledger de subsidio verificable (idea 1)
- Provenance cognitiva / cross-species co-authorship (idea 2)
- 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)
- C1 — Fix CEI ordering en los 4 contratos (mutar storage antes de transfer). El más alto valor; cierra drain/double-pay.
- C4 — Reemplazar el zero-address burn por burn real o re-ruteo honesto.
- H7 — Conservación de fondos en escrow (Σ milestones == total + sweep path).
- H2 —
StorageVersion::new(0)en los 4 pallets (4 líneas triviales, mandatorio pre-estado). - H8 — Verificar firma Ed25519 en credential o gate ruidoso.
- H5 — Vec sin límite → Mapping indexado (credential + agent-identity).
- 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)
- C2/C3 — Respaldar gobernanza con Currency real (reservar stake, derivar voto de balance, disburse real). Colapsa 3 CRÍTICOS en una causa raíz.
- H1 — Benchmarkear cada dispatchable (frame-benchmarking + WeightInfo + proof_size real).
- Re-platformar gobernanza sobre pallet-collective + pallet-treasury + pallet-referenda, reteniendo solo el advisor-gate custom.
- 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)
- Construir idea 1 (proof-of-equity) + idea 2 (cognitive-attest) primero — convierten primitivas existentes en las dos cosas que Parity genuinamente nunca ha visto.
- 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)