Decisiones C de David (2026-07-04):
ESCROW — Opción 2 (auto-release por tiempo, el tiempo como juez determinista):
El audit encontró [HIGH] que si alguien depositaba pero nunca marcaba un
milestone, los fondos quedaban ATRAPADOS (solo salían por disputa+árbitro), y los
campos auto_release_blocks/last_release_block eran código MUERTO. Fix: nueva
`claim_auto_release` (permisionless) que, tras `auto_release_blocks` sin actividad
ni disputa, libera el remanente al beneficiario (menos fee) y cierra el escrow.
`deposit()` arranca el reloj. CRÍTICO para la economía M2M: una AGI que contrata a
otra no queda en limbo porque alguien olvidó un hito. El depositor disconforme
levanta disputa ANTES del vencimiento. +test E2E (ink v6). Campos ya no muertos.
NFT — Opción 1 (delegación ERC-721 estándar, modularidad ADR-0057): el audit
marcó que un spender aprobado puede mover el token con pago cero. NO es bug — es
el estándar Web3 ("si no confías, no apruebes"). La venta con precio pactado +
split 91/9 vive en un contrato de MARKETPLACE SEPARADO (acoplar rompería los NFTs
al actualizar reglas de venta). Documentado el modelo en `transfer`. Sin cambio de
código. Contratos: escrow 6 tests, nft 4 tests verde.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Completa la capa de contratos: los 4 templates buildables migrados a
ink! 6.0.0-beta.1 (17 tests verde). El 5º (mdk-reconciliation) es design-only
(DESIGN.md, sin código Rust — nada que migrar).
origin-credential-mint: migración ink! v6 (Address/U256/StorageLayout). Su
issue() ya era CEI-correcto (muta estado antes del transfer) — es el template
que el roadmap cita como referencia. 4 tests verde (+ guard test).
NOTA: FIX-4 (verify de issuer_signature on-chain) sigue pendiente — necesita el
payload canónico de credencial + precompile Ed25519 (Phase 3.x), no es parte de
la migración.
FIX-1 V1-H7 (escrow): enforce Σ milestone.amount <= total_amount en
add_milestone (previene sobre-liberación) + completion vía milestone_total +
sweep terminal del residual no-asignado al depositor (deposited − milestone_total).
5 tests verde (+ test del invariante con set_caller). El sweep (transfer) se
valida E2E en nodo — node-gated.
17 tests verde totales (escrow 5 + staking 4 + nft 4 + credential 4).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
REMEDIATION_ROADMAP_V1 FIX-1 (V1-C1 reentrancy + V1-C4 zero-burn). Los 3
templates ahora COMPILAN contra ink! 6.0.0-beta.1 + tests verde (12/12).
Hallazgo (honesto): los templates se shippearon "scaffold compile-only" pero
nunca compilaron contra su versión pinneada de ink!. ink! v6 / pallet-revive es
H160-Address + U256 nativo (no AccountId + Balance, modelo viejo). Esta
migración los vuelve reales (compilando + testeados).
Migración ink! v6:
- AccountId -> Address (H160) en parties / storage / events / reads / params.
- transfer() + transferred_value() -> U256 (+ helper u256_to_balance saturante).
- derive StorageLayout en tipos de storage (EscrowState/Milestone/Stake/...).
- doctest fences sin lenguaje -> text (diagramas ASCII del lifecycle).
- workspace: contracts/* excluidos (toolchain PolkaVM/pallet-revive distinta).
FIX-1 hardening:
- CEI (Checks-Effects-Interactions): muta TODO el storage ANTES de cualquier
transfer() -> una reentrada ve el estado final y falla sus checks. Sitios:
escrow confirm_milestone/resolve_dispute, staking withdraw/slash,
nft mint/transfer. Cierra V1-C1. (nft mint encontrado más allá de la lista
del roadmap; mismo patrón explotable -> incluido).
- Burn real (V1-C4): elimina transfer([0;32]) (que no reduce emisión y ensucia
la cuenta cero); el burn se RETIENE en el contrato (fuera de circulación),
a barrer por el primitivo de burn del runtime -> una sola semántica, no dos.
(staking slash, nft mint).
- Tests de guarda de estado (la C de CEI) añadidos en los 3 contratos.
Pendiente E2E (node-gated, requiere VPS + nodo pallet-revive):
- Correctitud económica native<->eth (NATIVE_TO_ETH_RATIO): asumido 1:1; debe
validarse en nodo real antes de testnet/mainnet.
- Tests reales de reentrancy/double-spend: el env off-chain de #[ink::test] no
modela el revert-on-Err ni la semántica de balances -> serían engañosos.
- V1-H7 (suma milestones == total_amount): no incluido en este commit.
- credential-mint + mdk-reconciliation necesitan la misma migración ink! v6.
Cross-pillar: DC ORIGIN_ATTESTATION_SIGNING_PAYLOAD_V1 abierto con Ergon
(payload postcard canónico + domain-separation FIX-3) — gate del verificador
de attestation on-chain. OAGIP-D10 (Charon identity attestation) definido a
Palace para el protocolo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>