OpenZeppelin: Bloqueo De Tiempo

Al darle la responsabilidad de ejecutar ciertas tareas en un contrato inteligente a un reducido grupo de usuarios, podemos caer en problemas de centralizaci贸n del mismo. Una buena pr谩ctica para remediar esto, es colocando un retraso en la ejecuci贸n de la acci贸n.

Demoras en la ejecuci贸n de una tarea

OpenZeppelin implementa un contrato inteligente llamado TimelockController que permite establecer una demora antes de la ejecuci贸n de una tarea.

Supongamos que en un contrato inteligente que emite tokens, sus administradores deciden aumentar la emisi贸n de los mismos. Esto podr铆a llevar a que el precio de los tokens baje considerablemente. Ser铆a oportuno darles 48 o 72 horas a sus usuarios para que decidan retirar sus fondos o continuar participando del proyecto.

Implementaci贸n de TimelockController

TimelockController, a su vez, hereda del contrato AccessControl para que el mismo sea administrado por diferentes roles de usuarios.

bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");

Es contrato tiene roles variados, desde sus administradores, los usuarios que proponen los cambios, los que ejecutan las tareas y los que cancelan las mismas. Pudiendo ser, una misma cuenta, responsable de todas las operaciones.

Por otro lado, para el despliegue de este contrato se requiere definir tanto el tiempo de espera como los responsables de proponer y ejecutar las tareas.

constructor(
  uint256 minDelay,
  address[] memory proposers,
  address[] memory executors
) {
Adem谩s de disponer de una serie de eventos para notificar a los usuarios de una nueva propuesta o de la pronta ejecuci贸n de una tarea que puede provocar cambios en el contrato.

event CallScheduled(
  bytes32 indexed id,
  uint256 indexed index,
  address target,
  uint256 value,
  bytes data,
  bytes32 predecessor,
  uint256 delay
);
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
event Cancelled(bytes32 indexed id);
event MinDelayChange(uint256 oldDuration, uint256 newDuration);

Consejo Es importante que los usuarios del contrato sepan de cu谩nto tiempo disponen para tomar una decisi贸n. Tal vez no sea aconsejable otorgar escasos minutos. La comunicaci贸n con los mismos enviando notificaciones o en redes sociales es de vital importancia para mantener su confianza.

Es un contrato que puede causar problemas o malos entendidos con la comunidad que participa del proyecto, es crucial la notificaci贸n a los usuarios de cualquier cambio trascendental en el contrato.

Conclusi贸n

Este tipo de contratos pueden caer f谩cilmente en problemas de centralizaci贸n. Su utilizaci贸n est谩 limitada a casos de uso con buenos motivos para ser implementada una funcionalidad como tal.

Es importante conocer conceptualmente todo lo que pude desarrollarse en un contrato inteligente para proponerlo y/o implementarlo llegada la necesidad en un proyecto.


Post creado en colaboraci贸n con el Curso de OpenZeppelin de Platzi.