Unchecked Return Values

The foundation of the Web3 ecosystem is built upon three core technologies: blockchain, smart contracts, and decentralized applications. While these innovations have ushered in a new era of possibilities, they’ve also become a target for cybercriminals. Hackers relentlessly seek out weaknesses, particularly within the code of smart contracts.
A seemingly insignificant oversight, like failing to verify return values, can trigger catastrophic breaches. In this exploration, we’ll delve into the root causes of this vulnerability and explore effective mitigation strategies.
What are the risks?
The return value of a function in a smart contract acts as an indicator of its success or failure. Ignoring this value is like closing our eyes to the outcome of an operation, potentially allowing the contract to work with incorrect data and lead to unforeseen consequences.
Let’s imagine the following scenario
We have two smart contracts:
- Contract A: Its primary task is to initiate a specific action. To do this, it calls a function in contract B.
- Contract B: Performs a specific operation required by contract A. Upon completion, it returns a value indicating the result of the operation: success, failure, or a detailed error description.
What happens if contract A ignores the return value of contract B?
Contract A continues running, assuming that the operation in contract B was successful. However, if there was actually an error, the following actions of contract A can lead to unpredictable and potentially dangerous consequences.
Why does this happen?
When smart contracts interact with each other to perform certain tasks, they use external calls. Different functions like send(), call(), and transfer() are used for this. However, each of these functions has its own way of handling errors:
- The functions
send()
andcall()
return a true or false value, showing if the operation was successful. A common mistake made by developers is ignoring this returned value. If the external call fails, these functions won’t undo the whole transaction, they’ll just returnfalse
. - Unlike them, the function
transfer()
will automatically cancel the whole transaction if the external call fails, making it more reliable for sending Ether.
Example with Сode
Let’s look at the whitelistedTokensDistribution
contract.
pragma solidity ^0.8.0;
contract whitelistedTokensDistribution {
bool public isPayoutComplete = false;
address public whitelistedAddress;
uint public tokensAmount;
function sendTokenToWhitelisted public {
require(!isPayoutComplete);
whitelistedAddress.send(tokensAmount);
isPayoutComplete = true;
}
function withdrawLeftoverFunds public {
require(isPayoutComplete);
msg.sender.send(this.balance);
}
}
The main problem with this contract is that it uses the send()
function without checking if it worked. This creates a security issue: if there’s a problem sending the tokens (like not having enough gas or if there’s a bad function where the tokens should go), the contract will still think the payment was made.
Because of this, anyone can take the leftover money, even if the payment wasn’t actually sent.
Security Best Practices
- Always check the return values of
send()
andcall()
functions. If they returnfalse
, something went wrong, and appropriate actions should be taken. - Prefer
transfer()
oversend()
. It is a safer option as the transaction will be reverted on failure. - Use events to track important actions within the contract, especially those related to transfers and errors.
- Always consider gas consumption when performing operations in the contract. Ensure the user has enough gas to complete the transaction.
- Leverage well-audited libraries such as OpenZeppelin’s SafeMath or similar tools that provide built-in checks for arithmetic operations and external calls.
- Instead of direct transfers, use a withdrawal pattern where users must call a separate function to withdraw funds. This pattern allows the contract to better manage state changes and gracefully handle failures.
Regular audits of smart contracts are equally crucial for security, particularly to identify potential risks stemming from unchecked return values.
Identified Vulnerabilities
Let’s take a look at some of the victims who have been affected by this attack.
- Fyde May https://solodit.xyz/issues/m-03-low-level-call-is-not-checked-in-swapon1inch-pashov-audit-group-none-fyde-may-markdown
- Zokyo https://solodit.xyz/issues/validators-with-dust-collateral-can-join-the-network-zokyo-none-interplanetary-consensus-ipc-markdown
- Reality Cards https://solodit.xyz/issues/h-01-unchecked-erc20-transfers-can-cause-lock-up-code4rena-reality-cards-reality-cards-contest-git
- Mass https://solodit.xyz/issues/risk-of-unlimited-slippage-in-nesteddca-swaps-trailofbits-none-mass-pdf
- 1inch Limit Order Protocol https://solodit.xyz/issues/h03-malicious-maker-could-take-advantage-of-partial-fills-to-steal-takers-assets-openzeppelin-1inch-limit-order-protocol-audit-markdown
Conclusion
Contents
YOU MAY ALSO LIKE

What is Solana Storage?
Education
Discover Solana's unique approach to blockchain storage with an in-depth exploration of its Programs and Accounts model.

Defending Against DoS: Strategies to Prevent Denial of Service Attacks in Smart Contracts
Education
Explore how DoS attacks like Unexpected Reverts, Block Gas Limits, and Block Stuffing disrupt Solidity smart contracts. Learn security methods to safeguard your blockchain projects.

Why Smart Contract Audits are Non-Negotiable
Education
Unlock Web3's full potential by securing your smart contracts. Learn why audits are essential, explore real-world risks, and see how Oxor.io fortifies your blockchain projects against threats.

Mastering Access Control Issue: Ensuring Only Authorized Interactions with Your Contract
Education
Explore how access control vulnerabilities led to the $7 million GAMEE Token hack. Learn from code examples, discover prevention strategies, and see how OXORIO can secure your blockchain projects.
Have a question?
Stay Connected with OXORIO
We're here to help and guide you through any inquiries you might have about blockchain security and audits.