State Change After External Call

Why is this important?

External contracts can take over the control flow. In the reentrancy attack, a malicious contract calls back into the calling contract before an internal state change is performed. This may cause undesirable or incorrect states.

Calling External Contracts Securely

Option A: Perform Internal State Change Before Calling External Contracts

  1. Go through the issues that GuardRails identified in the PR.
  2. Identify the code that looks like this:

     function withdraw(uint amount) public{
         if (credit[msg.sender]>= amount) {
         /* Note that the external contract is called
           before the internal state change. */
         require(msg.sender.call.value(amount)());
         credit[msg.sender]-=amount;
         }
     }
    
  3. Perform the internal state change before calling the contract, like this:

     function withdraw(uint amount) public{
         if (credit[msg.sender]>= amount) {
         credit[msg.sender]-=amount;
         /* Note that the external contract is called
           after the internal state change. */
         require(msg.sender.call.value(amount)());
         }
     }
    
  4. Test it

  5. Ship it 🚢 and relax 🌴

More information: