Unchecked Call Return Value| Solidity Security #1

Sm4rty
3 min readOct 2, 2022

Hey there, I am Samrat Gupta aka Sm4rty, a Smart Contract Auditor and a Bug Bounty Hunter. This is the first blog in Solidity Security Series. In this blog we will learning about Unchecked Call and how it can lead to losses. Lets get started:

Calls in Solidity:

There are a number of ways of performing external calls in Solidity. Sending ether to external accounts is commonly performed via the transfer method. However, the send function can also be used, and for more versatile external calls the CALL opcode can be directly employed in Solidity.

You can send Ether to other contracts by

  • transfer (2300 gas, throws error)
  • send (2300 gas, returns bool)
  • call (forward all gas or set gas, returns bool)

Here we can see that when we use send or call to send ether or perform any transactions, it returns a boolean value i.e. true or false.

Why Unchecked Call value is a Problem?

The call and send functions return a Boolean indicating whether the call succeeded or failed. As a result, if the call return value is not checked, execution will resume even if the called contract throws an exception. If the call fails accidentally or an attacker forces the call to fail, this may cause unexpected behavior in the subsequent program logic.

Code Example:

In the above code, you can see that there is Transfer function that uses call method to transfer amount. Now in first case it doesn’t check for return value, where if the transfer fails also there is no error handling.

In second one, there is check for return value of call. If the call fails it will revert with “transfer failed” message.

Real Life Scenario - Kings of Ether:

Sending ether from one contract to another contract — such as from the King of the Ether contract to an Ethereum Mist “contract-based wallet” contract — is quite likely to fail if implemented in the “obvious” way in the Solidity contract language due to insufficient gas.

This led to failed transfers from Kings of Ether contract to users. But as there was no checks for call return value, a failed transaction was registered as completed transaction in contract.

Mitigations:

If send or call is used, Always make sure to handle the possibility that the call will fail, by checking the return value.

References:

https://swcregistry.io/docs/SWC-104

Connect with me:

Twitter
LinkedIn
Github
Instagram
Hashnode

Thanks for Reading. Any Suggestions are always welcomed!!

--

--

Sm4rty

Smart contract Auditor and Web3 Security Researcher. Interested in Web3 and SmartContract Security.