Quick Guide to the "Checks Effect Interactions" Pattern to Remember when writing your Smart Contracts!

Quick Guide to the "Checks Effect Interactions" Pattern to Remember when writing your Smart Contracts!

Although it is commonly understood that data in a blockchain cannot be edited or deleted once it is added (which is true!) that does not mean a blockchain network is completely secure! Knowing the vulnerability of the blockchain network and taking measures to block illicit activity is still needed.

A possible attack vector is a re-entrancy attack, in which the malicious contract is reentering the initial contract before the first instance of the function containing the call is finished. Example is

function widthdrawAllMoney(address payable _to) public {
//checking the balance of user in the network (check)
         unit balanceToSend = balanceReceived[msg.sender];             

//transferring the balance to the user (interaction with smart contract)
         _to.transfer(balanceToSend);                                                     

//setting balance of user to zero (effect on the network)
        balanceReveived[msg.sender] = 0;                                           
}

In the above simple scenario, we have to transfer all the money of the user back to the account the user passes to the function. The function then checks the balance of the user who is initiating the function, transfers the balance in his account to the requested address and then eventually sets the balance of the user to zero.

Here, we are first checking the balance, transferring the crypto and then setting the balance to zero. This is a check-interact-effect method. And this is where a malicious user can perform a re-entrancy attack in a way that the crypto can be transferred to the address multiple times - called as recursive send pattern. And this has happened in the past! You can read all about this here. The DAO was hacked for a whopping $150M!

There is a simple and trivial way out, we can edit the code as below:

function widthdrawAllMoney(address payable _to) public {
//checking the balance of user in the network (check)
         unit balanceToSend = balanceReceived[msg.sender];             

//setting balance of user to zero (effect on the network)
        balanceReveived[msg.sender] = 0;  

//transferring the balance to the user (interaction with smart contract)
         _to.transfer(balanceToSend);                                                     
}

The difference here is that we first perform the check (how much balance is in users account), perform the necessary effect FIRST (bring the balance of user back to zero) and THEN we interact with the blockchain to transfer the crypto!

This is the check-effect-interaction best practice.

Found it interesting? You can read more about it here!