Análise de smart contracts
23.01.2024

Contratos inteligentes com a função BlackList

Continuamos a série de artigos dedicados à descrição de esquemas fraudulentos em contratos inteligentes. Hoje vamos analisar os contratos inteligentes com a função Black List (BlackList).

Os perigos dos contratos inteligentes com a funcionalidade BlackList:

Os contratos inteligentes que incluem uma funcionalidade de lista negra acarretam certos riscos e problemas tanto para o projeto como para os seus utilizadores. Aqui estão alguns dos perigos associados às funcionalidades de lista negra:

  1. Controlo centralizado: As funções de lista negra fornecem frequentemente um controlo centralizado ao proprietário ou aos administradores do contrato.

  2. Abuso da lista negra para práticas desleais: Os abusadores (incluindo o titular do contrato) podem utilizar a lista negra para visar endereços específicos. Isso pode incluir o congelamento ou a restrição da funcionalidade de contas sem uma boa razão.

  3. Falta de transparência: A presença de uma função de lista negra, especialmente se não estiver documentada, pode levar a uma falta de transparência. Os utilizadores podem não estar cientes dos critérios da lista negra ou do procedimento de lista negra.

  4. Riscos de segurança: Se a BlackList não for implementada de forma segura, existe o risco de vulnerabilidades que podem permitir que pessoas não autorizadas manipulem a lista negra, o que pode levar ao congelamento ou à transferência não autorizada de fundos.

  5. Confiança do utilizador: A existência de uma funcionalidade de lista negra pode minar a confiança do utilizador porque os seus bens podem ser colocados numa lista negra sem regras claras.

  6. Confisco de tokens: Os atacantes podem utilizar uma lista negra para confiscar tokens ou activos de determinados endereços sem a devida justificação. Isto pode resultar em perdas financeiras significativas.

Como é que podes determinar de forma independente se essas ameaças estão presentes nos contratos inteligentes?

Ao validar um contrato inteligente, podem ser tomadas certas medidas para determinar se existe uma ameaça associada a funcionalidades de lista negra:

  • Antes de começares a trabalhar com um contrato inteligente, lê e estuda cuidadosamente o seu código, incluindo quaisquer características relacionadas com a colocação em lista negra. Procura características relacionadas com a colocação na lista negra, o congelamento ou a restrição da funcionalidade da conta. Verifica se existem características que te permitam adicionar ou remover endereços da lista negra.

  • Analisar quem detém a propriedade ou o controlo administrativo do contrato. Avaliar o grau de controlo e os direitos associados ao proprietário ou aos administradores.

  • Examina a documentação do contrato para compreender como se pretende utilizar a função de inclusão na lista negra. Procura informações sobre os mecanismos de governação que controlam a utilização da colocação na lista negra.

  • Avalia a transparência: O contrato garante que os critérios de inclusão na lista negra são transparentes? Verifica se existem procedimentos claros para eliminar os falsos positivos ou retirar endereços da lista negra.

  • Auditorias de segurança: verifica se o contrato inteligente foi submetido a auditorias de segurança por empresas terceiras de renome.

  • Familiariza-te com os comentários da comunidade ou dos fóruns em linha sobre a utilização de listas negras no projeto. Fica atento a quaisquer sinais de alerta levantados pelos membros da comunidade sobre práticas injustas ou falta de transparência.

  • Ao realizar uma análise minuciosa e tendo em conta os factores acima referidos, estarás mais apto a avaliar os riscos associados às funcionalidades de lista negra em contratos inteligentes. Mantém-te a par dos últimos desenvolvimentos na nossa comunidade (canal Telegram) e das melhores práticas para a deteção de fraudes (o nosso Blogue e canal YouTube).

 

Boas notícias: o nosso Security Scanner encontra todas as funcionalidades comuns (incluindo as ocultas) da Lista Negra (BlackList) 99,9% das vezes. Utiliza a nossa subscrição premium e protege os teus fundos contra ameaças.

 

De seguida, vamos analisar alguns dos exemplos mais comuns da função BlackList que a nossa Plataforma detecta com sucesso.

Nota que estes são exemplos simplificados e que a implementação real pode ser diferente. Ao analisar contratos inteligentes, deves sempre efetuar uma revisão completa do código e considerar factores dependentes do contexto.

Exemplo 1: Funcionalidade básica da Lista Negra


contract TokenWithBlackListAndFee {
    address public owner;
    mapping(address => bool) public BlackList;
    uint256 public BlackListFee;

    constructor(uint256 _fee) {
        owner = msg.sender;
        BlackListFee = _fee;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListWithFee(address _account) public payable onlyOwner {
        require(msg.value >= BlackListFee, "Insufficient fee");
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Procura funções (por exemplo, addToBlackList e removeFromBlackList) que tenham modificadores de acesso (onlyOwner). A presença de tais modificadores significa que apenas o Proprietário pode modificar a lista negra.

common tips

Exemplo 2: Mecanismo de lista negra com taxa (BlackList com taxa)


contract TokenWithBlackListAndFee {
    address public owner;
    mapping(address => bool) public BlackList;
    uint256 public BlackListFee;

    constructor(uint256 _fee) {
        owner = msg.sender;
        BlackListFee = _fee;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListWithFee(address _account) public payable onlyOwner {
        require(msg.value >= BlackListFee, "Insufficient fee");
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Define funções (como addToBlackListWithFee) que requerem uma taxa (msg.value) para serem colocadas na lista negra. Este é um sinal muito perigoso.

Exemplo 3: Lista negra com condições dependentes do tempo


contract TokenWithTimeLock {
    address public owner;
    mapping(address => bool) public BlackList;
    uint256 public BlackListTimeLock;

    constructor(uint256 _timeLock) {
        owner = msg.sender;
        BlackListTimeLock = _timeLock;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListTimed(address _account) public onlyOwner {
        require(block.timestamp >= BlackListTimeLock, "Time lock not yet expired");
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Define funções (por exemplo, addToBlackListTimed) que impõem condições dependentes do tempo de bloqueio na lista negra. Isto é normalmente utilizado para listas negras atrasadas ou programadas.

Exemplo 4: Lista negra com registo de eventos


contract TokenWithBlackListAndEvents {
    address public owner;
    mapping(address => bool) public BlackList;

    event AddressAddedToBlackList(address indexed account);
    event AddressRemovedFromBlackList(address indexed account);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackList(address _account) public onlyOwner {
        BlackList[_account] = true;
        emit AddressAddedToBlackList(_account);
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
        emit AddressRemovedFromBlackList(_account);
    }
}

Dicas de deteção:Registo de eventos: Procura eventos que registem acções de colocação na lista negra. Os eventos proporcionam transparência e são muito importantes para monitorizar as acções do contrato. Pode dizer-se que este é o tipo mais seguro de BlackList porque os programadores não escondem esta funcionalidade, mas registam abertamente todas as suas chamadas nos registos de eventos.

Exemplo 5: Lista negra com função de lista branca (Whitelist)


contract TokenWithBlackListAndWhitelist {
    address public owner;
    mapping(address => bool) public BlackList;
    mapping(address => bool) public whitelist;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the lists");
        _;
    }

    function addToBlackList(address _account) public onlyOwner {
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }

    function addToWhitelist(address _account) public onlyOwner {
        whitelist[_account] = true;
    }

    function removeFromWhitelist(address _account) public onlyOwner {
        whitelist[_account] = false;
    }
}

Dicas de deteção:Funcionalidade de lista branca: Presta atenção aos contratos que têm simultaneamente funcionalidades de lista negra e de lista branca. Esta dupla funcionalidade pode ter implicações para transferências de fichas sem o conhecimento do proprietário ou outras actividades fraudulentas.

common tips

Exemplo 6: Colocação na lista negra com controlo de governação (Controlo de Governação)


interface Governance {
    function canBlackList(address _caller) external view returns (bool);
}

contract TokenWithGovernanceControl {
    address public owner;
    address public governanceContract;
    mapping(address => bool) public BlackList;

    constructor(address _governanceContract) {
        owner = msg.sender;
        governanceContract = _governanceContract;
    }

    modifier onlyOwnerOrGovernance() {
        require(msg.sender == owner || Governance(governanceContract).canBlackList(msg.sender), "Not authorized");
        _;
    }

    function addToBlackListGoverned(address _account) public onlyOwnerOrGovernance {
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwnerOrGovernance {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Identifica os contratos em que as actividades de colocação na lista negra estão sujeitas ao controlo de gestores de contratos externos. Ao considerar um contrato inteligente, analisa cuidadosamente o código, prestando atenção aos controlos de acesso, mecanismos de pagamento, termos e condições dependentes do tempo, registo de eventos, protecções anti-circunvenção e outros factores importantes. Além disso, considera as especificidades do projeto e os seus objectivos quando avaliares as implicações da utilização da funcionalidade de lista negra.

Exemplo 7: Lista negra com paragem de emergência


contract TokenWithEmergencyStop {
    address public owner;
    bool public emergencyStop;
    mapping(address => bool) public BlackList;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    modifier whenNotPaused() {
        require(!emergencyStop, "Contract is paused");
        _;
    }

    function addToBlackList(address _account) public onlyOwner whenNotPaused {
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner whenNotPaused {
        BlackList[_account] = false;
    }

    function toggleEmergencyStop() public onlyOwner {
        emergencyStop = !emergencyStop;
    }
}

Dicas de deteção:O mecanismo de pausa por colisão pode colocar em pausa algumas funcionalidades, incluindo alterações à lista negra.

Exemplo 8: Lista negra com condições dinâmicas


contract TokenWithDynamicBlackList {
    address public owner;
    mapping(address => bool) public BlackList;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function conditionallyBlackList(address _account, uint256 _threshold) public onlyOwner {
        require(getBalance(_account) < _threshold, "Account balance exceeds threshold");
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Muitas vezes, as listas negras podem basear-se em determinadas condições ou eventos. Estuda cuidadosamente as funções que são verificadas antes de activares a lista negra. Estas funções contêm a lógica para adicionar o proprietário à lista negra. Neste exemplo, a condição para adicionar é que o saldo da conta seja superior ao limite especificado.

Exemplo 9: Lista negra com remoção bloqueada por tempo (Remoção bloqueada por tempo)


contract TokenWithTimeLockedRemoval {
    address public owner;
    mapping(address => bool) public BlackList;
    mapping(address => uint256) public removalTimeLock;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackList(address _account) public onlyOwner {
        BlackList[_account] = true;
        removalTimeLock[_account] = block.timestamp + 7 days;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        require(block.timestamp >= removalTimeLock[_account], "Time lock not expired");
        BlackList[_account] = false;
        removalTimeLock[_account] = 0;
    }
}

Dicas de deteção:Identifica os contratos em que a remoção da lista negra é limitada no tempo. Muitas vezes, nestes casos, são utilizados cálculos de tempo baseados em block.timestamp.

Exemplo 10: Lista negra com proteção do limite de gás (proteção do limite de gás)


contract TokenWithGasLimitProtection {
    address public owner;
    mapping(address => bool) public BlackList;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    modifier limitGas() {
        require(gasleft() >= 100000, "Insufficient gas");
        _;
    }

    function addToBlackListGasLimited(address _account) public onlyOwner limitGas {
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }
}

Dicas de deteção:Identifica os contratos em que certas funções, como a inclusão na lista negra, estão sujeitas a limites de gás.

common tips

Exemplo 11: Lista negra com integração externa com a Oracle (Oracle)


interface Oracle {
    function isBlackListed(address _account) external view returns (bool);
}

contract TokenWithOracleIntegration {
    address public owner;
    Oracle public oracle;

    constructor(address _oracleAddress) {
        owner = msg.sender;
        oracle = Oracle(_oracleAddress);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListByOracle(address _account) public onlyOwner {
        require(oracle.isBlackListed(_account), "Oracle did not confirm BlackListing");
    }
}

Dicas de deteção:Tem cuidado com os contratos que dependem de oráculos externos para tomar decisões de colocação na lista negra. Verifica sempre a fiabilidade e a transparência dos oráculos que um contrato inteligente utiliza.

Exemplo 12: Colocação na lista negra com interação com um contrato externo


interface ExternalContract {
    function addToBlackList(address _account) external;
    function removeFromBlackList(address _account) external;
}

contract TokenWithExternalInteraction {
    address public owner;
    ExternalContract public externalContract;

    constructor(address _externalContract) {
        owner = msg.sender;
        externalContract = ExternalContract(_externalContract);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListExternal(address _account) public onlyOwner {
        externalContract.addToBlackList(_account);
    }

    function removeFromBlackListExternal(address _account) public onlyOwner {
        externalContract.removeFromBlackList(_account);
    }
}            

Dicas de deteção:Ao tomar decisões de colocação na lista negra, tem cuidado com os contratos que interagem com contratos externos, especialmente se o código-fonte do contrato externo não for verificado.

Exemplo 13: Lista negra com limiar dinâmico (limiar dinâmico)


contract TokenWithDynamicThreshold {
    address public owner;
    mapping(address => bool) public BlackList;
    uint256 public dynamicThreshold;

    constructor(uint256 _initialThreshold) {
        owner = msg.sender;
        dynamicThreshold = _initialThreshold;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can modify the BlackList");
        _;
    }

    function addToBlackListDynamicThreshold(address _account) public onlyOwner {
        require(getBalance(_account) > dynamicThreshold, "Account balance is below threshold");
        BlackList[_account] = true;
    }

    function removeFromBlackList(address _account) public onlyOwner {
        BlackList[_account] = false;
    }

    function updateDynamicThreshold(uint256 _newThreshold) public onlyOwner {
        dynamicThreshold = _newThreshold;
    }
}

Dicas de deteção:Identifica os contratos em que o limiar de colocação na lista negra é dinâmico e pode ser definido pelo proprietário ao longo do tempo (chamando determinados métodos de contrato).

Dicas gerais para identificar características da Lista Negra (BlackList)

  1. Procura funções que modificam a lista de endereços (mapeamento):
    Examina o código do contrato inteligente para identificar as funções que modificam a lista de endereços, como adicionar ou remover endereços.

  2. Verifica se há acesso somente do proprietário:
    As funções da lista negra geralmente têm restrições de acesso que permitem que apenas o proprietário ou os administradores do contrato as executem. Procura a utilização do modificador onlyOwner ou mecanismos de controlo de acesso semelhantes.

  3. Verifica a função do construtor constructor():
    A função do construtor especifica o estado inicial do contrato. Verifica se quaisquer ligações ou listas de endereços são inicializadas no construtor, indicando uma lista negra.

  4. Explora a lógica dos modificadores:
    Analisa a lógica dos modificadores do tipo onlyOwner para compreender em que condições as funções relacionadas com a lista negra podem ser executadas.

  5. Encontrar termos chave:
    Procura palavras-chave como "BlackList", "addBlackList", "removeBlackList" ou termos semelhantes no código do contrato inteligente (nos casos mais simples estas funções têm nomes semelhantes, em variantes mais complexas os nomes podem não refletir a essência da função para a disfarçar).

  6. Verifica a documentação e os comentários:
    Examina a documentação e os comentários do contrato para ver se há alguma menção a recursos relacionados à lista negra. Os desenvolvedores geralmente fornecem informações sobre como determinados recursos, incluindo a lista negra, devem ser usados.

  7. Verifica chamadas externas (call) ou eventos (event):
    Procura chamadas ou eventos externos que possam ser accionados quando um endereço é adicionado ou removido da lista negra. Isso pode fornecer informações sobre como o contrato interage com componentes externos com base nas ações associadas à lista negra.

  8. Avalia as capacidades de atualização e gestão do código do contrato:
    Avalia o contrato inteligente para mecanismos de atualização ou estruturas de governação que permitam alterações à sua lógica de lista negra. Compreender como as atualizações são gerenciadas é fundamental para antecipar possíveis alterações na funcionalidade da lista negra.

  9. Verifica a lógica da lista negra noutras funções:
    Examina outras funções de contrato para verificações para determinar se um endereço está na lista negra antes de executar determinadas ações.

  10. Descobre os casos de utilização e a tokenomics:
    Compreende os cenários de utilização e a tokenomics do projeto. Se o projeto estiver relacionado com a gestão de endereços de utilizadores ou tiver funcionalidades relacionadas com os direitos dos utilizadores, poderá haver uma razão para ativar a lista negra.

  11. Registo de eventos:
    Observa a existência de um registo de eventos associado a acções de lista negra. Os eventos são freqüentemente usados para registrar mudanças significativas de estado, fornecendo transparência no comportamento do contrato.

  12. Proteção do limite de gás:
    Tem cuidado com as funcionalidades que têm proteção de limite de gás. Embora isso possa ser uma implementação de um recurso de segurança, ele também pode ser usado para controlar ou limitar o desempenho de algumas funções críticas do contrato.

  13. Condições dependentes do tempo:
    Verifica se existem condições dependentes do tempo relacionadas com a colocação na lista negra. Por exemplo, os contratos podem implementar bloqueios de tempo na eliminação ou outros mecanismos sensíveis ao tempo.

  14. Auditorias independentes:
    Procura contratos inteligentes que tenham sido auditados de forma independente por empresas de auditoria de renome. Os relatórios de auditoria fornecem informações sobre a segurança e a funcionalidade do contrato.

  15. Analisa os comentários da comunidade:
    Consulta os fóruns da comunidade, as redes sociais ou os canais de comunicação oficiais para ver se existem discussões sobre a presença e a utilização da funcionalidade de colocação na lista negra. Os utilizadores podem fornecer informações e preocupações valiosas.

common tips

Ao analisar um contrato inteligente, é crucial que tenhas uma compreensão completa das suas características e funcionalidades. Estas dicas vão ajudar-te a identificar e avaliar a presença de uma caraterística de lista negra, permitindo-te tomar decisões informadas sobre a interação com o contrato.

Sempre que possível, escolhe contratos que cumpram as normas estabelecidas (por exemplo, ERC-20). Estas normas são frequentemente controladas e têm uma reputação de fiabilidade.

 

Esperamos que estes exemplos te tenham ajudado a compreender melhor os esquemas de Lista Negra (BlackList) em contratos inteligentes.

 

Uma vez que toda a informação na cadeia de blocos é aberta (desde que, obviamente, o código fonte do contrato seja verificado), munido deste conhecimento podes estudar independentemente os contratos inteligentes e identificar vários esquemas fraudulentos.

No entanto, nós já fizemos tudo isso por ti! Inscreve-te para uma subscrição premium e obtém acesso a filtros exclusivos sobre características de contratos inteligentes e novas análises. Aumenta as tuas hipóteses de investir com sucesso em tokens lucrativos.

Cumprimentos, equipa do Lotus Market.

All posts

Connect to a wallet

Metamask