ERC-1167: Minimal Proxy


Cuando trabajamos con smart contracts, siempre se intenta reducir coste de gas y ser lo más eficiente posible. Por eso el ERC-1167 puede ser un gran aliado, más conocido como Minimal Proxy Contract o simplemente Clon.

Este estándar nos permite de forma sencilla y súper eficiente de desplegar contratos que comparten la misma lógica, haciendo que todo sea más rápido y, sobre todo, más barato.


¿Qué es ERC-1167?

El ERC-1167 es un estándar de Solidity que define un contrato proxy lo más simple posible.

Este proxy apunta a una única implementación de lógica (llamada contrato maestro) y delega todas las llamadas a él.

Este enfoque permite crear clones de un contrato sin necesidad de desplegar su código completo cada vez.

¿Cómo funciona?

El Minimal Proxy redirige todas las llamadas al contrato maestro con un conjunto mínimo de instrucciones, optimizando al máximo los costos de gas.

En la práctica, esto significa que cuando un usuario interactúa con el proxy, este delega la ejecución al contrato maestro. Aunque utiliza el código del contrato maestro para ejecutar la lógica, el proxy conserva su propio almacenamiento, manteniendo así su independencia en términos de datos.

El bytecode del proxy se reduce a algo tan simple como:

3d602d80600a3d3981f3363d3d373d3d3d363d73[MASTER_ADDRESS]5af43d82803e903d91602b57fd5bf3
<----INIT CODE----><---COPY CALLDATA--->                <------DELEGATE CALLDATA----->

El MASTER_ADDRESS se reemplaza con la dirección del contrato maestro.

Ventajas

  • Ahorro de gas: Solo se despliega una versión completa del contrato maestro, mientras que los proxies son instancias ligeras que delegan las llamadas a este contrato.
  • Eficiencia: Los clones se despliegan rápidamente debido a su bytecode reducido.
  • Lógica centralizada: Las actualizaciones se realizan en el contrato maestro. Los proxies existentes no se actualizan, pero los nuevos proxies que se despliegan después de una actualización usarán automáticamente la nueva versión del contrato maestro.
  • Escalabilidad: Permite crear muchas instancias del contrato a un costo y tiempo mucho menores, ideal para aplicaciones que requieren múltiples copias de un mismo contrato

Ejemplo en Solidity

Aquí tienes un ejemplo de cómo implementar un clon con ERC-1167:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Master {
    uint256 public value;

    function setValue(uint256 _value) public {
        value = _value;
    }
}

contract CloneFactory {
    function createClone(address master) external returns (address) {
        bytes20 targetBytes = bytes20(master);
        address clone;
        assembly {
            let code := mload(0x40)
            mstore(code, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(code, 0x14), targetBytes)
            mstore(add(code, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            clone := create(0, code, 0x37)
        }
        require(clone != address(0), "ERC1167: create failed");
        return clone;
    }
}

En este ejemplo:

  • Master es el contrato maestro que contiene la lógica.
  • CloneFactory permite desplegar Minimal proxies apuntando al maestro.

Para inicializar correctamente los clones, considera agregar una función de inicialización en el contrato maestro y asegurarte de llamarla después de desplegar cada clon.

Casos de uso

  • Tokens repetitivos: Ideal para proyectos que necesitan desplegar tokens con la misma lógica pero con configuraciones específicas.
  • Factory patterns: Permite a los desarrolladores desplegar contratos rápidamente desde una única fuente.
  • Proyectos DeFi: Clonación eficiente para estrategias de rendimiento o vaults.
  • NFTs: Creación de contratos repetitivos para colecciones personalizables.

Limitaciones y Consideraciones

  • Dependencia centralizada: Si el contrato maestro tiene un fallo, todos los clones se verán afectados sin posibilidad de actualizar los proxies ya desplegados.
  • Complejidad de depuración: Dado que los proxies delegan llamadas, puede ser más difícil rastrear errores durante la ejecución.
  • Restricciones en inicialización: Asegúrate de configurar correctamente los valores iniciales para cada proxy para evitar problemas en la ejecución.
  • Consistencia: Es esencial garantizar que los datos específicos de cada clon no interfieran con otros clones.

Consejos adicionales y optimizaciones

  • Seguridad: Asegúrate de auditar la implementación del contrato maestro, ya que cualquier vulnerabilidad en este afectará a todos los clones desplegados.
  • Customización: Considera permitir parámetros iniciales para cada clon mediante una función de inicialización.
  • Gas: Usa herramientas como eth-gas-reporter para medir el ahorro real de gas al usar proxies minimalistas.
  • Actualizaciones: Implementa medidas para facilitar migraciones futuras si necesitas reemplazar el contrato maestro.

No confundir Minimal Proxy con Beacon Proxy

Aunque el Minimal Proxy (ERC-1167) y el Beacon Proxy comparten la idea de optimizar recursos al reutilizar lógica compartida, no deben confundirse, ya que funcionan de maneras muy diferentes. Ambos permiten desplegar contratos inteligentes de forma más eficiente, pero el Minimal Proxy es extremadamente simple y directo: cada clon delega las llamadas a un contrato de implementación fijo.

En cambio, el Beacon Proxy introduce una capa adicional mediante un contrato Beacon, que actúa como intermediario para gestionar actualizaciones de lógica de forma centralizada.

La confusión puede surgir porque ambos evitan duplicar lógica en cada despliegue. Sin embargo, la clave está en la flexibilidad: el Minimal Proxy es inmutable respecto a la lógica que sigue, mientras que el Beacon Proxy permite cambiarla sin redeployar los contratos. Este matiz es fundamental para elegir la solución correcta según las necesidades del proyecto.

Conclusión

ERC-1167 ofrece una solución eficiente cuando buscques optimizar tus contratos. Su enfoque minimalista permite desplegar contratos de manera rápida y económica, con un ahorro significativo de gas. Al centralizar la lógica en un único contrato maestro, facilita la gestión y escalabilidad sin complicaciones. Aunque no permite actualizaciones directas a los proxies existentes, su simplicidad y capacidad para crear múltiples instancias lo convierten en un patrón muy interesante cuando se busca eficiencia y agilidad.

Si tu objetivo es minimizar el gas y escalar tu aplicación, los clones minimalistas podrían ser una opción sólida.