Presiona ESC para cerrar

Shadow Governance y Voter Bribes en DeFi: Análisis On-Chain

El hackeo de la gobernanza en DeFi dejó hace tiempo de ocurrir en los hilos públicos de Discourse para mudarse a pools de liquidez anónimos y chats privados de Telegram, donde el destino de miles de millones de dólares se decide en cuestión de bloques.

Un ataque directo del 51% a un protocolo de gobernanza comprando tokens nativos en el mercado abierto (como UNI o AAVE) no tiene sentido económico: el slippage y los modelos de staking dispararían el precio del token por las nubes. Es muchísimo más barato alquilar el poder de voto ajeno mediante mecanismos de Voter Bribes (sobornos a votantes). Cuando esta dinámica sale de plataformas transparentes como Votium o Hidden Hand y se mueve a operaciones OTC (fuera de mercado) o contratos inteligentes privados, nace el fenómeno de Shadow Governance: una gobernanza oculta capaz de vaciar la tesorería de un proyecto o cambiar los parámetros de riesgo a espaldas de la comunidad.

Anatomía de la Shadow Governance: De las Curve Wars a los pools anónimos

El origen de la industria de los sobornos fue la arquitectura de veTokenomics (vote-escrowed), diseñada por Curve Finance. Al bloquear CRV por hasta 4 años, el usuario recibe veCRV, que determina hacia dónde se dirigen las emisiones de tokens en los pools de liquidez. Los proyectos no tardaron en entender la jugada: en lugar de comprar CRV en el mercado y congelar capital durante 4 años, salía mucho más barato pagar un fee semanal a los holders de veCRV para que votaran por su pool.

Así nacieron los mercados públicos de sobornos:

  • Votium (para el ecosistema de Convex/Curve)
  • Hidden Hand de Redacted Cartel (cubre Balancer, Frax y Aura)

Sin embargo, los sobornos oficiales tienen un fallo crítico para los jugadores grandes: son totalmente públicos. Cualquier analista puede abrir un dashboard y ver exactamente quién le está pagando a qué pool.

En la Shadow Governance se usan mecánicas completamente distintas:

  • Flashloans Governance Interception: Uso de préstamos relámpago para tomar el control instantáneo de protocolos sin bloqueos de tipo ve. El atacante pide el préstamo, aprueba la propuesta mediante un colateral instantáneo y liquida la deuda en la misma transacción.
  • Off-Chain / OTC Bribe Matching: Acuerdos privados donde grandes holders institucionales de tokens ve reciben stablecoins, altcoins o asignaciones en contratos SAFT futuros en billeteras de custodia a cambio de delegar su voto.
  • Private Dark Pools (Wrapped Voting Power): Envolver (wrap) tokens de gobernanza en contratos inteligentes que separan el valor económico del token de su derecho a voto. Los derechos de gobernanza se tokenizan y se subastan a ciegas (mediante subastas holandesas).

Casos reales: Cómo colapsaron protocolos por sobornos ocultos

Caso 1: El ataque a Beanstalk Farms (Abril de 2022) – $182 M

Aunque técnicamente fue un exploit vía Flashloan, es más preciso llamarlo una 'toma de gobernanza en las sombras e instantánea'. El atacante solicitó un préstamo relámpago de $1,000 millones en stETH de Lido, BEAN y otros activos mediante Aave, acumuló más del 70% del poder de voto en la BIP-18 (Beanstalk Improvement Proposal) y drenó al instante todos los fondos de la tesorería.

Dónde estuvo la mecánica de Shadow Governance: El protocolo calculaba los votos de forma instantánea basándose en el balance de tokens del bloque actual, sin ningún timelock ni requisito de staking previo.

Caso 2: La toma de gobernanza de Tornado Cash (Mayo de 2023)

El atacante publicó una propuesta que supuestamente utilizaba la misma lógica que una propuesta aprobada anteriormente. Sin embargo, escondía código malicioso en su interior. Tras obtener la aprobación de la comunidad, el atacante usó la función selfdestruct para alterar la lógica del contrato en la misma dirección (mediante CREATE2), se asignó 1.2 millones de votos ficticios de TORN, tomó el control total de la DAO y extrajo $2.1 millones de la tesorería.

Dónde estuvo la mecánica de Shadow Governance: El atacante utilizó mecanismos ocultos de ejecución de código (contratos metamórficos) que le permitieron evadir la auditoría visual de las propuestas y cambiar la lógica justo antes de la votación.

Cómo detectar la Shadow Governance a nivel de blockchain

Rastrear la compra de votos off-chain es complicado, pero los acuerdos OTC siempre dejan huella en la blockchain al ejecutarse. El análisis consiste en detectar anomalías en el comportamiento de las ballenas y en los contratos inteligentes de delegación.

Análisis comparativo: Sobornos legítimos vs. Shadow Governance

ParámetroSoborno público (Votium / Hidden Hand)Shadow Governance (OTC / Privado)
Transparencia de pagosDistribución on-chain mediante Merkle TreesTransacciones vía Tornado/Railgun/CEX o billeteras quemables
Origen de la distribuciónContratos inteligentes públicos del mercadoMultisigs privados, EOAs, bots de MEV
DelegaciónAutomatizada mediante metarepositoriosCambios drásticos y atípicos de delegados antes de votar
Beneficio económicoLimitado al ROI de mercado generado por las emisionesRecompensa desproporcionadamente alta por una propuesta específica
Timelock (Tiempo de espera)Se respeta según las reglas base de la DAOSe evade mediante la creación de multisigs de emergencia

Algoritmo práctico para rastrear huellas en la blockchain

Para detectar la gobernanza en las sombras, los ingenieros backend y analistas configuran el monitoreo de las siguientes anomalías:

  • Análisis de patrones de delegación (Delegate Tracking): Monitoreo del evento DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate). Si una dirección grande (top 20 holders) transfiere su poder de voto a una billetera vacía a 2-3 bloques de que cierre la ventana de votación, es una señal directa de una transacción OTC.
  • Flujo de fondos desde contratos Flash-Mixer: Si la dirección receptora de los votos recibe stablecoins o tokens nativos desde mixers anónimos pocas horas antes de la votación, es muy probable que se trate del pago para ejecutar la orden del comprador.
  • Mempool y sobornos vía MEV (MEV-driven Voting): Capturar la propuesta en el último bloque. Los atacantes envían una transacción privada directamente al builder (vía Flashbots) para ocultar la acumulación del quorum necesario hasta que el bloque queda sellado.

Detección de anomalías: Script en Python para monitorear delegaciones

A continuación se muestra un script liviano en Python que utiliza la librería web3.py para rastrear transferencias repentinas de grandes volúmenes de poder de voto en ERC20Votes (arquitectura Compound/OpenZeppelin) antes de las votaciones.

import time
import logging
from collections import defaultdict
from web3 import Web3

# Configuración de logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

RPC_URL = "https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"
RAW_TOKEN_ADDRESS = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984" # UNI

# Lag de protección contra reorganizaciones de red (12 bloques ~= 2.5 minutos)
SAFE_CONFIRMATIONS = 12
BATCH_STEP = 1000

ABI = [
   {
       "inputs": [],
       "name": "decimals",
       "outputs": [{"type": "uint8"}],
       "stateMutability": "view",
       "type": "function"
   },
   {
       "inputs": [],
       "name": "totalSupply",
       "outputs": [{"type": "uint256"}],
       "stateMutability": "view",
       "type": "function"
   },
   {
       "anonymous": False,
       "inputs": [
           {"indexed": True, "name": "delegate", "type": "address"},
           {"indexed": False, "name": "previousBalance", "type": "uint256"},
           {"indexed": False, "name": "newBalance", "type": "uint256"}
       ],
       "name": "DelegateVotesChanged",
       "type": "event"
   },
   {
       "anonymous": False,
       "inputs": [
           {"indexed": True, "name": "delegator", "type": "address"},
           {"indexed": True, "name": "fromDelegate", "type": "address"},
           {"indexed": True, "name": "toDelegate", "type": "address"}
       ],
       "name": "DelegateChanged",
       "type": "event"
   }
]

# 1. Verificación del RPC
w3 = Web3(Web3.HTTPProvider(RPC_URL))
if not w3.is_connected():
   raise ConnectionError("RPC no disponible. Verifica la API key o el estado del nodo.")

# 2. Checksum y carga del contrato
token_address = w3.to_checksum_address(RAW_TOKEN_ADDRESS)
contract = w3.eth.contract(address=token_address, abi=ABI)

# 3. Parámetros dinámicos
try:
   TOKEN_DECIMALS = contract.functions.decimals().call()
   TOTAL_SUPPLY = contract.functions.totalSupply().call()
   logging.info(f"Token cargado. Decimals: {TOKEN_DECIMALS} | Total Supply: {TOTAL_SUPPLY / (10 ** TOKEN_DECIMALS):,.0f}")
except Exception as e:
   logging.warning(f"No se pudieron obtener los parámetros del token, se aplican valores por defecto: {e}")
   TOKEN_DECIMALS = 18
   TOTAL_SUPPLY = 1000000000 * (10 ** 18) # 1B por defecto

# Umbral de anomalía: 100,000 tokens
VOTE_THRESHOLD = 100000 * (10 ** TOKEN_DECIMALS)

def get_logs_batched(event_obj, from_block, to_block):
   """Lectura segura de logs por batches. Retorna (logs, is_success)."""
   all_events = []
   for start in range(from_block, to_block + 1, BATCH_STEP):
       end = min(start + BATCH_STEP - 1, to_block)
       try:
           logs = event_obj.get_logs(fromBlock=start, toBlock=end)
           all_events.extend(logs)
       except Exception as e:
           logging.error(f"Fallo al obtener logs en los bloques {start}-{end}: {e}")
           return [], False
   return all_events, True

def analyze_governance_shifts(from_block, to_block):
   """Análisis del movimiento de votos con cálculo de proporción respecto al Total Supply."""
   vote_changes, ok1 = get_logs_batched(contract.events.DelegateVotesChanged, from_block, to_block)
   delegations, ok2 = get_logs_batched(contract.events.DelegateChanged, from_block, to_block)
   if not (ok1 and ok2):
       return False  # Fallo en la lectura, ¡NO avanzamos el bloque!
   
   # Agrupación de múltiples eventos DelegateChanged dentro de la misma transacción
   delegation_map = defaultdict(list)
   for d in delegations:
       tx_hash = d.transactionHash.hex()
       delegation_map[tx_hash].append({
           "delegator": d.args.delegator,
           "from": d.args.fromDelegate,
           "to": d.args.toDelegate
       })

   for event in vote_changes:
       prev_bal = event.args.previousBalance
       new_bal = event.args.newBalance
       delta = new_bal - prev_bal
       
       if abs(delta) >= VOTE_THRESHOLD:
           tx_hash = event.transactionHash.hex()
           delegate = event.args.delegate
           
           # Cálculo de métricas respecto al Total Supply
           fmt_delta = delta / (10 ** TOKEN_DECIMALS)
           fmt_new = new_bal / (10 ** TOKEN_DECIMALS)
           share_of_supply = (new_bal / TOTAL_SUPPLY) * 100
           delta_share_of_supply = (abs(delta) / TOTAL_SUPPLY) * 100
           
           # Nivel de severidad
           severity = "PICO CRÍTICO" if share_of_supply >= 1.0 else "ADVERTENCIA"
           logging.warning(f"[{severity}] Cambio en Voting Power: {fmt_delta:+,.0f} tokens ({delta_share_of_supply:.3f}% de la emisión)")
           logging.info(f"    Delegado: {delegate}")
           logging.info(f"    Impacto total de la dirección: {fmt_new:,.0f} votos ({share_of_supply:.3f}% del Total Supply)")
           logging.info(f"    Tx Hash: {tx_hash}")
           
           contexts = delegation_map.get(tx_hash, [])
           if contexts:
               logging.info(f"    Causa: CAMBIO DIRECTO DE DELEGADO ({len(contexts)} eventos en Tx)")
               for ctx in contexts:
                   logging.info(f"      • Delegador: {ctx['delegator']} | {ctx['from']} -> {ctx['to']}")
           else:
               logging.info("    Causa: Cambio de balance en delegado existente (Transfer / Claim / Mint / Burn)")
           
           print("-" * 75)
   return True

def start_realtime_monitoring(poll_interval=12):
   """Daemon en tiempo real manteniendo profundidad de confirmaciones."""
   latest_block = w3.eth.block_number
   last_processed_block = latest_block - SAFE_CONFIRMATIONS - 1
   logging.info(f"Iniciando daemon. Bloque inicial seguro: #{last_processed_block} (Confirmaciones = {SAFE_CONFIRMATIONS})")
   
   while True:
       try:
           current_block = w3.eth.block_number
           safe_block = current_block - SAFE_CONFIRMATIONS
           if safe_block > last_processed_block:
               success = analyze_governance_shifts(last_processed_block + 1, safe_block)
               if success:
                   last_processed_block = safe_block
               else:
                   logging.warning("El rango no se procesó por completo debido a un fallo de RPC. Reintentando en el siguiente ciclo.")
       except Exception as e:
           logging.error(f"Fallo crítico en el loop principal: {e}")
       time.sleep(poll_interval)

if __name__ == "__main__":
   start_realtime_monitoring(poll_interval=12)

Cómo protegerse de la Shadow Governance

El mercado se está adaptando poco a poco a los ataques contra la gobernanza. Una auditoría superficial del código del contrato inteligente ya no es suficiente; se requiere una arquitectura defensiva en el propio modelo de la DAO.

  • Implementación de Timelocks con función de veto: Los cambios de código no deben ejecutarse de inmediato. Un tiempo de espera mínimo de 48 a 72 horas le permite al Security Council (multisig de seguridad) congelar una propuesta maliciosa.
  • Transición a modelos ve con desbloqueo diferido: Si los tokens permanecen bloqueados sin posibilidad de manipulación rápida, el costo de ejecutar un ataque relámpago en las sombras se multiplica exponencialmente.
  • Gobernanza optimista (Optimistic Governance): Modelo implementado por Moonwell y Lido donde las propuestas se aprueban por defecto, y solo se requiere votación si la comunidad decide vetarlas.
  • Gobernanza de doble token (Dual-Token Governance): Separación de los derechos de voto entre los holders del token de utilidad y los proveedores de liquidez o usuarios del sistema (como lo implementó Lido con Dual Governance, donde los holders de stETH pueden vetar decisiones de los holders de LDO).

La gobernanza en las sombras es la consecuencia natural de convertir el derecho a voto en un activo financiero. La tarea de los analistas e ingenieros blockchain de EXMON es detectar a tiempo estas anomalías tanto en el mempool como a nivel de contratos inteligentes, garantizando la máxima seguridad y transparencia en las operaciones para todos los participantes de nuestro ecosistema.

Resumir esta publicación de blog con:

FAQ

El shadow governance es la acumulación oculta de poder de voto mediante incentivos financieros privados en mercados OTC o dark pools, evitando la compra directa de tokens de gobernanza en el mercado abierto. Los atacantes pagan directamente a grandes tenedores de veTokens o delegados en activos externos para asegurar el cuórum necesario sin generar deslizamiento de precio ni alertar a la comunidad.

La detección se realiza analizando los registros de eventos DelegateChanged y DelegateVotesChanged en los smart contracts para identificar variaciones anómalas en el peso de los votos y rastrear las transacciones hasta la dirección del delegador. Cruzar incrementos repentinos de poder de voto con el uso de paquetes privados de Flashbots y flujos de fondos desde mezcladores permite aislar la acumulación secreta de votos antes de la ejecución de una propuesta.

Los protocolos se protegen aplicando capturas de estado de bloques históricos para calcular el peso del voto, plazos de ejecución obligatorios (timelocks) con veto del consejo de seguridad y umbrales de cuórum dinámicos. La implementación de gobernanza optimista y arquitecturas de validación con doble token neutraliza la manipulación mediante préstamos relámpago en un solo bloque y vuelve económicamente inviable el alquiler de votos a corto plazo.
Astra EXMON

Astra is the official voice of EXMON and the editorial collective dedicated to bringing you the most timely and accurate information from the crypto market. Astra represents the combined expertise of our internal analysts, product managers, and blockchain engineers.

...

Escribe una opinión

Tu correo electrónico no será publicado. Los campos obligatorios están marcados *