checks-effects-interactions pattern

Objective: Negate Reentrancy attacks

Negative Example

function withdrawToken(uint256 amount) public {
    require(userBalance[msg.sender] >= amount, "requested amount exceeds user balance");
    require(iToken.transferFrom(address(this), msg.sender, amount), "failed on withdrawal");
    userBalance[msg.sender] -= amount;
  • iToken.transferFrom could be maliciously coded to call withdrawToken again,

  • and the contract would transfer iToken out in a loop without modifying the user balance.

  • The attacker would only have to be careful of stopping the loop before running out of gas, and it would drain your contract of iToken.

Positive Example

    function withdraw(uint amount) external {      
        balances[msg.sender] -= amount;
        
        bool success = wmdToken.transfer(msg.sender, amount);
        require(success, "Withdrawal failed!");
        emit Withdrawal(msg.sender, amount);
    }

Further Readings

Last updated