0
mapping (address => uint) private userBalances;

function withdrawBalance() public {
    uint amountToWithdraw = userBalances[msg.sender];
    userBalances[msg.sender] = 0;
    (bool success, ) = msg.sender.call.value(amountToWithdraw)(""); // The user's 
balance is already 0, so future invocations won't withdraw anything
    require(success);
}

I understand that the reentrancy attack is not able here since we make the 'userBalances[msg.sender] = 0;' before the call, the attacker cannot repeat the attack indefinitely.

There are 2 problems that I face with this example.

  1. What I cannot understand is how this code is functional since we set 'userBalances[msg. sender] = 0;' before the call, which means that when the next line is executed, the user always withdraws zero amount. What am I missing here?

  2. How is possible for an attacker to call the function '.call' multiple times in this specific example?

1 Answer 1

1

Let's see.

  1. When you assign an integer in Solidity, it copies the value. So regardless of what happens to the origin of the value for amountToWithdraw, the value of amountToWithdraw remains the original value. Therefore it doesn't get set to zero.
  2. Re-entrancy attacks typically happen with Ether fallback functions. So the receiver of the Ether transfer is a contract which calls your example contract again upon receiving Ether. Because msg.sender is used as the target, therefore that address is a contract which A) has a fallback function which triggers on Ether transfers and B) calls the function withdrawBalance (both in the callback and once somewhere else to trigger the re-entrancy attack)

I'm not exactly sure if this answers your questions, but please specify if some part is still unclear.

3
  • Totally understood. One more question on that, As a preventative technique for reentrancy attacks which one is better: checks-effects-interactions pattern or mutex state variable? Thanks
    – CC_Zio
    Commented Mar 21, 2023 at 21:22
  • 1
    mutex costs gas and makes the code harder to understand. Using checks-effects-interactions doesn't cost anything and makes the code easier to understand, so I'd go for that any day. Commented Mar 22, 2023 at 7:34
  • Thanks a lot for the valuable help @Lauri
    – CC_Zio
    Commented Mar 22, 2023 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.