Bird
Raised Fist0
Blockchain / Solidityprogramming~5 mins

Withdrawal patterns in Blockchain / Solidity - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What is a withdrawal pattern in blockchain smart contracts?
A withdrawal pattern is a design approach where users request to withdraw funds, and the contract lets them pull their funds later, instead of sending funds directly during a transaction. This helps avoid security issues like reentrancy attacks.
Click to reveal answer
beginner
Why is the withdrawal pattern safer than sending funds directly in a smart contract?
Because it separates the action of requesting funds from the actual transfer, it prevents attackers from repeatedly calling the contract during a transfer (reentrancy), which can drain funds.
Click to reveal answer
beginner
In the withdrawal pattern, what is the typical flow for a user to get their funds?
First, the user calls a function to record how much they can withdraw. Then, they call a separate function to actually withdraw their funds, which sends the money safely.
Click to reveal answer
intermediate
What is a reentrancy attack and how does the withdrawal pattern help prevent it?
A reentrancy attack happens when a malicious contract calls back into the vulnerable contract before the first call finishes, causing repeated withdrawals. The withdrawal pattern avoids this by updating balances before sending funds, stopping repeated calls.
Click to reveal answer
intermediate
Give a simple example of a withdrawal pattern in Solidity.
A contract stores user balances. When a user wants to withdraw, the contract sets their balance to zero first, then sends the funds. This order stops reentrancy attacks.
Click to reveal answer
What is the main benefit of using a withdrawal pattern in smart contracts?
APrevents reentrancy attacks by separating withdrawal requests from fund transfers
BMakes transactions faster by sending funds immediately
CAllows unlimited withdrawals without checks
DAutomatically refunds gas fees
In a withdrawal pattern, when are user balances updated?
AAfter sending funds
BOnly when the contract owner approves
CBalances are never updated
DBefore sending funds
Which attack does the withdrawal pattern primarily protect against?
APhishing attack
BReentrancy attack
CSybil attack
D51% attack
What happens if a contract sends funds directly without using a withdrawal pattern?
AIt saves gas fees
BIt is always safe
CIt can be vulnerable to reentrancy attacks
DIt prevents all attacks
Which of these is a key step in implementing a withdrawal pattern?
AUpdate user balance to zero before sending funds
BSend funds first, then update balances
CAllow users to withdraw funds without recording balances
DDisable withdrawals completely
Explain the withdrawal pattern and why it is important in smart contract security.
Think about how withdrawing funds safely can stop attackers from stealing money repeatedly.
You got /3 concepts.
    Describe the steps a smart contract takes when a user withdraws funds using the withdrawal pattern.
    Focus on the order of operations to keep funds safe.
    You got /3 concepts.

      Practice

      (1/5)
      1. What is the main purpose of using a withdrawal pattern in blockchain smart contracts?
      easy
      A. To let users safely withdraw their funds by calling a function
      B. To automatically send funds to users without their request
      C. To increase the contract's balance automatically
      D. To prevent users from withdrawing funds

      Solution

      1. Step 1: Understand withdrawal pattern purpose

        The withdrawal pattern lets users request their funds instead of sending automatically.
      2. Step 2: Identify safety benefits

        This prevents security issues like reentrancy by updating balances before sending.
      3. Final Answer:

        To let users safely withdraw their funds by calling a function -> Option A
      4. Quick Check:

        Withdrawal pattern = user-initiated safe withdrawal [OK]
      Hint: Withdrawal pattern means user calls to get funds safely [OK]
      Common Mistakes:
      • Thinking funds are sent automatically
      • Confusing withdrawal with deposit
      • Ignoring security benefits
      2. Which of the following Solidity code snippets correctly implements the withdrawal pattern?
      easy
      A. function withdraw() public { payable(msg.sender).transfer(balances[msg.sender]); balances[msg.sender] = 0; }
      B. function withdraw() public { payable(msg.sender).transfer(1 ether); }
      C. function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); }
      D. function withdraw() public { balances[msg.sender] += 1 ether; }

      Solution

      1. Step 1: Check balance update before transfer

        function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); } sets balance to zero before sending funds, preventing reentrancy.
      2. Step 2: Verify other options

        function withdraw() public { payable(msg.sender).transfer(balances[msg.sender]); balances[msg.sender] = 0; } sends funds before zeroing balance (unsafe). Options C and D do not handle balances properly.
      3. Final Answer:

        function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); } -> Option C
      4. Quick Check:

        Update balance before transfer = function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); } [OK]
      Hint: Set balance to zero before sending funds [OK]
      Common Mistakes:
      • Sending funds before updating balance
      • Not updating balance at all
      • Sending fixed amounts ignoring user balance
      3. What will be the output if a user calls withdraw() twice in a row on this contract snippet?
      mapping(address => uint) balances;
      
      function withdraw() public {
        uint amount = balances[msg.sender];
        balances[msg.sender] = 0;
        payable(msg.sender).transfer(amount);
      }
      medium
      A. The user receives funds both times
      B. The user receives double the funds on second call
      C. The contract throws an error on second call
      D. The user receives funds only the first time, second call sends zero

      Solution

      1. Step 1: Analyze first withdraw call

        First call reads balance, sends funds, then sets balance to zero.
      2. Step 2: Analyze second withdraw call

        Second call reads balance which is now zero, so sends zero funds.
      3. Final Answer:

        The user receives funds only the first time, second call sends zero -> Option D
      4. Quick Check:

        Balance zero after first withdraw = second call sends zero [OK]
      Hint: Balance zeroed after first withdraw means second sends zero [OK]
      Common Mistakes:
      • Assuming funds sent twice
      • Expecting error on second call
      • Thinking balance resets automatically
      4. Identify the bug in this withdrawal function:
      function withdraw() public {
        payable(msg.sender).transfer(balances[msg.sender]);
        balances[msg.sender] = 0;
      }
      medium
      A. Balance is never updated
      B. Balance is updated after transfer, risking reentrancy attack
      C. Function does not send funds
      D. Function uses wrong address type

      Solution

      1. Step 1: Check order of operations

        The function sends funds before setting balance to zero.
      2. Step 2: Understand security risk

        This allows reentrancy attacks where attacker calls withdraw repeatedly before balance is zeroed.
      3. Final Answer:

        Balance is updated after transfer, risking reentrancy attack -> Option B
      4. Quick Check:

        Update balance before transfer to prevent reentrancy [OK]
      Hint: Always update balance before sending funds [OK]
      Common Mistakes:
      • Updating balance after transfer
      • Ignoring reentrancy risks
      • Not using payable correctly
      5. You want to implement a withdrawal pattern that also logs each withdrawal event with amount and user address. Which of the following Solidity code snippets correctly does this safely?
      hard
      A. event Withdraw(address indexed user, uint amount); function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Withdraw(msg.sender, amount); }
      B. event Withdraw(address indexed user, uint amount); function withdraw() public { payable(msg.sender).transfer(balances[msg.sender]); emit Withdraw(msg.sender, balances[msg.sender]); balances[msg.sender] = 0; }
      C. event Withdraw(address indexed user, uint amount); function withdraw() public { emit Withdraw(msg.sender, balances[msg.sender]); balances[msg.sender] = 0; payable(msg.sender).transfer(balances[msg.sender]); }
      D. event Withdraw(address indexed user, uint amount); function withdraw() public { balances[msg.sender] = 0; emit Withdraw(msg.sender, balances[msg.sender]); payable(msg.sender).transfer(balances[msg.sender]); }

      Solution

      1. Step 1: Check balance update and transfer order

        event Withdraw(address indexed user, uint amount); function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Withdraw(msg.sender, amount); } updates balance before transfer, preventing reentrancy.
      2. Step 2: Verify event emits correct amount

        event Withdraw(address indexed user, uint amount); function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Withdraw(msg.sender, amount); } emits event after transfer with correct amount saved before zeroing balance.
      3. Step 3: Check other options

        The other snippets emit event with wrong amount or update balance after transfer, causing errors or security risks.
      4. Final Answer:

        event Withdraw(address indexed user, uint amount); function withdraw() public { uint amount = balances[msg.sender]; balances[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Withdraw(msg.sender, amount); } -> Option A
      5. Quick Check:

        Update balance, transfer, then emit event with saved amount [OK]
      Hint: Save amount first, update balance, transfer, then emit event [OK]
      Common Mistakes:
      • Emitting event before saving amount
      • Updating balance after transfer
      • Emitting event with zero amount
      Recommended

      Ready to prove it?

      Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

      10 questions~5 mineasy hard