Re-entrancy
reentrancy attack
Last updated
reentrancy attack
Last updated
The goal of this level is for you to steal all the funds from the contract.
Things that might help:
Untrusted contracts can execute code where you least expect it.
Fallback methods
Throw/revert bubbling
Sometimes the best way to attack a contract is with another contract.
See the Help page above, section "Beyond the console"
handles the call()
(interaction) too early in the implementation. This call()
(interaction) is supposed to happen after balances[msg.sender] -= _amount
(effect):
When calling withdraw
it invokes our contract again before resetting the balance, allowing us to enter the contract again with another withdraw action. This is the classic re-entrancy attack.
Enumerate how many ether is stored in the target contract:
The target contract has 0.001 ether, which is 1000000000000000 wei.
Write an attack contract in Remix IDE:
Call donateAndWithdraw()
with msg.value == 1000000000000000
.
Always assume that the receiver of the funds you are sending can be another contract, not just a regular address. Hence, it can execute code in its payable fallback method and re-enter your contract, possibly messing up your state/logic.
Re-entrancy is a common attack. You should always be prepared for it!
This contract fails to follow the pattern. In the withdraw()
function:
In order to prevent re-entrancy attacks when moving funds out of your contract, use the being aware that call
will only return false without interrupting the execution flow. Solutions such as or can also be used.
transfer
and send
are no longer recommended solutions as they can potentially break contracts after the Istanbul hard fork .
The famous DAO hack used reentrancy to extract a huge amount of ether from the victim contract. See .