WEB3DEV Español

Cover image for Token de Reflejo: Cómo funciona y por qué SafeMoon fue exitoso
Hector
Hector

Posted on

Token de Reflejo: Cómo funciona y por qué SafeMoon fue exitoso

Image description

Triángulos Imposibles y Concesiones

Al embarcarnos en un viaje fascinante en el mundo DeFi, usualmente comienza con una inmersión profunda en el whitepaper Bitcoin. Allí es cuando encontré la intriga con el “triángulo imposible”, un concepto que elocuentemente ilustra el balance complejo entre la descentralización, seguridad y escalabilidad.

En esencia, la descentralización representa un principio fundamental del espacio de las cripto, permitiendo a los individuos la libertad para volverse validadores dentro de la red. Sin embargo, cuando consideramos los requisitos fundamentales en una blockchain pública, la seguridad surge como el eje. Es la fundación no negociable en la que todo lo demás descansa, convirtiéndolo en la piedra angular del triángulo imposible.

En contraste, la escalabilidad usualmente toma el asiento trasero en la ecuación, dando paso a los otros dos componentes críticos. Por eso es que te has dado cuenta que las tasas de la transacción en Bitcoin o las tasas de gas en Ethereum sobrepasan aquellos de los métodos tradicionales de pago, a pesar de la velocidad perceptible o la desventaja del ancho de banda.

Aún así, incluso con las restricciones de escalabilidad han surgido soluciones ingeniosas. Permiten transacciones complejas de los token con la mayor eficiencia, mientras mantienen diseños elegantes para los contratos inteligentes. Una creación particularmente cautivadora que emerge luego del Verano de fervor post DeFi, es la introducción en los tokens de reflejo: un acercamiento único y creativo para apoyar las tokenomics para asegurar el éxito continuo de las DeFi.

Image description

¿Qué son los tokens de reflejo?

Imagina que cada vez que un titular de un token hace una transferencia o un intercambio, un pequeño porcentaje de ese token es deducido desde su balance. Lo que pasa después es donde la magia sucede: una porción de este token regresa a la piscina de liquidez, mientras que el resto es distribuído junto a los demás titulares. El cálculo subyacente y la lógica del código puede que parezca sencillo en el mundo de las finanzas tradicionales. Sin embargo, en el reino de las criptomonedas, introducir una tarifa en cada transferencia, combinado con recalcular el balance con cada dirección envuelta puede resultar en grandes consumos de gas.

Aquí entra el concepto ingenioso de los tokens de reflejo: una innovación de código abierto, promovida por el renombrado proyecto SafeMoon. No sólo provee conocimientos valiosos sino también sirve como una fuente de inspiración para mejorar la eficiencia de gas y simplificar el proceso entero a la mayor simplicidad.

Explicación del Código

Variables de la Administración de Cuenta

En primer lugar, dos variables son las más importantes para, respectivamente, guardar el balance de la cuenta del token de reflejo y el saldo de la cuenta del token original. Bien sea que una cuenta o no pueda recibir las recompensas, también está destrozado por las variables entre ellos.

mapping(address => uint256) private _rOwned; // tokens reflejados poseídos
 mapping(address => uint256) private _tOwned; // token poseído

 mapping(address => mapping(address => uint256)) private _allowances;

 mapping(address => bool) private _isExcludedFromFee; // Cuenta que paga o no paga la tasa de la transacción

 mapping(address => bool) private _isExcluded; // Las cuentas que recibirán recompensas o no (si es verdadero: (la cuenta se excluye de recibir la recompensa), si es falsa: la cuenta no se excluye: por lo tanto, puede recibir recompensas)

 address[] private _excluded; // Las cuentas que no reciben recompensas
Enter fullscreen mode Exit fullscreen mode

Variables Aritméticas

La única cosa que vale mencionar para las variables de abajo es que la cantidad de los tokens de reflejo es exactamente ciertos tiempos de cantidad del token original.

uint256 private constant MAX = ~uint256(0); // 2^256 -1 = 1.15792089237316195423570985008687907853269984665640564039457584007913129639935×10⁷⁷
 uint256 private _tTotal = 1000000000 * 10**6 * 10**9; // 10^9 * 10^6 * 10^9 = 10^24 = One Septillion
 uint256 private _rTotal = (MAX - (MAX % _tTotal)); // 1.15792089237316195423570985008687907853269984665640564×10^77

 /// @notice Todas las tarifas coleccionadas a través de las transferencias
 uint256 private _tFeeTotal;

 string private _name = "Reflecive Token";
 string private _symbol = "RFT";
 uint8 private _decimals = 9;

 uint256 public _taxFee = 5;
 uint256 private _previousTaxFee = _taxFee;

 uint256 public _liquidityFee = 5;
 uint256 private _previousLiquidityFee = _liquidityFee;

 IUniswapV2Router02 public immutable uniswapV2Router;
 address public immutable uniswapV2Pair;

 bool inSwapAndLiquify;
 bool public swapAndLiquifyEnabled = true;

 uint256 public _maxTxAmount = 5000000 * 10**6 * 10**9; // 50^21
 uint256 private numTokensSellToAddToLiquidity = 500000 * 10**6 * 10**9; // 50^20
Enter fullscreen mode Exit fullscreen mode

Balance del Cálculo

Hay dos cálculos principales para el balance del cálculo. En el primero, usamos un valor de tasa para dividir la cantidad de los tokens de reflejo de una dirección para calcular el balance original de su token.

balanceOf(address) = rAmount / currentRate

El segundo es sobre cómo el valor es calculado. Hasta ahora, sabemos que el denominador de la fórmula es un número fijo el cual es igual a la cantidad total del token original (es decir, _tTotal).

Ahora tienes un entendimiento superficial de cuando el suministro total de tokens reflejantes disminuye, la tasa también disminuye. Cuando esa situación ocurre durante el intercambio o las transferencias, la tasa disminuye. Combinando esto con la primera fórmula, la cantidad del token original en la cuenta del usuario se incrementará.

currentRate = rSupply / tSupply

function balanceOf(address account) public view override returns (uint256) {
   if (_isExcluded[account]) return _tOwned[account];

   return tokenFromReflection(_rOwned[account]);
 }

 /// @notice Esta función calcula cuántos tokens hay por reflejo
 /// @dev En el reflejo inicial el valor debería ser mayor, o puede que tengas una idea
 /// ejecutando {reflectionFromToken} para obtener el reflejo del token
 function tokenFromReflection(uint256 rAmount) public view returns (uint256) {
   require(rAmount <= _rTotal, "Amount must be less than total reflections");

   uint256 currentRate = _getRate(); // 1.15792089237316195423570985008687907853269984665640564×10⁵³
   return rAmount.div(currentRate); // (2 * 10^53)  / (1.15792089237316195423570985008687907853269984665640564×10⁵³) = 1
 }

 /// @notice Calcula la tasa actual del token.
 /// @return Tasa actual de la fórmula simple (el reflejo de la oferta restante / oferta restante total)
 function _getRate() private view returns (uint256) {
   (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); // (1.1579×10^53 , 10^24)
   return rSupply.div(tSupply); // 1.15792089237316195423570985008687907853269984665640564×10⁵³
 }
Enter fullscreen mode Exit fullscreen mode

Token de Transferencia

Hay condiciones típicas de la transferencia del token, lo que quiere decir que ni el remitente ni el receptor no son excluídos desde la distribución de la recompensa, la implementación del código es una función _transferStandard.

/// @notice Esta función obtiene el reflejo y el valor de la transferencia (incluyendo el reflejo y la atasa de la transferencia.
 /// sustrae la cantidad del reflejo del remitente desde el balance de su reflejo
 /// añade la cantidad de reflejo de transferencia al balance de la transferencia del receptor
 /// contrato inteligente toma la liquidez y refleja ambas tasas
 /// @param {sender} dirección del remitente
 /// @param {recipient} dirección del receptor
 /// @param {tAmount} cantidad de transferencia
 function _transferStandard(
   address sender,
   address recipient,
   uint256 tAmount
 ) private {
   (
     uint256 rAmount,
     uint256 rTransferAmount,
     uint256 rFee,
     uint256 tTransferAmount,
     uint256 tFee,
     uint256 tLiquidity
   ) = _getValues(tAmount);

   _rOwned[sender] = _rOwned[sender].sub(rAmount);
   _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
   _takeLiquidity(tLiquidity);
   _reflectFee(rFee, tFee);
   emit Transfer(sender, recipient, tTransferAmount);
 }
Enter fullscreen mode Exit fullscreen mode

Antes de actualizar el balance de la cuenta, necesitas calcular la transferencia, la tasa del impuesto y los valores de la tasa de liquidez para ambos el token original y de reflejo. Los valores originales del token son calculados en primer lugar y luego los valores del token reflejo son computados a través de la multiplicación de tasas a ellos.

El balance del token reflejo del emisor y receptor es actualizado, sustrayendo o añadiendo valores a través de _getValues.

/// @notice Calcula la Transferencia y los valores de Reflejo
 /// @param {tAmount} Cantidad total de la transferencia
 /// @return rAmount Cantidad reflejo
 /// @return rTransferAmount Cantidad de la transferencia reflejo
 /// @return rFee tasas de reflejo
 /// @return tTransferAmount cantidad de transferencia
 /// @return tFee tasas de transferencia
 /// @return tLiquidity transferencia de liquidez
 function _getValues(uint256 tAmount)
   private
   view
   returns (
     uint256,
     uint256,
     uint256,
     uint256,
     uint256,
     uint256
   )
 {
   // 100000000000 (tAmount)
   (uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getTValues(tAmount); // (90000000000 , 5000000000 , 5000000000 )
   (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(
     tAmount,
     tFee,
     tLiquidity,
     _getRate()
   );
   //(9.26336713898529563388567880069503262826159877325124512×10⁶³ , 5.7896044618658097711785492504343953926634992332820282×10⁶² , 5.7896044618658097711785492504343953926634992332820282×10⁶²)
   return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tLiquidity);
 }
Enter fullscreen mode Exit fullscreen mode

La cantidad de la tasa de liquidez se graba en el balance del token reflejo del contrato del token. Si el contrato se excluye de recibir recompensas, entonces se requiere que el balance original del token sea refrescado. Y luego del estado de la exclusión se revierte a falso, el balance del token original será configurado a 0

/// @notice Esta función incrementará el reflejo y el balance de transferencia del contrato inteligente por rLiquidity y tLiquidity
 /// @param {tLiquidity} Es calculado por la función calculateLiquidityFee()
 function _takeLiquidity(uint256 tLiquidity) private {
   uint256 currentRate = _getRate();
   uint256 rLiquidity = tLiquidity.mul(currentRate);
   _rOwned[address(this)] = _rOwned[address(this)].add(rLiquidity);
   if (_isExcluded[address(this)]) _tOwned[address(this)] = _tOwned[address(this)].add(tLiquidity);
 }
Enter fullscreen mode Exit fullscreen mode

Con la tarifa del impuesto cortada desde la cantidad total del token reflejo, el valor del intercambio entre el token reflejo y el token original sube, lo que quiere decir que la misma cantidad del token reflejo puede convertirse en una mayor cantidad del token original.

/// @notice Tasas reflejo, sustrae rFee desde _rTotal y añade tFee en _tFeeTotal
 /// @param {rFee} tasa reflejo
 /// @param {tFee} tasa de transferencia
 function _reflectFee(uint256 rFee, uint256 tFee) private {
   _rTotal = _rTotal.sub(rFee);
   _tFeeTotal = _tFeeTotal.add(tFee);
 }
Enter fullscreen mode Exit fullscreen mode

La lógica de la implementación del código bajo las diferentes condiciones de la transferencia del código es muy similar a la función _transferStandard.

/// @notice Esta función realiza las revisiones de la tarifa y luego, de acuerdo al remitente y el receptor
 /// excluido las marcas de transferencia dado la cantidad del receptor.
 /// @param {sender} dirección del emisor
 /// @param {recipient} dirección del receptor
 /// @param {amount} cantidad de transferencia
 /// @param {takeFee} marca el cargo de una tarifa o no
 function _tokenTransfer(
   address sender,
   address recipient,
   uint256 amount,
   bool takeFee
 ) private {
   // si tomar la tarifa es falso, removeAllFee() se llama para configurar las tarifas (taxFee and liquidityFee) a cero
   if (!takeFee) removeAllFee();

   if (_isExcluded[sender] && !_isExcluded[recipient]) {
     _transferFromExcluded(sender, recipient, amount);
   } else if (!_isExcluded[sender] && _isExcluded[recipient]) {
     _transferToExcluded(sender, recipient, amount);
   } else if (!_isExcluded[sender] && !_isExcluded[recipient]) {
     // La función _transferStandard se llama si ambos el emisor y receptor no son excluidos desde las recompensas recibidas (ambos pueden recibir recompensas)
     _transferStandard(sender, recipient, amount);
   } else if (_isExcluded[sender] && _isExcluded[recipient]) {
     _transferBothExcluded(sender, recipient, amount);
   } else {
     _transferStandard(sender, recipient, amount);
   }

   if (!takeFee) restoreAllFee();
 }
Enter fullscreen mode Exit fullscreen mode

Otros Elementos para la bomba de SafeMoon

Tiempo: Una apuesta bien colocada

Todo comenzó en Noviembre 2021 cuando profundicé el tiempo de verificación en el proxy del token del contrato inteligente. Antes, el mundo de los memes en cadena aún se mantenía, con la sombra de los retos subsecuentes como el escándalo de SBF y el espiral de muerte que aún se asoma de LUNA. Los inversores minoristas buscaban ansiosamente el siguiente Dogecoin o la siguiente sensación de paquete de meme como la locura de WallStreetBets. Con este contexto, Ethereum y Bitcoin estaban alcanzando su récord máximos, saturando el mercado con liquidez. Fue precisamente en esta coyuntura que SafeMoon hizo su debut, capitalizando en la tormenta perfecta.

Operaciones de Mercado: El Liderazgo Visionario

En la cabeza de SafeMoon estaba John Karony, un líder visionario adepto en la administración de programa y la escritura técnica. Dirigió el proyecto con una serie de estrategias de mercados bien creadas, creando un nuevo estándar en confiabilidad para los inversores minoristas. Mientras muchos proyectos, en ese entonces, expresaron su preocupación distribuyendo un intercambio significativo de tokens para empresas o miembros principales, SafeMoon tomó un camino distinto. No sólo quemaron todos los tokens del desarrollador en el lanzamiento pero también abrazaron mecanismos IEO e IDO, justos y transparentes. Los tokenomics y el esquema del reflejo innovador fueron ejecutados con precisión. Trillones de monedas fueron sistemáticamente removidas de la circulación para mantener un suministro escaso, creando una ola de entusiasmo en el mercado.

Espiral de Muerte

Fundamentales cero y uso

Entre la locura de la subida de precio realizada por el FOMO (Fear of Missing Out, miedo a perderse (algo)), el valor del mercado de SafeMoon una vez se elevó a más de mil millones de dólares. Sin embargo, desde entonces se ha desplomado por más de 90% en su valor de mercado y su bajo volumen de intercambio ahora da la apariencia de un proyecto inactivo. Los resultados indican una falta de utilidad o incentivos para las manos de diamantes si la tendencia de precios cambia de una tendencia en alta a una tendencia en baja.

Más aún, la inactividad del proyecto en ambos, el desarrollo y el mercado de intercambio, sugiere que el equipo no ha mostrado mucho compromiso por mantener o mejorar la utilidad del token.

¿Es un caso de mal tokenomics?

Se parece más a las ponzinomics más que a un pobre tokenomics. Estos dos conceptos comparten algunas similitudes. En un esquema Ponzi, ganas dividendos desde nuevos participantes uniéndose al esquema, mientras que en monedas terribles, ganas reflejos desde otros comprando.

Sin embargo, hay un inconveniente notable: los propietarios están obligados a pagar impuestos cuando se involucran en el trading. Esto quiere decir que el enfoque primario del proyecto es en inflar el precio, pero usualmente esa estrategia es de corto plazo.

Fuente

búsqueda del mercado

discusión del algoritmo

explicación del código en video

discusión de reddit

Este artículo es una traducción de 0xCryptoQuant, hecha por Héctor Botero. Puedes encontrar el artículo original aquí.
Sería genial escucharte en nuestro Discord, puedes contarnos tus ideas, comentarios, sugerencias y dejarnos saber lo que necesitas.
Si prefieres puedes escribirnos a @web3dev_es en Twitter.

Discussion (0)