So, I'm learning advanced smart contract development. Two days ago, I learned about Reentrancy attacks and then I also created two contracts Protocol.sol
(vulnerable contract) + Hacker.sol
(attacker contract) to put my knowledge to the test. I was able to perform everything smoothly, I was importing the Protocol.sol (ABI + address) contract in my Hacker.sol
. Today, I learned that we can call another smart contract function without importing the ABI, just using the contract address via ".call" & delegate call.
So, again to put my knowledge to the test, I used Protocol.sol & Hacker.sol.
Protocol.sol
:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract Protocol {
mapping(address => uint256) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw() public payable {
require(balances[msg.sender] > 0, "BRUH");
(bool success, ) = (msg.sender).call{value: 1 ether}("");
require(success);
balances[msg.sender] = 0;
}
function getBalance() public view returns(uint256) {
return address(this).balance;
}
}
Hacker.sol
:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract Hacker {
function protocolDeposit(address protocol) public payable {
(bool success,) = protocol.call{value: msg.value}(abi.encodeWithSignature("deposit()"));
require(success, "call failed");
}
function attack(address protocol) public payable {
(bool hacked,) = protocol.call(abi.encodeWithSignature("withdraw()"));
require(hacked, "attack failed");
}
// fallback() external payable {
// (bool hacked,) = protocol.call(abi.encodeWithSignature("withdraw()"));
// require(hacked, "hack failed");
// }
function rektMoney() public view returns(uint256) {
return address(this).balance;
}
}
The problem, I am facing right now is calling withdraw()
func. I am able to deposit ETH using Hacker.sol
into Protocol.sol
but I'm unable to call withdraw()
using attack
Maybe it is because the withdraw
func in the protocol.sol
is also using call
to transfer ETH.
How to ".call" a function of another contract which is using ".call" as well?
How I can solve this problem? Pls Help, Thanks in Advance
I need to implement receive
or fallback
function in order to receive money in the hacker contract.
fallback() external payable {}
Working now Alhumdulilah