Falha na Inicialização (Failure to Initialize)
Ocorre quando um contrato não é corretamente inicializado antes de seu uso, deixando variáveis críticas, como o endereço do proprietário ou configurações essenciais, em estados padrão. Isso pode permitir que qualquer usuário assuma o controle do contrato ou que ele funcione de maneira inesperada.
Exemplo:
Imagine um contrato inteligente que deveria ser inicializado com o endereço do proprietário (owner), que possui privilégios especiais como pausar ou destruir o contrato. Se o contrato não tiver um construtor que defina esse proprietário, ou se for implantado via proxy sem uma função de inicialização adequada, a variável owner
pode permanecer no valor padrão — como o endereço 0x0
ou outro endereço padrão.
contract VulnerableContract {
address public owner;
function initialize(address _owner) external {
owner = _owner;
}
function pauseContract() external {
require(msg.sender == owner, "Not the contract owner");
// Lógica para pausar el contrato
}
}
Neste exemplo, se a função initialize
não for chamada após o contrato ser implantado, a variável owner
permanecerá não definida, permitindo que qualquer usuário potencialmente chame initialize
e se defina como proprietário, assumindo o controle do contrato.
Mitigação:
Uso de um construtor: Caso o contrato não utilize o padrão proxy e seja implantado diretamente, é altamente recomendável usar um construtor para inicializar variáveis críticas como
owner
. O construtor garante que essas variáveis sejam definidas no momento da implantação e não possam ser modificadas posteriormente.contract SecureContract { address public owner; constructor(address _owner) { owner = _owner; } function pauseContract() external { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar el contrato } }
Inicialização em proxies: Quando se utiliza o padrão proxy para implantar contratos (uma prática comum para facilitar atualizações), é fundamental incluir uma função de inicialização que garanta que o contrato só possa ser inicializado uma única vez. Essa função deve ser protegida para que possa ser chamada apenas uma vez e não possa ser reutilizada por um atacante.
contract SecureContract { address public owner; bool private initialized; function initialize(address _owner) external { require(!initialized, "Already initialized"); owner = _owner; initialized = true; } function pauseContract() external { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar el contrato } }
Proteção contra a re-inicialização: Além de garantir que a função de inicialização só possa ser executada uma única vez, é possível implementar um modificador que verifique se o contrato já foi inicializado antes de permitir a execução de funções críticas.
modifier onlyInitialized() { require(initialized, "Contract not initialized"); _; } function pauseContract() external onlyInitialized { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar el contrato }
Last updated
Was this helpful?