Verificador de Auditoría Blockchain — CULTIVA IA / Seguridad
| Tipo | Identificador | Secciones relevantes | Estado |
|---|---|---|---|
| Whitepaper | verdeswap-whitepaper-v2.pdf | §3.1 Invariante, §3.2 Fee, §3.3 Control acceso, §3.4 Swap, §3.5 Emergencia | Procesado |
| Codigo | CarbonPool.sol | Contrato completo — 70 lineas efectivas | Procesado |
| ID | Tipo Semantico | Extracto Spec | Seccion | Confianza |
|---|---|---|---|---|
SI-01 |
invariante | "x * y ≥ k siempre; si k disminuye tras swap, revertir" | §3.1 |
0.95
|
SI-02 |
formula-fee | "fee fijo 0.3%; amount_in_net = amount_in * (1 - 0.003); fee al feeRecipient" | §3.2 |
0.98
|
SI-03 |
acceso | "addLiquidity() solo para direcciones en whitelist" | §3.3 |
0.99
|
SI-04 |
flujo-swap | "Paso 1: verificar paused antes de swap" | §3.4 |
0.99
|
SI-05 |
acceso-emergencia | "emergencyWithdraw() SIEMPRE requiere contrato pausado" | §3.5 |
0.99
|
SI-06 |
evento | "Emitir Swap(caller, amount_in, amount_out, fee)" | §3.4 |
0.95
|
SI-07 |
acceso | "Solo owner actualiza feeRecipient" | §3.3 |
0.99
|
SI-08 |
acceso | "Solo owner puede pausar/reanudar" | §3.3 |
0.99
|
SI-09 |
precondicion | "amount_in > 0" | §3.4 |
0.99
|
SI-10 |
flujo-swap | "Paso 4-5: transferir amount_in del caller; transferir amount_out al caller" | §3.4 |
0.95
|
SI-11 |
threshold | "MIN_RESERVE = 1000 tokens" | §3.5 |
0.90
|
Total Spec-IR: 11 items — 5 items con divergencias identificadas.
| Spec-IR | Descripcion | Codigo (archivo:linea) | Resultado | Severidad | Conf. |
|---|---|---|---|---|---|
SI-01 |
Invariante x*y ≥ k post-swap | CarbonPool.sol:48–65 | FALTA | CRITICA | 0.98 |
SI-02 |
Fee 0.3% transferido a feeRecipient | CarbonPool.sol:52–58 | MISMATCH | CRITICA | 0.99 |
SI-03 |
addLiquidity solo whitelist | CarbonPool.sol:33–39 | FALTA | ALTA | 0.99 |
SI-04 |
Verificar paused en swap() | CarbonPool.sol:41 | FALTA | ALTA | 0.99 |
SI-05 |
emergencyWithdraw requiere paused | CarbonPool.sol:67–72 | MISMATCH | MEDIA | 0.98 |
SI-06 |
Evento Swap emitido | CarbonPool.sol:63 | MATCH | — | 0.95 |
SI-07 |
setFeeRecipient solo owner | CarbonPool.sol:26 | MATCH | — | 0.99 |
SI-08 |
setPaused solo owner | CarbonPool.sol:30 | MATCH | — | 0.99 |
SI-09 |
require(amount_in > 0) | CarbonPool.sol:43 | MATCH | — | 0.99 |
SI-10 |
Flujo transfer in/out | CarbonPool.sol:52–60 | MATCH | — | 0.95 |
SI-11 |
MIN_RESERVE = 1000e18 | CarbonPool.sol:14 | MATCH | — | 0.90 |
swap() actualiza reserveA/B y emite evento sin ningun require(reserveA * reserveB ≥ k).
uint256 kBefore = reserveA * reserveB antes del swap y agregar require(reserveA * reserveB >= kBefore, "Invariant violated") despues de actualizar ambas reservas. Usar arithmetic con overflow protection.
fee se calcula correctamente pero nunca se llama a tokenA.transfer(feeRecipient, fee) ni equivalente.
tokenX.transfer(feeRecipient, fee) al final de cada rama del swap, o acumular fees en variable de estado accruedFees y exponer funcion claimFees() llamable solo por feeRecipient.
function addLiquidity(...) external { — sin modifier ni require de whitelist.
require(whitelist[msg.sender], "Not whitelisted"). O crear un modifier onlyWhitelisted reutilizable.
swap() es require(amountIn > 0) — el flag paused nunca se comprueba.
require(!paused, "Contract paused") como primera sentencia de swap(). Considerar OpenZeppelin Pausable.
function emergencyWithdraw() external onlyOwner — sin require paused.
require(paused, "Must be paused") como primera sentencia. Esto impide que owner drene fondos inesperadamente durante operacion normal (proteccion adicional contra rug-pull).
| Categoria | Estado | Accion requerida |
|---|---|---|
| Invariante de liquidez | AUSENTE | Implementar verificacion k post-swap (DV-001) |
| Distribucion de fees | INCORRECTA | Agregar transferencia a feeRecipient (DV-002) |
| Control de acceso addLiquidity | AUSENTE | Implementar require whitelist (DV-003) |
| Mecanismo de pausa | INCOMPLETO | Agregar check paused en swap() (DV-004) |
| Proteccion emergencyWithdraw | INCOMPLETO | Requerir paused=true (DV-005) |
| Logica de swap (matematica) | CORRECTA | Ninguna |
| Emision de eventos | CORRECTA | Ninguna |
| Gestion de owner/feeRecipient | CORRECTA | Ninguna |
Proximos pasos: (1) Corregir DV-001 a DV-005 en CarbonPool.sol. (2) Ejecutar suite de tests con casos de borde para cada remediacion. (3) Solicitar re-auditoria completa antes de deploy en mainnet. (4) Actualizar whitepaper §3.5 para aclarar condicion MIN_RESERVE en emergencyWithdraw.