QX ERC20 Science Token /** *Enviado para verificação no EtherScan.io em 2020-12-24 * /
Solidez de Pragma ^0,6,0;
/**
@Dev Wrappers sobre operações aritméticas da Solidity com o transbordamento adicional
cheques.
Operações aritméticas em Solity Wrap no transbordamento. Isso pode resultar facilmente
nos insetos, porque os programadores geralmente assumem que um transbordamento levanta um
Erro, que é o comportamento padrão em linguagens de programação de alto nível.
SafeMath restaura essa intuição revertendo a transação quando um
Operação transborda.
Usar esta biblioteca em vez das operações desmarcadas elimina um inteiro
classe de bugs, por isso é recomendável usá -lo sempre. / Biblioteca SafeMath { / *
@dev retorna a adição de dois números inteiros não assinados, revertendo
transbordamento.
Contraparte ao operador da Solidity + .
Requisitos:
retornar c; }
/**
- da Solidity./**
@Dev retorna a subtração de dois números inteiros não assinados, revertendo com a mensagem personalizada em
estouro (quando o resultado é negativo).
Contraparte ao - da Solidity.
Requisitos:
retornar c; }
/**
@dev retorna a multiplicação de dois números inteiros não assinados, revertendo
transbordamento.
Contraparte ao operador * do Solidity.
Requisitos:
uint256 c = a * b; requer (c / a == b, "safemath: excesso de multiplicação");
retornar c; }
/**
/ Operator. Nota: Esta função usa umrevert o código de opções (que deixa o gás restante intocado) enquanto a solidez/**
@Dev retorna a divisão inteira de dois números inteiros não assinados. Reverte com a mensagem personalizada em
divisão por zero. O resultado é arredondado para zero.
Contraparte ao Solidity's / Operator. Nota: Esta função usa um
revert o código de opções (que deixa o gás restante intocado) enquanto a solidez
usa um código opcode inválido para reverter (consumindo todo o gás restante).
Requisitos:
retornar c; }
/**
% da solidez. Esta função usa uma revert/**
% da solidez. Esta função usa uma revert// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
@Dev Standard Math Utilities ausentes no idioma da solidez. / biblioteca matemática { / *
/**
/**
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
@Dev pesquisa uma array classificada e retorna o primeiro índice que contém
um valor maior ou igual ao element . Se não existe esse índice (ou seja, todos
Os valores na matriz são estritamente menores que element ), o comprimento da matriz é
retornou. Complexidade do tempo o (log n).
Espera -se que array seja classificada em ordem ascendente e para conter não
elementos repetidos. */ function findUpperBound (UINT256 [] Array de armazenamento, elemento uint256) Vista interna retorna (uint256) {if (array.length == 0) {return 0; }
uint256 baixo = 0; UINT256 High = Array.Length;
while (baixo <alto) {uint256 mid = math.average (baixo, 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;
}
}
// Neste ponto, low é o limite superior exclusivo. Retornaremos o limite superior inclusivo. if (baixo> 0 && Array [baixo - 1] == elemento) {return low - 1; } else {return baixo; }}}
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
@title contadores
@Author Matt Condon (@shrugs)
O @Dev fornece contadores que só podem ser incrementados ou diminuídos por um. Isso pode ser usado, por exemplo, para rastrear o número
de elementos em um mapeamento, emitindo IDs ERC721 ou contando IDs de solicitação.
Incluir no using Counters for Counters.Counter;
Como não é possível transbordar um número inteiro de 256 bits com incrementos de um, increment pode pular o {safemath}
Verificação de transbordamento, economizando o gás. Isso assume o uso correto, pois o _value subjacente nunca é
acessado diretamente. */ contadores da biblioteca {usando o safemath para uint256;
contador struct {// Essa variável nunca deve ser acessada diretamente pelos usuários da biblioteca: as interações devem ser restritas à função da biblioteca. A partir da Solidity v0.5.2, isso não pode ser aplicado, embora exista uma proposta para adicionar // esse recurso: consulte Ethereum/Solidity#4637 UINT256 _Value; // Padrão: 0}
Função atual (contador contador de armazenamento) Retornos de exibição interna (uint256) {return contat._value; }
Incremento da função (contador contador de armazenamento) interno {// A verificação {safemath} sobreflow pode ser ignorada aqui, consulte o comentário no balcão superior._value += 1; }
decremento da função (contador contador de armazenamento) interno {contat._value = contador._value.sub (1); }}
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/*
@Dev fornece informações sobre o contexto atual de execução, incluindo o
remetente da transação e seus dados. Enquanto estes geralmente estão disponíveis
via msg.sender e msg.data, eles não devem ser acessados em tal direto
maneira, desde quando lida com GSN meta-transações, a conta enviando e
Pagar pela execução pode não ser o remetente real (tanto quanto um aplicativo
está preocupado).
Este contrato é necessário apenas para contratos intermediários semelhantes à biblioteca. */ Abstract Contract Context {function _msgsender () Visualização interna Retornos virtuais (endereço a pagar) {return msg.sender; }
função _msgdata () Visualização interna retorna virtual (bytes memória) {this; // Aviso de mutabilidade do estado de silêncio sem gerar bytecode - consulte Ethereum/Solididade#2691 Return msg.data; }}
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
Interface @Dev do padrão ERC20, conforme definido no EIP. / interface ierc20 { / *
/**
account . */ Balance de função (conta de endereço) visualização externa retorna (uint256);/**
amount da conta do chamador para o recipient ./**
spender seráowner através de {transferFrom}. Isso é/**
amount como o subsídio de spender sobre os tokens do chamador./**
amount do sender para o recipient usando oamount é então deduzido do chamador/**
value são movidos de uma conta ( from ) parato ).value pode ser zero. */ transferência de eventos (endereço indexado de, endereço indexado para, valor uint256);/**
spender para um owner é definido porvalue é o novo subsídio. */ aprovação do evento (proprietário indexado por endereço, interrupção indexada de endereço, valor uint256); }// Licença parcial: MIT
Solidez de Pragma ^0,6,2;
/**
Coleção @Dev de funções relacionadas ao endereço de endereço / biblioteca { / *
@dev retorna true se account for um contrato.
[IMPORTANTE]
====
Não é seguro assumir que um endereço para o qual essa função retorna
False é uma conta de propriedade externamente (EOA) e não um contrato.
Entre outros, isContract retornará falso para o seguinte
Tipos de endereços:
==== */ função isContract (Address Conta) View Returns (bool) {// Este método se baseia no ExtCodesize, que retorna 0 para contratos em // de construção, pois o código é armazenado apenas no final da execução // construtor.
tamanho uint256; // SOLHINT-DISABLE-NEXT-LINE ONLINE-MONTA-MOMPLO MONTAGEM {size: = extcodesize (conta)} Tamanho do retorno> 0; }
/**
@Dev Substacting for Solity's transfer : envia amount Wei para
recipient , encaminhando todo o gás disponível e revertendo os erros.
https://eips.ethereum.org/EIPS/EIP-1884 OhEIP1884] Aumenta o custo do gás
de certos códigos de operações, possivelmente fazendo contratos ultrapassarem o limite de gás 2300
imposto pela transfer , tornando -os incapazes de receber fundos via
transfer . {SendValue} remove essa limitação.
https://diligence.consensys.net/postss/2019/09/stop-using-solitys-transfer-now/llearn mais].
Importante: como o controle é transferido para o recipient , o cuidado deve ser
levado para não criar vulnerabilidades de reentrância. Considere usar
{Reentrancyguard} ou o
https://solity.readthedocs.io/en/v0.5.11/security-consideration.html#use-the-checks-effects-interactions-tattern[checks-effects-interactions padrão]. */ function sendValue (endereço de endereço a pagar, valor uint256) interno {requer (endereço (this) .alance> = valor, "endereço: balanço insuficiente");
// Solhint-Disable-next-line Evite-LOW-LEVEL-LEVEL, EVITE-CALL-VALUE (BOOL SUCCEST) = receptor.Call {Value: valor} (""); requer (sucesso, "Endereço: Não é possível enviar valor, o destinatário pode ter revertido"); }
/**
call de baixo nível. UMcall é um substituto inseguro para uma chamada de função: use issotarget reverter com um motivo de reversão, é borbulhado por issotarget deve ser um contrato.target de chamada com data não deve reverter./**
functionCall ], mas comerrorMessage como um fallback reverter a razão quando target reverte./**
functionCall ],value WEI para target .value .payable ./**
functionCallWithValue ], maserrorMessage como um fallback reverter a razão quando target reverte.função _functionCallWithValue (destino de endereço, dados de memória bytes, uint256 weivalue, string memória errorMessage) devoluções privadas (Memória bytes) {require (iscontract (Target), "Endereço: Chamada para não-contrato");
// 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);
}
}
}}
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
@Dev Implementação da interface {ierc20}.
Essa implementação é agnóstica à maneira como os tokens são criados. Isso significa
que um mecanismo de fornecimento deve ser adicionado em um contrato derivado usando {_mint}.
Para um mecanismo genérico, consulte {erc20PresetMinterpaUser}.
Dica: para uma redação detalhada, consulte nosso guia
https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226 Ohhow
Para implementar mecanismos de fornecimento].
Seguimos as diretrizes do General Openzeppelin: as funções revertem em vez disso
de retornar false no fracasso. Este comportamento é, no entanto, convencional
e não entra em conflito com as expectativas dos aplicativos ERC20.
Além disso, um evento {aprovação} é emitido em chamadas para {transferFrom}.
Isso permite que os aplicativos reconstruam o subsídio para todas as contas apenas
Ouvindo os referidos eventos. Outras implementações do EIP não podem emitir
Esses eventos, como não são exigidos pela especificação.
Finalmente, o não-padrão {DimcleSeallowance} e {aumentaseallowance}
funções foram adicionadas para mitigar os problemas bem conhecidos em torno da configuração
subsídios. Veja {ierc20-abordagem}. */ contrato ERC20 é o contexto, ierc20 {usando o safemath para uint256; usando endereço para endereço;
mapeamento (endereço => uint256) _balances privados;
mapeamento (endereço => mapeamento (endereço => uint256)) privado _allowances;
uint256 privado _totalsupply;
string private _name; string private _symbol; uint8 _decimals privados;
/**
/**
/**
/**
decimals for igual 2 , um saldo de 505 tokens deve5,05 ( 505 / 10 ** 2 )./**
/**
/**
recipient não pode ser o endereço zero.amount . */ transferência de função (destinatário de endereço, valor uint256) Retornos de substituição virtual pública (bool) {_transfer (_msgsender (), destinatário, quantidade); retornar true; }/**
/**
spender não pode ser o endereço zero. */ Função Aprovar (Spedo de endereço, valor uint256) Retornos de substituição virtual pública (BOOL) {_Approve (_msgSender (), Spender, quantidade); retornar true; }/**
sender e recipient não podem ser o endereço zero.sender deve ter um saldo de pelo menos amount .sender de pelo menosamount . */ função transferFrom (remetente de endereço, receptor de endereço, valor uint256) Public Virtual Substituir Retornos (BOOL) {_Transfer (remetente, destinatário, valor); _Approve (remetente, _msgSender (), _ROWROURS [remetente] [_ msgsender ()]. retornar true; }/**
spender pelo chamador.spender não pode ser o endereço zero. */ Função crescente (Spender, uint256 Adicionado) retornos virtuais públicos (bool) {_Approve (_msgsender (), Spender, _Arlowances [_msgsender ()] [Spender] .add (AddedValue)); retornar true; }/**
spender pelo chamador.spender não pode ser o endereço zero.spender deve ter um subsídio para o chamador de pelo menossubtractedValue . */ função diminuiLlowance (Spender, uint256 subttrateValue) Retornos virtuais públicos (BOOL) {_Approve (_MSGSender (), Spender, _RoRagonces [_msgSender ()] [Spender] .Sub (subtractValue, "Erc20: diminuição da perito; retornar true; }/**
@dev move amount dos tokens do sender para recipient .
Esta função interna é equivalente a {transfer} e pode ser usada para
por exemplo, implemente taxas de token automáticas, mecanismos de corte, etc.
Emite um evento {transfer}.
Requisitos:
sender não pode ser o endereço zero.recipient não pode ser o endereço zero.sender deve ter um saldo de pelo menos amount . */ função _transfer (remetente de endereço, receptor de endereço, valor uint256) virtual interno {require (remetente! = endereço (0), "erc20: transferência do endereço zero"); requer (destinatário! = Endereço (0), "ERC20: transferência para o endereço zero");_BeforeTokentRansfer (remetente, destinatário, quantidade);
_balances [remetente] = _balances [remetente] .sub (quantidade, "erc20: o valor da transferência excede o saldo"); _balances [destinatário] = _balances [receptor] .add (quantidade); transferência de emitir (remetente, destinatário, quantidade); }
/** @Dev cria tokens amount e os atribui à account , aumentando
a oferta total.
Emite um evento {transfer} com from set para o endereço zero.
Requisitos
to pode ser o endereço zero. */ function _mint (conta de endereço, valor uint256) virtual interno {requer (conta! = endereço (0), "erc20: hortelã para o endereço zero");_BeforeTokentRansfer (endereço (0), conta, valor);
_totalsupply = _totalsupply.add (valor); _balances [conta] = _balances [conta] .add (valor); emitir transferência (endereço (0), conta, valor); }
/**
@dev destrói os tokens amount da account , reduzindo o
fornecimento total.
Emite um evento {transfer} com to definir para o endereço zero.
Requisitos
account não pode ser o endereço zero.account deve ter pelo menos tokens amount . */ function _burn (conta de endereço, valor uint256) virtual interno {requer (conta! = endereço (0), "erc20: queima do endereço zero");_BeforeTokentRansfer (conta, endereço (0), valor);
_balances [conta] = _balances [conta] .sub (quantidade, "erc20: o valor da queima excede o saldo"); _totalsupply = _totalsupply.sub (valor); transferência emit (conta, endereço (0), valor); }
/**
@dev define amount como o subsídio de spender nos tokens do owner .
Esta função interna é equivalente a approve e pode ser usada para
Por exemplo, defina subsídios automáticos para certos subsistemas, etc.
Emite um evento {aprovação}.
Requisitos:
owner não pode ser o endereço zero.spender não pode ser o endereço zero. */ função _APPROVE (proprietário de endereço, Spender de endereço, valor uint256) Virtual interno {requim (proprietário! = Endereço (0), "ERC20: aprovar no endereço zero"); requer (gastador! = endereço (0), "ERC20: aprovar o endereço zero");_ROWROWACES [Proprietário] [Spender] = quantidade; emitir aprovação (proprietário, gastador, quantidade); }
/**
/**
from e to ambos são diferentes de zero, amount de tokens fromto .from zero, amount dos tokens será cunhado to .to zero, amount de tokens from tokens será queimada.from e to nunca são zero.// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
@Dev Este contrato estende um token ERC20 com um mecanismo de instantâneo. Quando um instantâneo é criado, os saldos e
A oferta total na época é registrada para acesso posterior.
Isso pode ser usado para criar mecanismos com segurança com base em saldos de token, como dividendos sem confiança ou votação ponderada.
Em implementações ingênuas, é possível realizar um ataque de "gasto duplo" reutilizando o mesmo equilíbrio de diferentes
Contas. Usando instantâneos para calcular dividendos ou poder de voto, esses ataques não se aplicam mais. Também pode ser
usado para criar um mecanismo de forking ERC20 eficiente.
Os instantâneos são criados pela função interna {_snapshot}, que emitirá o evento {snapshot} e retornará um
ID do instantâneo. Para obter a oferta total no momento de um instantâneo, chame a função {Totalsupplyat} com o instantâneo
eu ia. Para obter o saldo de uma conta no momento de um instantâneo, ligue para a função {balafat} com o ID do instantâneo
e o endereço da conta.
==== Custos de gás
Instantâneos são eficientes. A criação de instantâneos é O (1) . Recuperação de saldos ou suprimento total de um instantâneo é _o (log
n) _ no número de instantâneos que foram criados, embora n para uma conta específica geralmente seja muito
Menores, pois os saldos idênticos nos instantâneos subsequentes são armazenados como uma única entrada.
Há uma sobrecarga constante para transferências normais do ERC20 devido à contabilidade adicional de instantâneos. Esta sobrecarga é
Somente significativo para a primeira transferência que segue imediatamente um instantâneo para uma conta específica. Subsequente
As transferências terão custo normal até o próximo instantâneo e assim por diante. */ abstract contract ERC20Snapshot is ERC20 { // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol
usando o safemath para uint256; usando matrizes para uint256 []; usando contadores para contadores.counter;
// Os valores instantâneos têm matrizes de IDs e o valor correspondente a esse ID. Isso pode ser uma matriz de uma estrutura de instantâneos, mas isso impediria o uso de funções que funcionam em uma matriz. STRUCT instantâneos {uint256 [] ids; valores uint256 []; }
mapeamento (endereço => instantâneos) Private _AccountBalancesNAPShots; Instantâneos privados _totalsupplysnapshots;
// IDs de instantâneos aumentam monotonicamente, com o primeiro valor sendo 1. Um ID de 0 é inválido. Contadores.
/**
id é criado. */ instantâneo do evento (UINT256 ID);/**
@Dev cria um novo instantâneo e retorna seu ID de instantâneo.
Emite um evento {Snapshot} que contém o mesmo ID.
{_snapshot} é internal e você deve decidir como expô -lo externamente. Seu uso pode ser restrito a um
Conjunto de contas, por exemplo, usando {AccessControl}, ou pode estar aberto ao público.
[AVISO]
====
Embora seja necessária uma maneira aberta de chamar {_snapshot} para certos mecanismos de minimização de confiança, como bobinas,
Você deve considerar que ele pode ser potencialmente usado pelos invasores de duas maneiras.
Primeiro, pode ser usado para aumentar o custo de recuperação de valores dos instantâneos, embora cresça
Logaritmicamente, tornando esse ataque ineficaz a longo prazo. Segundo, pode ser usado para segmentar
contas específicas e aumentar o custo da transferência do ERC20 para eles, da maneira especificada nos custos de gás
seção acima.
Não medimos os números reais; Se isso é algo em que você está interessado, entre em contato conosco.
==== */ function _SNAPSHOT () RETURNS VIRTUAL ENTRADO (UINT256) {_CURRINSNAPSHOTID.INCRENT ();
uint256 currentID = _currentsnapshotid.current (); emitir instantâneo (currentID); retornar currentID; }
/**
@Dev recupera o saldo da account no momento em que snapshotId foi criado. */ função balancefat (conta de endereço, uint256 snapshotid) public View Returns (uint256) {(instantâneo bool, uint256 valor) = _valuEat (snapshotid, _accountBalancesnapShots [conta]);
retornar instantâneo? Valor: balancef (conta); }
/**
@Dev recupera a oferta total no momento em que snapshotId foi criado. */ function totalsupplyat (uint256 snapshotid) public View Returns (uint256) {(instantâneo bool, uint256 value) = _valuEat (snapshotid, _totalsupplyplysNapshots);
retornar instantâneo? Valor: TotalSupply (); }
// Atualize o saldo e/ou os instantâneos totais de suprimento antes que os valores sejam modificados. Isso é implementado // no gancho _beforetokentransfer, que é executado para operações _mint, _burn e _transfer. função _beforeTokentransfer (endereço de, endereço para, valor uint256) substituição virtual interna {super._beforetokentransfer (de, a, quantidade);
if (de == endereço (0)) {// Mint _UpDateAcCountSnapshot (to); _UPDATETALSUPPLYSNAPSHOT (); } else if (to == endereço (0)) {// queima _UpDateAcCountsNapShot (de); _UPDATETALSUPPLYSNAPSHOT (); } else {// transfer _upDateAcCountsnapshot (de); _UpDateAcCountsNapShot (to); }}
função _valueat (uint256 snapshotid, instantâneos instantâneos de armazenamento) Retornos de visualização privada (bool, uint256) {requer (snapshotid> 0, "erc20snapshot: id é 0"); // SOLHINT-DISABLE-NEXT-LINE MAX-LINE-LENGLE requer (snapshotid <= _currentsnapshotid.current (), "erc20snapshot: id não existente");
// 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]);
}
}
função _UpDateAcCountSNAPSHOT (conta de endereço) privado {_UpDatesNapShot (_AccountBalancesNAPShots [conta], balancef (conta)); }
função _UpDateTotalSupplysnapshot () private {_UpDatesNapShot (_TotalSupplysNAPShots, TotalSupply ()); }
função _updatesnapshot (instantâneos de armazenamento instantâneos, uint256 currentValue) privado {uint256 currentID = _currentsnapshotid.current (); if (_LastsNAPShotId (snapshots.ids) <currentId) {snapshots.ids.push (currentId); snapshots.values.push (currentValue); }}
função _LASTSNAPSHOTID (UINT256 [] IDs de armazenamento) Vista privada Retornos (uint256) {if (ids.length == 0) {return 0; } else {return ids [ids.length - 1]; }}}
// Licença parcial: MIT
Solidez de Pragma ^0,6,0;
/**
Biblioteca @Dev para gerenciar
https://en.wikipedia.org/wiki/set_(abstract_data_type)
tipos.
Os conjuntos têm as seguintes propriedades:
(O (1)).
Exemplo de contrato {
// Add the library methods
using EnumerableSet for EnumerableSet.AddressSet;
// Declare a set state variable
EnumerableSet.AddressSet private mySet;
}
A partir da v3.0.0, apenas conjuntos de address de tipo ( AddressSet ) e uint256
( UintSet ) são suportados. */ Biblioteca enumerableSet {// Para implementar esta biblioteca para vários tipos com o mínimo de código // repetição possível, escrevemos em termos de um tipo de conjunto genérico com // valores de bytes32. // A implementação do SET usa funções privadas e as implementações voltadas para o usuário (como o endereço de endereço) são apenas embalagens em torno do conjunto // subjacente. // Isso significa que só podemos criar novos enumeráveis para tipos que se encaixam // em bytes32.
conjunto de estruturas {// armazenamento de valores definidos 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 remove um valor de um conjunto. O (1).
Retorna true se o valor foi removido do conjunto, ou seja, se fosse
presente. */ função _Remove (Definir conjunto de armazenamento, Bytes32 Value) Retornos Privados (BOOL) {// Lemos e armazenamos o índice do valor para evitar várias leituras do mesmo slot de armazenamento uint256 valueIndex = set._indexes [valor];
if (valueIndex! = 0) {// equivalente a contém (set, value) // para excluir um elemento da matriz _values em O (1), trocamos o elemento para excluir com o último em // a matriz e depois removemos o último elemento (às vezes chamado de 'troca e pop'). // Isso modifica a ordem da matriz, conforme observado em {em}.
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 posição no conjunto. O (1).index must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(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 . Pode ser usado/**
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();
}
}