QX ERC20 Token de ciencia /** *Enviado para su verificación en Etherscan.io el 2020-12-24 * /
solidez de pragma ^0.6.0;
/**
@dev envolturas sobre las operaciones aritméticas de Solity con desbordamiento adicional
cheques.
Operaciones aritméticas en la envoltura de solidez sobre el desbordamiento. Esto puede resultar fácilmente
en errores, porque los programadores generalmente asumen que un desbordamiento plantea un
Error, que es el comportamiento estándar en los lenguajes de programación de alto nivel.
SafeMath restaura esta intuición volviendo la transacción cuando un
Operación desbordamientos.
El uso de esta biblioteca en lugar de las operaciones no controladas elimina un completo
Clase de errores, por lo que se recomienda usarlo siempre. / Biblioteca Safemath { / *
@dev devuelve la adición de dos enteros sin firmar, volviendo a
rebosar.
Contraparte del operador + operador de solidez.
Requisitos:
regreso c; }
/**
- solidez./**
@dev devuelve la resta de dos enteros sin firmar, volviendo con un mensaje personalizado en
desbordamiento (cuando el resultado es negativo).
Contraparte del operador - solidez.
Requisitos:
regreso c; }
/**
@dev devuelve la multiplicación de dos enteros sin firmar, volviendo a
rebosar.
Contraparte del operador * del operador de Solity.
Requisitos:
uint256 c = a * b; requiere (c / a == b, "Safemath: desbordamiento de multiplicación");
regreso c; }
/**
/ operador. NOTA: Esta función usa unrevert el código de operación (que deja el gas restante intacto) mientras la solidez/**
@dev devuelve la división entera de dos enteros sin firmar. Revertida con un mensaje personalizado en
división por cero. El resultado se redondea hacia cero.
Contraparte del solidez / operador. NOTA: Esta función usa un
revert el código de operación (que deja el gas restante intacto) mientras la solidez
Utiliza un código de operación no válido para revertir (consumir todo el gas restante).
Requisitos:
regreso c; }
/**
% de solidez. Esta función usa una revert/**
% de solidez. Esta función usa una revert// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@dev Utilidades de matemáticas estándar que faltan en el lenguaje de solidez. / Biblioteca Math { / *
/**
/**
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@dev busca una array ordenada y devuelve el primer índice que contiene
un valor mayor o igual al element . Si no existe dicho índice (es decir, todo
Los valores en la matriz son estrictamente menores que element ), la longitud de la matriz es
devuelto. Complejidad del tiempo o (log n).
Se espera que array se clasifique en orden ascendente y no contenga
elementos repetidos. */ function FindUpperBound (UINT256 [] Array de almacenamiento, elemento UINT256) Vista interna devuelve (uint256) {if (array.length == 0) {return 0; }
uint256 bajo = 0; uint256 high = array.length;
while (bajo <alto) {uint256 mid = math.average (bajo, alto);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// En este punto, low es el límite superior exclusivo. Devolveremos el límite superior inclusivo. if (low> 0 && array [bajo - 1] == elemento) {return low - 1; } else {return Low; }}}
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@Title Counters
@author Matt Condon (@shrrugs)
@dev proporciona contadores que solo pueden ser incrementados o disminuidos por uno. Esto se puede usar, por ejemplo, para rastrear el número
de elementos en una asignación, emitiendo ID de ERC721 o contando ID de solicitud.
Incluir con using Counters for Counters.Counter;
Dado que no es posible desbordar un entero de 256 bits con incrementos de uno, increment puede omitir el {Safemath}
Verificación de desbordamiento, ahorrando así gas. Esto supone el uso correcto, ya que el _value subyacente nunca es nunca
accedido directamente. */ Contadores de biblioteca {usando Safemath para uint256;
Struct Counter {// Esta variable nunca debe ser accedida directamente por los usuarios de la biblioteca: las interacciones deben restringirse a // la función de la biblioteca. A partir de la solidez v0.5.2, esto no se puede hacer cumplir, aunque hay una propuesta para agregar // esta característica: ver Ethereum/Solidity#4637 UINT256 _Value; // predeterminado: 0}
Función actual (contador de almacenamiento de contador) Vista interna devuelve (uint256) {return contador._value; }
Función Incremento (contador de almacenamiento de contador) Interno {// La verificación de desbordamiento {Safemath} se puede omitir aquí, vea el comentario en el contador superior ._value += 1; }
disminución de la función (contador de almacenamiento) interno {contador._value = contador._value.sub (1); }}
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/*
@dev proporciona información sobre el contexto de ejecución actual, incluido el
remitente de la transacción y sus datos. Mientras que estos están generalmente disponibles
a través de msg.sender y msg.data, no se debe acceder a ellos en tal dirección directa
manera, ya que al tratar con las meta-transacciones de GSN, el envío de la cuenta y
Pagar por la ejecución puede no ser el remitente real (en cuanto a una aplicación
está preocupado).
Este contrato solo se requiere para contratos intermedios similares a la biblioteca. */ contexto de contrato abstracto {function _msgsender () Vista interna Virtual Devueltas (Dirección Payable) {return msg.sender; }
function _msgData () Vista interna Virtual Devueltos (Memoria Bytes) {this; // Advertencia de mutabilidad del estado de silencio sin generar bytecode - ver Ethereum/Solidity#2691 Devuelto Msg.Data; }}
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@dev interfaz del estándar ERC20 como se define en el EIP. / Interface IERC20 { / *
/**
account . */ Funcion BalanceOf (cuenta de dirección) Vista externa devuelos (uint256);/**
amount de tokens de la cuenta de la persona que llama al recipient ./**
spender seráowner a través de {TransferFrom}. Esto es/**
amount como la asignación de spender sobre los tokens de la persona que llama./**
amount de tokens del sender al recipient usando elamount se deduce de la persona que llama/**
value se mueven de una cuenta ( from ) ato ).value puede ser cero. */ transferencia de eventos (dirección indexada desde, dirección indexada a, valor uint256);/**
spender para un owner se establece convalue es la nueva asignación. */ Aprobación del evento (Dirección del propietario indexado, Dirección de gastador indexado, valor UINT256); }// Licencia parcial: MIT
solidez de pragma ^0.6.2;
/**
@dev colección de funciones relacionadas con el tipo de dirección / dirección de la biblioteca { / *
@dev devuelve verdadero si account es un contrato.
[IMPORTANTE]
====
No es seguro asumir que una dirección para la que devuelve esta función
FALSO es una cuenta de propiedad externamente (EOA) y no un contrato.
Entre otros, isContract devolverá falso para lo siguiente
Tipos de direcciones:
==== */ function IsContract (cuenta de dirección) Vista interna devuelve (bool) {// Este método se basa en ExtCodesize, que devuelve 0 para contratos en // construcción, ya que el código solo se almacena al final de la ejecución del constructor //.
tamaño uint256; // ensamblaje solhint-desesable-next-line sinline-ensembly {size: = extCodesize (cuenta)} Tamaño de retorno> 0; }
/**
@dev reemplazo para transfer de solidez: envía amount wei a
recipient , reenviar todo el gas disponible y volver a los errores.
https://eips.ethereum.org/eips/eip-1884[eip1884] aumenta el costo de gas
de ciertos códigos de operación, posiblemente hacer contratos superan el límite de gas de 2300
impuesto por transfer , haciéndolos incapaces de recibir fondos a través de
transfer . {SendValue} elimina esta limitación.
https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/ighlearn más].
IMPORTANTE: Debido a que el control se transfiere al recipient , la atención debe ser
tomado para no crear vulnerabilidades reentradas. Considerar usar
{ReentrancyGuard} o el
https://solidies.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-patterntima checks-alfects-interacciones patrón]. */ function sendValue (Dirección de destinatario por pagar, UINT256 Cantidad) Interno {requirir (dirección (this) .balance> = monto, "dirección: saldo insuficiente");
// solhint-desesable-next-line-low-nivel-llamas, evitar-chall-value (bool éxito,) = destinatario.call {value: cantidad} (""); requiere (éxito, "Dirección: No se puede enviar el valor, el destinatario puede haber revertido"); }
/**
call de bajo nivel. Acall simple es un reemplazo inseguro para una llamada de función: use estotarget vuelve con una razón de revertir, es burbujeante por estetarget debe ser un contrato.target con data no debe revertir./**
functionCall ], pero conerrorMessage como un revertir de retroceso cuando target se vuelve./**
functionCall ],value a Wei al target .value .payable ./**
functionCallWithValue ], peroerrorMessage como una razón revertida cuando target se vuelve.función _functionCallWithValue (Dirección de destino, Bytes Memory Data, UINT256 Wealue, String Memory errorMessage) Devoluciones privadas (Bytes Memory) {requerir (ISContract (Target), "Dirección: Llame a No Contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}}
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@DEV Implementación de la interfaz {IERC20}.
Esta implementación es agnóstica a la forma en que se crean los tokens. Esto significa
que se debe agregar un mecanismo de suministro en un contrato derivado usando {_MINT}.
Para un mecanismo genérico, ver {ERC20PresetMinterPauser}.
Consejo: Para una redacción detallada, consulte nuestra guía
https://forum.zeppelin.solutions/t/how-to-implement-c20-supply-mechaniss/226=wow
para implementar mecanismos de suministro].
Hemos seguido las pautas generales de OpenZeppelin: las funciones se vuelven en su lugar
de devolver false al fallo. Este comportamiento es, sin embargo, convencional
y no entra en conflicto con las expectativas de las aplicaciones ERC20.
Además, se emite un evento {aprobación} en las llamadas a {transferFrom}.
Esto permite que las aplicaciones reconstruyan la asignación para todas las cuentas solo
escuchando dichos eventos. Otras implementaciones del EIP pueden no emitir
Estos eventos, como no es requerido por la especificación.
Finalmente, el no estándar {DeceaseLlowance} y {aumentan la luz}
Se han agregado funciones para mitigar los problemas bien conocidos en torno a la configuración
subsidios. Ver {iERC20-apel}. */ Contract ERC20 es contexto, iERC20 {usando Safemath para uint256; Uso de la dirección para la dirección;
mapeo (dirección => uint256) privado _balances;
asignación (dirección => mapeo (dirección => uint256)) privado _allowances;
uint256 privado _totalSupply;
cadena privada _name; cadena privada _symbol; uint8 privado _Decimals;
/**
/**
/**
/**
decimals equivalen 2 , un saldo de 505 tokens debería5,05 ( 505 / 10 ** 2 )./**
/**
/**
recipient no puede ser la dirección cero.amount . */ Funcion Transfer (Dirección Dinestante, UINT256 Cantidad) Public Virtual Override Devuelve (bool) {_transfer (_msgsender (), destinatario, cantidad); devolver verdadero; }/**
/**
spender no puede ser la dirección cero. */ function aprobar (direcciones Spender, UINT256 Cantidad) Public Virtual Anulación Devoluciones (bool) {_Approve (_msgsender (), Spender, cantidad); devolver verdadero; }/**
sender y recipient no pueden ser la dirección cero.sender debe tener un saldo de al menos amount .sender de al menosamount . */ function transferFrom (remitente de dirección, destinatario de dirección, monto uint256) public virtual anulación de devoluciones (bool) {_transfer (remitente, destinatario, cantidad); _Approve (remitente, _msgsender (), _Allowances [remitente] [_ msgsender ()]. sub (monto, "ERC20: la cantidad de transferencia excede la asignación")); devolver verdadero; }/**
spender por la persona que llama.spender no puede ser la dirección cero. */ function increaseAllowance (direcciones Spender, UINT256 Se agregue Value) Returnos virtuales públicos (bool) {_Approve (_MSGSender (), Spender, _Allowances [_msgsender ()] [Spender] .Add (agregado)); devolver verdadero; }/**
spender por la persona que llama.spender no puede ser la dirección cero.spender debe tener una asignación para la persona que llama al menossubtractedValue . */ function disminuyeLlowance (Spender de direcciones, uint256 RESTRATEDVALUE) Public Virtual Devueltas (bool) {_Approve (_MSGSender (), Spender, _LOWANSE [_MSGSender ()] [Spender] .sub (SISTATREDVALUE, "ERC20: disminuyó la subsidio por debajo de cero")); devolver verdadero; }/**
@dev mueve amount de tokens del sender al recipient .
Esta es la función interna es equivalente a {transferir} y se puede usar para
por ejemplo, implementar tarifas de token automática, mecanismos de corte, etc.
Emite un evento {Transfer}.
Requisitos:
sender no puede ser la dirección cero.recipient no puede ser la dirección cero.sender debe tener un saldo de al menos amount . */ function _transfer (remitente de dirección, destinatario de dirección, cantidad de uint256) virtual interno {request (remitente! = dirección (0), "ERC20: transferir desde la dirección cero"); requerir (¡Destino! = Dirección (0), "ERC20: transferir a la dirección cero");_BeForETOKEntransfer (remitente, destinatario, cantidad);
_balances [remitente] = _balances [remitente] .sub (cantidad, "ERC20: la cantidad de transferencia excede el saldo"); _balances [destinatario] = _balances [destinatario] .add (cantidad); transferencia de emit (remitente, destinatario, cantidad); }
/** @dev crea tokens amount y los asigna a tener en account , aumentando
el suministro total.
Emite un evento {Transfer} con from SET a la dirección cero.
Requisitos
to puede ser la dirección cero. */ function _mint (cuenta de dirección, cantidad uint256) virtual interno {require (cuenta! = dirección (0), "ERC20: menta a la dirección cero");_BeForETOKEnTRANSFER (dirección (0), cuenta, cantidad);
_totalSupply = _totalSupply.add (cantidad); _balances [cuenta] = _balances [cuenta] .add (cantidad); transferencia emit (dirección (0), cuenta, cantidad); }
/**
@dev destruye los tokens amount de account , reduciendo el
suministro total.
Emite un evento {Transfer} con to establecer la dirección cero.
Requisitos
account no puede ser la dirección cero.account debe tener al menos amount de tokens. */ function _burn (cuenta de dirección, cantidad de uint256) virtual interno {request (cuenta! = dirección (0), "ERC20: BURN desde la dirección cero");_BeForETOKEnTRANSFER (cuenta, dirección (0), cantidad);
_balances [cuenta] = _balances [cuenta] .sub (cantidad, "ERC20: la cantidad de quemado excede el saldo"); _totalSupply = _totalSupply.sub (cantidad); transferencia emit (cuenta, dirección (0), cantidad); }
/**
@dev establece amount como la asignación de spender sobre los tokens del owner .
Esta función interna es equivalente a approve , y se puede utilizar para
por ejemplo, establezca asignaciones automáticas para ciertos subsistemas, etc.
Emite un evento {aprobación}.
Requisitos:
owner no puede ser la dirección cero.spender no puede ser la dirección cero. */ function _approve (propietario de la dirección, gastador de direcciones, cantidad de uint256) virtual interno {require (propietario! = dirección (0), "ERC20: aprobar desde la dirección cero"); requerir (Spender! = Dirección (0), "ERC20: aprobar a la dirección cero");_Allowances [propietario] [spender] = cantidad; aprobación de emits (propietario, gastador, monto); }
/**
/**
from y to distintos de cero, amount de tokens fromto .from es cero, los tokens amount se acuzarán to .to es cero, se quemará amount de tokens from las cosas.from y to son cero.// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@dev Este contrato extiende un token ERC20 con un mecanismo de instantánea. Cuando se crea una instantánea, los saldos y
El suministro total en ese momento se registra para el acceso posterior.
Esto se puede utilizar para crear mecanismos de forma segura basados en saldos de token como dividendos sin confianza o votación ponderada.
En implementaciones ingenuas es posible realizar un ataque de "doble gasto" al reutilizar el mismo equilibrio de diferentes
cuentas. Al usar instantáneas para calcular dividendos o poder de voto, esos ataques ya no se aplican. También puede ser
utilizado para crear un mecanismo eficiente de bifurcación ERC20.
Las instantáneas se crean mediante la función interna {_snapshot}, que emitirá el evento {Snapshot} y devolverá un
ID de instantánea. Para obtener el suministro total en el momento de una instantánea, llame a la función {TotalSupplyat} con la instantánea
identificación. Para obtener el saldo de una cuenta en el momento de una instantánea, llame a la función {Balofat} con la ID de instantánea
y la dirección de la cuenta.
==== Costos de gas
Las instantáneas son eficientes. La creación de instantáneas es O (1) . La recuperación de saldos o el suministro total de una instantánea es _O (registro
n) _ En el número de instantáneas que se han creado, aunque N para una cuenta específica generalmente será mucho
Más pequeños, ya que los saldos idénticos en las instantáneas posteriores se almacenan como una sola entrada.
Hay una sobrecarga constante para las transferencias ERC20 normales debido a la contabilidad adicional de instantáneas. Esta sobrecarga es
Solo significativo para la primera transferencia que sigue inmediatamente una instantánea para una cuenta en particular. Posterior
Las transferencias tendrán un costo normal hasta la próxima instantánea, y así sucesivamente. */Abstract Contract ERC20SnapShot es ERC20 {// Inspirado en Minimetoken de Jordi Baylina con los saldos históricos registrados: // https://github.com/giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/minkoken
usando Safemath para UINT256; usando matrices para uint256 []; usando contadores para contadores.
// Los valores instantáneos tienen matrices de ID y el valor correspondiente a esa ID. Estos podrían ser una matriz de A // Snapshot Struct, pero eso impediría el uso de funciones que funcionan en una matriz. estructurar instantáneas {uint256 [] ids; valores uint256 []; }
mapeo (dirección => instantáneas) privado _AcCountBalancesnapshots; Instantáneas privadas _totalsupplysnapshots;
// Los ID de instantánea aumentan monotónicamente, con el primer valor 1. Una ID de 0 no es válida. Counters.Counter Private _CurrentSnapShotid;
/**
id . */ Snapshot de eventos (ID UINT256);/**
@dev crea una nueva instantánea y devuelve su ID de instantánea.
Emite un evento {Snapshot} que contiene la misma ID.
{_snapshot} es internal y debe decidir cómo exponerlo externamente. Su uso puede estar restringido a un
Conjunto de cuentas, por ejemplo, usando {AccessControl}, o puede estar abierto al público.
[ADVERTENCIA]
====
Mientras que se requiere una forma abierta de llamar {_snapshot} para ciertos mecanismos de minimización de confianza, como el bifurcación,
Debe considerar que los atacantes pueden ser utilizados de dos maneras.
Primero, se puede usar para aumentar el costo de recuperación de valores de las instantáneas, aunque crecerá
Logarítmicamente, lo que hace que este ataque sea ineficaz a largo plazo. En segundo lugar, se puede usar para apuntar
Cuentas específicas y aumentar el costo de las transferencias ERC20 para ellos, en las formas especificadas en los costos de gas
Sección arriba.
No hemos medido los números reales; Si esto es algo que le interesa, comuníquese con nosotros.
==== */ function _snapShot () Internone Virtual Devuelve (uint256) {_CurrentSnapShotID.Increment ();
uint256 tenturid = _CurrentSnapShotid.Current (); emitir instantánea (CurrentId); return -tricnid; }
/**
@dev recupera el saldo de account en el momento en que se creó snapshotId . */ function BaloFAT (cuenta de dirección, uint256 snapshotid) Vista pública devuelve (uint256) {(bool snapshoted, uint256 valor) = _valueat (snapshotID, _AccountBalancesNapShots [cuenta]);
¿Volver a Stapshoted? valor: balance (cuenta); }
/**
@dev recupera el suministro total en el momento en que se creó snapshotId . */ function TotalSupplyat (uint256 snapshotid) View public View devuelve (uint256) {(bool snapshotted, uint256 valor) = _valueat (snapshotid, _totalsUpplySnapShots);
¿Volver a Stapshoted? Valor: TotalSupply (); }
// Actualizar el saldo y/o las instantáneas totales de suministro antes de modificar los valores. Esto se implementa // en el gancho _beforetokentRansfer, que se ejecuta para las operaciones _MINT, _BURN y _TRANSFER. función _beForETOKEnTRANSFER (dirección desde, dirección a, cantidad de uint256) anulación virtual interna {super._beforetOkEndransfer (desde, hasta, cantidad);
if (from == dirección (0)) {// menta _updataAcCountsnapShot (a); _UpDatetotalSupplySnapShot (); } else if (a == dirección (0)) {// quemar _updataAcCountsnapShot (desde); _UpDatetotalSupplySnapShot (); } else {// transferir _updataAcCountSnapShot (desde); _UpdataAcCountsnapshot (a); }}
función _valueat (uint256 snapshotid, instantáneas de almacenamiento de instantáneas) Vista privada devuelve (bool, uint256) {request (snapshotid> 0, "ERC20SNAPSHOT: ID es 0"); // Solhint-Disable-Next-Line Max-Line-Length Request (SnapShotID <= _CurrentSnapShotid.Current (), "ERC20SNAPSHOT: ID noxistente");
// When a valid snapshot is queried, there are three possibilities:
// a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
// created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
// to this id is the current one.
// b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
// requested id, and its value is the one to return.
// c) More snapshots were created after the requested one, and the queried value was later modified. There will be
// no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
// larger than the requested one.
//
// In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
// it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
// exactly this.
uint256 index = snapshots.ids.findUpperBound(snapshotId);
if (index == snapshots.ids.length) {
return (false, 0);
} else {
return (true, snapshots.values[index]);
}
}
function _UpDateAcCountSnapShot (cuenta de dirección) Private {_UpdatesNapShot (_AcCountBalancesNapshots [cuenta], balance (cuenta)); }
function _UpDATTOTALSUPPLYSNAPSHOT () privado {_UpdatesNapShot (_totalsUpplySnapShots, TotalSupply ()); }
función _UpdatesNapShot (instantáneas de almacenamiento de instantáneas, uint256 currentValue) privado {uint256 tenturid = _CurrentSnapShotid.current (); if (_lastsnapShotID (snapshots.ids) <currentId) {snapshots.ids.push (tenturid); Snapshots.Values.push (CurrentValue); }}
función _lastsnapShotID (uint256 [] IDS de almacenamiento) Vista privada devuelve (uint256) {if (id.length == 0) {return 0; } else {return ids [id.length - 1]; }}}
// Licencia parcial: MIT
solidez de pragma ^0.6.0;
/**
@dev Biblioteca para administrar
https://en.wikipedia.org/wiki/set_(abstract_data_type)[sets] de primitivo
tipos.
Los conjuntos tienen las siguientes propiedades:
(O (1)).
Ejemplo de contrato {
// Add the library methods
using EnumerableSet for EnumerableSet.AddressSet;
// Declare a set state variable
EnumerableSet.AddressSet private mySet;
}
A partir de v3.0.0, solo conjuntos de address de tipo ( AddressSet ) y uint256
( UintSet ) son compatibles. */ biblioteca enumerableset {// Para implementar esta biblioteca para múltiples tipos con el más pequeño código // repetición como sea posible, la escribimos en términos de un tipo de conjunto genérico con los valores // bytes32. // La implementación establecida utiliza funciones privadas, y las implementaciones de referencia de usuario // (como DirectSet) son solo envoltorios alrededor del conjunto subyacente. // Esto significa que solo podemos crear nuevos conjuntos de enumerables para tipos que se ajustan // en Bytes32.
struct set {// almacenamiento de valores establecidos bytes32 [] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
/**
@dev elimina un valor de un conjunto. O (1).
Devuelve verdadero si el valor se eliminó del conjunto, es decir, si era
presente. */ function _remove (set de almacenamiento establecido, bytes32 valor) devoluciones privadas (bool) {// leemos y almacenamos el índice del valor para evitar múltiples lecturas de la misma ranura de almacenamiento uint256 valueIndex = set._indexes [valor];
if (valueIndex! = 0) {// equivalente a contiene (set, value) // Para eliminar un elemento de la matriz de Values en o (1), intercambiamos el elemento para eliminar con el último en // la matriz, y luego eliminar el último elemento (a veces llamado como 'swap y pop'). // Esto modifica el orden de la matriz, como se señaló en {AT}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {return false; }}
/**
/**
/**
index de posición en el conjunto. O (1).index debe ser estrictamente menor que {longitud}. */ function _at (set de almacenamiento set, uint256 índice) vista privada devuelve (bytes32) {request (set._values.length> index, "enumerableset: index out of bounds"); return set._values[index]; }// AddressSet
struct AddressSet { Set _inner; }
/**
/**
/**
/**
/**
index in the set. O(1).index must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); }// UintSet
struct UintSet { Set _inner; }
/**
/**
/**
/**
/**
index in the set. O(1).index must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }// Partial License: MIT
pragma solidity ^0.6.0;
/**
@dev Contract module that allows children to implement role-based access
control mechanisms.
Roles are referred to by their bytes32 identifier. These should be exposed
in the external API and be unique. The best way to achieve this is by
using public constant hash digests:
bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
Roles can be used to represent a set of permissions. To restrict access to a
function call, use {hasRole}:
function foo() public {
require(hasRole(MY_ROLE, msg.sender));
...
}
Roles can be granted and revoked dynamically via the {grantRole} and
{revokeRole} functions. Each role has an associated admin role, and only
accounts that have a role's admin role can call {grantRole} and {revokeRole}.
By default, the admin role for all roles is DEFAULT_ADMIN_ROLE , which means
that only accounts with this role will be able to grant or revoke other
roles. More complex role relationships can be created by using
{_setRoleAdmin}.
WARNING: The DEFAULT_ADMIN_ROLE is also its own admin: it has permission to
grant and revoke this role. Extra precautions should be taken to secure
accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address;
struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; }
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
newAdminRole is set as role 's admin role, replacing previousAdminRoleDEFAULT_ADMIN_ROLE is the starting admin for all roles, despite/**
account is granted role .sender is the account that originated the contract call, an admin role/**
account is revoked role .sender is the account that originated the contract call:revokeRole , it is the admin role bearerrenounceRole , it is the role bearer (ie account ) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);/**
true if account has been granted role . */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); }/**
role . Can be used/**
role . index must be a/**
role . See {grantRole} and/**
@dev Grants role to account .
If account had not been already granted role , emits a {RoleGranted}
evento.
Requisitos:
role 's admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");_grantRole(role, account); }
/**
@dev Revokes role from account .
If account had been granted role , emits a {RoleRevoked} event.
Requisitos:
role 's admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");_revokeRole(role, account); }
/**
@dev Revokes role from the calling account.
Roles are often managed via {grantRole} and {revokeRole}: this function's
purpose is to provide a mechanism for accounts to lose their privileges
if they are compromised (such as when a trusted device is misplaced).
If the calling account had been granted role , emits a {RoleRevoked}
evento.
Requisitos:
account . */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self");_revokeRole(role, account); }
/**
role to account .account had not been already granted role , emits a {RoleGranted}/**
adminRole as role 's admin role.function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } }
function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); }}}
pragma solidity 0.6.8;
contract QXToken is Context, AccessControl, ERC20Snapshot { bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");
constructor(uint256 amount, uint8 decimals) ERC20("QX ERC20", "QX") public {
_setupDecimals(decimals);
_mint(msg.sender, amount);
// set up required roles
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(SNAPSHOT_ROLE, _msgSender());
}
/**
* @dev Creates a new snapshot and returns its snapshot id.
* Emits a {Snapshot} event that contains the same id.
*/
function snapshot() public {
require(hasRole(SNAPSHOT_ROLE, _msgSender()), "Must have snapshot role to create a snapshot");
_snapshot();
}
}