What is a reentrancy attack in blockchain smart contracts?
A reentrancy attack happens when a smart contract calls another contract that calls back into the original contract before the first call finishes, allowing repeated withdrawals or actions that can drain funds or cause unexpected behavior.
Click to reveal answer
beginner
Why are reentrancy attacks dangerous?
They let attackers repeatedly withdraw funds or manipulate contract state before the contract updates its balance or state, leading to loss of money or corrupted data.
Click to reveal answer
intermediate
What is the common pattern to prevent reentrancy attacks?
Use the 'checks-effects-interactions' pattern: first check conditions, then update state, and only after that interact with other contracts or send funds.
Click to reveal answer
intermediate
How does the 'ReentrancyGuard' contract help prevent attacks?
It uses a lock mechanism to prevent a contract function from being called again before the first call finishes, blocking reentrant calls.
Click to reveal answer
advanced
Give a simple example of a vulnerable Solidity function to reentrancy.
A function that sends Ether to a user before updating their balance, like: <pre>function withdraw(uint amount) public { require(balances[msg.sender] >= amount); (bool success, ) = msg.sender.call{value: amount}(""); require(success); balances[msg.sender] -= amount; }</pre> This allows reentrancy because balance is updated after sending Ether.
Click to reveal answer
What is the main cause of a reentrancy attack?
ASending Ether without a fallback function
BUsing too much gas in a transaction
CNot verifying user input
DCalling an external contract before updating state
✗ Incorrect
Reentrancy attacks happen when a contract calls another contract before updating its own state, allowing the called contract to call back and exploit the original contract.
Which pattern helps prevent reentrancy attacks?
AEvent logging
BChecks-Effects-Interactions
CLazy loading
DGas optimization
✗ Incorrect
The Checks-Effects-Interactions pattern ensures state changes happen before external calls, preventing reentrancy.
What does the ReentrancyGuard contract do?
APrevents multiple calls to a function at the same time
BEncrypts contract data
CLimits gas usage
DAutomatically updates balances
✗ Incorrect
ReentrancyGuard uses a lock to prevent a function from being reentered before the first call finishes.
In Solidity, what is a risky way to send Ether that can cause reentrancy?
AUsing call.value() without updating state first
BUsing transfer() after updating state
CUsing send() with a gas limit
DUsing payable fallback functions
✗ Incorrect
Using call.value() (or call with value) before updating state allows the called contract to reenter and exploit the contract.
Which of these is NOT a way to prevent reentrancy?
AUpdate state before external calls
BUse mutex locks like ReentrancyGuard
CAllow multiple reentrant calls
DAvoid external calls entirely
✗ Incorrect
Allowing multiple reentrant calls is exactly what causes reentrancy attacks, so it is not a prevention method.
Explain what a reentrancy attack is and why it can cause loss of funds in smart contracts.
Think about a contract calling another contract that calls back before state updates.
You got /3 concepts.
Describe the 'checks-effects-interactions' pattern and how it helps prevent reentrancy attacks.
Focus on the order of operations in a function.
You got /4 concepts.
Practice
(1/5)
1. What is a reentrancy attack in blockchain smart contracts?
easy
A. An attack where a contract is called repeatedly before finishing its first call
B. An attack that steals private keys from a wallet
C. An attack that floods the network with transactions
D. An attack that changes the blockchain consensus rules
Solution
Step 1: Understand the concept of reentrancy
Reentrancy happens when a contract allows another call to itself before the first call finishes, causing unexpected behavior.
Step 2: Identify the correct description
An attack where a contract is called repeatedly before finishing its first call correctly describes repeated calls before finishing, which is the core of reentrancy attacks.
Final Answer:
An attack where a contract is called repeatedly before finishing its first call -> Option A
Quick Check:
Repeated calls before finish = Reentrancy attack [OK]
Hint: Look for repeated calls before state update to spot reentrancy [OK]
Common Mistakes:
Confusing reentrancy with key theft
Thinking it floods network instead
Mixing with consensus attacks
2. Which Solidity code snippet correctly prevents reentrancy by updating state before sending Ether?
easy
A. payable(msg.sender).transfer(amount); balances[msg.sender] = 0;
B. require(balances[msg.sender] > 0); payable(msg.sender).transfer(amount);
C. balances[msg.sender] = 0; payable(msg.sender).transfer(amount);
D. balances[msg.sender] += amount; payable(msg.sender).transfer(amount);
Solution
Step 1: Identify the safe order of operations
To prevent reentrancy, update the user's balance before sending Ether to avoid repeated withdrawals.
Step 2: Check each option's order
balances[msg.sender] = 0; payable(msg.sender).transfer(amount); updates balance first, then sends Ether, which is the correct pattern.
Final Answer:
balances[msg.sender] = 0; payable(msg.sender).transfer(amount); -> Option C
Quick Check:
Update state before transfer = Safe pattern [OK]
Hint: Always update balances before sending Ether to avoid reentrancy [OK]
Common Mistakes:
Sending Ether before updating balance
Not checking balance before transfer
Increasing balance instead of resetting
3. Consider this Solidity function snippet:
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount);
payable(msg.sender).transfer(amount);
balances[msg.sender] -= amount;
}
What is the likely outcome if this contract is attacked by a reentrancy exploit?
medium
A. The attacker can withdraw more than their balance multiple times
B. The contract will reject the withdrawal due to require failing
C. The contract will revert due to syntax error
D. The attacker cannot withdraw more than their balance
Solution
Step 1: Analyze the order of operations in withdraw
The contract sends Ether before reducing the balance, allowing reentrant calls to withdraw repeatedly.
Step 2: Understand the attack effect
Because balance is reduced after transfer, attacker can call withdraw again before balance updates, draining funds.
Final Answer:
The attacker can withdraw more than their balance multiple times -> Option A
Quick Check:
Transfer before balance update = Vulnerable to reentrancy [OK]
Hint: Check if balance updates happen after transfer to spot vulnerability [OK]
Common Mistakes:
Assuming require protects fully
Thinking syntax error occurs
Believing attacker can't withdraw extra
4. This Solidity function is vulnerable to reentrancy. What is the best fix?
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount);
payable(msg.sender).transfer(amount);
balances[msg.sender] -= amount;
}
medium
A. Add a loop to call transfer multiple times
B. Remove the require statement
C. Increase balances[msg.sender] after transfer
D. Move balances[msg.sender] -= amount; before transfer call
Solution
Step 1: Identify vulnerability cause
Balance is updated after sending Ether, allowing reentrant calls to exploit the contract.
Step 2: Apply fix by reordering
Moving balance update before transfer prevents reentrancy by blocking repeated withdrawals.
Final Answer:
Move balances[msg.sender] -= amount; before transfer call -> Option D
Quick Check:
Update state before transfer = Fix reentrancy [OK]
Hint: Update balances before sending Ether to fix reentrancy [OK]
Common Mistakes:
Removing require weakens security
Adding loops increases risk
Increasing balance after transfer worsens issue
5. You want to secure a smart contract against reentrancy attacks. Which combination of techniques is best practice?
hard
A. Allow multiple reentrant calls to improve performance
B. Update state before external calls and use a reentrancy guard modifier
C. Use only require statements without updating state
D. Send Ether first, then update state, and avoid using modifiers
Solution
Step 1: Recall best practices for reentrancy protection
Update contract state before external calls and use reentrancy guard modifiers to block repeated calls.
Step 2: Evaluate options
Update state before external calls and use a reentrancy guard modifier combines both safe state update order and reentrancy guard, providing strong protection.
Final Answer:
Update state before external calls and use a reentrancy guard modifier -> Option B
Quick Check:
State update + guard = Best reentrancy defense [OK]
Hint: Combine state update and guard modifier for strong defense [OK]
Common Mistakes:
Sending Ether before state update
Ignoring reentrancy guard usage
Allowing reentrant calls for speed
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.