Consider the following contracts
contract Victim{
//...
function donate() public payable
{
credit[msg.sender] += msg.value;
}
function withdraw(uint amount) public {
if (credit[msg.sender] >= amount)
{
(bool success, ) = msg.sender.call.value(amount)("");
require(success);
credit[msg.sender] -= amount;
}
}
//...
}
contract Attack{
Victim victim;
//...
function () payable {
victim.withdraw.value(0)(balance);
}
}
//...
My question: how do we initiate attack as an end-user?
Scenario 1. First call occurs from an EOA (say Bob), for example using a Javascript library like this attack.withdraw(1)
. Here, Bob calls the withdraw
function and so msg.sender
is Bob's EOA address (assuming Bob signs the transaction with his private key). Inside the withdraw
function we transfer funds to Bob msg.sender.call.value(amount)("");
. But how is Attack
's fallback function called in this case if msg.sender
is not a contract address?
Scenario 2. We call victim.withdraw.value(0)(balance)
from inside Attack
contract. This time around msg.sender
is the contract's address. Inside the withdraw
function there is a check if (credit[msg.sender] >= amount)
. So, does the Attack
contract have to have nonzero balance inside the Victim
contract? I cannot transfer ethers to the contract's address from truffle console: 'Error: Returned error: sender account not recognized'
.