Análise de smart contracts
03.04.2024

Contratos inteligentes com função de Pause

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 Pause.

Os contratos inteligentes com recursos de Pause oferecem a capacidade de interromper temporária ou permanentemente determinadas operações ou funções dentro do contrato. Embora os recursos de pausa possam ser úteis para segurança e manutenção, também representam um risco potencial se forem explorados por fraudadores. Para te protegeres e identificares potenciais ameaças, tens de compreender os riscos, os esquemas de fraude comuns e como os reconhecer num contrato inteligente.

Os perigos dos contratos inteligentes com uma função Pause:

  • Pausa não autorizada: Os autores de fraudes podem obter o controlo da função Pausa e interromper o contrato sem a devida autorização, o que pode resultar em perturbações da atividade ou perdas financeiras.

  • Atrasos enganosos: Os contratos maliciosos podem suspender transacções críticas, como levantamentos ou transferências, sob o pretexto de manutenção temporária ou de medidas de segurança, com a intenção de negar aos utilizadores o acesso aos seus activos.

  • Falsas alegações de emergências: Os autores de fraudes podem alegar falsamente emergências ou vulnerabilidades para justificar a suspensão de um contrato e depois utilizar os fundos dos utilizadores durante a pausa.

  • Pretexto de segurança: Os contratos maliciosos podem alegar que foi descoberta uma vulnerabilidade de segurança, o que resulta na ativação da função de suspensão. Na realidade, os autores de fraudes podem pretender tirar partido da situação.

  • Esquemas de emergência: Os burlões podem utilizar uma linguagem ou cenários que induzam o medo, como uma "tentativa de assalto" ou uma "emergência", para justificar uma pausa durante a qual podem cometer actos ilegais.

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

Se quiseres determinar a presença de funções de Pause em contratos inteligentes por ti próprio, as dicas seguintes serão úteis para o fazeres.

  1. Examina o código-fonte do contrato para ver se existe uma funcionalidade de Pause. Assegura-te de que o mecanismo de pausa está bem documentado e possui controlos de acesso adequados.

  2. Descobre quem controla a função Pause. A posse não autorizada ou não verificada da função Pause é um problema potencial.

  3. Familiariza-te com a documentação e a especificação do projeto para garantir que fornece informações claras e precisas sobre a função Pause, a sua finalidade e as circunstâncias em que pode ser utilizada.

  4. Verifica a transparência da utilização da função Pause. Assegura-te de que existem procedimentos claros para gerir e decidir se a Pause deve ser activada ou desactivada.

  5. Presta atenção às auditorias externas à segurança dos contratos inteligentes, especialmente ao mecanismo de pausa. Os auditores devem avaliar a segurança e a transparência da função Pause.

  6. Observa o comportamento do contrato e certifica-te de que a função Pause só é activada em circunstâncias legítimas, por exemplo, por razões de manutenção ou de segurança.

  7. Interage com a comunidade do projeto e outros utilizadores para compreender as suas experiências e desafios na utilização da funcionalidade Pause.

  8. 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).

Para detetar uma funcionalidade potencialmente maliciosa num contrato inteligente com uma funcionalidade de pausa, efectua a devida diligência e examina o código e a documentação do projeto. Evita contratos com comportamento suspeito ou falta de transparência relativamente à utilização da funcionalidade Pause.

O scanner de segurança do Lotus Market encontra todos os recursos comuns (incluindo os ocultos) do Pause 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 funcionalidade Pause que a Lotus Market Platform encontra com sucesso.

quiseres determinar a presença

Exemplo 1: Função básica Pause


    contract BasicPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Dicas de identificação: Procura um contrato com funções como pausar e despausar ou funções semelhantes que possam alternar o estado de pausa.

Verifica se existe um modificador do tipo whenNotPaused aplicado a determinadas funções para garantir que só podem ser executadas quando o contrato não está suspenso.

Verifica o mecanismo de controlo do acesso, que deve permitir que apenas o proprietário ou pessoas autorizadas suspendam e revoguem a suspensão do contrato.

Exemplo 2: Pausa activada por tempo


    contract TimeActivatedPauseToken {
        address public owner;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(uint256 _duration) {
            owner = msg.sender;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Dicas de identificação: Procura um contrato com um mecanismo de pausa ativado por tempo, em que a pausa e o cancelamento da pausa tenham uma duração específica.

Verifica se existe um modificador do tipo whenNotPaused aplicado a determinadas funções. Certifica-te de que o contrato impõe a duração da pausa e permite que esta seja cancelada apenas depois de decorrido o período de tempo especificado.

Ao identificar características de Pause num contrato inteligente, é fundamental examinar o código, os controlos de acesso e a finalidade do mecanismo de pausa. Analisa cuidadosamente a documentação e o modelo de gestão do contrato e interage com a comunidade do projeto para avaliar a legitimidade do contrato e se este é adequado à sua finalidade. Tem sempre cuidado e efectua as devidas diligências antes de participares em qualquer transação ou investimento que envolva contratos suspensos.

pausa activada por tempo

Exemplo 3: Função de pausa condicional


    contract ConditionalPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner
        }
    }

Dicas de identificação: Procura um contrato com um mecanismo de pausa condicional que permita ao proprietário efetuar determinadas transacções mesmo que o contrato esteja suspenso.

Verifica se o modificador de tipo whenNotPaused se aplica a funções que exigem que o contrato esteja num estado não pausado.

Exemplo 4: Função de pausa de emergência


    contract EmergencyPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function emergencyPause() public {
            require(msg.sender == owner, "Only the owner can initiate emergency pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner
        }
    }

Dicas de identificação: Procura um contrato com uma função de pausa de emergência que permita ao proprietário suspender imediatamente o contrato, mesmo sem os procedimentos de suspensão normais.

Verifica se existe um modificador do tipo whenNotPaused para determinar quais as operações que são restringidas quando o contrato é suspenso.

Presta atenção às características de pausa de emergência do contrato e assegura que a sua utilização é rigorosamente controlada e bem documentada.

Faz corresponder as funções de suspensão do contrato ao seu modelo de governação e aos processos de tomada de decisão para ativar e desativar a função de suspensão.

Exemplo 5: Pausa controlada pelo proprietário com limite de tempo


    contract TimedPauseToken {
        address public owner;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(uint256 _duration) {
            owner = msg.sender;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Dicas de identificação: Procura um contrato com uma pausa controlada pelo proprietário que inclua uma duração específica da pausa e o cancelamento da pausa.

Verifica se existe um modificador do tipo whenNotPaused aplicado às funções adequadas para restringir as operações quando o contrato é suspenso.

pausa controlada pelo proprietário com limite de tempo

Exemplo 6: Pausa de terceiros com limite de tempo


    contract ThirdPartyTimedPauseToken {
        address public owner;
        address public thirdParty;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(address _thirdParty, uint256 _duration) {
            owner = msg.sender;
            thirdParty = _thirdParty;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner || msg.sender == thirdParty, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == thirdParty, "Only the third party can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == thirdParty, "Only the third party can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner and the third party
        }
    }

Dicas de identificação: Procura um contrato com um mecanismo de suspensão gerido por terceiros, em que o terceiro pode suspender e desligar o contrato com uma duração definida.

Verifica se existe um modificador do tipo whenNotPaused para determinar que operações são restringidas quando um contrato é suspenso.

Assegura que os mecanismos de controlo do acesso às funcionalidades de pausa no contrato, quer sejam propriedade do proprietário, geridos pela comunidade ou por terceiros, são transparentes e bem concebidos.

Quando uma função de Pause é identificada num contrato inteligente, deve ser realizada uma análise exaustiva do código, os controlos de acesso devem ser testados e a finalidade e o modelo de controlo do mecanismo de Pause devem ser compreendidos. É fundamental realizar a devida diligência e envolver-se com a comunidade do projeto para avaliar a legitimidade do contrato e se este é adequado à sua finalidade. Tem sempre cuidado e faz uma pesquisa adequada antes de celebrares contratos que ofereçam uma opção de pausa para mitigar potenciais riscos.

 

Esperamos que estes exemplos te tenham ajudado a compreender melhor o esquema da função Pause nos 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