Ethernaut Puzzle 10 Re-entrancy
This is a classic Reentrancy problem in Solidity, so classic that it has even appeared in the Solidity example code. See here:
https://solidity-by-example.org/hacks/re-entrancy/
The problem code appears in the withdraw
function of the Reentrance smart contract. In this function, we first check if balances[msg.sender] >= _amount
, and then we transfer money to msg.sender
. The msg.sender.call
can be problematic because we don’t know how the receive
or fallback
function in the other smart contract is implemented. Here, our Attack
smart contract implements a method to re-enter the withdraw
function, which leads to the second entry into the Reentrance.withdraw
function. The balances[msg.sender]
is still the original value and has not been changed, which results in more money in the Reentrance contract than what was expected from the original withdraw
.
In theory, it is possible to re-enter indefinitely until all the money in the Reentrance contract is depleted. But because we don’t want to be reverted, we set a targetValue
, and as soon as we get that much money, we withdraw.
Finally, since all the ETH is in this smart contract, we even wrote a withDrawAll
function to transfer all the ETH earned by this smart contract to our account.
1 | // SPDX-License-Identifier: MIT |