What is the Checks-Effects-Interactions pattern in smart contract programming?
It is a design pattern that helps prevent security issues by first checking conditions, then updating the contract's state, and finally interacting with other contracts or external addresses.
Click to reveal answer
beginner
Why do we perform checks before effects and interactions in the Checks-Effects-Interactions pattern?
Performing checks first ensures that the function only proceeds if conditions are met, preventing wasted work or vulnerabilities. It helps avoid unexpected behavior or attacks.
Click to reveal answer
beginner
In the Checks-Effects-Interactions pattern, what does 'effects' mean?
Effects refer to updating the contract's internal state, like changing balances or flags, after all checks pass but before interacting with external contracts.
Click to reveal answer
intermediate
What kind of vulnerabilities does the Checks-Effects-Interactions pattern help prevent?
It helps prevent reentrancy attacks, where an external contract calls back into the original contract before the state is updated, causing inconsistent or malicious behavior.
Click to reveal answer
beginner
Show the correct order of steps in the Checks-Effects-Interactions pattern.
What is the first step in the Checks-Effects-Interactions pattern?
ASend funds to users
BUpdate the contract's state
CInteract with external contracts
DPerform checks to validate conditions
✗ Incorrect
The pattern starts by performing checks to ensure conditions are met before any state changes or interactions.
Why should state changes happen before interactions in this pattern?
ATo save gas fees
BTo prevent reentrancy attacks
CTo make the contract faster
DTo allow multiple interactions
✗ Incorrect
Updating state before interactions prevents attackers from exploiting reentrancy by calling back before state updates.
Which vulnerability is most directly mitigated by the Checks-Effects-Interactions pattern?
AReentrancy attack
BDenial of service
CPhishing attack
DInteger overflow
✗ Incorrect
The pattern is designed to prevent reentrancy attacks by controlling the order of operations.
What happens if you interact with external contracts before updating your state?
AIt can cause inconsistent state or vulnerabilities
BIt saves gas
CNothing special
DIt improves security
✗ Incorrect
Interacting first can allow external contracts to reenter and exploit the contract before state updates.
Which of these is NOT part of the Checks-Effects-Interactions pattern?
AInteractions
BEffects
CLoops
DChecks
✗ Incorrect
Loops are not a step in this pattern; the pattern focuses on checks, effects, and interactions.
Explain the Checks-Effects-Interactions pattern and why it is important in smart contract security.
Think about the order of operations and how attackers might exploit the contract.
You got /4 concepts.
Describe a simple example scenario where following the Checks-Effects-Interactions pattern prevents a security problem.
Imagine sending money to a user and what could go wrong if you don't update balances first.
You got /4 concepts.
Practice
(1/5)
1.
What is the main purpose of the Checks-Effects-Interactions pattern in smart contracts?
easy
A. To reduce the gas cost of transactions
B. To prevent reentrancy attacks by ordering operations safely
C. To increase the speed of contract execution
D. To allow contracts to call external APIs
Solution
Step 1: Understand the pattern's purpose
The Checks-Effects-Interactions pattern is designed to prevent security issues by ordering operations carefully.
Step 2: Identify the main security benefit
By checking conditions first, updating state second, and interacting last, it prevents reentrancy attacks.
Final Answer:
To prevent reentrancy attacks by ordering operations safely -> Option B
Quick Check:
Pattern purpose = Prevent reentrancy [OK]
Hint: Remember: check first, update second, interact last [OK]
Common Mistakes:
Thinking it speeds up contract execution
Believing it reduces gas costs
Assuming it enables external API calls
2.
Which of the following Solidity code snippets correctly follows the Checks-Effects-Interactions pattern?
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount);
(bool success, ) = msg.sender.call{value: amount}('');
require(success);
balances[msg.sender] -= amount;
}
easy
A. Yes, it checks, then interacts, then effects
B. Yes, it updates state before checks
C. No, it interacts before updating state
D. No, it updates state before interaction
Solution
Step 1: Analyze the order of operations
The code first checks the balance, then calls the external address, then updates the balance.
Step 2: Compare with pattern order
The pattern requires checks, then effects (state update), then interactions. Here, interaction happens before effects.
Final Answer:
No, it interacts before updating state -> Option C
Quick Check:
Interaction before effect = Incorrect order [OK]
Hint: State update must come before external calls [OK]
Common Mistakes:
Ignoring the order of state update and interaction
Thinking checks alone are enough
Confusing effects with interactions
3.
What will be the output of the following Solidity function if balances[msg.sender] is 100 and amount is 50?
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
(bool success, ) = msg.sender.call{value: amount}('');
require(success);
}
Assume the call succeeds.
medium
A. The balance becomes 50 and 50 ether is sent
B. The balance remains 100 and 50 ether is sent
C. The balance becomes 50 but no ether is sent
D. Transaction reverts due to incorrect order
Solution
Step 1: Check balance and update state
The require passes since 100 >= 50, then balance is reduced to 50.
Step 2: Send ether and confirm success
The call sends 50 ether and returns success, so require(success) passes.
Final Answer:
The balance becomes 50 and 50 ether is sent -> Option A
Quick Check:
Balance updated then ether sent = Correct [OK]
Hint: State updates before sending ether means balance changes [OK]
Common Mistakes:
Thinking balance stays the same after withdrawal
Assuming call fails without reason
Confusing order causing revert
4.
Identify the bug in this Solidity function violating the Checks-Effects-Interactions pattern:
function withdraw(uint amount) public {
(bool success, ) = msg.sender.call{value: amount}('');
require(success);
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
}
medium
A. It correctly follows the pattern
B. It updates balance before checking conditions
C. It does not check for call success
D. It calls external address before checking balance
Solution
Step 1: Review order of operations
The function calls the external address first, then checks balance, then updates state.
Step 2: Compare with pattern rules
Pattern requires checks first, then effects, then interactions. Here, interaction is first, violating the pattern.
Final Answer:
It calls external address before checking balance -> Option D
Quick Check:
Interaction before checks = Bug [OK]
Hint: Always check before calling external contracts [OK]
Common Mistakes:
Ignoring the order of require and call
Assuming call success check is missing
Thinking balance update order is wrong
5.
You want to write a Solidity function that sends a reward to a user only if they have enough points. Which code snippet correctly applies the Checks-Effects-Interactions pattern?