Esta publicación del blog trata sobre dos errores conectados a matrices de almacenamiento que, de lo contrario, no están relacionados. Ambos han estado presentes en el compilador durante mucho tiempo y solo se han descubierto ahora, aunque es probable que un contrato que los contenga muestre un mal funcionamiento en las pruebas.
Daenam Kim descubrió un problema en el que los datos no válidos se almacenan en conexión con matrices de enteros con signo.
Este error ha estado presente desde Solidity 0.4.7 y lo consideramos el más serio de los dos. Si estas matrices utilizan enteros negativos en una situación determinada, causará daños en los datos y, por lo tanto, el error debería ser fácil de detectar.
A través del programa de recompensas de errores Ethereum, recibimos un informe sobre una falla en el nuevo codificador ABI experimental (denominado ABIEncoderV2). El nuevo codificador ABI todavía está marcado como experimental, pero, sin embargo, creemos que merece un anuncio prominente ya que ya se utiliza en mainnet.
¡Créditos a Ming Chuan Lin (de https://www.secondstate.io) por descubrir y corregir el error!
La versión 0.5.10 contiene las correcciones a los errores.
Por el momento, no planeamos publicar una solución a la serie 0.4.x de Solidity heredada, pero podríamos hacerlo si existe una demanda popular.
Ambos errores deben ser fácilmente visibles en las pruebas que tocan las rutas de código relevantes.
Los detalles sobre los dos errores se pueden encontrar a continuación.
A quien debería preocuparse
Si ha implementado contratos que utilizan matrices de enteros con signo en el almacenamiento y asigne directamente
- una matriz literal con al menos un valor negativo en ella (
x = (-1, -2, -3)
) o - una matriz existente de un diferente tipo entero con signo
para ello, esto conducirá a la corrupción de datos en la matriz de almacenamiento.
Cómo comprobar si el contrato es vulnerable.
Si usa matrices de enteros con signo en el almacenamiento, intente ejecutar pruebas en las que use valores negativos. El efecto debe ser que el valor real almacenado sea positivo en lugar de negativo.
Si tiene un contrato que cumple con estas condiciones y desea verificar si el contrato es realmente vulnerable, puede comunicarse con nosotros a través de (correo electrónico protegido)
Detalles técnicos
Las matrices de almacenamiento se pueden asignar a partir de matrices de diferentes tipos. Durante esta operación de copia y asignación, se realiza una conversión de tipo en cada uno de los elementos. Además de la conversión, especialmente si el tipo de entero con signo es más corto que 256 bits, ciertos bits del valor tienen que ponerse a cero en preparación para almacenar múltiples valores en la misma ranura de almacenamiento.
Los bits a cero se determinaron incorrectamente a partir del origen y no del tipo de destino. Esto lleva a demasiados bits a cero. En particular, el bit de signo será cero, lo que hace que el valor sea positivo.
A quien debería preocuparse
Si ha implementado contratos que utilizan el codificador experimental ABI V2, estos pueden verse afectados. Esto significa que solo los contratos que usan la siguiente directiva dentro del código fuente pueden verse afectados:
pragma experimental ABIEncoderV2;
Además, hay una serie de requisitos para que el error se active. Ver detalles técnicos más abajo para más información.
Cómo comprobar si el contrato es vulnerable.
El error solo se manifiesta cuando se cumplen todas las condiciones siguientes:
- Los datos de almacenamiento que involucran matrices o estructuras se envían directamente a una llamada de función externa, para
abi.encode
o para datos de eventos sin asignación previa a una variable local (memoria) Y - estos datos contienen una matriz de estructuras o una matriz de matrices de tamaño estático (es decir, al menos bidimensional).
Además de eso, en la siguiente situación, su código NO se ve afectado:
- Si solo devuelve dichos datos y no los usa en
abi.encode
, llamadas externas o datos de eventos.
Posibles consecuencias
Naturalmente, cualquier error puede tener consecuencias muy variadas dependiendo del flujo de control del programa, pero esperamos que sea más probable que provoque un mal funcionamiento que la vulnerabilidad.
El error, cuando se desencadena, en ciertas circunstancias enviará parámetros corruptos en invocaciones de métodos a otros contratos.
Detalles técnicos
Durante el proceso de codificación, el codificador ABI experimental no avanza correctamente al siguiente elemento de una matriz en caso de que los elementos ocupen más de una ranura en el almacenamiento.
Este es solo el caso de elementos que son estructuras o matrices de tamaño estático. Las matrices de matrices de tamaño dinámico o de tipos de datos elementales no se ven afectadas.
El efecto específico que verá es que los datos se "desplazan" en la matriz codificada: si tiene una matriz de tipo uint (2) ()
y contiene los datos
((1, 2), (3, 4), (5, 6))
, entonces será codificado como ((1, 2), (2, 3), (3, 4))
porque el codificador solo avanza por una sola ranura entre elementos en lugar de dos.
Este post fue compuesto conjuntamente por @axic, @chriseth, @holiman
Fuente: https://blog.ethereum.org/2019/06/25/solidity-storage-array-bugs/
Descargo de responsabilidad
Toda la información contenida en este sitio web se publica solo con fines de información general y no como un consejo de inversión. Cualquier acción que el lector realice sobre la información que se encuentra en nuestro sitio web es estrictamente bajo su propio riesgo. Nuestra prioridad es brindar información de alta calidad. Nos tomamos nuestro tiempo para identificar, investigar y crear contenido educativo que sea útil para nuestros lectores. Para mantener este estándar y continuar creando contenido de buena calidad. Pero nuestros lectores pueden basarse en su propia investigación.