> For the complete documentation index, see [llms.txt](https://novacont.gitbook.io/nova-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://novacont.gitbook.io/nova-docs/novacont-docs/espanol/seguridad-y-desarrolladores/modelo-de-seguridad.md).

# Modelo de seguridad

### Arquitectura de pago pull

NovaCont no envía fondos forzosamente a los destinatarios. En cambio, todas las distribuciones de fondos se registran como créditos en un mapeo `pendingWithdrawals`, y los destinatarios inician sus propios retiros explícitamente.

Esta es una elección de seguridad deliberada. Los sistemas de pago basados en push — donde el contrato envía ETH directamente a las direcciones de los destinatarios — son vulnerables a ataques de reentrada si el destinatario es un contrato malicioso que vuelve a entrar en la función de envío antes de que se actualice el estado. Al separar el paso de acreditación del paso de retiro, NovaCont elimina completamente esta superficie de ataque.

Cada función de retiro está adicionalmente protegida por el modificador `nonReentrant` como capa secundaria de defensa.

<figure><img src="/files/Eb0KqnBaXRDzd8QWaNwA" alt=""><figcaption></figcaption></figure>

### Protección contra reentrada

Todas las funciones que interactúan con saldos de ETH o ERC-20 están marcadas con el modificador `nonReentrant` de ReentrancyGuard de OpenZeppelin. Este modificador usa una variable de bloqueo para garantizar que ninguna función del contrato pueda ser llamada recursivamente — si se intenta una llamada reentrante, la transacción se revierte inmediatamente.

Las transferencias de ERC-20 usan el envoltorio `SafeERC20` de OpenZeppelin, que maneja implementaciones de tokens no estándar con elegancia y revierte en transferencias fallidas en lugar de tener éxito silenciosamente con un valor de retorno falso.

### Control de acceso

**Propietario** — La dirección de despliegue. Puede pausar el contrato, actualizar tarifas, registrar tokens, establecer fuentes de precios y gestionar la configuración del resolutor y del sistema de jurado. Las transferencias de propiedad requieren dos pasos para evitar transferencias accidentales.

**Resolutor** — Una dirección designada autorizada para resolver disputas en modo administrador. Por defecto es el propietario al momento del despliegue. Puede ser cambiado por el propietario en cualquier momento. Cuando el sistema de jurado se activa, el resolutor se establece automáticamente en la dirección del contrato NovaJury.

**onlyJuryContract** — Un modificador que restringe ciertas funciones de liquidación exclusivamente a la dirección registrada de NovaJury. No puede ser llamado por el propietario, el resolutor ni ningún actor externo.

**Acceso basado en partes** — La mayoría de las funciones del flujo de trabajo están restringidas a las direcciones específicas registradas como cliente o proveedor en la creación del contrato. Ninguna otra dirección puede aceptar, entregar, aprobar, disputar o cancelar en nombre de una parte.

### Pausa de emergencia

El propietario del contrato puede invocar `pause()` en cualquier momento para detener todas las operaciones que modifican el estado. Esto está pensado como una medida de emergencia en caso de una vulnerabilidad descubierta o un ataque en curso.

Cuando está pausado:

* No se pueden crear nuevos contratos
* No se pueden activar transiciones de estado
* Los retiros de `pendingWithdrawals` permanecen completamente funcionales — los usuarios siempre pueden recuperar los fondos acreditados

El contrato puede ser despausado por el propietario en cualquier momento a través de `unpause()`.

#### Limitaciones y suposiciones conocidas

**Selección pseudoaleatoria de jurados:** La asignación de jurados utiliza un mecanismo pseudoaleatorio en cadena basado en `blockhash`, `prevrandao`, `gasleft` y un nonce incremental. Esto no es aleatoriedad criptográficamente segura. Un validador con suficiente control sobre la producción de bloques podría teóricamente influir en los resultados de selección de jurados. Para la escala actual del protocolo este riesgo se considera aceptable, pero se reconoce como una limitación. La integración con una solución de aleatoriedad verificable como Chainlink VRF es una posible actualización futura.

**Dependencia del oráculo:** NovaCont depende de las fuentes de precios de Chainlink para los cálculos de depósito. El contrato realiza múltiples validaciones en cada llamada al oráculo: verifica que el precio sea mayor que cero, que los datos de ronda estén completos y que el precio no tenga más de 24 horas. Una interrupción prolongada del oráculo o una fuente comprometida aún podría afectar la precisión de las conversiones de USD a tokens, pero estos múltiples controles reducen significativamente el riesgo.

**Sin mecanismo de apelación:** Los veredictos de disputas — ya sea emitidos por el administrador o el jurado — son definitivos e irreversibles una vez ejecutados en cadena. No hay proceso de apelación. Los usuarios deben abordar las disputas con evidencia completa y bien organizada desde el principio.

**Evidencia fuera de cadena:** Los URI de evidencia apuntan a recursos fuera de cadena. NovaCont no puede garantizar la permanencia ni la integridad de estos recursos. Un proveedor o cliente que envíe un enlace que posteriormente se vuelva inaccesible asume las consecuencias de esa inaccesibilidad en cualquier evaluación de disputa.

#### Análisis de superficie de ataque

Entender dónde es más vulnerable un contrato inteligente es tan importante como entender qué hace. A continuación se presenta una evaluación honesta de las principales superficies de ataque de NovaCont y las mitigaciones implementadas para cada una.

#### **cancelContract — Ruta de acceso del propietario y lógica posterior a la entrega**

La función `cancelContract` tiene dos comportamientos importantes:

**Autoridad de cancelación del propietario.** El propietario del contrato puede cancelar cualquier acuerdo en cualquier momento, independientemente del estado o el consentimiento de las partes:

```
require(canCancel || msg.sender == owner(), "Cannot cancel");
```

Esta es una capacidad administrativa intencional — existe para manejar casos extremos como direcciones sancionadas, obligaciones legales o errores críticos que requieren intervención manual. Sin embargo, representa una suposición de centralización de la que los usuarios deben ser conscientes. Las cancelaciones iniciadas por el propietario siempre resultan en un reembolso completo al cliente sin aplicar ninguna penalización.

#### **settleDispute — Validación de división**

La función de liquidación del administrador aplica un invariante estricto:

```
require(_clientRefund + _grossProviderPayment == c.totalLocked)
```

Esto garantiza que el monto total distribuido siempre sea igual al monto total bloqueado — ningún fondo puede crearse o destruirse durante la liquidación. Cualquier resolución que no contabilice cada wei del saldo bloqueado se revertirá. Esta es una verificación de corrección crítica que previene tanto la malasignación accidental como maliciosa de fondos durante la resolución de disputas.

#### **claimTimeout — Dependencia del tiempo**

El mecanismo de tiempo de espera depende de `block.timestamp` para su verificación de la ventana de 7 días. Los mineros y validadores tienen un pequeño grado de influencia sobre las marcas de tiempo de los bloques — típicamente dentro de un rango de unos pocos segundos a unos pocos minutos. Esto no es un vector de ataque significativo para una ventana de 7 días, pero vale la pena señalarlo como una propiedad general de la lógica dependiente de marcas de tiempo. NovaCont no usa marcas de tiempo para nada donde la precisión a nivel de segundos sea crítica para la seguridad.

### Consideraciones de front-running

El front-running ocurre cuando un actor malicioso observa una transacción pendiente en el mempool y envía su propia transacción con una tarifa de gas más alta para ser procesada primero.

**Front-running del precio del oráculo:** Cuando un cliente llama a `createContract`, el precio ETH/USD se obtiene de Chainlink en ese bloque exacto. Un actor sofisticado podría teóricamente observar una transacción `createContract` pendiente, predecir el precio del oráculo en el momento de la inclusión y diseñar un ataque alrededor de ello. Sin embargo, no hay ningún exploit significativo disponible aquí — el cliente es quien bloquea sus propios fondos, y el precio del oráculo solo afecta cuánto ETH debe enviar, no si los fondos pueden ser robados.

**Front-running de disputa:** Un proveedor que ve la transacción `disputeWork` del cliente en el mempool no puede hacer front-running de ella de una manera que le beneficie — el estado del contrato solo permite que se abra una disputa, y la disputa solo puede abrirse mientras está en el estado "Entregado". No hay ninguna condición de carrera que pudiera permitir a un proveedor adelantarse a una disputa legítima.

### Casos extremos de ERC-20

**Condición de carrera en la aprobación:** La función estándar ERC-20 `approve` es técnicamente vulnerable a una condición de carrera donde un gastador puede observar una aprobación que se está cambiando y hacer front-running para gastar tanto el límite antiguo como el nuevo. NovaCont mitiga esto usando `safeTransferFrom` a través de `SafeERC20`, y se aconseja a los usuarios que establezcan los límites en cero antes de aumentarlos si están interactuando con los contratos directamente en lugar de a través de la interfaz de la aplicación.

**Valores de retorno no estándar:** Algunos tokens ERC-20 no devuelven un valor booleano de `transfer` y `transferFrom`, contrariamente a la especificación EIP-20. El envoltorio `SafeERC20` de OpenZeppelin maneja esto con elegancia verificando la longitud de los datos de retorno y tratando los valores de retorno faltantes como éxito solo cuando la propia llamada no se revirtió. Esto garantiza la compatibilidad con una gama más amplia de implementaciones de tokens.

### Riesgos de centralización

NovaCont no es completamente sin confianza en su forma actual. Las siguientes capacidades del propietario representan suposiciones de centralización que los usuarios deben evaluar antes de usar el protocolo:

<table><thead><tr><th>Capacidad</th><th width="249">Función</th><th>Impacto</th></tr></thead><tbody><tr><td>Pausar todas las operaciones</td><td><code>pause()</code></td><td>Detiene la creación de contratos y las transiciones de estado. Los retiros no se ven afectados.</td></tr><tr><td>Cancelar cualquier contrato</td><td><code>cancelContract()</code></td><td>El propietario puede cancelar forzosamente cualquier acuerdo. El cliente siempre recibe un reembolso completo.</td></tr><tr><td>Cambiar la tarifa de plataforma</td><td><code>setPlatformFee()</code></td><td>La tarifa puede cambiarse hasta un máximo del 10%. Solo afecta liquidaciones futuras.</td></tr><tr><td>Cambiar el resolutor</td><td><code>setResolver()</code></td><td>Puede redirigir la autoridad de resolución de disputas a cualquier dirección.</td></tr><tr><td>Activar o desactivar el jurado</td><td><code>activateJurySystem()</code> / <code>deactivateJurySystem()</code></td><td>Puede cambiar entre modos de disputa administrado y descentralizado en cualquier momento.</td></tr><tr><td>Agregar o eliminar tokens soportados</td><td><code>addSupportedToken()</code> / <code>removeSupportedToken()</code></td><td>Puede expandir o restringir las opciones de pago. No se puede eliminar ETH ni USDT.</td></tr><tr><td>Actualizar fuentes de precios</td><td><code>setPriceFeed()</code></td><td>Puede cambiar la fuente del oráculo para cualquier token. Una fuente maliciosa podría afectar los cálculos de depósito.</td></tr></tbody></table>

Estas capacidades son necesarias para que el protocolo opere de manera segura durante su etapa actual de desarrollo. A medida que el protocolo madure, la intención es reducir progresivamente la autoridad del propietario a través de bloqueos de tiempo, requisitos de multifirma y eventualmente gobernanza en cadena. Cualquier cambio en el modelo de privilegios del propietario será documentado y anunciado con anticipación.

### Estado de auditoría

NovaCont aún no ha sido sometido a una auditoría de seguridad formal de terceros. Los contratos han sido desarrollados siguiendo las mejores prácticas de seguridad establecidas y hacen uso extensivo de bibliotecas auditadas de OpenZeppelin, pero la ausencia de una auditoría formal significa que pueden existir vulnerabilidades desconocidas.

Los usuarios deben tratar el protocolo como experimental hasta que se complete una auditoría formal y se publiquen sus hallazgos. No deposites fondos que no puedas permitirte perder.

Un compromiso de auditoría está planificado como parte del camino del protocolo hacia el despliegue en la red principal. Los informes de auditoría se publicarán en su totalidad y se vincularán desde esta documentación cuando estén disponibles.
