Chapter 8 · The Breach Lab · lesson 2
Now make it hold
15 min
Builds on Interfaces and external calls
Chapter 8 · The Breach Lab · lesson 2
15 min
Builds on Interfaces and external calls
You drained that vault. Now make it hold.
The exploit you wrote last lesson is aimed at the vault below. Fix the vault, run the exploit against it, and keep going until the attack fails.
VulnerableVault
? ETH
Checks. Effects. Interactions. In that order, every time.
The vault broke the order: it interacted (sent ETH) before applying the effect (zeroing the balance). Reversing those two lines closes the window entirely.
When the attacker re-enters, bal reads zero and require(bal > 0) reverts the
reentrant call. There is nothing to steal, because the books were already
updated before control ever left the contract.
Ordering is the better fix when you can manage it — it costs no extra gas. But sometimes the logic genuinely cannot be reordered, and then you reach for a reentrancy guard:
modifier nonReentrant() {
require(!locked, "reentrant");
locked = true;
_;
locked = false;
}
This is the wrapping modifier from track 4, and it is exactly what
OpenZeppelin's ReentrancyGuard provides. It sets a flag on the way in and
refuses any call that arrives while the flag is set.
Predict
Check