CoinEx Research: Introducción a las vulnerabilidades más comunes y ataques en smart-contracts

CoinEx en Español
18 min readDec 10, 2023

--

¿Qué es un smart-contract?

Ethereum tiene dos tipos comunes de cuentas: Cuentas de Propiedad Externa (EOA) y Cuentas de Contratos Inteligentes (SCA).

Las EOA son muy similares a las cuentas financieras electrónicas que comúnmente usamos para almacenar fondos e interactuar con aplicaciones. Por ejemplo, los usuarios depositan moneda fiduciaria a través de PayPal e interactúan con varios sitios web, tiendas y aplicaciones para realizar pagos. Los mineros de DeFi suelen almacenar criptomonedas en sus EOA, interactúan con aplicaciones descentralizadas de DeFi y depositan fondos en ellas para obtener beneficios. Sin embargo, las EOA tienen una característica que las cuentas financieras electrónicas no poseen: los usuarios deben verificar su control sobre la EOA mediante la propiedad de claves privadas; no tus claves, no tus monedas.

Las SCA son también un tipo de cuenta que está asociada esencialmente con un segmento de bytecode ejecutable (también conocido como un contrato inteligente). El contrato inteligente describe varias lógicas comerciales y sirve como el backend para aplicaciones descentralizadas. Sin embargo, a pesar de tener más restricciones en comparación con los lenguajes de desarrollo Turing completos tradicionales, los contratos inteligentes cuasi-Turing completos aún han sido vulnerables a numerosos ataques, infligiendo numerosos golpes a la industria blockchain.

Ataques más comunes a Smart-contracts

Ataque de reentrada

El ataque más común y notorio es el ataque de reentrada, que fue responsable de la bifurcación de Ethereum que llevó a la creación de Ethereum Classic. En 2016, los piratas informáticos ejecutaron un ataque de reentrada en el contrato de The DAO, robando 3,600,000 ETH valorados en más de $150 millones en ese momento. Este ataque, que ocurrió durante las primeras etapas de Ethereum, devastó el ecosistema y quebrantó la confianza de los inversores, llevando finalmente a una bifurcación.

Lógica específica

Aquí hay un ejemplo para ayudarte a comprender mejor el principio del ataque de reentrada. El Bank B prestó dinero anteriormente al Bank A. Un día, el Bank B inicia una transferencia a Bank A, solicitando la transferencia de todo el dinero de vuelta al Bank B. El camino normal es el siguiente:

Paso 1: Bank B solicita el retiro de fondos.

Paso 2: Bank A transfiere los fondos a Bank B.

Paso 3: Bank A confirma la transferencia exitosa a Bank B.

Paso 4: Bank A actualiza el saldo de la cuenta de Bank B.

Sin embargo, si el Bank B crea un vacío después del Paso 2 y continúa solicitando todo el dinero de Bank A sin confirmación en el Paso 3, entonces el saldo de la cuenta de Bank A en Bank B permanecerá sin cambios. Esta llamada recursiva vaciará todos los activos de Bank A.

Smart-contracts relacionados

El contrato de Bank A incluye dos funciones:

  • depositar(): Una función de depósito que ingresa dinero en Bank A y actualiza el saldo del usuario;
  • retirar(): Una función de retiro que permite a los usuarios retirar todos sus fondos de Bank A.

El contrato de ataque de Bank B principalmente involucra un bucle que activa la función de devolución de llamada receive(), la cual a su vez llama a la función withdraw() del contrato de Bank para drenar los activos de Bank A a través de una secuencia de 1 depósito, 1 retiro y llamadas de funciones de devolución de llamada receive(), y finalmente actualiza el saldo de B en A. Incluye dos funciones:

  • receive(): Una función de devolución de llamada que se activa cuando se recibe ETH, la cual llama de manera recursiva a la función withdraw() del contrato de Bank para realizar retiros.
  • attack(): Primero llama a la función deposit() del contrato de Bank para actualizar el saldo y luego a la función withdraw() para iniciar el primer retiro, y activa la función de devolución de llamada receive() para llamar de manera recursiva a withdraw() y drenar los activos del contrato de Bank.

Solución

Implementación de un bloqueo de reentrada

Un bloqueo de reentrada es un modificador utilizado para prevenir la reentrada, asegurando que una llamada debe completar su ejecución antes de que pueda ser invocada nuevamente. Por ejemplo, dado que el ataque realizado por Bank B requiere llamar a la función withdraw() del contrato de Bank varias veces, fallará con la implementación de un bloqueo de reentrada.

Como usarlo

2. Uso indebido de tx.origin

La función principal de tx.origin en un contrato inteligente es recuperar la cuenta original que inició la transacción. Aquí, discutiremos dos variables comunes en contratos inteligentes: msg.sender y tx.origin. msg.sender recupera la cuenta que llama directamente al contrato inteligente, mientras que en el mundo de la cadena de bloques, debido a las llamadas anidadas y mutuas de diferentes contratos inteligentes (como DeFi Lego), se necesita tx.origin para obtener la cuenta original que inició la transacción. Surge una vulnerabilidad cuando los desarrolladores de dApp solo verifican la seguridad de tx.origin en el código, descuidando la verificación de seguridad de los atacantes que implementan contratos intermedios para eludir tx.origin y lanzar ataques.

Lógica específica

Aquí tienes un ejemplo para sumergirte en el escenario común de ataque. Bill tiene una billetera inteligente que verifica si Bill es el iniciador de una transferencia. Una vez, Bill creó un NFT en un sitio web de phishing. Esto permitió al sitio web obtener la identidad de Bill e iniciar una transferencia desde su billetera inteligente utilizando su identidad, lo que resultó en pérdidas de activos. En circunstancias normales, los usuarios son menos propensos a caer en esta trampa, pero al interactuar con dApps utilizando una billetera, a menudo olvidan verificar las indicaciones de interacción. Por ejemplo, si ambos involucran la función Mint(), los usuarios descuidados pueden caer fácilmente en una trampa de phishing. La lógica comercial dentro del sitio web de phishing está llena de trampas, por lo que es importante verificar las indicaciones de interacción en busca de errores durante las interacciones regulares.

Contrato de billetera inteligente

El contrato de billetera inteligente incluye una función:

  • transfer(): Una función de retiro que solo puede ser iniciada por el propietario de la billetera, que en este caso es Bill.

Contrato de ataque de phishing

En un contrato de ataque de phishing, Mint() induce a los usuarios a transferir fondos a la dirección de un hacker. Incluye una función:

  • Mint(): Una vez llamada, la función de phishing ejecuta internamente transfer() del contrato de la billetera. Dado que el iniciador original es el usuario (en este ejemplo, Bill) mismo, la verificación require(tx.origin == owner, “Not owner”); no será un problema. Sin embargo, la dirección de destino para la transferencia ya ha sido manipulada a la dirección del hacker, lo que resulta en el robo de fondos.

Soluciones

Usar msg.sender en lugar de tx.origin

No importa cuántas llamadas a contratos estén involucradas (Contrato A → Contrato B →…→ contrato objetivo), solo verifica msg.sender, es decir, el llamante directo, para evitar ataques causados por contratos intermedios maliciosos.

2. Verificar tx.origin == msg.sender

Este método puede mantener alejados a los contratos maliciosos, pero los desarrolladores deben considerar sus propias realidades comerciales, ya que efectivamente aísla todas las demás llamadas de contratos externos.

3. Ataque al generador de números aleatorios (RNG)

Esto se remonta a la tendencia de aplicaciones descentralizadas de apuestas o juegos de azar alrededor de 2018 y 2019. Típicamente, los desarrolladores utilizan ciertas semillas en contratos inteligentes para generar números aleatorios y seleccionar ganadores durante los sorteos. Las semillas comunes incluyen block.number, block.timestamp, blockhash y keccak256. Sin embargo, los mineros pueden controlar completamente estas semillas, por lo que, en algunos casos, mineros maliciosos pueden manipular las variables para obtener beneficios.

Contratos comunes de dados

El contrato de dados incluye una función:

  • Stake(): Una función de apuestas donde los usuarios ingresan un número de apuesta y pagan con ETH. Se genera un número aleatorio con varias semillas y, si el número de apuesta coincide con el número aleatorio, el usuario gana todo el fondo de premios.

Contrato de ataque del Minero

Los mineros pueden ganar siempre y cuando precalculen el número aleatorio ganador y lo ejecuten en el mismo bloque. Esto incluye una función:

  • attack(): Una función de ataque de apuestas, donde el minero precalcula el número aleatorio ganador. Dado que se ejecuta en el mismo bloque, blockhash(block.number — 1) y block.timestamp en el mismo bloque son iguales. Luego, el minero llama a Bet() del contrato de Dados para completar el ataque.

Solución

Utilizar números aleatorios fuera de la cadena, proporcionados por proyectos oráculo.

A través de servicios proporcionados por proyectos oráculo como Chainlink, se introducen números aleatorios en contratos dentro de la cadena para garantizar la aleatoriedad y la seguridad. Sin embargo, los proyectos oráculo también conllevan riesgos de centralización, lo que hace necesario contar con servicios oráculo más maduros.

4. Ataque de repetición

Un ataque de repetición implica reiniciar una transacción utilizando una firma previamente utilizada para robar fondos. Uno de los ataques de repetición más conocidos en los últimos años fue el robo de 20 millones de tokens $OP al creador de mercado Wintermute en Optimism, que fue un ataque de repetición entre cadenas. Dado que la cuenta de billetera multi-firma de Wintermute se implementó temporalmente solo en la red principal de Ethereum, el hacker utilizó la firma de la transacción de la implementación de Wintermute de una dirección multi-firma en Ethereum para volver a ejecutar la misma transacción en la cadena de Optimism, ganando así control sobre la cuenta de billetera multi-firma en Optimism. Una cuenta de billetera multi-firma es esencialmente una cuenta de contrato inteligente, lo que también demuestra una diferencia significativa entre SCA y EOA. Para un EOA, un usuario normal solo necesita una clave privada para controlar todas las direcciones en Ethereum y cadenas compatibles con EVM (las cadenas de direcciones son exactamente iguales), mientras que un SCA es efectivo solo en una cadena después de ser implementado.

Lógica específica

Aquí proporcionamos un ejemplo de un típico ataque de repetición (ataque de repetición en la misma cadena). Bill tiene una billetera inteligente que requiere que ingrese su firma electrónica antes de que se pueda ejecutar cada transacción. Ahora que la hacker Lucy ha robado la firma electrónica de Bill, puede iniciar un número ilimitado de transacciones para vaciar la billetera inteligente de Bill.

Ejemplo

Un contrato con vulnerabilidades consta de tres funciones:

  • checkSig(): Función de verificación ECDSA, asegurando que el resultado de la verificación sea el firmante originalmente establecido.
  • getMsgHash(): Función para generar un hash, que combina el destinatario y la cantidad para formar el hash.
  • transfer(): Función de transferencia, que permite a los usuarios retirar fondos del fondo de liquidez. Debido a la falta de restricciones en la firma, la misma firma se puede reutilizar, lo que permite a los hackers robar continuamente fondos.

Solución

Incluya el nonce en la combinación de la firma para evitar ataques de reproducción. El principio del parámetro es el siguiente:

  • nonce: Describe la variable del número de transacciones de una cuenta externa autónoma (EOA, por sus siglas en inglés) en la red de blockchain. Tiene orden y singularidad. Con cada transacción adicional, el valor de nonce aumentará en 1. La red de blockchain verificará si el nonce de la transacción es consistente con el nonce actual de la cuenta. Por lo tanto, un hacker fallaría si utiliza una firma ya utilizada porque el valor de nonce en la combinación de la firma es menor que el valor de nonce actual de la EOA.

5. Ataque de denegación de servicio (DoS)

El ataque de Denegación de Servicio (DoS) no es nada nuevo en el mundo tradicional de la Web2. Se refiere a cualquier interferencia con un servidor, como enviar una gran cantidad de información basura o disruptiva, obstaculizando o destruyendo completamente la disponibilidad. De manera similar, los contratos inteligentes también sufren este tipo de ataques, que básicamente tienen como objetivo hacer que el contrato inteligente funcione de manera incorrecta.

Lógica específica

Veamos un ejemplo. El Proyecto A está llevando a cabo una oferta pública para el token de protocolo, donde todos los usuarios pueden contribuir fondos al grupo de liquidez (contrato inteligente) para comprar cuotas en orden de llegada, y los fondos excedentes se devolverán a los participantes. La hacker Alice aprovecha el contrato de ataque para participar en la oferta pública. Una vez que el grupo de liquidez intenta devolver fondos al contrato de ataque de Alice, se desencadenará un ataque DoS, impidiendo que la acción de devolución se lleve a cabo. Como resultado, una gran cantidad de fondos quedan bloqueados en el contrato inteligente.

Ejemplo

El contrato de oferta pública incluye dos funciones:

  • deposit(): función de depósito, que registra la dirección del depositante y la cantidad aportada.
  • refund(): función de reembolso, mediante la cual el equipo del proyecto devuelve fondos a los inversores.

Contrato de ataque DoS

El contrato de ataque DoS incluye una función:

  • attack(): A pesar de ser una función de ataque, no presenta problemas. El problema principal radica en la función de retorno de pago receive() incorporada en el contrato del Hacker, que incluye una evaluación de excepciones. Cualquier contrato externo que transfiera fondos al contrato del Hacker provocará una excepción a través de revert(), evitando así que la operación se complete.

Soluciones

1. Evitar que la funcionalidad crítica quede bloqueada al invocar contratos externos

  • Delete require(success, “Refund Fail!”); de la función refund() del contrato PublicSale mencionado anteriormente, asegurando que la operación de reembolso pueda continuar incluso si falla un reembolso a una dirección única.

2. Desacoplamiento

En la función refund() del contrato PublicSale mencionado anteriormente, permitir a los usuarios reclamar reembolsos por sí mismos en lugar de distribuir los reembolsos, minimizando así las interacciones innecesarias con contratos externos.

3. Ataque con permiso

En un ataque con permiso, la Cuenta A proporciona la firma para una parte designada de antemano, y luego la Cuenta B, al obtener la firma, puede llevar a cabo transferencias de tokens autorizadas para robar una cierta cantidad de tokens. Aquí, discutimos principalmente dos funciones comunes para la autorización de tokens en contratos inteligentes: approve() y permit().

En el contrato ERC20 común, la Cuenta A puede llamar a approve() para autorizar una cierta cantidad de tokens para la Cuenta B, permitiéndole a esta última transferir esos tokens desde la primera. Además, permit() se introdujo en los contratos ERC20 en la Propuesta de Mejora de Ethereum (EIP) 2612, y Uniswap ha lanzado un nuevo estándar de autorización de tokens, Permit2, en noviembre de 2022.

Lógica específica

Aquí hay un ejemplo. Un día, Bill estaba navegando por un sitio web de noticias de blockchain cuando de repente apareció una ventana emergente de firma de Metamask. Dado que muchos sitios web o aplicaciones de blockchain utilizan firmas para verificar el inicio de sesión del usuario, Bill no le dio mucha importancia y completó la firma directamente. Cinco minutos después, sus activos de Metamask se agotaron. Bill luego descubrió en el explorador de bloques que una dirección desconocida inició una transacción permit(), seguida de una transacción transferFrom() que vació su billetera.

Ejemplo

Las dos funciones son las siguientes:

  • approve(): Una función de autorización estándar donde la Cuenta A autoriza una cierta cantidad de fondos a la Cuenta B.
  • permit(): Una función de autorización de firma donde la Cuenta B envía y completa la verificación de la firma para obtener la cantidad autorizada de la Cuenta A. Los parámetros incluyen el propietario que otorga la autorización, el gastador autorizado, la cantidad autorizada, la fecha límite de la firma y los datos de firma v, r y s del propietario.

Soluciones

  • 1. Prestar atención a cada firma en las interacciones dentro de la cadena

A pesar de las medidas que algunas billeteras toman para descodificar y mostrar información de firma de autorización de approve(), proporcionan casi ninguna advertencia para el phishing de firma de permit(), aumentando el riesgo de ataques. Por lo tanto, se recomienda encarecidamente inspeccionar rigurosamente cada firma desconocida para asegurarse de si está dirigida a la función permit().

  • 2. Separar la billetera para interacciones regulares de la billetera que almacena activos

Esto es extremadamente importante para los usuarios de criptomonedas, especialmente los cazadores de airdrops, ya que interactúan con innumerables dApps o sitios web todos los días y son propensos a trampas. Almacenar solo una pequeña cantidad de fondos en una billetera para interacciones regulares puede mantener las pérdidas dentro de un rango manejable.

3. Ataque de trampa (Honeypot)

En la industria blockchain, un ataque de trampa se refiere a un tipo de contratos de tokens maliciosos desplegados por equipos de proyectos. El contrato solo otorga al equipo del proyecto el permiso para vender, mientras que los usuarios regulares solo pueden comprar en lugar de vender, sufriendo así pérdidas.

Lógica específica

Aquí hay un ejemplo. En un anuncio en Telegram, el Proyecto A informa a los usuarios que el token ha sido desplegado en la red principal y está disponible para negociar. Dado que el token solo puede ser comprado y no vendido, el precio aumenta al principio y los usuarios que temen perderse siguen comprando. Después de un tiempo, cuando los usuarios descubren que no pueden vender, el equipo del proyecto aprovecha la oportunidad y descarga los tokens, haciendo que el precio se desplome.

Ejemplo

Función principal:

  • _beforeTokenTransfer(): Una función interna llamada durante las transferencias de tokens, que solo puede tener éxito cuando la llama el propietario; las llamadas desde otras cuentas fallarán.

Solución

Utilizar herramientas de escaneo de seguridad

  • a. Token Sniffer para tokens de Ethereum
  • b. Ave Check para tokens en otras cadenas
  • c. Sitios web de mercado con herramientas de detección incorporadas como Dextools

Evitar negociar tokens con puntajes bajos.

8. Ataque de Front-Running

El front-running surgió originalmente en los mercados financieros tradicionales, donde la asimetría de la información permitía a los intermediarios financieros obtener ganancias al tomar acciones rápidas basadas en información específica de la industria. En la industria blockchain, el front-running se deriva principalmente del front-running en cadena, que implica manipular a los mineros para que prioricen la inclusión de las propias transacciones en la cadena para obtener ganancias.

En el campo blockchain, los mineros pueden obtener ganancias manipulando las transacciones que incluyen en los bloques, excluyendo ciertas transacciones y reordenando otras. Dichas ganancias se pueden medir con el Valor Extraíble por el Minero (MEV, por sus siglas en inglés). Antes de que la transacción de un usuario se agregue a la red principal de Ethereum, la mayoría de las transacciones se agrupan en el mempool. Los mineros buscan transacciones con precios de gas más altos en este mempool y las priorizan para maximizar sus ganancias. Por lo general, las transacciones con precios de gas más altos son más fáciles de incluir para los mineros. Mientras tanto, algunos bots de MEV también escudriñan el mempool en busca de transacciones con rentabilidad.

Lógica específica

A continuación se presenta un ejemplo. Bill descubre un nuevo token popular con fluctuaciones significativas en el precio. Para asegurar el éxito de las transacciones de tokens en Uniswap, Bill establece un rango de deslizamiento excepcionalmente amplio. Desafortunadamente, el bot de MEV de Alice detecta esta transacción en el mempool y aumenta rápidamente la tarifa de gas, iniciando una transacción de compra antes que la de Bill e insertando una transacción de venta después de la de Bill dentro del mismo bloque. Después de la confirmación del bloque, esto provoca pérdidas significativas por deslizamiento para Bill, mientras que Alice obtiene ganancias de una operación de arbitraje comprando bajo y vendiendo alto.

Ejemplo

La función es la siguiente:

  • solve(): Una función de adivinanza donde cualquiera puede enviar una respuesta, y si la respuesta enviada coincide con la respuesta objetivo, el remitente puede recibir 10 ethers.

Proceso:

1. Bill encuentra la respuesta correcta.

2. Alice monitorea el mempool, esperando a que alguien envíe la respuesta correcta.

3. Bill llama a solve() para enviar la respuesta y establece el precio del gas en 100 Gwei.

4. Alice ve la transacción enviada por Bill y descubre la respuesta. Ella establece un precio de gas más alto que los 200 Gwei de Bill y llama a solve().

5. La transacción de Alice es incluida por el minero antes que la de Bill.

6. Alice gana una recompensa de 10 ethers.

Solución

Las tres funciones principales son las siguientes:

1. commitSolution(): Una función para enviar resultados, colocando la respuesta enviada por el usuario solutionHash, el tiempo de envío commitTime y el estado revelado en la estructura Commit.

2. getMySolution(): Una función para obtener resultados, que permite a los usuarios ver sus respuestas enviadas e información relacionada, incluida la respuesta enviada por el usuario solutionHash, el tiempo de envío commitTime y el estado revelado.

3. revealSolution(): Una función para reclamar recompensas por adivinar el acertijo, que permite a los usuarios reclamar recompensas después de proporcionar la respuesta y la contraseña que establecieron.

Proceso:

1. Bill encuentra la respuesta correcta.

2. Bill llama a commitSolution() para enviar la respuesta correcta.

3. En el siguiente bloque, Bill llama a revealSolution(), proporcionando la respuesta y la contraseña que estableció para reclamar la recompensa.

4. En commitSolution(), Bill envía una cadena encriptada, manteniendo los datos en texto plano enviados solo para sí mismo. En este paso, también se registra el tiempo del bloque de envío commitTime. Luego, en revealSolution(), se verifica el tiempo del bloque para evitar el front-running dentro del mismo bloque. Dado que llamar a revealSolution() requiere la presentación de la respuesta en texto plano, este paso tiene como objetivo evitar que otros eludan commitSolution() y llamen directamente a revealSolution(). Después de la verificación exitosa, se distribuirá la recompensa si se confirma que la respuesta es correcta.

Conclusión

Los contratos inteligentes desempeñan un papel crucial en la tecnología blockchain y ofrecen numerosas ventajas. En primer lugar, permiten la ejecución descentralizada y automatizada, garantizando la seguridad y confiabilidad de las transacciones sin necesidad de terceros. En segundo lugar, los contratos inteligentes reducen pasos y costos intermedios, mejorando la eficiencia de las transacciones.

A pesar de tantos beneficios, los contratos inteligentes también enfrentan el riesgo de ataques que generan pérdidas financieras para los usuarios. Como tal, algunos hábitos son esenciales para los usuarios en la cadena. En primer lugar, los usuarios siempre deben elegir cuidadosamente las dApps para interactuar y revisar minuciosamente el código del contrato y las reglas relacionadas. Además, deben actualizar y utilizar regularmente billeteras seguras y herramientas de interacción con contratos para mitigar el riesgo de ataques de hackers. Además, es aconsejable almacenar sus fondos en múltiples direcciones para minimizar posibles pérdidas por ataques a contratos.

Para los actores de la industria, garantizar la seguridad y estabilidad de los contratos inteligentes es de igual importancia. La primera prioridad debería ser fortalecer la auditoría de contratos inteligentes para identificar y corregir posibles vulnerabilidades y riesgos de seguridad. En segundo lugar, los actores de la industria deben estar informados sobre los últimos avances en blockchain relacionados con los ataques a contratos y tomar medidas de seguridad en consecuencia. Por último, pero no menos importante, también deben mejorar la educación de los usuarios y la conciencia de seguridad en cuanto al uso correcto de los contratos inteligentes.

En conclusión, con esfuerzos concertados tanto de los usuarios como de los actores de la industria, los riesgos de seguridad planteados por los contratos inteligentes pueden mitigarse significativamente. Los usuarios siempre deben seleccionar cuidadosamente los contratos y proteger sus activos personales, mientras que los actores de la industria deben intensificar la auditoría de contratos, mantenerse al tanto de los avances tecnológicos y mejorar la educación de los usuarios y la conciencia de seguridad. Juntos, impulsaremos el desarrollo seguro y confiable de los contratos inteligentes.

Referencias

  • Solidity by Example
  • Blockchain Know-how of SlowMist

https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU4ODQ3NTM2OA==&action=getalbum&album_id=1378673890158936067&scene=173&from_msgid=2247498135&from_itemidx=1&count=3&nolastread=1#wechat_redirect

  • WTF — Solidity 104 Contract Security
  • Vulnerabilities in DeFi Smart Contracts in 4 Categories with 38 Scenarios
  • OpenZeppelin

Acerca de CoinEx

Haciendo más fácil el trading de criptomonedas.

Fundada en 2017, CoinEx es una plataforma global de intercambio de criptomonedas comprometida a simplificar el trading. La plataforma ofrece una variedad de servicios, incluyendo trading spot y de margen, futuros, swaps, creador de mercado automatizado (AMM) y servicios de gestión financiera para más de 5 millones de usuarios en más de 200 países y regiones. Fundada con la intención inicial de crear un entorno de criptomonedas igualitario y respetuoso, CoinEx se dedica a derribar las barreras de las finanzas tradicionales, ofreciendo productos y servicios fáciles de usar para que el trading de criptomonedas sea accesible para todos.

Llega a CoinEx a través de:
Sitio web | Registro | Discord | Facebook | Instagram | Publish0x | Telegram | Telegram Noticias | Twitter | YouTube
API | Descarga la APP

El Grupo ViaBTC es

CoinEx Charity: Fondo de caridad basado en la blockchain.
CoinEx Exchange: Intercambio de criptomonedas y sus derivados.
CoinEx Smart Chain: Sistema descentralizado de cadena pública.
OneSwap: Intercambio descentralizado.
ViaBTC Capital: Plataforma de inversión que integra capital.
ViaBTC Pool: Pool de minería de múltiples criptomonedas.
ViaWallet: Billetera móvil de múltiples criptomonedas.

ViaBTC: haciendo del mundo un lugar mejor.

--

--

CoinEx en Español
CoinEx en Español

Written by CoinEx en Español

CoinEx.com es un proveedor global y profesional de servicios de intercambio de monedas digitales. CoinEx, hace más fácil el trading de criptomonedas.

No responses yet