SafeMath: Evita errores matemáticos


Al desarrollar smart contracts, uno de los temas más recurrentes es la necesidad de manejar adecuadamente las operaciones matemáticas para evitar errores como desbordamientos y subdesbordamientos. Estos errores pueden tener consecuencias desastrosas, especialmente cuando se manejan valores financieros. Aquí es donde entra en juego SafeMath.

¿Qué es SafeMath?

SafeMath es una biblioteca de Solidity diseñada para prevenir errores de desbordamiento (overflow) y subdesbordamiento (underflow) en operaciones aritméticas. En versiones anteriores de Solidity, los desbordamientos eran una preocupación real porque la aritmética en Solidity es modular.

Esto significa que, si sumas dos números y el resultado excede el límite del tipo de datos (por ejemplo, uint256), el valor se “envuelve” y se reinicia desde cero, lo cual puede llevar a comportamientos inesperados o vulnerabilidades de seguridad.

La biblioteca intercepta estas operaciones y arroja un error si se detecta un posible desbordamiento o subdesbordamiento.

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract MyContract {
    using SafeMath for uint256;

    uint256 public totalSupply;

    function addTokens(uint256 amount) public {
        totalSupply = totalSupply.add(amount);
    }
}

En este ejemplo, SafeMath se asegura de que la suma en la línea totalSupply = totalSupply.add(amount); no cause un desbordamiento.

¿Es necesario usar SafeMath en Solidity?

La respuesta a esta pregunta ha cambiado con el tiempo. SafeMath era indispensable en versiones anteriores de Solidity, pero desde la versión 0.8.0, Solidity incorpora protección contra desbordamientos y subdesbordamientos de manera nativa. Esto significa que ahora, si se produce un desbordamiento o subdesbordamiento, el contrato lanzará una excepción automáticamente.

pragma solidity ^0.8.0;

contract MyContract {
 uint256 public totalSupply;

 function addTokens(uint256 amount) public {
  // Lanza un error automáticamente si hay overflow.
  totalSupply += amount; 
 }
}

Dado que las versiones modernas de Solidity ya manejan estos problemas, el uso de SafeMath ha pasado de ser una necesidad a una opción.

Algunos desarrolladores aún lo utilizan por costumbre o por claridad en el código, pero en la mayoría de los casos, ya no es estrictamente necesario.

unchecked para desactivar la verificación

Aunque la verificación de desbordamiento y subdesbordamiento está habilitada por defecto a partir de Solidity 0.8.0, puedes optar por desactivarla en ciertas secciones de tu código utilizando el bloque unchecked. Esto puede ser útil si estás seguro de que una operación no causará un desbordamiento o si deseas optimizar el rendimiento en situaciones específicas donde la verificación es innecesaria.

pragma solidity ^0.8.0;

contract MyContract {
 uint256 public totalSupply;

 function addTokens(uint256 amount) public {
  unchecked {
   totalSupply += amount; // No se realiza la verificación de overflow.
  }
 }
}

En este caso, el bloque unchecked permite realizar la suma sin lanzar errores por posibles desbordamientos, asumiendo que el desarrollador ha validado que no hay riesgo de overflow en esta operación específica.

Conclusión

Si estás trabajando con versiones de Solidity anteriores a la 0.8.0, SafeMath es fundamental para proteger tus contratos de desbordamientos y subdesbordamientos.

Sin embargo, si utilizas una versión más reciente, Solidity ya incluye estas protecciones de manera nativa, lo que hace que SafeMath no sea estrictamente necesario. Aun así, puede ser útil por razones de legibilidad y mantenimiento del código.

Además, puedes utilizar el bloque unchecked si necesitas desactivar temporalmente la verificación para optimizar el rendimiento.

Como siempre, la clave está en comprender las herramientas y utilizar las que mejor se adapten a las necesidades de tu proyecto.