Decisión A (David 2026-07-04). El audit ultra encontró [HIGH] que el "mínimo
1.000 OGC" de submit_proposal era un número caller-supplied SIN respaldo: una
cuenta vacía podía spamear propuestas ilimitadas, y ese `stake` fabricado era el
`baseline` denominador del override_council_veto (manipulable).
Fix (sin esperar a NPoS — el stake de propuesta es piel-en-el-juego anti-spam,
distinto del voto pesado por stake): el stake se RETIENE de verdad en una cuenta-
bond determinista `og/props` (transfer, Preservation::Preserve → falla si el
proponente no tiene fondos) y se DEVUELVE al proponente cuando la propuesta se
decide. Clave del lifecycle: el release ocurre en AMBAS transiciones fuera de
Voting — finalize_proposal Y veto_proposal — o el bond de una propuesta vetada
quedaría atrapado (no hay withdraw dispatchable). `og/props` separada del vault
para que treasury_disbursement jamás toque un bond.
Enfoque escrow-account: usa solo Currency::transfer (ya en el bound) — cero
cambios de Config/runtime-wiring. submit_proposal + submit_emergency_proposal
ambos bond. +3 regression tests (retiene+devuelve al finalizar, devuelve al
vetar, rechaza si no alcanza). Mock refondeado >= MIN_PROPOSAL_STAKE. 48 gov
tests, workspace 283 verde.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>